diff mbox

Commit: AArch64 sim: Add support for FMLA by element

Message ID 87shxv5y3o.fsf@redhat.com
State New
Headers show

Commit Message

Nick Clifton May 6, 2016, 9:34 a.m. UTC
Hi Guys,

  I am applying the patch below to add support for the FMLA (by element)
  instruction to the AArch64 simulator.

Cheers
  Nick

sim/aarch64/ChangeLog
2016-05-06  Nick Clifton  <nickc@redhat.com>

	* simulator.c (do_FMLA_by_element): New function.
	(do_vec_op2): Call it.
diff mbox

Patch

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