diff options
author | Jim Wilson <jim.wilson@linaro.org> | 2016-06-30 09:10:41 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2016-06-30 09:10:41 +0100 |
commit | c7be441465094e5ffce2f4205ea887676965d0be (patch) | |
tree | da0afb6462365bfbfb9d7d1f52ca56887096f419 | |
parent | 6e2565079204ae2d2c0a5fa15fcd233e9c614f0b (diff) | |
download | gdb-c7be441465094e5ffce2f4205ea887676965d0be.zip gdb-c7be441465094e5ffce2f4205ea887676965d0be.tar.gz gdb-c7be441465094e5ffce2f4205ea887676965d0be.tar.bz2 |
Add support for simulating big-endian AArch64 binaries.
* cpustate.h: Include config.h.
(union GRegisterValue): Add WORDS_BIGENDIAN check. For big endian code
use anonymous structs to align members.
* simulator.c (aarch64_step): Use sim_core_read_buffer and
endian_le2h_4 to read instruction from pc.
-rw-r--r-- | sim/aarch64/ChangeLog | 8 | ||||
-rw-r--r-- | sim/aarch64/cpustate.h | 25 | ||||
-rw-r--r-- | sim/aarch64/simulator.c | 6 |
3 files changed, 30 insertions, 9 deletions
diff --git a/sim/aarch64/ChangeLog b/sim/aarch64/ChangeLog index 90e501a..2d9a9d2 100644 --- a/sim/aarch64/ChangeLog +++ b/sim/aarch64/ChangeLog @@ -1,3 +1,11 @@ +2016-06-30 Jim Wilson <jim.wilson@linaro.org> + + * cpustate.h: Include config.h. + (union GRegisterValue): Add WORDS_BIGENDIAN check. For big endian code + use anonymous structs to align members. + * simulator.c (aarch64_step): Use sim_core_read_buffer and + endian_le2h_4 to read instruction from pc. + 2016-05-06 Nick Clifton <nickc@redhat.com> * simulator.c (do_FMLA_by_element): New function. diff --git a/sim/aarch64/cpustate.h b/sim/aarch64/cpustate.h index 07446a2..fc0c68b 100644 --- a/sim/aarch64/cpustate.h +++ b/sim/aarch64/cpustate.h @@ -22,6 +22,7 @@ #ifndef _CPU_STATE_H #define _CPU_STATE_H +#include "config.h" #include <sys/types.h> #include <stdint.h> #include <inttypes.h> @@ -123,16 +124,14 @@ typedef enum VReg } VReg; /* All the different integer bit patterns for the components of a - general register are overlaid here using a union so as to allow all - reading and writing of the desired bits. - - N.B. the ARM spec says that when you write a 32 bit register you - are supposed to write the low 32 bits and zero the high 32 - bits. But we don't actually have to care about this because Java - will only ever consume the 32 bits value as a 64 bit quantity after - an explicit extend. */ + general register are overlaid here using a union so as to allow + all reading and writing of the desired bits. Note that we have + to take care when emulating a big-endian AArch64 as we are + running on a little endian host. */ + typedef union GRegisterValue { +#if !WORDS_BIGENDIAN int8_t s8; int16_t s16; int32_t s32; @@ -141,6 +140,16 @@ typedef union GRegisterValue uint16_t u16; uint32_t u32; uint64_t u64; +#else + struct { int64_t :56; int8_t s8; }; + struct { int64_t :48; int16_t s16; }; + struct { int64_t :32; int32_t s32; }; + int64_t s64; + struct { uint64_t :56; uint8_t u8; }; + struct { uint64_t :48; uint16_t u16; }; + struct { uint64_t :32; uint32_t u32; }; + uint64_t u64; +#endif } GRegister; /* Float registers provide for storage of a single, double or quad diff --git a/sim/aarch64/simulator.c b/sim/aarch64/simulator.c index 88cb03d..7c15e7a 100644 --- a/sim/aarch64/simulator.c +++ b/sim/aarch64/simulator.c @@ -14083,7 +14083,11 @@ aarch64_step (sim_cpu *cpu) return FALSE; aarch64_set_next_PC (cpu, pc + 4); - aarch64_get_instr (cpu) = aarch64_get_mem_u32 (cpu, pc); + + /* Code is always little-endian. */ + sim_core_read_buffer (CPU_STATE (cpu), cpu, read_map, + & aarch64_get_instr (cpu), pc, 4); + aarch64_get_instr (cpu) = endian_le2h_4 (aarch64_get_instr (cpu)); TRACE_INSN (cpu, " pc = %" PRIx64 " instr = %08x", pc, aarch64_get_instr (cpu)); |