diff options
author | Nick Clifton <nickc@redhat.com> | 2016-05-06 10:35:33 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2016-05-06 10:35:33 +0100 |
commit | fd7ed446fbee07c70ebc7d1e92f1ece665d7fc64 (patch) | |
tree | 497fe5576d87e1593eb021acb990920ae9c75bfc | |
parent | 405b757bdf23ea6612e0943bca05297049291612 (diff) | |
download | fsf-binutils-gdb-fd7ed446fbee07c70ebc7d1e92f1ece665d7fc64.zip fsf-binutils-gdb-fd7ed446fbee07c70ebc7d1e92f1ece665d7fc64.tar.gz fsf-binutils-gdb-fd7ed446fbee07c70ebc7d1e92f1ece665d7fc64.tar.bz2 |
Add support for FMLA (by element) to AArch64 sim.
* simulator.c (do_FMLA_by_element): New function.
(do_vec_op2): Call it.
-rw-r--r-- | sim/aarch64/ChangeLog | 5 | ||||
-rw-r--r-- | sim/aarch64/simulator.c | 74 |
2 files changed, 77 insertions, 2 deletions
diff --git a/sim/aarch64/ChangeLog b/sim/aarch64/ChangeLog index f031596..90e501a 100644 --- a/sim/aarch64/ChangeLog +++ b/sim/aarch64/ChangeLog @@ -1,3 +1,8 @@ +2016-05-06 Nick Clifton <nickc@redhat.com> + + * simulator.c (do_FMLA_by_element): New function. + (do_vec_op2): Call it. + 2016-04-27 Nick Clifton <nickc@redhat.com> * simulator.c: Add TRACE_DECODE statements to all emulation diff --git a/sim/aarch64/simulator.c b/sim/aarch64/simulator.c index 2441cce..88cb03d 100644 --- a/sim/aarch64/simulator.c +++ b/sim/aarch64/simulator.c @@ -6034,6 +6034,67 @@ do_vec_MUL_by_element (sim_cpu *cpu) } static void +do_FMLA_by_element (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half/full + instr[29,23] = 00 1111 1 + instr[22] = size + instr[21] = L + instr[20,16] = m + instr[15,12] = 0001 + instr[11] = H + instr[10] = 0 + instr[9,5] = Vn + instr[4,0] = Vd */ + + unsigned full = INSTR (30, 30); + unsigned size = INSTR (22, 22); + unsigned L = INSTR (21, 21); + unsigned vm = INSTR (20, 16); + unsigned H = INSTR (11, 11); + unsigned vn = INSTR (9, 5); + unsigned vd = INSTR (4, 0); + unsigned e; + + NYI_assert (29, 23, 0x1F); + NYI_assert (15, 12, 0x1); + NYI_assert (10, 10, 0); + + TRACE_DECODE (cpu, "emulated at line %d", __LINE__); + if (size) + { + double element1, element2; + + if (! full || L) + HALT_UNALLOC; + + element2 = aarch64_get_vec_double (cpu, vm, H); + + for (e = 0; e < 2; e++) + { + element1 = aarch64_get_vec_double (cpu, vn, e); + element1 *= element2; + element1 += aarch64_get_vec_double (cpu, vd, e); + aarch64_set_vec_double (cpu, vd, e, element1); + } + } + else + { + float element1; + float element2 = aarch64_get_vec_float (cpu, vm, (H << 1) | L); + + for (e = 0; e < (full ? 4 : 2); e++) + { + element1 = aarch64_get_vec_float (cpu, vn, e); + element1 *= element2; + element1 += aarch64_get_vec_float (cpu, vd, e); + aarch64_set_vec_float (cpu, vd, e, element1); + } + } +} + +static void do_vec_op2 (sim_cpu *cpu) { /* instr[31] = 0 @@ -6051,9 +6112,18 @@ do_vec_op2 (sim_cpu *cpu) { switch (INSTR (15, 10)) { + case 0x04: + case 0x06: + do_FMLA_by_element (cpu); + return; + case 0x20: - case 0x22: do_vec_MUL_by_element (cpu); return; - default: HALT_NYI; + case 0x22: + do_vec_MUL_by_element (cpu); + return; + + default: + HALT_NYI; } } else |