aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Wilson <jim.wilson@linaro.org>2016-06-30 09:10:41 +0100
committerNick Clifton <nickc@redhat.com>2016-06-30 09:10:41 +0100
commitc7be441465094e5ffce2f4205ea887676965d0be (patch)
treeda0afb6462365bfbfb9d7d1f52ca56887096f419
parent6e2565079204ae2d2c0a5fa15fcd233e9c614f0b (diff)
downloadgdb-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/ChangeLog8
-rw-r--r--sim/aarch64/cpustate.h25
-rw-r--r--sim/aarch64/simulator.c6
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));