X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Faarch64%2Fcpustate.c;h=ce503c62de4a0e2d8511ac281bc11421c6cf4434;hb=af0b2a3e85df9f49a3528e5b7578fcf9412f1acc;hp=86b1b15cb4b7c3859940c3e5942c837adc820f98;hpb=e101a78be9388651099af079899b8654292d24f6;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/aarch64/cpustate.c b/sim/aarch64/cpustate.c index 86b1b15cb4..ce503c62de 100644 --- a/sim/aarch64/cpustate.c +++ b/sim/aarch64/cpustate.c @@ -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. @@ -20,10 +20,12 @@ along with this program. If not, see . */ #include +#include #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 \ - { \ - if (ELEMENT > ARRAY_SIZE (cpu->fr[0].FIELD)) \ +#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; +}