x86: SYSENTER/SYSEXIT are unavailable in 64-bit mode on AMD
[deliverable/binutils-gdb.git] / sim / aarch64 / cpustate.c
index 19f485e81eaf60e587d7f5a805a6a05963ee8796..ce503c62de4a0e2d8511ac281bc11421c6cf4434 100644 (file)
@@ -1,6 +1,6 @@
 /* cpustate.h -- Prototypes for AArch64 simulator functions.
 
-   Copyright (C) 2015-2016 Free Software Foundation, Inc.
+   Copyright (C) 2015-2020 Free Software Foundation, Inc.
 
    Contributed by Red Hat.
 
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <stdio.h>
+#include <math.h>
 
 #include "sim-main.h"
 #include "cpustate.h"
 #include "simulator.h"
+#include "libiberty.h"
 
 /* Some operands are allowed to access the stack pointer (reg 31).
    For others a read from r31 always returns 0, and a write to r31 is ignored.  */
@@ -87,6 +89,46 @@ aarch64_get_reg_s32 (sim_cpu *cpu, GReg reg, int r31_is_sp)
   return cpu->gr[reg_num(reg)].s32;
 }
 
+void
+aarch64_set_reg_s32 (sim_cpu *cpu, GReg reg, int r31_is_sp, int32_t val)
+{
+  if (reg == R31 && ! r31_is_sp)
+    {
+      TRACE_REGISTER (cpu, "GR[31] NOT CHANGED!");
+      return;
+    }
+
+  if (val != cpu->gr[reg].s32)
+    TRACE_REGISTER (cpu, "GR[%2d] changes from %8x to %8x",
+                   reg, cpu->gr[reg].s32, val);
+
+  /* The ARM ARM states that (C1.2.4):
+        When the data size is 32 bits, the lower 32 bits of the
+       register are used and the upper 32 bits are ignored on
+       a read and cleared to zero on a write.
+     We simulate this by first clearing the whole 64-bits and
+     then writing to the 32-bit value in the GRegister union.  */
+  cpu->gr[reg].s64 = 0;
+  cpu->gr[reg].s32 = val;
+}
+
+void
+aarch64_set_reg_u32 (sim_cpu *cpu, GReg reg, int r31_is_sp, uint32_t val)
+{
+  if (reg == R31 && ! r31_is_sp)
+    {
+      TRACE_REGISTER (cpu, "GR[31] NOT CHANGED!");
+      return;
+    }
+
+  if (val != cpu->gr[reg].u32)
+    TRACE_REGISTER (cpu, "GR[%2d] changes from %8x to %8x",
+                   reg, cpu->gr[reg].u32, val);
+
+  cpu->gr[reg].u64 = 0;
+  cpu->gr[reg].u32 = val;
+}
+
 uint32_t
 aarch64_get_reg_u16 (sim_cpu *cpu, GReg reg, int r31_is_sp)
 {
@@ -277,6 +319,21 @@ aarch64_clear_CPSR_bit (sim_cpu *cpu, FlagMask bit)
                    decode_cpsr (old_flags), decode_cpsr (cpu->CPSR));
 }
 
+float
+aarch64_get_FP_half (sim_cpu *cpu, VReg reg)
+{
+  union
+  {
+    uint16_t h[2];
+    float    f;
+  } u;
+
+  u.h[0] = 0;
+  u.h[1] = cpu->fr[reg].h[0];
+  return u.f;
+}
+
+
 float
 aarch64_get_FP_float (sim_cpu *cpu, VReg reg)
 {
@@ -296,10 +353,27 @@ aarch64_get_FP_long_double (sim_cpu *cpu, VReg reg, FRegister *a)
   a->v[1] = cpu->fr[reg].v[1];
 }
 
+void
+aarch64_set_FP_half (sim_cpu *cpu, VReg reg, float val)
+{
+  union
+  {
+    uint16_t h[2];
+    float    f;
+  } u;
+
+  u.f = val;
+  cpu->fr[reg].h[0] = u.h[1];
+  cpu->fr[reg].h[1] = 0;
+}
+
+
 void
 aarch64_set_FP_float (sim_cpu *cpu, VReg reg, float val)
 {
-  if (val != cpu->fr[reg].s)
+  if (val != cpu->fr[reg].s
+      /* Handle +/- zero.  */
+      || signbit (val) != signbit (cpu->fr[reg].s))
     {
       FRegister v;
 
@@ -315,7 +389,9 @@ aarch64_set_FP_float (sim_cpu *cpu, VReg reg, float val)
 void
 aarch64_set_FP_double (sim_cpu *cpu, VReg reg, double val)
 {
-  if (val != cpu->fr[reg].d)
+  if (val != cpu->fr[reg].d
+      /* Handle +/- zero.  */
+      || signbit (val) != signbit (cpu->fr[reg].d))
     {
       FRegister v;
 
@@ -345,7 +421,7 @@ aarch64_set_FP_long_double (sim_cpu *cpu, VReg reg, FRegister a)
 #define GET_VEC_ELEMENT(REG, ELEMENT, FIELD)      \
   do                                              \
     {                                             \
-      if (element >= ARRAY_SIZE (cpu->fr[0].FIELD)) \
+      if (ELEMENT >= ARRAY_SIZE (cpu->fr[0].FIELD)) \
        {                                                               \
          TRACE_REGISTER (cpu, \
                          "Internal SIM error: invalid element number: %d ",\
@@ -418,12 +494,12 @@ aarch64_get_vec_double (sim_cpu *cpu, VReg reg, unsigned element)
 }
 
 
-#define SET_VEC_ELEMENT(REG, ELEMENT, VAL, FIELD, PRINTER)     \
-  do                                                           \
-    {                                                          \
+#define SET_VEC_ELEMENT(REG, ELEMENT, VAL, FIELD, PRINTER)             \
+  do                                                                   \
+    {                                                                  \
       if (ELEMENT >= ARRAY_SIZE (cpu->fr[0].FIELD))                    \
        {                                                               \
-         TRACE_REGISTER (cpu, \
+         TRACE_REGISTER (cpu,                                          \
                          "Internal SIM error: invalid element number: %d ",\
                          ELEMENT);                                     \
          sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu), \
@@ -434,31 +510,31 @@ aarch64_get_vec_double (sim_cpu *cpu, VReg reg, unsigned element)
                        "VR[%2d]." #FIELD " [%d] changes from " PRINTER \
                        " to " PRINTER , REG,                           \
                        ELEMENT, cpu->fr[REG].FIELD [ELEMENT], VAL);    \
-      \
-      cpu->fr[REG].FIELD [ELEMENT] = VAL;     \
-    }                                        \
+                                                                       \
+      cpu->fr[REG].FIELD [ELEMENT] = VAL;                              \
+    }                                                                  \
   while (0)
 
 void
-aarch64_set_vec_u64 (sim_cpu * cpu, VReg reg, unsigned element, uint64_t val)
+aarch64_set_vec_u64 (sim_cpu *cpu, VReg reg, unsigned element, uint64_t val)
 {
   SET_VEC_ELEMENT (reg, element, val, v, "%16lx");
 }
 
 void
-aarch64_set_vec_u32 (sim_cpu * cpu, VReg reg, unsigned element, uint32_t val)
+aarch64_set_vec_u32 (sim_cpu *cpu, VReg reg, unsigned element, uint32_t val)
 {
   SET_VEC_ELEMENT (reg, element, val, w, "%8x");
 }
 
 void
-aarch64_set_vec_u16 (sim_cpu * cpu, VReg reg, unsigned element, uint16_t val)
+aarch64_set_vec_u16 (sim_cpu *cpu, VReg reg, unsigned element, uint16_t val)
 {
   SET_VEC_ELEMENT (reg, element, val, h, "%4x");
 }
 
 void
-aarch64_set_vec_u8 (sim_cpu * cpu, VReg reg, unsigned element, uint8_t val)
+aarch64_set_vec_u8 (sim_cpu *cpu, VReg reg, unsigned element, uint8_t val)
 {
   SET_VEC_ELEMENT (reg, element, val, b, "%x");
 }
@@ -541,3 +617,24 @@ aarch64_test_FPSR_bit (sim_cpu *cpu, FPSRMask flag)
 {
   return cpu->FPSR & flag;
 }
+
+uint64_t
+aarch64_get_thread_id (sim_cpu *cpu)
+{
+  return cpu->tpidr;
+}
+
+uint32_t
+aarch64_get_FPCR (sim_cpu *cpu)
+{
+  return cpu->FPCR;
+}
+
+void
+aarch64_set_FPCR (sim_cpu *cpu, uint32_t val)
+{
+  if (cpu->FPCR != val)
+    TRACE_REGISTER (cpu,
+                   "FPCR changes from %x to %x", cpu->FPCR, val);
+  cpu->FPCR = val;
+}
This page took 0.037022 seconds and 4 git commands to generate.