More AArch64 simulator improvements.

* cpustate.c (aarch64_get_FP_half): New function.  Read a vector
	register as a half precision floating point number.
	(aarch64_set_FP_half): New function.  Similar, but for setting
	a half precision register.
	(aarch64_get_thread_id): New function.  Returns the value of the
	CPU's TPIDR register.
	(aarch64_get_FPCR): New function.  Returns the value of the CPU's
	floating point control register.
	(aarch64_set_FPCR): New function.  Set the value of the CPU's FPCR
	register.
	* cpustate.h: Add prototypes for new functions.
	* sim-main.h (struct _sim_cpu): Add FPCR and tpidr fields.
	* memory.c: Use unaligned core access functions for all memory
	reads and writes.
	* simulator.c (HALT_NYI): Generate an error message if tracing
	will not tell the user why the simulator is halting.
	(HALT_UNREACHABLE): Delete.  Delete (unneeded) uses of the macro.
	(INSTR): New time-saver macro.
	(fldrb_abs): New function.  Loads an 8-bit value using a scaled
	offset.
	(fldrh_abs): New function.  Likewise for 16-bit values.
	(do_vec_SSHL): Allow for negative shift values.
	(do_vec_USHL): Likewise.
	(do_vec_SHL): Correct computation of shift amount.
	(do_vec_SSHR_USHR): Correct decision of signed vs unsigned
	shifts and computation of shift value.
	(clz): New function.  Counts leading zero bits.
	(do_vec_CLZ): New function.  Implements CLZ (vector).
	(do_vec_MOV_element): Call do_vec_CLZ.
	(dexSimpleFPCondCompare): Implement.
	(do_FCVT_half_to_single): New function.  Implements one of the
	FCVT operations.
	(do_FCVT_half_to_double): New function.  Likewise.
	(do_FCVT_single_to_half): New function.  Likewise.
	(do_FCVT_double_to_half): New function.  Likewise.
	(dexSimpleFPDataProc1Source): Call new FCVT functions.
	(do_scalar_SHL): Handle negative shifts.
	(do_scalar_shift): Handle SSHR.
	(do_scalar_USHL): New function.
	(do_double_add): Simplify to just performing a double precision
	add operation.  Move remaining code into...
	(do_scalar_vec): ... New function.
	(dexLoadUnsignedImmediate): Call new fldrb_abs and fldrh_abs
	functions.
	(system_get): Add support for TPIDR, CTR, FPCR, FPSR and CPSR
	registers.
	(system_set): New function.
	(do_MSR_immediate): New function.  Stub for now.
	(do_MSR_reg): New function.  Likewise. Partially implements MSR
	instruction.
	(do_SYS): New function.  Stub for now,
	(dexSystem): Call new functions.
This commit is contained in:
Nick Clifton 2016-03-23 17:37:30 +00:00
parent cc651c1cdd
commit 5ab6d79e70
6 changed files with 722 additions and 279 deletions

View File

@ -1,3 +1,58 @@
2016-03-23 Nick Clifton <nickc@redhat.com>
* cpustate.c (aarch64_get_FP_half): New function. Read a vector
register as a half precision floating point number.
(aarch64_set_FP_half): New function. Similar, but for setting
a half precision register.
(aarch64_get_thread_id): New function. Returns the value of the
CPU's TPIDR register.
(aarch64_get_FPCR): New function. Returns the value of the CPU's
floating point control register.
(aarch64_set_FPCR): New function. Set the value of the CPU's FPCR
register.
* cpustate.h: Add prototypes for new functions.
* sim-main.h (struct _sim_cpu): Add FPCR and tpidr fields.
* memory.c: Use unaligned core access functions for all memory
reads and writes.
* simulator.c (HALT_NYI): Generate an error message if tracing
will not tell the user why the simulator is halting.
(HALT_UNREACHABLE): Delete. Delete (unneeded) uses of the macro.
(INSTR): New time-saver macro.
(fldrb_abs): New function. Loads an 8-bit value using a scaled
offset.
(fldrh_abs): New function. Likewise for 16-bit values.
(do_vec_SSHL): Allow for negative shift values.
(do_vec_USHL): Likewise.
(do_vec_SHL): Correct computation of shift amount.
(do_vec_SSHR_USHR): Correct decision of signed vs unsigned
shifts and computation of shift value.
(clz): New function. Counts leading zero bits.
(do_vec_CLZ): New function. Implements CLZ (vector).
(do_vec_MOV_element): Call do_vec_CLZ.
(dexSimpleFPCondCompare): Implement.
(do_FCVT_half_to_single): New function. Implements one of the
FCVT operations.
(do_FCVT_half_to_double): New function. Likewise.
(do_FCVT_single_to_half): New function. Likewise.
(do_FCVT_double_to_half): New function. Likewise.
(dexSimpleFPDataProc1Source): Call new FCVT functions.
(do_scalar_SHL): Handle negative shifts.
(do_scalar_shift): Handle SSHR.
(do_scalar_USHL): New function.
(do_double_add): Simplify to just performing a double precision
add operation. Move remaining code into...
(do_scalar_vec): ... New function.
(dexLoadUnsignedImmediate): Call new fldrb_abs and fldrh_abs
functions.
(system_get): Add support for TPIDR, CTR, FPCR, FPSR and CPSR
registers.
(system_set): New function.
(do_MSR_immediate): New function. Stub for now.
(do_MSR_reg): New function. Likewise. Partially implements MSR
instruction.
(do_SYS): New function. Stub for now,
(dexSystem): Call new functions.
2016-03-18 Nick Clifton <nickc@redhat.com>
* cpustate.c: Remove spurious spaces from TRACE strings.

View File

@ -277,6 +277,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] = cpu->fr[reg].h[0];
u.h[1] = 0;
return u.f;
}
float
aarch64_get_FP_float (sim_cpu *cpu, VReg reg)
{
@ -296,6 +311,21 @@ 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[0];
cpu->fr[reg].h[1] = 0;
}
void
aarch64_set_FP_float (sim_cpu *cpu, VReg reg, float val)
{
@ -541,3 +571,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;
}

View File

@ -168,10 +168,10 @@ typedef union FRegisterValue
float s;
double d;
uint64_t v[2];
uint32_t w[4];
uint16_t h[8];
uint8_t b[16];
uint64_t v[2];
uint32_t w[4];
uint16_t h[8];
uint8_t b[16];
int64_t V[2];
int32_t W[4];
@ -194,10 +194,10 @@ typedef union FRegisterValue
typedef enum FlagIdx
{
V_IDX,
C_IDX,
Z_IDX,
N_IDX
V_IDX = 0,
C_IDX = 1,
Z_IDX = 2,
N_IDX = 3
} FlagIdx;
typedef enum FlagMask
@ -216,7 +216,7 @@ typedef uint32_t FlagsRegister;
This register includes IDC, IXC, UFC, OFC, DZC, IOC and QC bits,
and the floating point N, Z, C, V bits but the latter are unused in
aarch64 mode. the sim ignores QC for now.
aarch64 mode. The sim ignores QC for now.
Bit positions are as per the ARMv7 FPSCR register
@ -272,9 +272,12 @@ extern void aarch64_set_reg_u64 (sim_cpu *, GReg, int, uint64_t);
extern void aarch64_set_reg_s64 (sim_cpu *, GReg, int, int64_t);
/* FP Register access functions. */
extern float aarch64_get_FP_half (sim_cpu *, VReg);
extern float aarch64_get_FP_float (sim_cpu *, VReg);
extern double aarch64_get_FP_double (sim_cpu *, VReg);
extern void aarch64_get_FP_long_double (sim_cpu *, VReg, FRegister *);
extern void aarch64_set_FP_half (sim_cpu *, VReg, float);
extern void aarch64_set_FP_float (sim_cpu *, VReg, float);
extern void aarch64_set_FP_double (sim_cpu *, VReg, double);
extern void aarch64_set_FP_long_double (sim_cpu *, VReg, FRegister);
@ -330,4 +333,9 @@ extern double aarch64_get_vec_double (sim_cpu *, VReg, unsigned);
extern void aarch64_set_vec_float (sim_cpu *, VReg, unsigned, float);
extern void aarch64_set_vec_double (sim_cpu *, VReg, unsigned, double);
/* System register accessors. */
extern uint64_t aarch64_get_thread_id (sim_cpu *);
extern uint32_t aarch64_get_FPCR (sim_cpu *);
extern void aarch64_set_FPCR (sim_cpu *, uint32_t);
#endif /* _CPU_STATE_H */

View File

@ -42,11 +42,13 @@ mem_error (sim_cpu *cpu, const char *message, uint64_t addr)
TRACE_MEMORY (cpu, "ERROR: %s: %" PRIx64, message, addr);
}
/* FIXME: Aarch64 requires aligned memory access if SCTRLR_ELx.A is set,
but we are not implementing that here. */
#define FETCH_FUNC(RETURN_TYPE, ACCESS_TYPE, NAME, N) \
RETURN_TYPE \
aarch64_get_mem_##NAME (sim_cpu *cpu, uint64_t address) \
{ \
RETURN_TYPE val = (RETURN_TYPE) sim_core_read_##N (cpu, 0, read_map, address); \
RETURN_TYPE val = (RETURN_TYPE) sim_core_read_unaligned_##N (cpu, 0, read_map, address); \
TRACE_MEMORY (cpu, \
"read of %" PRIx64 " (%d bytes) from %" PRIx64, \
(uint64_t) val, N, address); \
@ -54,29 +56,14 @@ mem_error (sim_cpu *cpu, const char *message, uint64_t addr)
return val; \
}
/* A variant of the FETCH_FUNC macro that uses unaligned reads.
The AArch64 only requires 4-byte alignment for 8-byte quantities
but the sim common core does not support this. */
#define FETCH_FUNC_U(RETURN_TYPE, ACCESS_TYPE, NAME) \
RETURN_TYPE \
aarch64_get_mem_##NAME (sim_cpu *cpu, uint64_t address) \
{ \
RETURN_TYPE val = (RETURN_TYPE) sim_core_read_unaligned_8 (cpu, 0, read_map, address); \
TRACE_MEMORY (cpu, \
"read of %" PRIx64 " (%d bytes) from %" PRIx64 " (unaligned double)", \
(uint64_t) val, N, address); \
\
return val; \
}
FETCH_FUNC_U (uint64_t, uint64_t, u64)
FETCH_FUNC_U (int64_t, int64_t, s64)
FETCH_FUNC (uint32_t, uint32_t, u32, 4)
FETCH_FUNC (int32_t, int32_t, s32, 4)
FETCH_FUNC (uint32_t, uint16_t, u16, 2)
FETCH_FUNC (int32_t, int16_t, s16, 2)
FETCH_FUNC (uint32_t, uint8_t, u8, 1)
FETCH_FUNC (int32_t, int8_t, s8, 1)
FETCH_FUNC (uint64_t, uint64_t, u64, 8)
FETCH_FUNC (int64_t, int64_t, s64, 8)
FETCH_FUNC (uint32_t, uint32_t, u32, 4)
FETCH_FUNC (int32_t, int32_t, s32, 4)
FETCH_FUNC (uint32_t, uint16_t, u16, 2)
FETCH_FUNC (int32_t, int16_t, s16, 2)
FETCH_FUNC (uint32_t, uint8_t, u8, 1)
FETCH_FUNC (int32_t, int8_t, s8, 1)
void
aarch64_get_mem_long_double (sim_cpu *cpu, uint64_t address, FRegister *a)
@ -85,6 +72,8 @@ aarch64_get_mem_long_double (sim_cpu *cpu, uint64_t address, FRegister *a)
a->v[1] = sim_core_read_unaligned_8 (cpu, 0, read_map, address + 8);
}
/* FIXME: Aarch64 requires aligned memory access if SCTRLR_ELx.A is set,
but we are not implementing that here. */
#define STORE_FUNC(TYPE, NAME, N) \
void \
aarch64_set_mem_##NAME (sim_cpu *cpu, uint64_t address, TYPE value) \
@ -96,28 +85,14 @@ aarch64_get_mem_long_double (sim_cpu *cpu, uint64_t address, FRegister *a)
sim_core_write_unaligned_##N (cpu, 0, write_map, address, value); \
}
/* A variant of the STORE_FUNC macro that uses unaligned writes.
The AArch64 only requires 4-byte alignment for 8-byte quantities
but the sim common core does not support this. */
#define STORE_FUNC_U(TYPE, NAME) \
void \
aarch64_set_mem_##NAME (sim_cpu *cpu, uint64_t address, TYPE value) \
{ \
TRACE_MEMORY (cpu, \
"write of %" PRIx64 " (8 bytes) to %" PRIx64, \
(uint64_t) value, address); \
\
sim_core_write_unaligned_8 (cpu, 0, write_map, address, value); \
}
STORE_FUNC_U (uint64_t, u64)
STORE_FUNC_U (int64_t, s64)
STORE_FUNC (uint32_t, u32, 4)
STORE_FUNC (int32_t, s32, 4)
STORE_FUNC (uint16_t, u16, 2)
STORE_FUNC (int16_t, s16, 2)
STORE_FUNC (uint8_t, u8, 1)
STORE_FUNC (int8_t, s8, 1)
STORE_FUNC (uint64_t, u64, 8)
STORE_FUNC (int64_t, s64, 8)
STORE_FUNC (uint32_t, u32, 4)
STORE_FUNC (int32_t, s32, 4)
STORE_FUNC (uint16_t, u16, 2)
STORE_FUNC (int16_t, s16, 2)
STORE_FUNC (uint8_t, u8, 1)
STORE_FUNC (int8_t, s8, 1)
void
aarch64_set_mem_long_double (sim_cpu *cpu, uint64_t address, FRegister a)

View File

@ -37,12 +37,14 @@ struct _sim_cpu
uint64_t pc;
uint32_t CPSR;
uint32_t FPSR;
uint32_t FPSR; /* Floating point Status register. */
uint32_t FPCR; /* Floating point Control register. */
uint64_t nextpc;
uint32_t instr;
uint64_t tpidr; /* Thread pointer id. */
sim_cpu_base base;
};

File diff suppressed because it is too large Load Diff