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.
This commit is contained in:
Jim Wilson 2016-06-30 09:10:41 +01:00 committed by Nick Clifton
parent 6e25650792
commit c7be441465
3 changed files with 29 additions and 8 deletions

View File

@ -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.

View File

@ -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.
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. */
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. */
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

View File

@ -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));