aboutsummaryrefslogtreecommitdiff
path: root/sim/aarch64
diff options
context:
space:
mode:
authorJim Wilson <jim.wilson@linaro.org>2017-02-25 20:06:36 -0800
committerJim Wilson <jim.wilson@linaro.org>2017-02-25 20:06:36 -0800
commit152e1e1bc90030cec9ce8318ab982675b1e90a00 (patch)
tree2268a3a64f01cdb436aa410784fb077e9b94daef /sim/aarch64
parentac189e7bf8865d61b4f5e89a530476f9e4c5c70b (diff)
downloadgdb-152e1e1bc90030cec9ce8318ab982675b1e90a00.zip
gdb-152e1e1bc90030cec9ce8318ab982675b1e90a00.tar.gz
gdb-152e1e1bc90030cec9ce8318ab982675b1e90a00.tar.bz2
Add missing smov support, and clean up existing umov support.
sim/aarch64/ * simulator.c (do_vec_SMOV_into_scalar): New. (do_vec_UMOV_into_scalar): Renamed from do_vec_MOV_into_scalar. Rewritten. (do_vec_UMOV): Merged into do_vec_UMOV_into_scalar and deleted. (do_vec_op1): Move do_vec_TRN call and do_vec_UZP call. Add do_vec_SMOV_into_scalar call. Delete do_vec_MOV_into_scalar and do_vec_UMOV calls. Add do_vec_UMOV_into_scalar call. sim/testsuite/sim/aarch64/ * sumov.s: New.
Diffstat (limited to 'sim/aarch64')
-rw-r--r--sim/aarch64/ChangeLog8
-rw-r--r--sim/aarch64/simulator.c201
2 files changed, 134 insertions, 75 deletions
diff --git a/sim/aarch64/ChangeLog b/sim/aarch64/ChangeLog
index 243ec0e..b6c0256 100644
--- a/sim/aarch64/ChangeLog
+++ b/sim/aarch64/ChangeLog
@@ -1,5 +1,13 @@
2017-02-25 Jim Wilson <jim.wilson@linaro.org>
+ * simulator.c (do_vec_SMOV_into_scalar): New.
+ (do_vec_UMOV_into_scalar): Renamed from do_vec_MOV_into_scalar.
+ Rewritten.
+ (do_vec_UMOV): Merged into do_vec_UMOV_into_scalar and deleted.
+ (do_vec_op1): Move do_vec_TRN call and do_vec_UZP call. Add
+ do_vec_SMOV_into_scalar call. Delete do_vec_MOV_into_scalar and
+ do_vec_UMOV calls. Add do_vec_UMOV_into_scalar call.
+
* simulator.c (popcount): New.
(do_vec_CNT): New.
(do_vec_op1): Add do_vec_CNT call.
diff --git a/sim/aarch64/simulator.c b/sim/aarch64/simulator.c
index f430159..1756ba1 100644
--- a/sim/aarch64/simulator.c
+++ b/sim/aarch64/simulator.c
@@ -2620,43 +2620,149 @@ do_vec_MOV_whole_vector (sim_cpu *cpu)
}
static void
-do_vec_MOV_into_scalar (sim_cpu *cpu)
+do_vec_SMOV_into_scalar (sim_cpu *cpu)
{
/* instr[31] = 0
instr[30] = word(0)/long(1)
instr[29,21] = 00 1110 000
- instr[20,18] = element size and index
- instr[17,10] = 00 0011 11
+ instr[20,16] = element size and index
+ instr[15,10] = 00 0010 11
instr[9,5] = V source
instr[4,0] = R dest */
unsigned vs = INSTR (9, 5);
unsigned rd = INSTR (4, 0);
+ unsigned imm5 = INSTR (20, 16);
+ unsigned full = INSTR (30, 30);
+ int size, index;
NYI_assert (29, 21, 0x070);
- NYI_assert (17, 10, 0x0F);
+ NYI_assert (15, 10, 0x0B);
TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
- switch (INSTR (20, 18))
+
+ if (imm5 & 0x1)
+ {
+ size = 0;
+ index = (imm5 >> 1) & 0xF;
+ }
+ else if (imm5 & 0x2)
{
- case 0x2:
- aarch64_set_reg_u64 (cpu, rd, NO_SP, aarch64_get_vec_u64 (cpu, vs, 0));
+ size = 1;
+ index = (imm5 >> 2) & 0x7;
+ }
+ else if (full && (imm5 & 0x4))
+ {
+ size = 2;
+ index = (imm5 >> 3) & 0x3;
+ }
+ else
+ HALT_UNALLOC;
+
+ switch (size)
+ {
+ case 0:
+ if (full)
+ aarch64_set_reg_s64 (cpu, rd, NO_SP,
+ aarch64_get_vec_s8 (cpu, vs, index));
+ else
+ aarch64_set_reg_s32 (cpu, rd, NO_SP,
+ aarch64_get_vec_s8 (cpu, vs, index));
break;
- case 0x6:
- aarch64_set_reg_u64 (cpu, rd, NO_SP, aarch64_get_vec_u64 (cpu, vs, 1));
+ case 1:
+ if (full)
+ aarch64_set_reg_s64 (cpu, rd, NO_SP,
+ aarch64_get_vec_s16 (cpu, vs, index));
+ else
+ aarch64_set_reg_s32 (cpu, rd, NO_SP,
+ aarch64_get_vec_s16 (cpu, vs, index));
break;
- case 0x1:
- case 0x3:
- case 0x5:
- case 0x7:
- aarch64_set_reg_u64 (cpu, rd, NO_SP, aarch64_get_vec_u32
- (cpu, vs, INSTR (20, 19)));
+ case 2:
+ aarch64_set_reg_s64 (cpu, rd, NO_SP,
+ aarch64_get_vec_s32 (cpu, vs, index));
break;
default:
- HALT_NYI;
+ HALT_UNALLOC;
+ }
+}
+
+static void
+do_vec_UMOV_into_scalar (sim_cpu *cpu)
+{
+ /* instr[31] = 0
+ instr[30] = word(0)/long(1)
+ instr[29,21] = 00 1110 000
+ instr[20,16] = element size and index
+ instr[15,10] = 00 0011 11
+ instr[9,5] = V source
+ instr[4,0] = R dest */
+
+ unsigned vs = INSTR (9, 5);
+ unsigned rd = INSTR (4, 0);
+ unsigned imm5 = INSTR (20, 16);
+ unsigned full = INSTR (30, 30);
+ int size, index;
+
+ NYI_assert (29, 21, 0x070);
+ NYI_assert (15, 10, 0x0F);
+
+ TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
+
+ if (!full)
+ {
+ if (imm5 & 0x1)
+ {
+ size = 0;
+ index = (imm5 >> 1) & 0xF;
+ }
+ else if (imm5 & 0x2)
+ {
+ size = 1;
+ index = (imm5 >> 2) & 0x7;
+ }
+ else if (imm5 & 0x4)
+ {
+ size = 2;
+ index = (imm5 >> 3) & 0x3;
+ }
+ else
+ HALT_UNALLOC;
+ }
+ else if (imm5 & 0x8)
+ {
+ size = 3;
+ index = (imm5 >> 4) & 0x1;
+ }
+ else
+ HALT_UNALLOC;
+
+ switch (size)
+ {
+ case 0:
+ aarch64_set_reg_u32 (cpu, rd, NO_SP,
+ aarch64_get_vec_u8 (cpu, vs, index));
+ break;
+
+ case 1:
+ aarch64_set_reg_u32 (cpu, rd, NO_SP,
+ aarch64_get_vec_u16 (cpu, vs, index));
+ break;
+
+ case 2:
+ aarch64_set_reg_u32 (cpu, rd, NO_SP,
+ aarch64_get_vec_u32 (cpu, vs, index));
+ break;
+
+ case 3:
+ aarch64_set_reg_u64 (cpu, rd, NO_SP,
+ aarch64_get_vec_u64 (cpu, vs, index));
+ break;
+
+ default:
+ HALT_UNALLOC;
}
}
@@ -5363,55 +5469,6 @@ do_vec_ADDP (sim_cpu *cpu)
}
static void
-do_vec_UMOV (sim_cpu *cpu)
-{
- /* instr[31] = 0
- instr[30] = 32-bit(0)/64-bit(1)
- instr[29,21] = 00 1110 000
- insrt[20,16] = size & index
- instr[15,10] = 0011 11
- instr[9,5] = V source
- instr[4,0] = R dest. */
-
- unsigned vs = INSTR (9, 5);
- unsigned rd = INSTR (4, 0);
- unsigned index;
-
- NYI_assert (29, 21, 0x070);
- NYI_assert (15, 10, 0x0F);
-
- TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
- if (INSTR (16, 16))
- {
- /* Byte transfer. */
- index = INSTR (20, 17);
- aarch64_set_reg_u64 (cpu, rd, NO_SP,
- aarch64_get_vec_u8 (cpu, vs, index));
- }
- else if (INSTR (17, 17))
- {
- index = INSTR (20, 18);
- aarch64_set_reg_u64 (cpu, rd, NO_SP,
- aarch64_get_vec_u16 (cpu, vs, index));
- }
- else if (INSTR (18, 18))
- {
- index = INSTR (20, 19);
- aarch64_set_reg_u64 (cpu, rd, NO_SP,
- aarch64_get_vec_u32 (cpu, vs, index));
- }
- else
- {
- if (INSTR (30, 30) != 1)
- HALT_UNALLOC;
-
- index = INSTR (20, 20);
- aarch64_set_reg_u64 (cpu, rd, NO_SP,
- aarch64_get_vec_u64 (cpu, vs, index));
- }
-}
-
-static void
do_vec_FABS (sim_cpu *cpu)
{
/* instr[31] = 0
@@ -5598,15 +5655,8 @@ do_vec_op1 (sim_cpu *cpu)
case 0x01: do_vec_DUP_vector_into_vector (cpu); return;
case 0x03: do_vec_DUP_scalar_into_vector (cpu); return;
case 0x07: do_vec_INS (cpu); return;
- case 0x0A: do_vec_TRN (cpu); return;
-
- case 0x0F:
- if (INSTR (17, 16) == 0)
- {
- do_vec_MOV_into_scalar (cpu);
- return;
- }
- break;
+ case 0x0B: do_vec_SMOV_into_scalar (cpu); return;
+ case 0x0F: do_vec_UMOV_into_scalar (cpu); return;
case 0x00:
case 0x08:
@@ -5618,6 +5668,8 @@ do_vec_op1 (sim_cpu *cpu)
case 0x16:
do_vec_UZP (cpu); return;
+ case 0x0A: do_vec_TRN (cpu); return;
+
case 0x0E:
case 0x1E:
do_vec_ZIP (cpu); return;
@@ -5632,7 +5684,6 @@ do_vec_op1 (sim_cpu *cpu)
case 0x6: do_vec_UZP (cpu); return;
case 0xE: do_vec_ZIP (cpu); return;
case 0xA: do_vec_TRN (cpu); return;
- case 0xF: do_vec_UMOV (cpu); return;
default: HALT_NYI;
}
}