mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
Compare commits
28 Commits
gdb-16.3-r
...
users/vapi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ce92948fc | ||
|
|
6ee0b6ea1e | ||
|
|
ad450d269d | ||
|
|
911ee5419e | ||
|
|
7a74f9f99f | ||
|
|
743aae1f82 | ||
|
|
de09c78f3c | ||
|
|
fe6e58267a | ||
|
|
d9c659aa83 | ||
|
|
e266d3d492 | ||
|
|
fb544966c2 | ||
|
|
c7d0b49d44 | ||
|
|
b4365b4b22 | ||
|
|
e18ff63ce2 | ||
|
|
dcf7087b4b | ||
|
|
0654bab6b5 | ||
|
|
5b0cecc550 | ||
|
|
125bea38ed | ||
|
|
ae9e64d685 | ||
|
|
8dbffa355c | ||
|
|
7f70ec4256 | ||
|
|
e59c1551fb | ||
|
|
337d951324 | ||
|
|
5d49c5c438 | ||
|
|
86da59040d | ||
|
|
d936c5d245 | ||
|
|
39764277cc | ||
|
|
35c1526367 |
@@ -38,73 +38,79 @@
|
||||
void
|
||||
aarch64_set_reg_u64 (sim_cpu *cpu, GReg reg, int r31_is_sp, uint64_t val)
|
||||
{
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
|
||||
if (reg == R31 && ! r31_is_sp)
|
||||
{
|
||||
TRACE_REGISTER (cpu, "GR[31] NOT CHANGED!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (val != cpu->gr[reg].u64)
|
||||
if (val != aarch64_cpu->gr[reg].u64)
|
||||
TRACE_REGISTER (cpu,
|
||||
"GR[%2d] changes from %16" PRIx64 " to %16" PRIx64,
|
||||
reg, cpu->gr[reg].u64, val);
|
||||
reg, aarch64_cpu->gr[reg].u64, val);
|
||||
|
||||
cpu->gr[reg].u64 = val;
|
||||
aarch64_cpu->gr[reg].u64 = val;
|
||||
}
|
||||
|
||||
void
|
||||
aarch64_set_reg_s64 (sim_cpu *cpu, GReg reg, int r31_is_sp, int64_t val)
|
||||
{
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
|
||||
if (reg == R31 && ! r31_is_sp)
|
||||
{
|
||||
TRACE_REGISTER (cpu, "GR[31] NOT CHANGED!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (val != cpu->gr[reg].s64)
|
||||
if (val != aarch64_cpu->gr[reg].s64)
|
||||
TRACE_REGISTER (cpu,
|
||||
"GR[%2d] changes from %16" PRIx64 " to %16" PRIx64,
|
||||
reg, cpu->gr[reg].s64, val);
|
||||
reg, aarch64_cpu->gr[reg].s64, val);
|
||||
|
||||
cpu->gr[reg].s64 = val;
|
||||
aarch64_cpu->gr[reg].s64 = val;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
aarch64_get_reg_u64 (sim_cpu *cpu, GReg reg, int r31_is_sp)
|
||||
{
|
||||
return cpu->gr[reg_num(reg)].u64;
|
||||
return AARCH64_SIM_CPU (cpu)->gr[reg_num(reg)].u64;
|
||||
}
|
||||
|
||||
int64_t
|
||||
aarch64_get_reg_s64 (sim_cpu *cpu, GReg reg, int r31_is_sp)
|
||||
{
|
||||
return cpu->gr[reg_num(reg)].s64;
|
||||
return AARCH64_SIM_CPU (cpu)->gr[reg_num(reg)].s64;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
aarch64_get_reg_u32 (sim_cpu *cpu, GReg reg, int r31_is_sp)
|
||||
{
|
||||
return cpu->gr[reg_num(reg)].u32;
|
||||
return AARCH64_SIM_CPU (cpu)->gr[reg_num(reg)].u32;
|
||||
}
|
||||
|
||||
int32_t
|
||||
aarch64_get_reg_s32 (sim_cpu *cpu, GReg reg, int r31_is_sp)
|
||||
{
|
||||
return cpu->gr[reg_num(reg)].s32;
|
||||
return AARCH64_SIM_CPU (cpu)->gr[reg_num(reg)].s32;
|
||||
}
|
||||
|
||||
void
|
||||
aarch64_set_reg_s32 (sim_cpu *cpu, GReg reg, int r31_is_sp, int32_t val)
|
||||
{
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
|
||||
if (reg == R31 && ! r31_is_sp)
|
||||
{
|
||||
TRACE_REGISTER (cpu, "GR[31] NOT CHANGED!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (val != cpu->gr[reg].s32)
|
||||
if (val != aarch64_cpu->gr[reg].s32)
|
||||
TRACE_REGISTER (cpu, "GR[%2d] changes from %8x to %8x",
|
||||
reg, cpu->gr[reg].s32, val);
|
||||
reg, aarch64_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
|
||||
@@ -112,94 +118,102 @@ aarch64_set_reg_s32 (sim_cpu *cpu, GReg reg, int r31_is_sp, int32_t val)
|
||||
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;
|
||||
aarch64_cpu->gr[reg].s64 = 0;
|
||||
aarch64_cpu->gr[reg].s32 = val;
|
||||
}
|
||||
|
||||
void
|
||||
aarch64_set_reg_u32 (sim_cpu *cpu, GReg reg, int r31_is_sp, uint32_t val)
|
||||
{
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
|
||||
if (reg == R31 && ! r31_is_sp)
|
||||
{
|
||||
TRACE_REGISTER (cpu, "GR[31] NOT CHANGED!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (val != cpu->gr[reg].u32)
|
||||
if (val != aarch64_cpu->gr[reg].u32)
|
||||
TRACE_REGISTER (cpu, "GR[%2d] changes from %8x to %8x",
|
||||
reg, cpu->gr[reg].u32, val);
|
||||
reg, aarch64_cpu->gr[reg].u32, val);
|
||||
|
||||
cpu->gr[reg].u64 = 0;
|
||||
cpu->gr[reg].u32 = val;
|
||||
aarch64_cpu->gr[reg].u64 = 0;
|
||||
aarch64_cpu->gr[reg].u32 = val;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
aarch64_get_reg_u16 (sim_cpu *cpu, GReg reg, int r31_is_sp)
|
||||
{
|
||||
return cpu->gr[reg_num(reg)].u16;
|
||||
return AARCH64_SIM_CPU (cpu)->gr[reg_num(reg)].u16;
|
||||
}
|
||||
|
||||
int32_t
|
||||
aarch64_get_reg_s16 (sim_cpu *cpu, GReg reg, int r31_is_sp)
|
||||
{
|
||||
return cpu->gr[reg_num(reg)].s16;
|
||||
return AARCH64_SIM_CPU (cpu)->gr[reg_num(reg)].s16;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
aarch64_get_reg_u8 (sim_cpu *cpu, GReg reg, int r31_is_sp)
|
||||
{
|
||||
return cpu->gr[reg_num(reg)].u8;
|
||||
return AARCH64_SIM_CPU (cpu)->gr[reg_num(reg)].u8;
|
||||
}
|
||||
|
||||
int32_t
|
||||
aarch64_get_reg_s8 (sim_cpu *cpu, GReg reg, int r31_is_sp)
|
||||
{
|
||||
return cpu->gr[reg_num(reg)].s8;
|
||||
return AARCH64_SIM_CPU (cpu)->gr[reg_num(reg)].s8;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
aarch64_get_PC (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->pc;
|
||||
return AARCH64_SIM_CPU (cpu)->pc;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
aarch64_get_next_PC (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->nextpc;
|
||||
return AARCH64_SIM_CPU (cpu)->nextpc;
|
||||
}
|
||||
|
||||
void
|
||||
aarch64_set_next_PC (sim_cpu *cpu, uint64_t next)
|
||||
{
|
||||
if (next != cpu->nextpc + 4)
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
|
||||
if (next != aarch64_cpu->nextpc + 4)
|
||||
TRACE_REGISTER (cpu,
|
||||
"NextPC changes from %16" PRIx64 " to %16" PRIx64,
|
||||
cpu->nextpc, next);
|
||||
aarch64_cpu->nextpc, next);
|
||||
|
||||
cpu->nextpc = next;
|
||||
aarch64_cpu->nextpc = next;
|
||||
}
|
||||
|
||||
void
|
||||
aarch64_set_next_PC_by_offset (sim_cpu *cpu, int64_t offset)
|
||||
{
|
||||
if (cpu->pc + offset != cpu->nextpc + 4)
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
|
||||
if (aarch64_cpu->pc + offset != aarch64_cpu->nextpc + 4)
|
||||
TRACE_REGISTER (cpu,
|
||||
"NextPC changes from %16" PRIx64 " to %16" PRIx64,
|
||||
cpu->nextpc, cpu->pc + offset);
|
||||
aarch64_cpu->nextpc, aarch64_cpu->pc + offset);
|
||||
|
||||
cpu->nextpc = cpu->pc + offset;
|
||||
aarch64_cpu->nextpc = aarch64_cpu->pc + offset;
|
||||
}
|
||||
|
||||
/* Install nextpc as current pc. */
|
||||
void
|
||||
aarch64_update_PC (sim_cpu *cpu)
|
||||
{
|
||||
cpu->pc = cpu->nextpc;
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
|
||||
aarch64_cpu->pc = aarch64_cpu->nextpc;
|
||||
/* Rezero the register we hand out when asked for ZR just in case it
|
||||
was used as the destination for a write by the previous
|
||||
instruction. */
|
||||
cpu->gr[32].u64 = 0UL;
|
||||
aarch64_cpu->gr[32].u64 = 0UL;
|
||||
}
|
||||
|
||||
/* This instruction can be used to save the next PC to LR
|
||||
@@ -207,12 +221,14 @@ aarch64_update_PC (sim_cpu *cpu)
|
||||
void
|
||||
aarch64_save_LR (sim_cpu *cpu)
|
||||
{
|
||||
if (cpu->gr[LR].u64 != cpu->nextpc)
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
|
||||
if (aarch64_cpu->gr[LR].u64 != aarch64_cpu->nextpc)
|
||||
TRACE_REGISTER (cpu,
|
||||
"LR changes from %16" PRIx64 " to %16" PRIx64,
|
||||
cpu->gr[LR].u64, cpu->nextpc);
|
||||
aarch64_cpu->gr[LR].u64, aarch64_cpu->nextpc);
|
||||
|
||||
cpu->gr[LR].u64 = cpu->nextpc;
|
||||
aarch64_cpu->gr[LR].u64 = aarch64_cpu->nextpc;
|
||||
}
|
||||
|
||||
static const char *
|
||||
@@ -244,88 +260,94 @@ decode_cpsr (FlagMask flags)
|
||||
uint32_t
|
||||
aarch64_get_CPSR (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->CPSR;
|
||||
return AARCH64_SIM_CPU (cpu)->CPSR;
|
||||
}
|
||||
|
||||
/* Set the CPSR register as an int. */
|
||||
void
|
||||
aarch64_set_CPSR (sim_cpu *cpu, uint32_t new_flags)
|
||||
{
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
|
||||
if (TRACE_REGISTER_P (cpu))
|
||||
{
|
||||
if (cpu->CPSR != new_flags)
|
||||
if (aarch64_cpu->CPSR != new_flags)
|
||||
TRACE_REGISTER (cpu,
|
||||
"CPSR changes from %s to %s",
|
||||
decode_cpsr (cpu->CPSR), decode_cpsr (new_flags));
|
||||
decode_cpsr (aarch64_cpu->CPSR), decode_cpsr (new_flags));
|
||||
else
|
||||
TRACE_REGISTER (cpu,
|
||||
"CPSR stays at %s", decode_cpsr (cpu->CPSR));
|
||||
"CPSR stays at %s", decode_cpsr (aarch64_cpu->CPSR));
|
||||
}
|
||||
|
||||
cpu->CPSR = new_flags & CPSR_ALL_FLAGS;
|
||||
aarch64_cpu->CPSR = new_flags & CPSR_ALL_FLAGS;
|
||||
}
|
||||
|
||||
/* Read a specific subset of the CPSR as a bit pattern. */
|
||||
uint32_t
|
||||
aarch64_get_CPSR_bits (sim_cpu *cpu, FlagMask mask)
|
||||
{
|
||||
return cpu->CPSR & mask;
|
||||
return AARCH64_SIM_CPU (cpu)->CPSR & mask;
|
||||
}
|
||||
|
||||
/* Assign a specific subset of the CPSR as a bit pattern. */
|
||||
void
|
||||
aarch64_set_CPSR_bits (sim_cpu *cpu, uint32_t mask, uint32_t value)
|
||||
{
|
||||
uint32_t old_flags = cpu->CPSR;
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
uint32_t old_flags = aarch64_cpu->CPSR;
|
||||
|
||||
mask &= CPSR_ALL_FLAGS;
|
||||
cpu->CPSR &= ~ mask;
|
||||
cpu->CPSR |= (value & mask);
|
||||
aarch64_cpu->CPSR &= ~ mask;
|
||||
aarch64_cpu->CPSR |= (value & mask);
|
||||
|
||||
if (old_flags != cpu->CPSR)
|
||||
if (old_flags != aarch64_cpu->CPSR)
|
||||
TRACE_REGISTER (cpu,
|
||||
"CPSR changes from %s to %s",
|
||||
decode_cpsr (old_flags), decode_cpsr (cpu->CPSR));
|
||||
decode_cpsr (old_flags), decode_cpsr (aarch64_cpu->CPSR));
|
||||
}
|
||||
|
||||
/* Test the value of a single CPSR returned as non-zero or zero. */
|
||||
uint32_t
|
||||
aarch64_test_CPSR_bit (sim_cpu *cpu, FlagMask bit)
|
||||
{
|
||||
return cpu->CPSR & bit;
|
||||
return AARCH64_SIM_CPU (cpu)->CPSR & bit;
|
||||
}
|
||||
|
||||
/* Set a single flag in the CPSR. */
|
||||
void
|
||||
aarch64_set_CPSR_bit (sim_cpu *cpu, FlagMask bit)
|
||||
{
|
||||
uint32_t old_flags = cpu->CPSR;
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
uint32_t old_flags = aarch64_cpu->CPSR;
|
||||
|
||||
cpu->CPSR |= (bit & CPSR_ALL_FLAGS);
|
||||
aarch64_cpu->CPSR |= (bit & CPSR_ALL_FLAGS);
|
||||
|
||||
if (old_flags != cpu->CPSR)
|
||||
if (old_flags != aarch64_cpu->CPSR)
|
||||
TRACE_REGISTER (cpu,
|
||||
"CPSR changes from %s to %s",
|
||||
decode_cpsr (old_flags), decode_cpsr (cpu->CPSR));
|
||||
decode_cpsr (old_flags), decode_cpsr (aarch64_cpu->CPSR));
|
||||
}
|
||||
|
||||
/* Clear a single flag in the CPSR. */
|
||||
void
|
||||
aarch64_clear_CPSR_bit (sim_cpu *cpu, FlagMask bit)
|
||||
{
|
||||
uint32_t old_flags = cpu->CPSR;
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
uint32_t old_flags = aarch64_cpu->CPSR;
|
||||
|
||||
cpu->CPSR &= ~(bit & CPSR_ALL_FLAGS);
|
||||
aarch64_cpu->CPSR &= ~(bit & CPSR_ALL_FLAGS);
|
||||
|
||||
if (old_flags != cpu->CPSR)
|
||||
if (old_flags != aarch64_cpu->CPSR)
|
||||
TRACE_REGISTER (cpu,
|
||||
"CPSR changes from %s to %s",
|
||||
decode_cpsr (old_flags), decode_cpsr (cpu->CPSR));
|
||||
decode_cpsr (old_flags), decode_cpsr (aarch64_cpu->CPSR));
|
||||
}
|
||||
|
||||
float
|
||||
aarch64_get_FP_half (sim_cpu *cpu, VReg reg)
|
||||
{
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
union
|
||||
{
|
||||
uint16_t h[2];
|
||||
@@ -333,7 +355,7 @@ aarch64_get_FP_half (sim_cpu *cpu, VReg reg)
|
||||
} u;
|
||||
|
||||
u.h[0] = 0;
|
||||
u.h[1] = cpu->fr[reg].h[0];
|
||||
u.h[1] = aarch64_cpu->fr[reg].h[0];
|
||||
return u.f;
|
||||
}
|
||||
|
||||
@@ -341,25 +363,28 @@ aarch64_get_FP_half (sim_cpu *cpu, VReg reg)
|
||||
float
|
||||
aarch64_get_FP_float (sim_cpu *cpu, VReg reg)
|
||||
{
|
||||
return cpu->fr[reg].s;
|
||||
return AARCH64_SIM_CPU (cpu)->fr[reg].s;
|
||||
}
|
||||
|
||||
double
|
||||
aarch64_get_FP_double (sim_cpu *cpu, VReg reg)
|
||||
{
|
||||
return cpu->fr[reg].d;
|
||||
return AARCH64_SIM_CPU (cpu)->fr[reg].d;
|
||||
}
|
||||
|
||||
void
|
||||
aarch64_get_FP_long_double (sim_cpu *cpu, VReg reg, FRegister *a)
|
||||
{
|
||||
a->v[0] = cpu->fr[reg].v[0];
|
||||
a->v[1] = cpu->fr[reg].v[1];
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
|
||||
a->v[0] = aarch64_cpu->fr[reg].v[0];
|
||||
a->v[1] = aarch64_cpu->fr[reg].v[1];
|
||||
}
|
||||
|
||||
void
|
||||
aarch64_set_FP_half (sim_cpu *cpu, VReg reg, float val)
|
||||
{
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
union
|
||||
{
|
||||
uint16_t h[2];
|
||||
@@ -367,74 +392,82 @@ aarch64_set_FP_half (sim_cpu *cpu, VReg reg, float val)
|
||||
} u;
|
||||
|
||||
u.f = val;
|
||||
cpu->fr[reg].h[0] = u.h[1];
|
||||
cpu->fr[reg].h[1] = 0;
|
||||
aarch64_cpu->fr[reg].h[0] = u.h[1];
|
||||
aarch64_cpu->fr[reg].h[1] = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
aarch64_set_FP_float (sim_cpu *cpu, VReg reg, float val)
|
||||
{
|
||||
if (val != cpu->fr[reg].s
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
|
||||
if (val != aarch64_cpu->fr[reg].s
|
||||
/* Handle +/- zero. */
|
||||
|| signbit (val) != signbit (cpu->fr[reg].s))
|
||||
|| signbit (val) != signbit (aarch64_cpu->fr[reg].s))
|
||||
{
|
||||
FRegister v;
|
||||
|
||||
v.s = val;
|
||||
TRACE_REGISTER (cpu,
|
||||
"FR[%d].s changes from %f to %f [hex: %0" PRIx64 "]",
|
||||
reg, cpu->fr[reg].s, val, v.v[0]);
|
||||
reg, aarch64_cpu->fr[reg].s, val, v.v[0]);
|
||||
}
|
||||
|
||||
cpu->fr[reg].s = val;
|
||||
aarch64_cpu->fr[reg].s = val;
|
||||
}
|
||||
|
||||
void
|
||||
aarch64_set_FP_double (sim_cpu *cpu, VReg reg, double val)
|
||||
{
|
||||
if (val != cpu->fr[reg].d
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
|
||||
if (val != aarch64_cpu->fr[reg].d
|
||||
/* Handle +/- zero. */
|
||||
|| signbit (val) != signbit (cpu->fr[reg].d))
|
||||
|| signbit (val) != signbit (aarch64_cpu->fr[reg].d))
|
||||
{
|
||||
FRegister v;
|
||||
|
||||
v.d = val;
|
||||
TRACE_REGISTER (cpu,
|
||||
"FR[%d].d changes from %f to %f [hex: %0" PRIx64 "]",
|
||||
reg, cpu->fr[reg].d, val, v.v[0]);
|
||||
reg, aarch64_cpu->fr[reg].d, val, v.v[0]);
|
||||
}
|
||||
cpu->fr[reg].d = val;
|
||||
aarch64_cpu->fr[reg].d = val;
|
||||
}
|
||||
|
||||
void
|
||||
aarch64_set_FP_long_double (sim_cpu *cpu, VReg reg, FRegister a)
|
||||
{
|
||||
if (cpu->fr[reg].v[0] != a.v[0]
|
||||
|| cpu->fr[reg].v[1] != a.v[1])
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
|
||||
if (aarch64_cpu->fr[reg].v[0] != a.v[0]
|
||||
|| aarch64_cpu->fr[reg].v[1] != a.v[1])
|
||||
TRACE_REGISTER (cpu,
|
||||
"FR[%d].q changes from [%0" PRIx64 " %0" PRIx64 "] to [%0"
|
||||
PRIx64 " %0" PRIx64 "] ",
|
||||
reg,
|
||||
cpu->fr[reg].v[0], cpu->fr[reg].v[1],
|
||||
aarch64_cpu->fr[reg].v[0], aarch64_cpu->fr[reg].v[1],
|
||||
a.v[0], a.v[1]);
|
||||
|
||||
cpu->fr[reg].v[0] = a.v[0];
|
||||
cpu->fr[reg].v[1] = a.v[1];
|
||||
aarch64_cpu->fr[reg].v[0] = a.v[0];
|
||||
aarch64_cpu->fr[reg].v[1] = a.v[1];
|
||||
}
|
||||
|
||||
#define GET_VEC_ELEMENT(REG, ELEMENT, FIELD) \
|
||||
do \
|
||||
{ \
|
||||
if (ELEMENT >= ARRAY_SIZE (cpu->fr[0].FIELD)) \
|
||||
#define GET_VEC_ELEMENT(REG, ELEMENT, FIELD) \
|
||||
do \
|
||||
{ \
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu); \
|
||||
\
|
||||
if (ELEMENT >= ARRAY_SIZE (aarch64_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), \
|
||||
sim_stopped, SIM_SIGBUS); \
|
||||
} \
|
||||
return cpu->fr[REG].FIELD [ELEMENT]; \
|
||||
return aarch64_cpu->fr[REG].FIELD [ELEMENT]; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@@ -502,7 +535,9 @@ 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)) \
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu); \
|
||||
\
|
||||
if (ELEMENT >= ARRAY_SIZE (aarch64_cpu->fr[0].FIELD)) \
|
||||
{ \
|
||||
TRACE_REGISTER (cpu, \
|
||||
"Internal SIM error: invalid element number: %d ",\
|
||||
@@ -510,13 +545,13 @@ aarch64_get_vec_double (sim_cpu *cpu, VReg reg, unsigned element)
|
||||
sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu), \
|
||||
sim_stopped, SIM_SIGBUS); \
|
||||
} \
|
||||
if (VAL != cpu->fr[REG].FIELD [ELEMENT]) \
|
||||
if (VAL != aarch64_cpu->fr[REG].FIELD [ELEMENT]) \
|
||||
TRACE_REGISTER (cpu, \
|
||||
"VR[%2d]." #FIELD " [%d] changes from " PRINTER \
|
||||
" to " PRINTER , REG, \
|
||||
ELEMENT, cpu->fr[REG].FIELD [ELEMENT], VAL); \
|
||||
ELEMENT, aarch64_cpu->fr[REG].FIELD [ELEMENT], VAL); \
|
||||
\
|
||||
cpu->fr[REG].FIELD [ELEMENT] = VAL; \
|
||||
aarch64_cpu->fr[REG].FIELD [ELEMENT] = VAL; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@@ -583,63 +618,68 @@ aarch64_set_vec_double (sim_cpu *cpu, VReg reg, unsigned element, double val)
|
||||
void
|
||||
aarch64_set_FPSR (sim_cpu *cpu, uint32_t value)
|
||||
{
|
||||
if (cpu->FPSR != value)
|
||||
TRACE_REGISTER (cpu,
|
||||
"FPSR changes from %x to %x", cpu->FPSR, value);
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
|
||||
cpu->FPSR = value & FPSR_ALL_FPSRS;
|
||||
if (aarch64_cpu->FPSR != value)
|
||||
TRACE_REGISTER (cpu,
|
||||
"FPSR changes from %x to %x", aarch64_cpu->FPSR, value);
|
||||
|
||||
aarch64_cpu->FPSR = value & FPSR_ALL_FPSRS;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
aarch64_get_FPSR (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->FPSR;
|
||||
return AARCH64_SIM_CPU (cpu)->FPSR;
|
||||
}
|
||||
|
||||
void
|
||||
aarch64_set_FPSR_bits (sim_cpu *cpu, uint32_t mask, uint32_t value)
|
||||
{
|
||||
uint32_t old_FPSR = cpu->FPSR;
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
uint32_t old_FPSR = aarch64_cpu->FPSR;
|
||||
|
||||
mask &= FPSR_ALL_FPSRS;
|
||||
cpu->FPSR &= ~mask;
|
||||
cpu->FPSR |= (value & mask);
|
||||
aarch64_cpu->FPSR &= ~mask;
|
||||
aarch64_cpu->FPSR |= (value & mask);
|
||||
|
||||
if (cpu->FPSR != old_FPSR)
|
||||
if (aarch64_cpu->FPSR != old_FPSR)
|
||||
TRACE_REGISTER (cpu,
|
||||
"FPSR changes from %x to %x", old_FPSR, cpu->FPSR);
|
||||
"FPSR changes from %x to %x", old_FPSR, aarch64_cpu->FPSR);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
aarch64_get_FPSR_bits (sim_cpu *cpu, uint32_t mask)
|
||||
{
|
||||
mask &= FPSR_ALL_FPSRS;
|
||||
return cpu->FPSR & mask;
|
||||
return AARCH64_SIM_CPU (cpu)->FPSR & mask;
|
||||
}
|
||||
|
||||
int
|
||||
aarch64_test_FPSR_bit (sim_cpu *cpu, FPSRMask flag)
|
||||
{
|
||||
return cpu->FPSR & flag;
|
||||
return AARCH64_SIM_CPU (cpu)->FPSR & flag;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
aarch64_get_thread_id (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->tpidr;
|
||||
return AARCH64_SIM_CPU (cpu)->tpidr;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
aarch64_get_FPCR (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->FPCR;
|
||||
return AARCH64_SIM_CPU (cpu)->FPCR;
|
||||
}
|
||||
|
||||
void
|
||||
aarch64_set_FPCR (sim_cpu *cpu, uint32_t val)
|
||||
{
|
||||
if (cpu->FPCR != val)
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
|
||||
if (aarch64_cpu->FPCR != val)
|
||||
TRACE_REGISTER (cpu,
|
||||
"FPCR changes from %x to %x", cpu->FPCR, val);
|
||||
cpu->FPCR = val;
|
||||
"FPCR changes from %x to %x", aarch64_cpu->FPCR, val);
|
||||
aarch64_cpu->FPCR = val;
|
||||
}
|
||||
|
||||
@@ -302,7 +302,7 @@ extern void aarch64_save_LR (sim_cpu *);
|
||||
|
||||
/* Instruction accessor - implemented as a
|
||||
macro as we do not need to annotate it. */
|
||||
#define aarch64_get_instr(cpu) ((cpu)->instr)
|
||||
#define aarch64_get_instr(cpu) (AARCH64_SIM_CPU (cpu)->instr)
|
||||
|
||||
/* Flag register accessors. */
|
||||
extern uint32_t aarch64_get_CPSR (sim_cpu *);
|
||||
|
||||
@@ -346,7 +346,8 @@ sim_open (SIM_OPEN_KIND kind,
|
||||
current_alignment = NONSTRICT_ALIGNMENT;
|
||||
|
||||
/* Perform the initialization steps one by one. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct aarch64_sim_cpu))
|
||||
!= SIM_RC_OK
|
||||
|| sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK
|
||||
|| sim_parse_args (sd, argv) != SIM_RC_OK
|
||||
|| sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "cpustate.h"
|
||||
|
||||
/* A per-core state structure. */
|
||||
struct _sim_cpu
|
||||
struct aarch64_sim_cpu
|
||||
{
|
||||
GRegister gr[33]; /* Extra register at index 32 is used to hold zero value. */
|
||||
FRegister fr[32];
|
||||
@@ -44,10 +44,10 @@ struct _sim_cpu
|
||||
uint32_t instr;
|
||||
|
||||
uint64_t tpidr; /* Thread pointer id. */
|
||||
|
||||
sim_cpu_base base;
|
||||
};
|
||||
|
||||
#define AARCH64_SIM_CPU(cpu) ((struct aarch64_sim_cpu *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AARCH64_MIN_GR = 0,
|
||||
|
||||
@@ -5394,6 +5394,7 @@ do_vec_ADDP (sim_cpu *cpu)
|
||||
instr[9,5] = Vn
|
||||
instr[4,0] = V dest. */
|
||||
|
||||
struct aarch64_sim_cpu *aarch64_cpu = AARCH64_SIM_CPU (cpu);
|
||||
FRegister copy_vn;
|
||||
FRegister copy_vm;
|
||||
unsigned full = INSTR (30, 30);
|
||||
@@ -5408,8 +5409,8 @@ do_vec_ADDP (sim_cpu *cpu)
|
||||
NYI_assert (15, 10, 0x2F);
|
||||
|
||||
/* Make copies of the source registers in case vd == vn/vm. */
|
||||
copy_vn = cpu->fr[vn];
|
||||
copy_vm = cpu->fr[vm];
|
||||
copy_vn = aarch64_cpu->fr[vn];
|
||||
copy_vm = aarch64_cpu->fr[vm];
|
||||
|
||||
TRACE_DECODE (cpu, "emulated at line %d", __LINE__);
|
||||
switch (size)
|
||||
|
||||
@@ -28,9 +28,4 @@
|
||||
|
||||
extern struct ARMul_State *state;
|
||||
|
||||
struct _sim_cpu {
|
||||
|
||||
sim_cpu_base base;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
199
sim/avr/interp.c
199
sim/avr/interp.c
@@ -729,19 +729,20 @@ static void
|
||||
do_call (SIM_CPU *cpu, unsigned int npc)
|
||||
{
|
||||
const struct avr_sim_state *state = AVR_SIM_STATE (CPU_STATE (cpu));
|
||||
struct avr_sim_cpu *avr_cpu = AVR_SIM_CPU (cpu);
|
||||
unsigned int sp = read_word (REG_SP);
|
||||
|
||||
/* Big endian! */
|
||||
sram[sp--] = cpu->pc;
|
||||
sram[sp--] = cpu->pc >> 8;
|
||||
sram[sp--] = avr_cpu->pc;
|
||||
sram[sp--] = avr_cpu->pc >> 8;
|
||||
if (state->avr_pc22)
|
||||
{
|
||||
sram[sp--] = cpu->pc >> 16;
|
||||
cpu->cycles++;
|
||||
sram[sp--] = avr_cpu->pc >> 16;
|
||||
avr_cpu->cycles++;
|
||||
}
|
||||
write_word (REG_SP, sp);
|
||||
cpu->pc = npc & PC_MASK;
|
||||
cpu->cycles += 3;
|
||||
avr_cpu->pc = npc & PC_MASK;
|
||||
avr_cpu->cycles += 3;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -775,18 +776,21 @@ get_lpm (unsigned int addr)
|
||||
static void
|
||||
gen_mul (SIM_CPU *cpu, unsigned int res)
|
||||
{
|
||||
struct avr_sim_cpu *avr_cpu = AVR_SIM_CPU (cpu);
|
||||
|
||||
write_word (0, res);
|
||||
sram[SREG] &= ~(SREG_Z | SREG_C);
|
||||
if (res == 0)
|
||||
sram[SREG] |= SREG_Z;
|
||||
if (res & 0x8000)
|
||||
sram[SREG] |= SREG_C;
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
}
|
||||
|
||||
static void
|
||||
step_once (SIM_CPU *cpu)
|
||||
{
|
||||
struct avr_sim_cpu *avr_cpu = AVR_SIM_CPU (cpu);
|
||||
unsigned int ipc;
|
||||
|
||||
int code;
|
||||
@@ -795,8 +799,8 @@ step_once (SIM_CPU *cpu)
|
||||
byte r, d, vd;
|
||||
|
||||
again:
|
||||
code = flash[cpu->pc].code;
|
||||
op = flash[cpu->pc].op;
|
||||
code = flash[avr_cpu->pc].code;
|
||||
op = flash[avr_cpu->pc].op;
|
||||
|
||||
#if 0
|
||||
if (tracing && code != OP_unknown)
|
||||
@@ -829,27 +833,27 @@ step_once (SIM_CPU *cpu)
|
||||
}
|
||||
|
||||
if (!tracing)
|
||||
sim_cb_eprintf (callback, "%06x: %04x\n", 2 * cpu->pc, flash[cpu->pc].op);
|
||||
sim_cb_eprintf (callback, "%06x: %04x\n", 2 * avr_cpu->pc, flash[avr_cpu->pc].op);
|
||||
else
|
||||
{
|
||||
sim_cb_eprintf (callback, "pc=0x%06x insn=0x%04x code=%d r=%d\n",
|
||||
2 * cpu->pc, flash[cpu->pc].op, code, flash[cpu->pc].r);
|
||||
disassemble_insn (CPU_STATE (cpu), cpu->pc);
|
||||
2 * avr_cpu->pc, flash[avr_cpu->pc].op, code, flash[avr_cpu->pc].r);
|
||||
disassemble_insn (CPU_STATE (cpu), avr_cpu->pc);
|
||||
sim_cb_eprintf (callback, "\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ipc = cpu->pc;
|
||||
cpu->pc = (cpu->pc + 1) & PC_MASK;
|
||||
cpu->cycles++;
|
||||
ipc = avr_cpu->pc;
|
||||
avr_cpu->pc = (avr_cpu->pc + 1) & PC_MASK;
|
||||
avr_cpu->cycles++;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case OP_unknown:
|
||||
flash[ipc].code = decode(ipc);
|
||||
cpu->pc = ipc;
|
||||
cpu->cycles--;
|
||||
avr_cpu->pc = ipc;
|
||||
avr_cpu->cycles--;
|
||||
goto again;
|
||||
|
||||
case OP_nop:
|
||||
@@ -857,23 +861,23 @@ step_once (SIM_CPU *cpu)
|
||||
|
||||
case OP_jmp:
|
||||
/* 2 words instruction, but we don't care about the pc. */
|
||||
cpu->pc = ((flash[ipc].r << 16) | flash[ipc + 1].op) & PC_MASK;
|
||||
cpu->cycles += 2;
|
||||
avr_cpu->pc = ((flash[ipc].r << 16) | flash[ipc + 1].op) & PC_MASK;
|
||||
avr_cpu->cycles += 2;
|
||||
break;
|
||||
|
||||
case OP_eijmp:
|
||||
cpu->pc = ((sram[EIND] << 16) | read_word (REGZ)) & PC_MASK;
|
||||
cpu->cycles += 2;
|
||||
avr_cpu->pc = ((sram[EIND] << 16) | read_word (REGZ)) & PC_MASK;
|
||||
avr_cpu->cycles += 2;
|
||||
break;
|
||||
|
||||
case OP_ijmp:
|
||||
cpu->pc = read_word (REGZ) & PC_MASK;
|
||||
cpu->cycles += 1;
|
||||
avr_cpu->pc = read_word (REGZ) & PC_MASK;
|
||||
avr_cpu->cycles += 1;
|
||||
break;
|
||||
|
||||
case OP_call:
|
||||
/* 2 words instruction. */
|
||||
cpu->pc++;
|
||||
avr_cpu->pc++;
|
||||
do_call (cpu, (flash[ipc].r << 16) | flash[ipc + 1].op);
|
||||
break;
|
||||
|
||||
@@ -886,7 +890,7 @@ step_once (SIM_CPU *cpu)
|
||||
break;
|
||||
|
||||
case OP_rcall:
|
||||
do_call (cpu, cpu->pc + sign_ext (op & 0xfff, 12));
|
||||
do_call (cpu, avr_cpu->pc + sign_ext (op & 0xfff, 12));
|
||||
break;
|
||||
|
||||
case OP_reti:
|
||||
@@ -898,16 +902,16 @@ step_once (SIM_CPU *cpu)
|
||||
unsigned int sp = read_word (REG_SP);
|
||||
if (state->avr_pc22)
|
||||
{
|
||||
cpu->pc = sram[++sp] << 16;
|
||||
cpu->cycles++;
|
||||
avr_cpu->pc = sram[++sp] << 16;
|
||||
avr_cpu->cycles++;
|
||||
}
|
||||
else
|
||||
cpu->pc = 0;
|
||||
cpu->pc |= sram[++sp] << 8;
|
||||
cpu->pc |= sram[++sp];
|
||||
avr_cpu->pc = 0;
|
||||
avr_cpu->pc |= sram[++sp] << 8;
|
||||
avr_cpu->pc |= sram[++sp];
|
||||
write_word (REG_SP, sp);
|
||||
}
|
||||
cpu->cycles += 3;
|
||||
avr_cpu->cycles += 3;
|
||||
break;
|
||||
|
||||
case OP_break:
|
||||
@@ -935,9 +939,9 @@ step_once (SIM_CPU *cpu)
|
||||
case OP_sbrs:
|
||||
if (((sram[get_d (op)] & flash[ipc].r) == 0) ^ ((op & 0x0200) != 0))
|
||||
{
|
||||
int l = get_insn_length (cpu->pc);
|
||||
cpu->pc += l;
|
||||
cpu->cycles += l;
|
||||
int l = get_insn_length (avr_cpu->pc);
|
||||
avr_cpu->pc += l;
|
||||
avr_cpu->cycles += l;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -947,7 +951,7 @@ step_once (SIM_CPU *cpu)
|
||||
sram[sp--] = sram[get_d (op)];
|
||||
write_word (REG_SP, sp);
|
||||
}
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_pop:
|
||||
@@ -956,7 +960,7 @@ step_once (SIM_CPU *cpu)
|
||||
sram[get_d (op)] = sram[++sp];
|
||||
write_word (REG_SP, sp);
|
||||
}
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_bclr:
|
||||
@@ -968,8 +972,8 @@ step_once (SIM_CPU *cpu)
|
||||
break;
|
||||
|
||||
case OP_rjmp:
|
||||
cpu->pc = (cpu->pc + sign_ext (op & 0xfff, 12)) & PC_MASK;
|
||||
cpu->cycles++;
|
||||
avr_cpu->pc = (avr_cpu->pc + sign_ext (op & 0xfff, 12)) & PC_MASK;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_eor:
|
||||
@@ -1206,9 +1210,9 @@ step_once (SIM_CPU *cpu)
|
||||
if (d == STDIO_PORT)
|
||||
putchar (res);
|
||||
else if (d == EXIT_PORT)
|
||||
sim_engine_halt (CPU_STATE (cpu), cpu, NULL, cpu->pc, sim_exited, 0);
|
||||
sim_engine_halt (CPU_STATE (cpu), cpu, NULL, avr_cpu->pc, sim_exited, 0);
|
||||
else if (d == ABORT_PORT)
|
||||
sim_engine_halt (CPU_STATE (cpu), cpu, NULL, cpu->pc, sim_exited, 1);
|
||||
sim_engine_halt (CPU_STATE (cpu), cpu, NULL, avr_cpu->pc, sim_exited, 1);
|
||||
break;
|
||||
|
||||
case OP_in:
|
||||
@@ -1229,18 +1233,18 @@ step_once (SIM_CPU *cpu)
|
||||
case OP_sbic:
|
||||
if (!(sram[get_biA (op) + 0x20] & 1 << get_b(op)))
|
||||
{
|
||||
int l = get_insn_length (cpu->pc);
|
||||
cpu->pc += l;
|
||||
cpu->cycles += l;
|
||||
int l = get_insn_length (avr_cpu->pc);
|
||||
avr_cpu->pc += l;
|
||||
avr_cpu->cycles += l;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_sbis:
|
||||
if (sram[get_biA (op) + 0x20] & 1 << get_b(op))
|
||||
{
|
||||
int l = get_insn_length (cpu->pc);
|
||||
cpu->pc += l;
|
||||
cpu->cycles += l;
|
||||
int l = get_insn_length (avr_cpu->pc);
|
||||
avr_cpu->pc += l;
|
||||
avr_cpu->cycles += l;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1251,23 +1255,23 @@ step_once (SIM_CPU *cpu)
|
||||
break;
|
||||
|
||||
case OP_lds:
|
||||
sram[get_d (op)] = sram[flash[cpu->pc].op];
|
||||
cpu->pc++;
|
||||
cpu->cycles++;
|
||||
sram[get_d (op)] = sram[flash[avr_cpu->pc].op];
|
||||
avr_cpu->pc++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_sts:
|
||||
sram[flash[cpu->pc].op] = sram[get_d (op)];
|
||||
cpu->pc++;
|
||||
cpu->cycles++;
|
||||
sram[flash[avr_cpu->pc].op] = sram[get_d (op)];
|
||||
avr_cpu->pc++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_cpse:
|
||||
if (sram[get_r (op)] == sram[get_d (op)])
|
||||
{
|
||||
int l = get_insn_length (cpu->pc);
|
||||
cpu->pc += l;
|
||||
cpu->cycles += l;
|
||||
int l = get_insn_length (avr_cpu->pc);
|
||||
avr_cpu->pc += l;
|
||||
avr_cpu->cycles += l;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1304,42 +1308,42 @@ step_once (SIM_CPU *cpu)
|
||||
case OP_brbc:
|
||||
if (!(sram[SREG] & flash[ipc].r))
|
||||
{
|
||||
cpu->pc = (cpu->pc + get_k (op)) & PC_MASK;
|
||||
cpu->cycles++;
|
||||
avr_cpu->pc = (avr_cpu->pc + get_k (op)) & PC_MASK;
|
||||
avr_cpu->cycles++;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_brbs:
|
||||
if (sram[SREG] & flash[ipc].r)
|
||||
{
|
||||
cpu->pc = (cpu->pc + get_k (op)) & PC_MASK;
|
||||
cpu->cycles++;
|
||||
avr_cpu->pc = (avr_cpu->pc + get_k (op)) & PC_MASK;
|
||||
avr_cpu->cycles++;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_lpm:
|
||||
sram[0] = get_lpm (read_word (REGZ));
|
||||
cpu->cycles += 2;
|
||||
avr_cpu->cycles += 2;
|
||||
break;
|
||||
|
||||
case OP_lpm_Z:
|
||||
sram[get_d (op)] = get_lpm (read_word (REGZ));
|
||||
cpu->cycles += 2;
|
||||
avr_cpu->cycles += 2;
|
||||
break;
|
||||
|
||||
case OP_lpm_inc_Z:
|
||||
sram[get_d (op)] = get_lpm (read_word_post_inc (REGZ));
|
||||
cpu->cycles += 2;
|
||||
avr_cpu->cycles += 2;
|
||||
break;
|
||||
|
||||
case OP_elpm:
|
||||
sram[0] = get_lpm (get_z ());
|
||||
cpu->cycles += 2;
|
||||
avr_cpu->cycles += 2;
|
||||
break;
|
||||
|
||||
case OP_elpm_Z:
|
||||
sram[get_d (op)] = get_lpm (get_z ());
|
||||
cpu->cycles += 2;
|
||||
avr_cpu->cycles += 2;
|
||||
break;
|
||||
|
||||
case OP_elpm_inc_Z:
|
||||
@@ -1352,97 +1356,97 @@ step_once (SIM_CPU *cpu)
|
||||
sram[REGZ_HI] = z >> 8;
|
||||
sram[RAMPZ] = z >> 16;
|
||||
}
|
||||
cpu->cycles += 2;
|
||||
avr_cpu->cycles += 2;
|
||||
break;
|
||||
|
||||
case OP_ld_Z_inc:
|
||||
sram[get_d (op)] = sram[read_word_post_inc (REGZ) & SRAM_MASK];
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_ld_dec_Z:
|
||||
sram[get_d (op)] = sram[read_word_pre_dec (REGZ) & SRAM_MASK];
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_ld_X_inc:
|
||||
sram[get_d (op)] = sram[read_word_post_inc (REGX) & SRAM_MASK];
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_ld_dec_X:
|
||||
sram[get_d (op)] = sram[read_word_pre_dec (REGX) & SRAM_MASK];
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_ld_Y_inc:
|
||||
sram[get_d (op)] = sram[read_word_post_inc (REGY) & SRAM_MASK];
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_ld_dec_Y:
|
||||
sram[get_d (op)] = sram[read_word_pre_dec (REGY) & SRAM_MASK];
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_st_X:
|
||||
sram[read_word (REGX) & SRAM_MASK] = sram[get_d (op)];
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_st_X_inc:
|
||||
sram[read_word_post_inc (REGX) & SRAM_MASK] = sram[get_d (op)];
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_st_dec_X:
|
||||
sram[read_word_pre_dec (REGX) & SRAM_MASK] = sram[get_d (op)];
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_st_Z_inc:
|
||||
sram[read_word_post_inc (REGZ) & SRAM_MASK] = sram[get_d (op)];
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_st_dec_Z:
|
||||
sram[read_word_pre_dec (REGZ) & SRAM_MASK] = sram[get_d (op)];
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_st_Y_inc:
|
||||
sram[read_word_post_inc (REGY) & SRAM_MASK] = sram[get_d (op)];
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_st_dec_Y:
|
||||
sram[read_word_pre_dec (REGY) & SRAM_MASK] = sram[get_d (op)];
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_std_Y:
|
||||
sram[read_word (REGY) + flash[ipc].r] = sram[get_d (op)];
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_std_Z:
|
||||
sram[read_word (REGZ) + flash[ipc].r] = sram[get_d (op)];
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_ldd_Z:
|
||||
sram[get_d (op)] = sram[read_word (REGZ) + flash[ipc].r];
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_ldd_Y:
|
||||
sram[get_d (op)] = sram[read_word (REGY) + flash[ipc].r];
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_ld_X:
|
||||
sram[get_d (op)] = sram[read_word (REGX) & SRAM_MASK];
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_sbiw:
|
||||
@@ -1468,7 +1472,7 @@ step_once (SIM_CPU *cpu)
|
||||
sram[SREG] |= SREG_S;
|
||||
write_word (d, wres);
|
||||
}
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_adiw:
|
||||
@@ -1494,14 +1498,14 @@ step_once (SIM_CPU *cpu)
|
||||
sram[SREG] |= SREG_S;
|
||||
write_word (d, wres);
|
||||
}
|
||||
cpu->cycles++;
|
||||
avr_cpu->cycles++;
|
||||
break;
|
||||
|
||||
case OP_bad:
|
||||
sim_engine_halt (CPU_STATE (cpu), cpu, NULL, cpu->pc, sim_signalled, SIM_SIGILL);
|
||||
sim_engine_halt (CPU_STATE (cpu), cpu, NULL, avr_cpu->pc, sim_signalled, SIM_SIGILL);
|
||||
|
||||
default:
|
||||
sim_engine_halt (CPU_STATE (cpu), cpu, NULL, cpu->pc, sim_signalled, SIM_SIGILL);
|
||||
sim_engine_halt (CPU_STATE (cpu), cpu, NULL, avr_cpu->pc, sim_signalled, SIM_SIGILL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1602,6 +1606,7 @@ sim_read (SIM_DESC sd, SIM_ADDR addr, void *buffer, int size)
|
||||
static int
|
||||
avr_reg_store (SIM_CPU *cpu, int rn, const void *buf, int length)
|
||||
{
|
||||
struct avr_sim_cpu *avr_cpu = AVR_SIM_CPU (cpu);
|
||||
const unsigned char *memory = buf;
|
||||
|
||||
if (rn < 32 && length == 1)
|
||||
@@ -1622,9 +1627,9 @@ avr_reg_store (SIM_CPU *cpu, int rn, const void *buf, int length)
|
||||
}
|
||||
if (rn == AVR_PC_REGNUM && length == 4)
|
||||
{
|
||||
cpu->pc = (memory[0] >> 1) | (memory[1] << 7)
|
||||
avr_cpu->pc = (memory[0] >> 1) | (memory[1] << 7)
|
||||
| (memory[2] << 15) | (memory[3] << 23);
|
||||
cpu->pc &= PC_MASK;
|
||||
avr_cpu->pc &= PC_MASK;
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
@@ -1633,6 +1638,7 @@ avr_reg_store (SIM_CPU *cpu, int rn, const void *buf, int length)
|
||||
static int
|
||||
avr_reg_fetch (SIM_CPU *cpu, int rn, void *buf, int length)
|
||||
{
|
||||
struct avr_sim_cpu *avr_cpu = AVR_SIM_CPU (cpu);
|
||||
unsigned char *memory = buf;
|
||||
|
||||
if (rn < 32 && length == 1)
|
||||
@@ -1653,10 +1659,10 @@ avr_reg_fetch (SIM_CPU *cpu, int rn, void *buf, int length)
|
||||
}
|
||||
if (rn == AVR_PC_REGNUM && length == 4)
|
||||
{
|
||||
memory[0] = cpu->pc << 1;
|
||||
memory[1] = cpu->pc >> 7;
|
||||
memory[2] = cpu->pc >> 15;
|
||||
memory[3] = cpu->pc >> 23;
|
||||
memory[0] = avr_cpu->pc << 1;
|
||||
memory[1] = avr_cpu->pc >> 7;
|
||||
memory[2] = avr_cpu->pc >> 15;
|
||||
memory[3] = avr_cpu->pc >> 23;
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
@@ -1665,13 +1671,13 @@ avr_reg_fetch (SIM_CPU *cpu, int rn, void *buf, int length)
|
||||
static sim_cia
|
||||
avr_pc_get (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->pc;
|
||||
return AVR_SIM_CPU (cpu)->pc;
|
||||
}
|
||||
|
||||
static void
|
||||
avr_pc_set (sim_cpu *cpu, sim_cia pc)
|
||||
{
|
||||
cpu->pc = pc;
|
||||
AVR_SIM_CPU (cpu)->pc = pc;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1696,7 +1702,8 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb,
|
||||
current_target_byte_order = BFD_ENDIAN_LITTLE;
|
||||
|
||||
/* The cpu data is kept in a separately allocated chunk of memory. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct avr_sim_cpu))
|
||||
!= SIM_RC_OK)
|
||||
{
|
||||
free_state (sd);
|
||||
return 0;
|
||||
|
||||
@@ -23,16 +23,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "sim-base.h"
|
||||
|
||||
struct _sim_cpu {
|
||||
struct avr_sim_cpu {
|
||||
/* The only real register. */
|
||||
uint32_t pc;
|
||||
|
||||
/* We update a cycle counter. */
|
||||
uint32_t cycles;
|
||||
|
||||
sim_cpu_base base;
|
||||
};
|
||||
|
||||
#define AVR_SIM_CPU(cpu) ((struct avr_sim_cpu *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
struct avr_sim_state {
|
||||
/* If true, the pc needs more than 2 bytes. */
|
||||
int avr_pc22;
|
||||
|
||||
@@ -643,8 +643,6 @@ free_state (SIM_DESC sd)
|
||||
static void
|
||||
bfin_initialize_cpu (SIM_DESC sd, SIM_CPU *cpu)
|
||||
{
|
||||
memset (&cpu->state, 0, sizeof (cpu->state));
|
||||
|
||||
PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu)) = 0;
|
||||
|
||||
bfin_model_cpu_init (sd, cpu);
|
||||
@@ -674,7 +672,8 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback,
|
||||
current_target_byte_order = BFD_ENDIAN_LITTLE;
|
||||
|
||||
/* The cpu data is kept in a separately allocated chunk of memory. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct bfin_cpu_state))
|
||||
!= SIM_RC_OK)
|
||||
{
|
||||
free_state (sd);
|
||||
return 0;
|
||||
|
||||
@@ -29,13 +29,7 @@
|
||||
|
||||
#include "machs.h"
|
||||
|
||||
struct _sim_cpu {
|
||||
/* ... simulator specific members ... */
|
||||
struct bfin_cpu_state state;
|
||||
sim_cpu_base base;
|
||||
};
|
||||
#define BFIN_CPU_STATE ((cpu)->state)
|
||||
|
||||
#define BFIN_CPU_STATE (*(struct bfin_cpu_state *) CPU_ARCH_DATA (cpu))
|
||||
#define STATE_BOARD_DATA(sd) ((struct bfin_board_data *) STATE_ARCH_DATA (sd))
|
||||
|
||||
#include "sim-config.h"
|
||||
|
||||
@@ -54,7 +54,7 @@ do { \
|
||||
CPU (h_pc) = (x);\
|
||||
;} while (0)
|
||||
} hardware;
|
||||
#define CPU_CGEN_HW(cpu) (& (cpu)->cpu_data.hardware)
|
||||
#define CPU_CGEN_HW(cpu) (& BPF_SIM_CPU (cpu)->cpu_data.hardware)
|
||||
} BPFBF_CPU_DATA;
|
||||
|
||||
/* Cover fns for register access. */
|
||||
|
||||
@@ -132,7 +132,7 @@ sim_open (SIM_OPEN_KIND kind,
|
||||
STATE_MACHS (sd) = bpf_sim_machs;
|
||||
STATE_MODEL_NAME (sd) = "bpf-def";
|
||||
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct bpf_sim_cpu)) != SIM_RC_OK)
|
||||
goto error;
|
||||
|
||||
if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
|
||||
|
||||
@@ -29,15 +29,19 @@
|
||||
#include "bpf-sim.h"
|
||||
#include "bpf-helpers.h"
|
||||
|
||||
|
||||
struct _sim_cpu
|
||||
struct bpf_sim_cpu
|
||||
{
|
||||
sim_cpu_base base;
|
||||
CGEN_CPU cgen_cpu;
|
||||
|
||||
/* CPU-model specific parts go here.
|
||||
Note that in files that don't need to access these pieces WANT_CPU_FOO
|
||||
won't be defined and thus these parts won't appear. This is ok in the
|
||||
sense that things work. It is a source of bugs though.
|
||||
One has to of course be careful to not take the size of this
|
||||
struct and no structure members accessed in non-cpu specific files can
|
||||
go after here. */
|
||||
#if defined (WANT_CPU_BPFBF)
|
||||
BPFBF_CPU_DATA cpu_data;
|
||||
#endif
|
||||
};
|
||||
#define BPF_SIM_CPU(cpu) ((struct bpf_sim_cpu *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
#endif /* ! SIM_MAIN_H */
|
||||
|
||||
@@ -20,6 +20,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#ifndef CGEN_CPU_H
|
||||
#define CGEN_CPU_H
|
||||
|
||||
#include "cgen-defs.h"
|
||||
#include "cgen-fpu.h"
|
||||
#include "cgen-par.h"
|
||||
#include "cgen-scache.h"
|
||||
|
||||
/* Type of function that is ultimately called by sim_resume. */
|
||||
typedef void (ENGINE_FN) (SIM_CPU *);
|
||||
|
||||
@@ -100,6 +105,6 @@ typedef struct {
|
||||
|
||||
/* Shorthand macro for fetching registers.
|
||||
CPU_CGEN_HW is defined in cpu.h. */
|
||||
#define CPU(x) (CPU_CGEN_HW (current_cpu)->x)
|
||||
//#define CPU(x) (CPU_CGEN_HW (current_cpu)->x)
|
||||
|
||||
#endif /* CGEN_CPU_H */
|
||||
|
||||
@@ -20,6 +20,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#ifndef CGEN_DEFS_H
|
||||
#define CGEN_DEFS_H
|
||||
|
||||
#include "opcode/cgen.h"
|
||||
#include "cgen-types.h"
|
||||
|
||||
/* Compute number of longs required to hold N bits. */
|
||||
#define HOST_LONGS_FOR_BITS(n) \
|
||||
(((n) + sizeof (long) * 8 - 1) / sizeof (long) * 8)
|
||||
|
||||
@@ -20,6 +20,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#ifndef CGEN_SCACHE_H
|
||||
#define CGEN_SCACHE_H
|
||||
|
||||
#include "cgen-types.h"
|
||||
|
||||
/* When caching bb's, instructions are extracted into "chains".
|
||||
SCACHE_MAP is a hash table into these chains. */
|
||||
|
||||
|
||||
@@ -31,12 +31,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* ??? wip. better solution must wait. */
|
||||
|
||||
SIM_RC
|
||||
sim_cpu_alloc_all (SIM_DESC sd, int ncpus)
|
||||
sim_cpu_alloc_all_extra (SIM_DESC sd, int ncpus, size_t extra_bytes)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < ncpus; ++c)
|
||||
STATE_CPU (sd, c) = sim_cpu_alloc (sd);
|
||||
STATE_CPU (sd, c) = sim_cpu_alloc_extra (sd, extra_bytes);
|
||||
return SIM_RC_OK;
|
||||
}
|
||||
|
||||
@@ -44,15 +44,18 @@ sim_cpu_alloc_all (SIM_DESC sd, int ncpus)
|
||||
EXTRA_BYTES is additional space to allocate for the sim_cpu struct. */
|
||||
|
||||
sim_cpu *
|
||||
sim_cpu_alloc (SIM_DESC sd)
|
||||
sim_cpu_alloc_extra (SIM_DESC sd, size_t extra_bytes)
|
||||
{
|
||||
int extra_bytes = 0;
|
||||
sim_cpu *cpu = zalloc (sizeof (*cpu));
|
||||
|
||||
#ifdef CGEN_ARCH
|
||||
extra_bytes += cgen_cpu_max_extra_bytes (sd);
|
||||
#ifndef CGEN_ARCH
|
||||
# define cgen_cpu_max_extra_bytes(sd) 0
|
||||
#endif
|
||||
extra_bytes += cgen_cpu_max_extra_bytes(sd);
|
||||
if (extra_bytes)
|
||||
CPU_ARCH_DATA (cpu) = zalloc (extra_bytes);
|
||||
|
||||
return zalloc (sizeof (sim_cpu) + extra_bytes);
|
||||
return cpu;
|
||||
}
|
||||
|
||||
/* Free all resources held by all cpus. */
|
||||
@@ -72,6 +75,7 @@ sim_cpu_free_all (SIM_DESC sd)
|
||||
void
|
||||
sim_cpu_free (sim_cpu *cpu)
|
||||
{
|
||||
free (CPU_ARCH_DATA (cpu));
|
||||
free (cpu);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* Type of function to return an insn name. */
|
||||
typedef const char * (CPU_INSN_NAME_FN) (sim_cpu *, int);
|
||||
|
||||
#include "cgen-cpu.h"
|
||||
|
||||
/* Types for register access functions.
|
||||
These routines implement the sim_{fetch,store}_register interface. */
|
||||
typedef int (CPUREG_FETCH_FN) (sim_cpu *, int, void *, int);
|
||||
@@ -42,39 +44,38 @@ typedef void (PC_STORE_FN) (sim_cpu *, sim_cia);
|
||||
|
||||
/* Pseudo baseclass for each cpu. */
|
||||
|
||||
typedef struct {
|
||||
|
||||
struct _sim_cpu {
|
||||
/* Backlink to main state struct. */
|
||||
SIM_DESC state;
|
||||
#define CPU_STATE(cpu) ((cpu)->base.state)
|
||||
#define CPU_STATE(cpu) ((cpu)->state)
|
||||
|
||||
/* Processor index within the SD_DESC */
|
||||
int index;
|
||||
#define CPU_INDEX(cpu) ((cpu)->base.index)
|
||||
#define CPU_INDEX(cpu) ((cpu)->index)
|
||||
|
||||
/* The name of the cpu. */
|
||||
const char *name;
|
||||
#define CPU_NAME(cpu) ((cpu)->base.name)
|
||||
#define CPU_NAME(cpu) ((cpu)->name)
|
||||
|
||||
/* Options specific to this cpu. */
|
||||
struct option_list *options;
|
||||
#define CPU_OPTIONS(cpu) ((cpu)->base.options)
|
||||
#define CPU_OPTIONS(cpu) ((cpu)->options)
|
||||
|
||||
/* Processor specific core data */
|
||||
sim_cpu_core core;
|
||||
#define CPU_CORE(cpu) (& (cpu)->base.core)
|
||||
#define CPU_CORE(cpu) (& (cpu)->core)
|
||||
|
||||
/* Number of instructions (used to iterate over CPU_INSN_NAME). */
|
||||
unsigned int max_insns;
|
||||
#define CPU_MAX_INSNS(cpu) ((cpu)->base.max_insns)
|
||||
#define CPU_MAX_INSNS(cpu) ((cpu)->max_insns)
|
||||
|
||||
/* Function to return the name of an insn. */
|
||||
CPU_INSN_NAME_FN *insn_name;
|
||||
#define CPU_INSN_NAME(cpu) ((cpu)->base.insn_name)
|
||||
#define CPU_INSN_NAME(cpu) ((cpu)->insn_name)
|
||||
|
||||
/* Trace data. See sim-trace.h. */
|
||||
TRACE_DATA trace_data;
|
||||
#define CPU_TRACE_DATA(cpu) (& (cpu)->base.trace_data)
|
||||
#define CPU_TRACE_DATA(cpu) (& (cpu)->trace_data)
|
||||
|
||||
/* Maximum number of debuggable entities.
|
||||
This debugging is not intended for normal use.
|
||||
@@ -86,7 +87,7 @@ typedef struct {
|
||||
|
||||
/* Boolean array of specified debugging flags. */
|
||||
char debug_flags[MAX_DEBUG_VALUES];
|
||||
#define CPU_DEBUG_FLAGS(cpu) ((cpu)->base.debug_flags)
|
||||
#define CPU_DEBUG_FLAGS(cpu) ((cpu)->debug_flags)
|
||||
/* Standard values. */
|
||||
#define DEBUG_INSN_IDX 0
|
||||
#define DEBUG_NEXT_IDX 2 /* simulator specific debug bits begin here */
|
||||
@@ -94,38 +95,48 @@ typedef struct {
|
||||
/* Debugging output goes to this or stderr if NULL.
|
||||
We can't store `stderr' here as stderr goes through a callback. */
|
||||
FILE *debug_file;
|
||||
#define CPU_DEBUG_FILE(cpu) ((cpu)->base.debug_file)
|
||||
#define CPU_DEBUG_FILE(cpu) ((cpu)->debug_file)
|
||||
|
||||
/* Profile data. See sim-profile.h. */
|
||||
PROFILE_DATA profile_data;
|
||||
#define CPU_PROFILE_DATA(cpu) (& (cpu)->base.profile_data)
|
||||
#define CPU_PROFILE_DATA(cpu) (& (cpu)->profile_data)
|
||||
|
||||
/* Machine tables for this cpu. See sim-model.h. */
|
||||
const SIM_MACH *mach;
|
||||
#define CPU_MACH(cpu) ((cpu)->base.mach)
|
||||
#define CPU_MACH(cpu) ((cpu)->mach)
|
||||
/* The selected model. */
|
||||
const SIM_MODEL *model;
|
||||
#define CPU_MODEL(cpu) ((cpu)->base.model)
|
||||
#define CPU_MODEL(cpu) ((cpu)->model)
|
||||
/* Model data (profiling state, etc.). */
|
||||
void *model_data;
|
||||
#define CPU_MODEL_DATA(cpu) ((cpu)->base.model_data)
|
||||
#define CPU_MODEL_DATA(cpu) ((cpu)->model_data)
|
||||
|
||||
/* Routines to fetch/store registers. */
|
||||
CPUREG_FETCH_FN *reg_fetch;
|
||||
#define CPU_REG_FETCH(c) ((c)->base.reg_fetch)
|
||||
#define CPU_REG_FETCH(c) ((c)->reg_fetch)
|
||||
CPUREG_STORE_FN *reg_store;
|
||||
#define CPU_REG_STORE(c) ((c)->base.reg_store)
|
||||
#define CPU_REG_STORE(c) ((c)->reg_store)
|
||||
PC_FETCH_FN *pc_fetch;
|
||||
#define CPU_PC_FETCH(c) ((c)->base.pc_fetch)
|
||||
#define CPU_PC_FETCH(c) ((c)->pc_fetch)
|
||||
PC_STORE_FN *pc_store;
|
||||
#define CPU_PC_STORE(c) ((c)->base.pc_store)
|
||||
#define CPU_PC_STORE(c) ((c)->pc_store)
|
||||
|
||||
} sim_cpu_base;
|
||||
/* Static parts of cgen. */
|
||||
CGEN_CPU cgen_cpu;
|
||||
#define CPU_CGEN_CPU(cpu) ((cpu)->cgen_cpu)
|
||||
|
||||
/* Pointer for sim target to store arbitrary cpu data. Normally the
|
||||
target should define a struct and use it here. */
|
||||
void *arch_data;
|
||||
#define CPU_ARCH_DATA(cpu) ((cpu)->arch_data)
|
||||
};
|
||||
|
||||
/* Create all cpus. */
|
||||
extern SIM_RC sim_cpu_alloc_all (SIM_DESC, int);
|
||||
extern SIM_RC sim_cpu_alloc_all_extra (SIM_DESC, int, size_t);
|
||||
#define sim_cpu_alloc_all(state, ncpus) sim_cpu_alloc_all_extra (state, ncpus, 0)
|
||||
/* Create a cpu. */
|
||||
extern sim_cpu *sim_cpu_alloc (SIM_DESC);
|
||||
extern sim_cpu *sim_cpu_alloc_extra (SIM_DESC, size_t);
|
||||
#define sim_cpu_alloc(sd) sim_cpu_alloc_extra (sd, 0)
|
||||
/* Release resources held by all cpus. */
|
||||
extern void sim_cpu_free_all (SIM_DESC);
|
||||
/* Release resources held by a cpu. */
|
||||
|
||||
@@ -29,9 +29,4 @@ typedef unsigned long int uword;
|
||||
|
||||
#include "cr16_sim.h"
|
||||
|
||||
struct _sim_cpu {
|
||||
|
||||
sim_cpu_base base;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -119,7 +119,7 @@ CPU (h_sr_v10[(index)]) = (x);\
|
||||
#define GET_H_PREFIXREG_PRE_V32() CPU (h_prefixreg_pre_v32)
|
||||
#define SET_H_PREFIXREG_PRE_V32(x) (CPU (h_prefixreg_pre_v32) = (x))
|
||||
} hardware;
|
||||
#define CPU_CGEN_HW(cpu) (& (cpu)->cpu_data.hardware)
|
||||
#define CPU_CGEN_HW(cpu) (& CRIS_SIM_CPU (cpu)->cpu_data.hardware)
|
||||
} CRISV10F_CPU_DATA;
|
||||
|
||||
/* Virtual regs. */
|
||||
|
||||
@@ -226,7 +226,7 @@ crisv32f_single_step_enabled (current_cpu);\
|
||||
}\
|
||||
;} while (0)
|
||||
} hardware;
|
||||
#define CPU_CGEN_HW(cpu) (& (cpu)->cpu_data.hardware)
|
||||
#define CPU_CGEN_HW(cpu) (& CRIS_SIM_CPU (cpu)->cpu_data.hardware)
|
||||
} CRISV32F_CPU_DATA;
|
||||
|
||||
/* Virtual regs. */
|
||||
|
||||
@@ -251,14 +251,13 @@ MY (set_target_thread_data) (SIM_CPU *current_cpu, USI val)
|
||||
static void *
|
||||
MY (make_thread_cpu_data) (SIM_CPU *current_cpu, void *context)
|
||||
{
|
||||
void *info = xmalloc (current_cpu->thread_cpu_data_size);
|
||||
struct cris_sim_cpu *cris_cpu = CRIS_SIM_CPU (current_cpu);
|
||||
void *info = xmalloc (cris_cpu->thread_cpu_data_size);
|
||||
|
||||
if (context != NULL)
|
||||
memcpy (info,
|
||||
context,
|
||||
current_cpu->thread_cpu_data_size);
|
||||
memcpy (info, context, cris_cpu->thread_cpu_data_size);
|
||||
else
|
||||
memset (info, 0, current_cpu->thread_cpu_data_size),abort();
|
||||
memset (info, 0, cris_cpu->thread_cpu_data_size),abort();
|
||||
return info;
|
||||
}
|
||||
|
||||
@@ -267,11 +266,13 @@ MY (make_thread_cpu_data) (SIM_CPU *current_cpu, void *context)
|
||||
void
|
||||
MY (f_specific_init) (SIM_CPU *current_cpu)
|
||||
{
|
||||
current_cpu->make_thread_cpu_data = MY (make_thread_cpu_data);
|
||||
current_cpu->thread_cpu_data_size = sizeof (current_cpu->cpu_data);
|
||||
current_cpu->set_target_thread_data = MY (set_target_thread_data);
|
||||
struct cris_sim_cpu *cris_cpu = CRIS_SIM_CPU (current_cpu);
|
||||
|
||||
cris_cpu->make_thread_cpu_data = MY (make_thread_cpu_data);
|
||||
cris_cpu->thread_cpu_data_size = sizeof (cris_cpu->cpu_data);
|
||||
cris_cpu->set_target_thread_data = MY (set_target_thread_data);
|
||||
#if WITH_HW
|
||||
current_cpu->deliver_interrupt = MY (deliver_interrupt);
|
||||
cris_cpu->deliver_interrupt = MY (deliver_interrupt);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -670,7 +670,8 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback, struct bfd *abfd,
|
||||
current_target_byte_order = BFD_ENDIAN_LITTLE;
|
||||
|
||||
/* The cpu data is kept in a separately allocated chunk of memory. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct cris_sim_cpu))
|
||||
!= SIM_RC_OK)
|
||||
{
|
||||
free_state (sd);
|
||||
return 0;
|
||||
@@ -926,6 +927,8 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback, struct bfd *abfd,
|
||||
for (i = 0; i < MAX_NR_PROCESSORS; ++i)
|
||||
{
|
||||
SIM_CPU *cpu = STATE_CPU (sd, i);
|
||||
struct cris_sim_cpu *cris_cpu = CRIS_SIM_CPU (cpu);
|
||||
|
||||
CPU_CPU_DESC (cpu) = cd;
|
||||
CPU_DISASSEMBLER (cpu) = cris_disassemble_insn;
|
||||
|
||||
@@ -936,20 +939,20 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback, struct bfd *abfd,
|
||||
(* CPU_REG_STORE (cpu)) (cpu, H_GR_SP, (const unsigned char *) sp_init, 4);
|
||||
|
||||
/* Set the simulator environment data. */
|
||||
cpu->highest_mmapped_page = NULL;
|
||||
cpu->endmem = endmem;
|
||||
cpu->endbrk = endbrk;
|
||||
cpu->stack_low = stack_low;
|
||||
cpu->syscalls = 0;
|
||||
cpu->m1threads = 0;
|
||||
cpu->threadno = 0;
|
||||
cpu->max_threadid = 0;
|
||||
cpu->thread_data = NULL;
|
||||
memset (cpu->sighandler, 0, sizeof (cpu->sighandler));
|
||||
cpu->make_thread_cpu_data = NULL;
|
||||
cpu->thread_cpu_data_size = 0;
|
||||
cris_cpu->highest_mmapped_page = NULL;
|
||||
cris_cpu->endmem = endmem;
|
||||
cris_cpu->endbrk = endbrk;
|
||||
cris_cpu->stack_low = stack_low;
|
||||
cris_cpu->syscalls = 0;
|
||||
cris_cpu->m1threads = 0;
|
||||
cris_cpu->threadno = 0;
|
||||
cris_cpu->max_threadid = 0;
|
||||
cris_cpu->thread_data = NULL;
|
||||
memset (cris_cpu->sighandler, 0, sizeof (cris_cpu->sighandler));
|
||||
cris_cpu->make_thread_cpu_data = NULL;
|
||||
cris_cpu->thread_cpu_data_size = 0;
|
||||
#if WITH_HW
|
||||
cpu->deliver_interrupt = NULL;
|
||||
cris_cpu->deliver_interrupt = NULL;
|
||||
#endif
|
||||
}
|
||||
#if WITH_HW
|
||||
|
||||
@@ -103,24 +103,18 @@ typedef int (*cris_interrupt_delivery_fn) (SIM_CPU *,
|
||||
enum cris_interrupt_type,
|
||||
unsigned int);
|
||||
|
||||
struct _sim_cpu {
|
||||
/* sim/common cpu base. */
|
||||
sim_cpu_base base;
|
||||
|
||||
/* Static parts of cgen. */
|
||||
CGEN_CPU cgen_cpu;
|
||||
|
||||
struct cris_sim_cpu {
|
||||
CRIS_MISC_PROFILE cris_misc_profile;
|
||||
#define CPU_CRIS_MISC_PROFILE(cpu) (& (cpu)->cris_misc_profile)
|
||||
#define CPU_CRIS_MISC_PROFILE(cpu) (& CRIS_SIM_CPU (cpu)->cris_misc_profile)
|
||||
|
||||
/* Copy of previous data; only valid when emitting trace-data after
|
||||
each insn. */
|
||||
CRIS_MISC_PROFILE cris_prev_misc_profile;
|
||||
#define CPU_CRIS_PREV_MISC_PROFILE(cpu) (& (cpu)->cris_prev_misc_profile)
|
||||
#define CPU_CRIS_PREV_MISC_PROFILE(cpu) (& CRIS_SIM_CPU (cpu)->cris_prev_misc_profile)
|
||||
|
||||
#if WITH_HW
|
||||
cris_interrupt_delivery_fn deliver_interrupt;
|
||||
#define CPU_CRIS_DELIVER_INTERRUPT(cpu) (cpu->deliver_interrupt)
|
||||
#define CPU_CRIS_DELIVER_INTERRUPT(cpu) (CRIS_SIM_CPU (cpu)->deliver_interrupt)
|
||||
#endif
|
||||
|
||||
/* Simulator environment data. */
|
||||
@@ -204,6 +198,7 @@ struct _sim_cpu {
|
||||
union { void *dummy[16]; } cpu_data_placeholder;
|
||||
#endif
|
||||
};
|
||||
#define CRIS_SIM_CPU(cpu) ((struct cris_sim_cpu *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
/* Misc. */
|
||||
|
||||
|
||||
412
sim/cris/traps.c
412
sim/cris/traps.c
@@ -160,7 +160,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Milliseconds since start of run. We use the number of syscalls to
|
||||
avoid introducing noise in the execution time. */
|
||||
#define TARGET_TIME_MS(cpu) ((cpu)->syscalls)
|
||||
#define TARGET_TIME_MS(cpu) (CRIS_SIM_CPU (cpu)->syscalls)
|
||||
|
||||
/* Seconds as in time(2). */
|
||||
#define TARGET_TIME(cpu) (TARGET_EPOCH + TARGET_TIME_MS (cpu) / 1000)
|
||||
@@ -936,10 +936,11 @@ void cris_dump_map (SIM_CPU *current_cpu);
|
||||
void
|
||||
cris_dump_map (SIM_CPU *current_cpu)
|
||||
{
|
||||
struct cris_sim_cpu *cris_cpu = CRIS_SIM_CPU (current_cpu);
|
||||
struct cris_sim_mmapped_page *mapp;
|
||||
USI start, end;
|
||||
|
||||
for (mapp = current_cpu->highest_mmapped_page,
|
||||
for (mapp = cris_cpu->highest_mmapped_page,
|
||||
start = mapp == NULL ? 0 : mapp->addr + 8192,
|
||||
end = mapp == NULL ? 0 : mapp->addr + 8191;
|
||||
mapp != NULL;
|
||||
@@ -954,7 +955,7 @@ cris_dump_map (SIM_CPU *current_cpu)
|
||||
start = mapp->addr;
|
||||
}
|
||||
|
||||
if (current_cpu->highest_mmapped_page != NULL)
|
||||
if (cris_cpu->highest_mmapped_page != NULL)
|
||||
sim_io_eprintf (CPU_STATE (current_cpu), "0x%x..0x%x\n", start, end);
|
||||
}
|
||||
|
||||
@@ -1077,6 +1078,8 @@ sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
|
||||
static void
|
||||
schedule (SIM_CPU *current_cpu, int next)
|
||||
{
|
||||
struct cris_sim_cpu *cris_cpu = CRIS_SIM_CPU (current_cpu);
|
||||
|
||||
/* Need to mark context-switches in the trace output. */
|
||||
if ((CPU_CRIS_MISC_PROFILE (current_cpu)->flags
|
||||
& FLAG_CRIS_MISC_PROFILE_XSIM_TRACE))
|
||||
@@ -1084,34 +1087,34 @@ schedule (SIM_CPU *current_cpu, int next)
|
||||
"\t#:%d\n", next);
|
||||
|
||||
/* Copy the current context (if there is one) to its slot. */
|
||||
if (current_cpu->thread_data[current_cpu->threadno].cpu_context)
|
||||
memcpy (current_cpu->thread_data[current_cpu->threadno].cpu_context,
|
||||
¤t_cpu->cpu_data_placeholder,
|
||||
current_cpu->thread_cpu_data_size);
|
||||
if (cris_cpu->thread_data[cris_cpu->threadno].cpu_context)
|
||||
memcpy (cris_cpu->thread_data[cris_cpu->threadno].cpu_context,
|
||||
&cris_cpu->cpu_data_placeholder,
|
||||
cris_cpu->thread_cpu_data_size);
|
||||
|
||||
/* Copy the new context from its slot. */
|
||||
memcpy (¤t_cpu->cpu_data_placeholder,
|
||||
current_cpu->thread_data[next].cpu_context,
|
||||
current_cpu->thread_cpu_data_size);
|
||||
memcpy (&cris_cpu->cpu_data_placeholder,
|
||||
cris_cpu->thread_data[next].cpu_context,
|
||||
cris_cpu->thread_cpu_data_size);
|
||||
|
||||
/* Update needed stuff to indicate the new context. */
|
||||
current_cpu->threadno = next;
|
||||
cris_cpu->threadno = next;
|
||||
|
||||
/* Handle pending signals. */
|
||||
if (current_cpu->thread_data[next].sigpending
|
||||
if (cris_cpu->thread_data[next].sigpending
|
||||
/* We don't run nested signal handlers. This means that pause(2)
|
||||
and sigsuspend(2) do not work in sighandlers, but that
|
||||
shouldn't be too hard a restriction. It also greatly
|
||||
simplifies the code. */
|
||||
&& current_cpu->thread_data[next].cpu_context_atsignal == NULL)
|
||||
&& cris_cpu->thread_data[next].cpu_context_atsignal == NULL)
|
||||
{
|
||||
int sig;
|
||||
|
||||
/* See if there's really a pending, non-blocked handler. We don't
|
||||
queue signals, so just use the first one in ascending order. */
|
||||
for (sig = 0; sig < 64; sig++)
|
||||
if (current_cpu->thread_data[next].sigdata[sig].pending
|
||||
&& !current_cpu->thread_data[next].sigdata[sig].blocked)
|
||||
if (cris_cpu->thread_data[next].sigdata[sig].pending
|
||||
&& !cris_cpu->thread_data[next].sigdata[sig].blocked)
|
||||
{
|
||||
bfd_byte regbuf[4];
|
||||
USI sp;
|
||||
@@ -1121,11 +1124,10 @@ schedule (SIM_CPU *current_cpu, int next)
|
||||
|
||||
/* It's simpler to save the CPU context inside the simulator
|
||||
than on the stack. */
|
||||
current_cpu->thread_data[next].cpu_context_atsignal
|
||||
= (*current_cpu
|
||||
->make_thread_cpu_data) (current_cpu,
|
||||
current_cpu->thread_data[next]
|
||||
.cpu_context);
|
||||
cris_cpu->thread_data[next].cpu_context_atsignal
|
||||
= (*cris_cpu->make_thread_cpu_data) (current_cpu,
|
||||
cris_cpu->thread_data[next]
|
||||
.cpu_context);
|
||||
|
||||
(*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_SP, regbuf, 4);
|
||||
sp = bfd_getl32 (regbuf);
|
||||
@@ -1146,12 +1148,12 @@ schedule (SIM_CPU *current_cpu, int next)
|
||||
blocked = 0;
|
||||
for (i = 0; i < 32; i++)
|
||||
blocked
|
||||
|= current_cpu->thread_data[next].sigdata[i + 1].blocked << i;
|
||||
|= cris_cpu->thread_data[next].sigdata[i + 1].blocked << i;
|
||||
sim_core_write_aligned_4 (current_cpu, pc, 0, sp, blocked);
|
||||
blocked = 0;
|
||||
for (i = 0; i < 31; i++)
|
||||
blocked
|
||||
|= current_cpu->thread_data[next].sigdata[i + 33].blocked << i;
|
||||
|= cris_cpu->thread_data[next].sigdata[i + 33].blocked << i;
|
||||
sim_core_write_aligned_4 (current_cpu, pc, 0, sp + 4, blocked);
|
||||
|
||||
/* Then, the actual instructions. This is CPU-specific, but we
|
||||
@@ -1180,12 +1182,12 @@ schedule (SIM_CPU *current_cpu, int next)
|
||||
(*CPU_REG_STORE (current_cpu)) (current_cpu, TARGET_SRP_REGNUM,
|
||||
regbuf, 4);
|
||||
|
||||
current_cpu->thread_data[next].sigdata[sig].pending = 0;
|
||||
cris_cpu->thread_data[next].sigdata[sig].pending = 0;
|
||||
|
||||
/* Block this signal (for the duration of the sighandler). */
|
||||
current_cpu->thread_data[next].sigdata[sig].blocked = 1;
|
||||
cris_cpu->thread_data[next].sigdata[sig].blocked = 1;
|
||||
|
||||
sim_pc_set (current_cpu, current_cpu->sighandler[sig]);
|
||||
sim_pc_set (current_cpu, cris_cpu->sighandler[sig]);
|
||||
bfd_putl32 (sig, regbuf);
|
||||
(*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R10,
|
||||
regbuf, 4);
|
||||
@@ -1211,7 +1213,7 @@ schedule (SIM_CPU *current_cpu, int next)
|
||||
|
||||
/* No, there actually was no pending signal for this thread. Reset
|
||||
this flag. */
|
||||
current_cpu->thread_data[next].sigpending = 0;
|
||||
cris_cpu->thread_data[next].sigpending = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1226,25 +1228,26 @@ static void
|
||||
reschedule (SIM_CPU *current_cpu)
|
||||
{
|
||||
SIM_DESC sd = CPU_STATE (current_cpu);
|
||||
struct cris_sim_cpu *cris_cpu = CRIS_SIM_CPU (current_cpu);
|
||||
int i;
|
||||
|
||||
/* Iterate over all thread slots, because after a few thread creations
|
||||
and exits, we don't know where the live ones are. */
|
||||
for (i = (current_cpu->threadno + 1) % SIM_TARGET_MAX_THREADS;
|
||||
i != current_cpu->threadno;
|
||||
for (i = (cris_cpu->threadno + 1) % SIM_TARGET_MAX_THREADS;
|
||||
i != cris_cpu->threadno;
|
||||
i = (i + 1) % SIM_TARGET_MAX_THREADS)
|
||||
if (current_cpu->thread_data[i].cpu_context
|
||||
&& current_cpu->thread_data[i].at_syscall == 0)
|
||||
if (cris_cpu->thread_data[i].cpu_context
|
||||
&& cris_cpu->thread_data[i].at_syscall == 0)
|
||||
{
|
||||
schedule (current_cpu, i);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Pick any next live thread. */
|
||||
for (i = (current_cpu->threadno + 1) % SIM_TARGET_MAX_THREADS;
|
||||
i != current_cpu->threadno;
|
||||
for (i = (cris_cpu->threadno + 1) % SIM_TARGET_MAX_THREADS;
|
||||
i != cris_cpu->threadno;
|
||||
i = (i + 1) % SIM_TARGET_MAX_THREADS)
|
||||
if (current_cpu->thread_data[i].cpu_context)
|
||||
if (cris_cpu->thread_data[i].cpu_context)
|
||||
{
|
||||
schedule (current_cpu, i);
|
||||
return;
|
||||
@@ -1260,18 +1263,18 @@ reschedule (SIM_CPU *current_cpu)
|
||||
static int
|
||||
deliver_signal (SIM_CPU *current_cpu, int sig, unsigned int pid)
|
||||
{
|
||||
struct cris_sim_cpu *cris_cpu = CRIS_SIM_CPU (current_cpu);
|
||||
int i;
|
||||
USI pc = sim_pc_get (current_cpu);
|
||||
|
||||
/* Find the thread index of the pid. */
|
||||
for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
|
||||
/* Apparently it's ok to send signals to zombies (so a check for
|
||||
current_cpu->thread_data[i].cpu_context != NULL would be
|
||||
wrong). */
|
||||
if (current_cpu->thread_data[i].threadid == pid - TARGET_PID)
|
||||
cris_cpu->thread_data[i].cpu_context != NULL would be wrong). */
|
||||
if (cris_cpu->thread_data[i].threadid == pid - TARGET_PID)
|
||||
{
|
||||
if (sig < 64)
|
||||
switch (current_cpu->sighandler[sig])
|
||||
switch (cris_cpu->sighandler[sig])
|
||||
{
|
||||
case TARGET_SIG_DFL:
|
||||
switch (sig)
|
||||
@@ -1340,8 +1343,8 @@ deliver_signal (SIM_CPU *current_cpu, int sig, unsigned int pid)
|
||||
/* Mark the signal as pending, making schedule () check
|
||||
closer. The signal will be handled when the thread is
|
||||
scheduled and the signal is unblocked. */
|
||||
current_cpu->thread_data[i].sigdata[sig].pending = 1;
|
||||
current_cpu->thread_data[i].sigpending = 1;
|
||||
cris_cpu->thread_data[i].sigdata[sig].pending = 1;
|
||||
cris_cpu->thread_data[i].sigpending = 1;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
@@ -1364,15 +1367,14 @@ static void
|
||||
make_first_thread (SIM_CPU *current_cpu)
|
||||
{
|
||||
SIM_DESC sd = CPU_STATE (current_cpu);
|
||||
current_cpu->thread_data
|
||||
= xcalloc (1,
|
||||
SIM_TARGET_MAX_THREADS
|
||||
* sizeof (current_cpu->thread_data[0]));
|
||||
current_cpu->thread_data[0].cpu_context
|
||||
= (*current_cpu->make_thread_cpu_data) (current_cpu,
|
||||
¤t_cpu
|
||||
->cpu_data_placeholder);
|
||||
current_cpu->thread_data[0].parent_threadid = -1;
|
||||
struct cris_sim_cpu *cris_cpu = CRIS_SIM_CPU (current_cpu);
|
||||
|
||||
cris_cpu->thread_data
|
||||
= xcalloc (1, SIM_TARGET_MAX_THREADS * sizeof (cris_cpu->thread_data[0]));
|
||||
cris_cpu->thread_data[0].cpu_context
|
||||
= (*cris_cpu->make_thread_cpu_data) (current_cpu,
|
||||
&cris_cpu->cpu_data_placeholder);
|
||||
cris_cpu->thread_data[0].parent_threadid = -1;
|
||||
|
||||
/* For good measure. */
|
||||
if (TARGET_SIG_DFL != 0)
|
||||
@@ -1413,11 +1415,12 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
{
|
||||
CB_SYSCALL s;
|
||||
SIM_DESC sd = CPU_STATE (current_cpu);
|
||||
struct cris_sim_cpu *cris_cpu = CRIS_SIM_CPU (current_cpu);
|
||||
host_callback *cb = STATE_CALLBACK (sd);
|
||||
int retval;
|
||||
int threadno = current_cpu->threadno;
|
||||
int threadno = cris_cpu->threadno;
|
||||
|
||||
current_cpu->syscalls++;
|
||||
cris_cpu->syscalls++;
|
||||
|
||||
CB_SYSCALL_INIT (&s);
|
||||
s.func = callnum;
|
||||
@@ -1434,7 +1437,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
s.arg2 = (SI) arg2;
|
||||
|
||||
if (callnum == TARGET_SYS_exit_group
|
||||
|| (callnum == TARGET_SYS_exit && current_cpu->m1threads == 0))
|
||||
|| (callnum == TARGET_SYS_exit && cris_cpu->m1threads == 0))
|
||||
{
|
||||
if (CPU_CRIS_MISC_PROFILE (current_cpu)->flags
|
||||
& FLAG_CRIS_MISC_PROFILE_ALL)
|
||||
@@ -1477,8 +1480,8 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
forever"; we re-run this insn. The wait is ended by a
|
||||
callback. Sanity check that this is the reason we got
|
||||
here. */
|
||||
if (current_cpu->thread_data == NULL
|
||||
|| (current_cpu->thread_data[threadno].pipe_write_fd == 0))
|
||||
if (cris_cpu->thread_data == NULL
|
||||
|| (cris_cpu->thread_data[threadno].pipe_write_fd == 0))
|
||||
goto unimplemented_syscall;
|
||||
|
||||
sim_pc_set (current_cpu, pc);
|
||||
@@ -1507,10 +1510,10 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
|
||||
case 3:
|
||||
/* F_GETFL. Check for the special case for open+fdopen. */
|
||||
if (current_cpu->last_syscall == TARGET_SYS_open
|
||||
&& arg1 == current_cpu->last_open_fd)
|
||||
if (cris_cpu->last_syscall == TARGET_SYS_open
|
||||
&& arg1 == cris_cpu->last_open_fd)
|
||||
{
|
||||
retval = current_cpu->last_open_flags & TARGET_O_ACCMODE;
|
||||
retval = cris_cpu->last_open_flags & TARGET_O_ACCMODE;
|
||||
break;
|
||||
}
|
||||
else if (arg1 == 0)
|
||||
@@ -1598,9 +1601,9 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
retval = arg1;
|
||||
|
||||
if (arg1 == 0)
|
||||
retval = current_cpu->endbrk;
|
||||
else if (arg1 <= current_cpu->endmem)
|
||||
current_cpu->endbrk = arg1;
|
||||
retval = cris_cpu->endbrk;
|
||||
else if (arg1 <= cris_cpu->endmem)
|
||||
cris_cpu->endbrk = arg1;
|
||||
else
|
||||
{
|
||||
USI new_end = (arg1 + 8191) & ~8191;
|
||||
@@ -1608,35 +1611,35 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
/* If the simulator wants to brk more than a certain very
|
||||
large amount, something is wrong. FIXME: Return an error
|
||||
or abort? Have command-line selectable? */
|
||||
if (new_end - current_cpu->endmem > SIM_MAX_ALLOC_CHUNK)
|
||||
if (new_end - cris_cpu->endmem > SIM_MAX_ALLOC_CHUNK)
|
||||
{
|
||||
current_cpu->endbrk = current_cpu->endmem;
|
||||
retval = current_cpu->endmem;
|
||||
cris_cpu->endbrk = cris_cpu->endmem;
|
||||
retval = cris_cpu->endmem;
|
||||
break;
|
||||
}
|
||||
|
||||
sim_core_attach (sd, NULL, 0, access_read_write_exec, 0,
|
||||
current_cpu->endmem,
|
||||
new_end - current_cpu->endmem,
|
||||
cris_cpu->endmem,
|
||||
new_end - cris_cpu->endmem,
|
||||
0, NULL, NULL);
|
||||
current_cpu->endbrk = arg1;
|
||||
current_cpu->endmem = new_end;
|
||||
cris_cpu->endbrk = arg1;
|
||||
cris_cpu->endmem = new_end;
|
||||
}
|
||||
break;
|
||||
|
||||
case TARGET_SYS_getpid:
|
||||
/* Correct until CLONE_THREAD is implemented. */
|
||||
retval = current_cpu->thread_data == NULL
|
||||
retval = cris_cpu->thread_data == NULL
|
||||
? TARGET_PID
|
||||
: TARGET_PID + current_cpu->thread_data[threadno].threadid;
|
||||
: TARGET_PID + cris_cpu->thread_data[threadno].threadid;
|
||||
break;
|
||||
|
||||
case TARGET_SYS_getppid:
|
||||
/* Correct until CLONE_THREAD is implemented. */
|
||||
retval = current_cpu->thread_data == NULL
|
||||
retval = cris_cpu->thread_data == NULL
|
||||
? TARGET_PID - 1
|
||||
: (TARGET_PID
|
||||
+ current_cpu->thread_data[threadno].parent_threadid);
|
||||
+ cris_cpu->thread_data[threadno].parent_threadid);
|
||||
break;
|
||||
|
||||
case TARGET_SYS_mmap2:
|
||||
@@ -1714,14 +1717,14 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
abort ();
|
||||
|
||||
if (flags & TARGET_MAP_FIXED)
|
||||
unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
|
||||
unmap_pages (sd, &cris_cpu->highest_mmapped_page,
|
||||
addr, newlen);
|
||||
else if (is_mapped (sd, ¤t_cpu->highest_mmapped_page,
|
||||
else if (is_mapped (sd, &cris_cpu->highest_mmapped_page,
|
||||
addr, newlen))
|
||||
addr = 0;
|
||||
|
||||
newaddr
|
||||
= create_map (sd, ¤t_cpu->highest_mmapped_page,
|
||||
= create_map (sd, &cris_cpu->highest_mmapped_page,
|
||||
addr != 0 || (flags & TARGET_MAP_FIXED)
|
||||
? addr : -1,
|
||||
newlen);
|
||||
@@ -1737,7 +1740,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
if ((flags & TARGET_MAP_FIXED) && newaddr != addr)
|
||||
{
|
||||
abort ();
|
||||
unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
|
||||
unmap_pages (sd, &cris_cpu->highest_mmapped_page,
|
||||
newaddr, newlen);
|
||||
retval = -cb_host_to_target_errno (cb, EINVAL);
|
||||
break;
|
||||
@@ -1799,13 +1802,13 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
USI newaddr;
|
||||
|
||||
if (flags & TARGET_MAP_FIXED)
|
||||
unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
|
||||
unmap_pages (sd, &cris_cpu->highest_mmapped_page,
|
||||
addr, newlen);
|
||||
else if (is_mapped (sd, ¤t_cpu->highest_mmapped_page,
|
||||
else if (is_mapped (sd, &cris_cpu->highest_mmapped_page,
|
||||
addr, newlen))
|
||||
addr = 0;
|
||||
|
||||
newaddr = create_map (sd, ¤t_cpu->highest_mmapped_page,
|
||||
newaddr = create_map (sd, &cris_cpu->highest_mmapped_page,
|
||||
addr != 0 || (flags & TARGET_MAP_FIXED)
|
||||
? addr : -1,
|
||||
newlen);
|
||||
@@ -1818,7 +1821,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
if ((flags & TARGET_MAP_FIXED) && newaddr != addr)
|
||||
{
|
||||
abort ();
|
||||
unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
|
||||
unmap_pages (sd, &cris_cpu->highest_mmapped_page,
|
||||
newaddr, newlen);
|
||||
retval = -cb_host_to_target_errno (cb, EINVAL);
|
||||
break;
|
||||
@@ -1838,7 +1841,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
USI prot = arg3;
|
||||
|
||||
if (prot != TARGET_PROT_NONE
|
||||
|| !is_mapped_only (sd, ¤t_cpu->highest_mmapped_page,
|
||||
|| !is_mapped_only (sd, &cris_cpu->highest_mmapped_page,
|
||||
addr, (len + 8191) & ~8191))
|
||||
{
|
||||
retval
|
||||
@@ -1880,7 +1883,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
USI addr = arg1;
|
||||
USI len = arg2;
|
||||
USI result
|
||||
= unmap_pages (sd, ¤t_cpu->highest_mmapped_page, addr,
|
||||
= unmap_pages (sd, &cris_cpu->highest_mmapped_page, addr,
|
||||
len);
|
||||
retval = result != 0 ? -cb_host_to_target_errno (cb, result) : 0;
|
||||
break;
|
||||
@@ -1904,7 +1907,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
&& (options == TARGET___WCLONE
|
||||
|| options == TARGET___WALL)))
|
||||
|| rusagep != 0
|
||||
|| current_cpu->thread_data == NULL)
|
||||
|| cris_cpu->thread_data == NULL)
|
||||
{
|
||||
retval
|
||||
= cris_unknown_syscall (current_cpu, pc,
|
||||
@@ -1920,20 +1923,20 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
if (pid == (USI) -1)
|
||||
for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
|
||||
{
|
||||
if (current_cpu->thread_data[threadno].threadid
|
||||
== current_cpu->thread_data[i].parent_threadid
|
||||
&& current_cpu->thread_data[i].threadid != 0
|
||||
&& current_cpu->thread_data[i].cpu_context == NULL)
|
||||
if (cris_cpu->thread_data[threadno].threadid
|
||||
== cris_cpu->thread_data[i].parent_threadid
|
||||
&& cris_cpu->thread_data[i].threadid != 0
|
||||
&& cris_cpu->thread_data[i].cpu_context == NULL)
|
||||
{
|
||||
/* A zombied child. Get the exit value and clear the
|
||||
zombied entry so it will be reused. */
|
||||
sim_core_write_unaligned_4 (current_cpu, pc, 0, saddr,
|
||||
current_cpu
|
||||
cris_cpu
|
||||
->thread_data[i].exitval);
|
||||
retval
|
||||
= current_cpu->thread_data[i].threadid + TARGET_PID;
|
||||
memset (¤t_cpu->thread_data[i], 0,
|
||||
sizeof (current_cpu->thread_data[i]));
|
||||
= cris_cpu->thread_data[i].threadid + TARGET_PID;
|
||||
memset (&cris_cpu->thread_data[i], 0,
|
||||
sizeof (cris_cpu->thread_data[i]));
|
||||
goto outer_break;
|
||||
}
|
||||
}
|
||||
@@ -1942,21 +1945,20 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
/* We're waiting for a specific PID. If we don't find
|
||||
it zombied on this run, rerun the syscall. */
|
||||
for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
|
||||
if (pid == current_cpu->thread_data[i].threadid + TARGET_PID
|
||||
&& current_cpu->thread_data[i].cpu_context == NULL)
|
||||
if (pid == cris_cpu->thread_data[i].threadid + TARGET_PID
|
||||
&& cris_cpu->thread_data[i].cpu_context == NULL)
|
||||
{
|
||||
if (saddr != 0)
|
||||
/* Get the exit value if the caller wants it. */
|
||||
sim_core_write_unaligned_4 (current_cpu, pc, 0,
|
||||
saddr,
|
||||
current_cpu
|
||||
->thread_data[i]
|
||||
.exitval);
|
||||
cris_cpu
|
||||
->thread_data[i].exitval);
|
||||
|
||||
retval
|
||||
= current_cpu->thread_data[i].threadid + TARGET_PID;
|
||||
memset (¤t_cpu->thread_data[i], 0,
|
||||
sizeof (current_cpu->thread_data[i]));
|
||||
= cris_cpu->thread_data[i].threadid + TARGET_PID;
|
||||
memset (&cris_cpu->thread_data[i], 0,
|
||||
sizeof (cris_cpu->thread_data[i]));
|
||||
|
||||
goto outer_break;
|
||||
}
|
||||
@@ -1986,7 +1988,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
if (old_sa != 0)
|
||||
{
|
||||
sim_core_write_unaligned_4 (current_cpu, pc, 0, old_sa + 0,
|
||||
current_cpu->sighandler[signum]);
|
||||
cris_cpu->sighandler[signum]);
|
||||
sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 4, 0);
|
||||
sim_core_write_unaligned_4 (current_cpu, pc, 0, arg3 + 8, 0);
|
||||
|
||||
@@ -2037,12 +2039,12 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
break;
|
||||
}
|
||||
|
||||
current_cpu->sighandler[signum] = target_sa_handler;
|
||||
cris_cpu->sighandler[signum] = target_sa_handler;
|
||||
|
||||
/* Because we may have unblocked signals, one may now be
|
||||
pending, if there are threads, that is. */
|
||||
if (current_cpu->thread_data)
|
||||
current_cpu->thread_data[threadno].sigpending = 1;
|
||||
if (cris_cpu->thread_data)
|
||||
cris_cpu->thread_data[threadno].sigpending = 1;
|
||||
}
|
||||
retval = 0;
|
||||
break;
|
||||
@@ -2065,18 +2067,18 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
else if (new_len < old_len)
|
||||
{
|
||||
/* Shrinking is easy. */
|
||||
if (unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
|
||||
if (unmap_pages (sd, &cris_cpu->highest_mmapped_page,
|
||||
addr + new_len, old_len - new_len) != 0)
|
||||
retval = -cb_host_to_target_errno (cb, EINVAL);
|
||||
else
|
||||
retval = addr;
|
||||
}
|
||||
else if (! is_mapped (sd, ¤t_cpu->highest_mmapped_page,
|
||||
else if (! is_mapped (sd, &cris_cpu->highest_mmapped_page,
|
||||
addr + old_len, new_len - old_len))
|
||||
{
|
||||
/* If the extension isn't mapped, we can just add it. */
|
||||
mapped_addr
|
||||
= create_map (sd, ¤t_cpu->highest_mmapped_page,
|
||||
= create_map (sd, &cris_cpu->highest_mmapped_page,
|
||||
addr + old_len, new_len - old_len);
|
||||
|
||||
if (mapped_addr > (USI) -8192)
|
||||
@@ -2094,7 +2096,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
USI prev_len = old_len;
|
||||
|
||||
mapped_addr
|
||||
= create_map (sd, ¤t_cpu->highest_mmapped_page,
|
||||
= create_map (sd, &cris_cpu->highest_mmapped_page,
|
||||
-1, new_len);
|
||||
|
||||
if (mapped_addr > (USI) -8192)
|
||||
@@ -2115,7 +2117,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
abort ();
|
||||
}
|
||||
|
||||
if (unmap_pages (sd, ¤t_cpu->highest_mmapped_page,
|
||||
if (unmap_pages (sd, &cris_cpu->highest_mmapped_page,
|
||||
prev_addr, prev_len) != 0)
|
||||
abort ();
|
||||
}
|
||||
@@ -2153,7 +2155,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
!= TARGET_POLLIN)
|
||||
|| ((cb->to_fstat) (cb, fd, &buf) != 0
|
||||
|| (buf.st_mode & S_IFIFO) == 0)
|
||||
|| current_cpu->thread_data == NULL)
|
||||
|| cris_cpu->thread_data == NULL)
|
||||
{
|
||||
retval
|
||||
= cris_unknown_syscall (current_cpu, pc,
|
||||
@@ -2171,8 +2173,8 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
/* Iterate over threads; find a marker that a writer is
|
||||
sleeping, waiting for a reader. */
|
||||
for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
|
||||
if (current_cpu->thread_data[i].cpu_context != NULL
|
||||
&& current_cpu->thread_data[i].pipe_read_fd == fd)
|
||||
if (cris_cpu->thread_data[i].cpu_context != NULL
|
||||
&& cris_cpu->thread_data[i].pipe_read_fd == fd)
|
||||
{
|
||||
revents = TARGET_POLLIN;
|
||||
retval = 1;
|
||||
@@ -2186,7 +2188,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
case. */
|
||||
timeout
|
||||
-= (TARGET_TIME_MS (current_cpu)
|
||||
- (current_cpu->thread_data[threadno].last_execution));
|
||||
- (cris_cpu->thread_data[threadno].last_execution));
|
||||
|
||||
/* Arrange to repeat this syscall until timeout or event,
|
||||
decreasing timeout at each iteration. */
|
||||
@@ -2347,7 +2349,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
/* At kill(2), glibc sets signal masks such that the thread
|
||||
machinery is initialized. Still, there is and was only
|
||||
one thread. */
|
||||
if (current_cpu->max_threadid == 0)
|
||||
if (cris_cpu->max_threadid == 0)
|
||||
{
|
||||
if (pid != TARGET_PID)
|
||||
{
|
||||
@@ -2406,26 +2408,26 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
|
||||
/* The sigmask is kept in the per-thread data, so we may
|
||||
need to create the first one. */
|
||||
if (current_cpu->thread_data == NULL)
|
||||
if (cris_cpu->thread_data == NULL)
|
||||
make_first_thread (current_cpu);
|
||||
|
||||
if (how == TARGET_SIG_SETMASK)
|
||||
for (i = 0; i < 64; i++)
|
||||
current_cpu->thread_data[threadno].sigdata[i].blocked = 0;
|
||||
cris_cpu->thread_data[threadno].sigdata[i].blocked = 0;
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
if ((set_low & (1 << i)))
|
||||
current_cpu->thread_data[threadno].sigdata[i + 1].blocked
|
||||
cris_cpu->thread_data[threadno].sigdata[i + 1].blocked
|
||||
= (how != TARGET_SIG_UNBLOCK);
|
||||
|
||||
for (i = 0; i < 31; i++)
|
||||
if ((set_high & (1 << i)))
|
||||
current_cpu->thread_data[threadno].sigdata[i + 33].blocked
|
||||
cris_cpu->thread_data[threadno].sigdata[i + 33].blocked
|
||||
= (how != TARGET_SIG_UNBLOCK);
|
||||
|
||||
/* The mask changed, so a signal may be unblocked for
|
||||
execution. */
|
||||
current_cpu->thread_data[threadno].sigpending = 1;
|
||||
cris_cpu->thread_data[threadno].sigpending = 1;
|
||||
}
|
||||
|
||||
if (oldsetp != 0)
|
||||
@@ -2434,11 +2436,11 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
USI set_high = 0;
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
if (current_cpu->thread_data[threadno]
|
||||
if (cris_cpu->thread_data[threadno]
|
||||
.sigdata[i + 1].blocked)
|
||||
set_low |= 1 << i;
|
||||
for (i = 0; i < 31; i++)
|
||||
if (current_cpu->thread_data[threadno]
|
||||
if (cris_cpu->thread_data[threadno]
|
||||
.sigdata[i + 33].blocked)
|
||||
set_high |= 1 << i;
|
||||
|
||||
@@ -2456,10 +2458,10 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
bfd_byte regbuf[4];
|
||||
int was_sigsuspended;
|
||||
|
||||
if (current_cpu->thread_data == NULL
|
||||
if (cris_cpu->thread_data == NULL
|
||||
/* The CPU context is saved with the simulator data, not
|
||||
on the stack as in the real world. */
|
||||
|| (current_cpu->thread_data[threadno].cpu_context_atsignal
|
||||
|| (cris_cpu->thread_data[threadno].cpu_context_atsignal
|
||||
== NULL))
|
||||
{
|
||||
retval
|
||||
@@ -2478,17 +2480,17 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
}
|
||||
|
||||
was_sigsuspended
|
||||
= current_cpu->thread_data[threadno].sigsuspended;
|
||||
= cris_cpu->thread_data[threadno].sigsuspended;
|
||||
|
||||
/* Restore the sigmask, either from the stack copy made when
|
||||
the sighandler was called, or from the saved state
|
||||
specifically for sigsuspend(2). */
|
||||
if (was_sigsuspended)
|
||||
{
|
||||
current_cpu->thread_data[threadno].sigsuspended = 0;
|
||||
cris_cpu->thread_data[threadno].sigsuspended = 0;
|
||||
for (i = 0; i < 64; i++)
|
||||
current_cpu->thread_data[threadno].sigdata[i].blocked
|
||||
= current_cpu->thread_data[threadno]
|
||||
cris_cpu->thread_data[threadno].sigdata[i].blocked
|
||||
= cris_cpu->thread_data[threadno]
|
||||
.sigdata[i].blocked_suspendsave;
|
||||
}
|
||||
else
|
||||
@@ -2506,22 +2508,22 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
= sim_core_read_unaligned_4 (current_cpu, pc, 0, sp + 4);
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
current_cpu->thread_data[threadno].sigdata[i + 1].blocked
|
||||
cris_cpu->thread_data[threadno].sigdata[i + 1].blocked
|
||||
= (set_low & (1 << i)) != 0;
|
||||
for (i = 0; i < 31; i++)
|
||||
current_cpu->thread_data[threadno].sigdata[i + 33].blocked
|
||||
cris_cpu->thread_data[threadno].sigdata[i + 33].blocked
|
||||
= (set_high & (1 << i)) != 0;
|
||||
}
|
||||
|
||||
/* The mask changed, so a signal may be unblocked for
|
||||
execution. */
|
||||
current_cpu->thread_data[threadno].sigpending = 1;
|
||||
cris_cpu->thread_data[threadno].sigpending = 1;
|
||||
|
||||
memcpy (¤t_cpu->cpu_data_placeholder,
|
||||
current_cpu->thread_data[threadno].cpu_context_atsignal,
|
||||
current_cpu->thread_cpu_data_size);
|
||||
free (current_cpu->thread_data[threadno].cpu_context_atsignal);
|
||||
current_cpu->thread_data[threadno].cpu_context_atsignal = NULL;
|
||||
memcpy (&cris_cpu->cpu_data_placeholder,
|
||||
cris_cpu->thread_data[threadno].cpu_context_atsignal,
|
||||
cris_cpu->thread_cpu_data_size);
|
||||
free (cris_cpu->thread_data[threadno].cpu_context_atsignal);
|
||||
cris_cpu->thread_data[threadno].cpu_context_atsignal = NULL;
|
||||
|
||||
/* The return value must come from the saved R10. */
|
||||
(*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_R10, regbuf, 4);
|
||||
@@ -2551,7 +2553,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
|
||||
/* Don't change the signal mask if we're already in
|
||||
sigsuspend state (i.e. this syscall is a rerun). */
|
||||
else if (!current_cpu->thread_data[threadno].sigsuspended)
|
||||
else if (!cris_cpu->thread_data[threadno].sigsuspended)
|
||||
{
|
||||
USI set_low
|
||||
= sim_core_read_unaligned_4 (current_cpu, pc, 0,
|
||||
@@ -2565,29 +2567,29 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
one. */
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
current_cpu->thread_data[threadno]
|
||||
cris_cpu->thread_data[threadno]
|
||||
.sigdata[i + 1].blocked_suspendsave
|
||||
= current_cpu->thread_data[threadno]
|
||||
= cris_cpu->thread_data[threadno]
|
||||
.sigdata[i + 1].blocked;
|
||||
|
||||
current_cpu->thread_data[threadno]
|
||||
cris_cpu->thread_data[threadno]
|
||||
.sigdata[i + 1].blocked = (set_low & (1 << i)) != 0;
|
||||
}
|
||||
for (i = 0; i < 31; i++)
|
||||
{
|
||||
current_cpu->thread_data[threadno]
|
||||
cris_cpu->thread_data[threadno]
|
||||
.sigdata[i + 33].blocked_suspendsave
|
||||
= current_cpu->thread_data[threadno]
|
||||
= cris_cpu->thread_data[threadno]
|
||||
.sigdata[i + 33].blocked;
|
||||
current_cpu->thread_data[threadno]
|
||||
cris_cpu->thread_data[threadno]
|
||||
.sigdata[i + 33].blocked = (set_high & (1 << i)) != 0;
|
||||
}
|
||||
|
||||
current_cpu->thread_data[threadno].sigsuspended = 1;
|
||||
cris_cpu->thread_data[threadno].sigsuspended = 1;
|
||||
|
||||
/* The mask changed, so a signal may be unblocked for
|
||||
execution. */
|
||||
current_cpu->thread_data[threadno].sigpending = 1;
|
||||
cris_cpu->thread_data[threadno].sigpending = 1;
|
||||
}
|
||||
|
||||
/* Because we don't use arg1 (newsetp) when this syscall is
|
||||
@@ -2837,8 +2839,8 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
/* FIXME: Save scheduler setting before threads are
|
||||
created too. */
|
||||
sim_core_write_unaligned_4 (current_cpu, pc, 0, paramp,
|
||||
current_cpu->thread_data != NULL
|
||||
? (current_cpu
|
||||
cris_cpu->thread_data != NULL
|
||||
? (cris_cpu
|
||||
->thread_data[threadno]
|
||||
.priority)
|
||||
: 0);
|
||||
@@ -3005,24 +3007,24 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
/* Here for all but the last thread. */
|
||||
int i;
|
||||
int pid
|
||||
= current_cpu->thread_data[threadno].threadid + TARGET_PID;
|
||||
= cris_cpu->thread_data[threadno].threadid + TARGET_PID;
|
||||
int ppid
|
||||
= (current_cpu->thread_data[threadno].parent_threadid
|
||||
= (cris_cpu->thread_data[threadno].parent_threadid
|
||||
+ TARGET_PID);
|
||||
int exitsig = current_cpu->thread_data[threadno].exitsig;
|
||||
int exitsig = cris_cpu->thread_data[threadno].exitsig;
|
||||
|
||||
/* Any children are now all orphans. */
|
||||
for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
|
||||
if (current_cpu->thread_data[i].parent_threadid
|
||||
== current_cpu->thread_data[threadno].threadid)
|
||||
if (cris_cpu->thread_data[i].parent_threadid
|
||||
== cris_cpu->thread_data[threadno].threadid)
|
||||
/* Make getppid(2) return 1 for them, poor little ones. */
|
||||
current_cpu->thread_data[i].parent_threadid = -TARGET_PID + 1;
|
||||
cris_cpu->thread_data[i].parent_threadid = -TARGET_PID + 1;
|
||||
|
||||
/* Free the cpu context data. When the parent has received
|
||||
the exit status, we'll clear the entry too. */
|
||||
free (current_cpu->thread_data[threadno].cpu_context);
|
||||
current_cpu->thread_data[threadno].cpu_context = NULL;
|
||||
current_cpu->m1threads--;
|
||||
free (cris_cpu->thread_data[threadno].cpu_context);
|
||||
cris_cpu->thread_data[threadno].cpu_context = NULL;
|
||||
cris_cpu->m1threads--;
|
||||
if (arg1 != 0)
|
||||
{
|
||||
sim_io_eprintf (sd, "Thread %d exited with status %d\n",
|
||||
@@ -3032,7 +3034,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
}
|
||||
|
||||
/* Still, we may want to support non-zero exit values. */
|
||||
current_cpu->thread_data[threadno].exitval = arg1 << 8;
|
||||
cris_cpu->thread_data[threadno].exitval = arg1 << 8;
|
||||
|
||||
if (exitsig)
|
||||
deliver_signal (current_cpu, exitsig, ppid);
|
||||
@@ -3041,7 +3043,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
|
||||
case TARGET_SYS_clone:
|
||||
{
|
||||
int nthreads = current_cpu->m1threads + 1;
|
||||
int nthreads = cris_cpu->m1threads + 1;
|
||||
void *thread_cpu_data;
|
||||
bfd_byte old_sp_buf[4];
|
||||
bfd_byte sp_buf[4];
|
||||
@@ -3078,7 +3080,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
break;
|
||||
}
|
||||
|
||||
if (current_cpu->thread_data == NULL)
|
||||
if (cris_cpu->thread_data == NULL)
|
||||
make_first_thread (current_cpu);
|
||||
|
||||
/* The created thread will get the new SP and a cleared R10.
|
||||
@@ -3095,39 +3097,39 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
(*CPU_REG_STORE (current_cpu)) (current_cpu,
|
||||
H_GR_R10, (bfd_byte *) zeros, 4);
|
||||
thread_cpu_data
|
||||
= (*current_cpu
|
||||
= (*cris_cpu
|
||||
->make_thread_cpu_data) (current_cpu,
|
||||
¤t_cpu->cpu_data_placeholder);
|
||||
&cris_cpu->cpu_data_placeholder);
|
||||
(*CPU_REG_STORE (current_cpu)) (current_cpu,
|
||||
H_GR_SP, old_sp_buf, 4);
|
||||
|
||||
retval = ++current_cpu->max_threadid + TARGET_PID;
|
||||
retval = ++cris_cpu->max_threadid + TARGET_PID;
|
||||
|
||||
/* Find an unused slot. After a few threads have been created
|
||||
and exited, the array is expected to be a bit fragmented.
|
||||
We don't reuse the first entry, though, that of the
|
||||
original thread. */
|
||||
for (i = 1; i < SIM_TARGET_MAX_THREADS; i++)
|
||||
if (current_cpu->thread_data[i].cpu_context == NULL
|
||||
if (cris_cpu->thread_data[i].cpu_context == NULL
|
||||
/* Don't reuse a zombied entry. */
|
||||
&& current_cpu->thread_data[i].threadid == 0)
|
||||
&& cris_cpu->thread_data[i].threadid == 0)
|
||||
break;
|
||||
|
||||
memcpy (¤t_cpu->thread_data[i],
|
||||
¤t_cpu->thread_data[threadno],
|
||||
sizeof (current_cpu->thread_data[i]));
|
||||
current_cpu->thread_data[i].cpu_context = thread_cpu_data;
|
||||
current_cpu->thread_data[i].cpu_context_atsignal = NULL;
|
||||
current_cpu->thread_data[i].threadid = current_cpu->max_threadid;
|
||||
current_cpu->thread_data[i].parent_threadid
|
||||
= current_cpu->thread_data[threadno].threadid;
|
||||
current_cpu->thread_data[i].pipe_read_fd = 0;
|
||||
current_cpu->thread_data[i].pipe_write_fd = 0;
|
||||
current_cpu->thread_data[i].at_syscall = 0;
|
||||
current_cpu->thread_data[i].sigpending = 0;
|
||||
current_cpu->thread_data[i].sigsuspended = 0;
|
||||
current_cpu->thread_data[i].exitsig = flags & TARGET_CSIGNAL;
|
||||
current_cpu->m1threads = nthreads;
|
||||
memcpy (&cris_cpu->thread_data[i],
|
||||
&cris_cpu->thread_data[threadno],
|
||||
sizeof (cris_cpu->thread_data[i]));
|
||||
cris_cpu->thread_data[i].cpu_context = thread_cpu_data;
|
||||
cris_cpu->thread_data[i].cpu_context_atsignal = NULL;
|
||||
cris_cpu->thread_data[i].threadid = cris_cpu->max_threadid;
|
||||
cris_cpu->thread_data[i].parent_threadid
|
||||
= cris_cpu->thread_data[threadno].threadid;
|
||||
cris_cpu->thread_data[i].pipe_read_fd = 0;
|
||||
cris_cpu->thread_data[i].pipe_write_fd = 0;
|
||||
cris_cpu->thread_data[i].at_syscall = 0;
|
||||
cris_cpu->thread_data[i].sigpending = 0;
|
||||
cris_cpu->thread_data[i].sigsuspended = 0;
|
||||
cris_cpu->thread_data[i].exitsig = flags & TARGET_CSIGNAL;
|
||||
cris_cpu->m1threads = nthreads;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3143,7 +3145,7 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
retval = -cb_host_to_target_errno (cb, EINVAL);
|
||||
break;
|
||||
}
|
||||
(*current_cpu->set_target_thread_data) (current_cpu, arg1);
|
||||
(*cris_cpu->set_target_thread_data) (current_cpu, arg1);
|
||||
retval = 0;
|
||||
break;
|
||||
|
||||
@@ -3161,28 +3163,28 @@ cris_break_13_handler (SIM_CPU *current_cpu, USI callnum, USI arg1,
|
||||
/* Minimal support for fcntl F_GETFL as used in open+fdopen. */
|
||||
if (callnum == TARGET_SYS_open)
|
||||
{
|
||||
current_cpu->last_open_fd = retval;
|
||||
current_cpu->last_open_flags = arg2;
|
||||
cris_cpu->last_open_fd = retval;
|
||||
cris_cpu->last_open_flags = arg2;
|
||||
}
|
||||
|
||||
current_cpu->last_syscall = callnum;
|
||||
cris_cpu->last_syscall = callnum;
|
||||
|
||||
/* A system call is a rescheduling point. For the time being, we don't
|
||||
reschedule anywhere else. */
|
||||
if (current_cpu->m1threads != 0
|
||||
if (cris_cpu->m1threads != 0
|
||||
/* We need to schedule off from an exiting thread that is the
|
||||
second-last one. */
|
||||
|| (current_cpu->thread_data != NULL
|
||||
&& current_cpu->thread_data[threadno].cpu_context == NULL))
|
||||
|| (cris_cpu->thread_data != NULL
|
||||
&& cris_cpu->thread_data[threadno].cpu_context == NULL))
|
||||
{
|
||||
bfd_byte retval_buf[4];
|
||||
|
||||
current_cpu->thread_data[threadno].last_execution
|
||||
cris_cpu->thread_data[threadno].last_execution
|
||||
= TARGET_TIME_MS (current_cpu);
|
||||
bfd_putl32 (retval, retval_buf);
|
||||
(*CPU_REG_STORE (current_cpu)) (current_cpu, H_GR_R10, retval_buf, 4);
|
||||
|
||||
current_cpu->thread_data[threadno].at_syscall = 1;
|
||||
cris_cpu->thread_data[threadno].at_syscall = 1;
|
||||
reschedule (current_cpu);
|
||||
|
||||
(*CPU_REG_FETCH (current_cpu)) (current_cpu, H_GR_R10, retval_buf, 4);
|
||||
@@ -3202,6 +3204,7 @@ cris_pipe_nonempty (host_callback *cb ATTRIBUTE_UNUSED,
|
||||
int reader, int writer)
|
||||
{
|
||||
SIM_CPU *cpu = current_cpu_for_cb_callback;
|
||||
struct cris_sim_cpu *cris_cpu = CRIS_SIM_CPU (cpu);
|
||||
const bfd_byte zeros[4] = { 0, 0, 0, 0 };
|
||||
|
||||
/* It's the current thread: we just have to re-run the current
|
||||
@@ -3213,7 +3216,7 @@ cris_pipe_nonempty (host_callback *cb ATTRIBUTE_UNUSED,
|
||||
This function may be called multiple times between cris_pipe_empty,
|
||||
but we must avoid e.g. decreasing PC every time. Check fd markers
|
||||
to tell. */
|
||||
if (cpu->thread_data == NULL)
|
||||
if (cris_cpu->thread_data == NULL)
|
||||
{
|
||||
sim_io_eprintf (CPU_STATE (cpu),
|
||||
"Terminating simulation due to writing pipe rd:wr %d:%d"
|
||||
@@ -3221,10 +3224,10 @@ cris_pipe_nonempty (host_callback *cb ATTRIBUTE_UNUSED,
|
||||
sim_engine_halt (CPU_STATE (cpu), cpu,
|
||||
NULL, sim_pc_get (cpu), sim_stopped, SIM_SIGILL);
|
||||
}
|
||||
else if (cpu->thread_data[cpu->threadno].pipe_write_fd == 0)
|
||||
else if (cris_cpu->thread_data[cris_cpu->threadno].pipe_write_fd == 0)
|
||||
{
|
||||
cpu->thread_data[cpu->threadno].pipe_write_fd = writer;
|
||||
cpu->thread_data[cpu->threadno].pipe_read_fd = reader;
|
||||
cris_cpu->thread_data[cris_cpu->threadno].pipe_write_fd = writer;
|
||||
cris_cpu->thread_data[cris_cpu->threadno].pipe_read_fd = reader;
|
||||
/* FIXME: We really shouldn't change registers other than R10 in
|
||||
syscalls (like R9), here or elsewhere. */
|
||||
(*CPU_REG_STORE (cpu)) (cpu, H_GR_R9, (bfd_byte *) zeros, 4);
|
||||
@@ -3244,6 +3247,7 @@ cris_pipe_empty (host_callback *cb,
|
||||
{
|
||||
int i;
|
||||
SIM_CPU *cpu = current_cpu_for_cb_callback;
|
||||
struct cris_sim_cpu *cris_cpu = CRIS_SIM_CPU (cpu);
|
||||
SIM_DESC sd = CPU_STATE (current_cpu_for_cb_callback);
|
||||
bfd_byte r10_buf[4];
|
||||
int remaining
|
||||
@@ -3251,20 +3255,20 @@ cris_pipe_empty (host_callback *cb,
|
||||
|
||||
/* We need to find the thread that waits for this pipe. */
|
||||
for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
|
||||
if (cpu->thread_data[i].cpu_context
|
||||
&& cpu->thread_data[i].pipe_write_fd == writer)
|
||||
if (cris_cpu->thread_data[i].cpu_context
|
||||
&& cris_cpu->thread_data[i].pipe_write_fd == writer)
|
||||
{
|
||||
int retval;
|
||||
|
||||
/* Temporarily switch to this cpu context, so we can change the
|
||||
PC by ordinary calls. */
|
||||
|
||||
memcpy (cpu->thread_data[cpu->threadno].cpu_context,
|
||||
&cpu->cpu_data_placeholder,
|
||||
cpu->thread_cpu_data_size);
|
||||
memcpy (&cpu->cpu_data_placeholder,
|
||||
cpu->thread_data[i].cpu_context,
|
||||
cpu->thread_cpu_data_size);
|
||||
memcpy (cris_cpu->thread_data[cris_cpu->threadno].cpu_context,
|
||||
&cris_cpu->cpu_data_placeholder,
|
||||
cris_cpu->thread_cpu_data_size);
|
||||
memcpy (&cris_cpu->cpu_data_placeholder,
|
||||
cris_cpu->thread_data[i].cpu_context,
|
||||
cris_cpu->thread_cpu_data_size);
|
||||
|
||||
/* The return value is supposed to contain the number of
|
||||
written bytes, which is the number of bytes requested and
|
||||
@@ -3286,14 +3290,14 @@ cris_pipe_empty (host_callback *cb,
|
||||
(*CPU_REG_STORE (cpu)) (cpu, H_GR_R10, r10_buf, 4);
|
||||
}
|
||||
sim_pc_set (cpu, sim_pc_get (cpu) + 2);
|
||||
memcpy (cpu->thread_data[i].cpu_context,
|
||||
&cpu->cpu_data_placeholder,
|
||||
cpu->thread_cpu_data_size);
|
||||
memcpy (&cpu->cpu_data_placeholder,
|
||||
cpu->thread_data[cpu->threadno].cpu_context,
|
||||
cpu->thread_cpu_data_size);
|
||||
cpu->thread_data[i].pipe_read_fd = 0;
|
||||
cpu->thread_data[i].pipe_write_fd = 0;
|
||||
memcpy (cris_cpu->thread_data[i].cpu_context,
|
||||
&cris_cpu->cpu_data_placeholder,
|
||||
cris_cpu->thread_cpu_data_size);
|
||||
memcpy (&cris_cpu->cpu_data_placeholder,
|
||||
cris_cpu->thread_data[cris_cpu->threadno].cpu_context,
|
||||
cris_cpu->thread_cpu_data_size);
|
||||
cris_cpu->thread_data[i].pipe_read_fd = 0;
|
||||
cris_cpu->thread_data[i].pipe_write_fd = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,4 @@ typedef unsigned long int uword;
|
||||
|
||||
#include "d10v_sim.h"
|
||||
|
||||
struct _sim_cpu {
|
||||
|
||||
sim_cpu_base base;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -88,7 +88,8 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback,
|
||||
current_target_byte_order = BFD_ENDIAN_LITTLE;
|
||||
|
||||
/* The cpu data is kept in a separately allocated chunk of memory. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct example_sim_cpu))
|
||||
!= SIM_RC_OK)
|
||||
{
|
||||
free_state (sd);
|
||||
return 0;
|
||||
|
||||
@@ -34,7 +34,7 @@ register_num (SIM_CPU *cpu, uint16_t num)
|
||||
SIM_DESC sd = CPU_STATE (cpu);
|
||||
|
||||
if (num < 0x8000 || num >= 0x8008)
|
||||
sim_engine_halt (sd, cpu, NULL, cpu->pc, sim_signalled, SIM_SIGILL);
|
||||
sim_engine_halt (sd, cpu, NULL, sim_pc_get (cpu), sim_signalled, SIM_SIGILL);
|
||||
|
||||
return num & 0xf;
|
||||
}
|
||||
@@ -44,6 +44,7 @@ static uint16_t
|
||||
interp_num (SIM_CPU *cpu, uint16_t num)
|
||||
{
|
||||
SIM_DESC sd = CPU_STATE (cpu);
|
||||
struct example_sim_cpu *example_cpu = EXAMPLE_SIM_CPU (cpu);
|
||||
|
||||
if (num < 0x8000)
|
||||
{
|
||||
@@ -55,13 +56,13 @@ interp_num (SIM_CPU *cpu, uint16_t num)
|
||||
{
|
||||
/* Numbers 32768..32775 instead mean registers 0..7. */
|
||||
TRACE_DECODE (cpu, "%#x is register R%i", num, num & 0xf);
|
||||
return cpu->regs[num & 0xf];
|
||||
return example_cpu->regs[num & 0xf];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Numbers 32776..65535 are invalid. */
|
||||
TRACE_DECODE (cpu, "%#x is an invalid number", num);
|
||||
sim_engine_halt (sd, cpu, NULL, cpu->pc, sim_signalled, SIM_SIGILL);
|
||||
sim_engine_halt (sd, cpu, NULL, example_cpu->pc, sim_signalled, SIM_SIGILL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +70,7 @@ interp_num (SIM_CPU *cpu, uint16_t num)
|
||||
void step_once (SIM_CPU *cpu)
|
||||
{
|
||||
SIM_DESC sd = CPU_STATE (cpu);
|
||||
struct example_sim_cpu *example_cpu = EXAMPLE_SIM_CPU (cpu);
|
||||
uint16_t iw1, num1;
|
||||
sim_cia pc = sim_pc_get (cpu);
|
||||
|
||||
@@ -96,7 +98,7 @@ void step_once (SIM_CPU *cpu)
|
||||
TRACE_INSN (cpu, "SET R%i %#x", num2, num3);
|
||||
|
||||
TRACE_REGISTER (cpu, "R%i = %#x", num2, num3);
|
||||
cpu->regs[num2] = num3;
|
||||
example_cpu->regs[num2] = num3;
|
||||
|
||||
pc += 6;
|
||||
}
|
||||
@@ -110,9 +112,9 @@ void step_once (SIM_CPU *cpu)
|
||||
TRACE_EXTRACT (cpu, "PUSH %#x", iw2);
|
||||
TRACE_INSN (cpu, "PUSH %#x", num2);
|
||||
|
||||
sim_core_write_aligned_2 (cpu, pc, write_map, cpu->sp, num2);
|
||||
cpu->sp -= 2;
|
||||
TRACE_REGISTER (cpu, "SP = %#x", cpu->sp);
|
||||
sim_core_write_aligned_2 (cpu, pc, write_map, example_cpu->sp, num2);
|
||||
example_cpu->sp -= 2;
|
||||
TRACE_REGISTER (cpu, "SP = %#x", example_cpu->sp);
|
||||
|
||||
pc += 4;
|
||||
}
|
||||
@@ -126,12 +128,12 @@ void step_once (SIM_CPU *cpu)
|
||||
num2 = register_num (cpu, iw2);
|
||||
TRACE_EXTRACT (cpu, "POP %#x", iw2);
|
||||
TRACE_INSN (cpu, "POP R%i", num2);
|
||||
cpu->sp += 2;
|
||||
TRACE_REGISTER (cpu, "SP = %#x", cpu->sp);
|
||||
result = sim_core_read_aligned_2 (cpu, pc, read_map, cpu->sp);
|
||||
example_cpu->sp += 2;
|
||||
TRACE_REGISTER (cpu, "SP = %#x", example_cpu->sp);
|
||||
result = sim_core_read_aligned_2 (cpu, pc, read_map, example_cpu->sp);
|
||||
|
||||
TRACE_REGISTER (cpu, "R%i = %#x", num2, result);
|
||||
cpu->regs[num2] = result;
|
||||
example_cpu->regs[num2] = result;
|
||||
|
||||
pc += 4;
|
||||
}
|
||||
@@ -153,7 +155,7 @@ void step_once (SIM_CPU *cpu)
|
||||
TRACE_DECODE (cpu, "R%i = (%#x == %#x) = %i", num2, num3, num4, result);
|
||||
|
||||
TRACE_REGISTER (cpu, "R%i = %#x", num2, result);
|
||||
cpu->regs[num2] = result;
|
||||
example_cpu->regs[num2] = result;
|
||||
|
||||
pc += 8;
|
||||
}
|
||||
@@ -175,7 +177,7 @@ void step_once (SIM_CPU *cpu)
|
||||
TRACE_DECODE (cpu, "R%i = (%#x > %#x) = %i", num2, num3, num4, result);
|
||||
|
||||
TRACE_REGISTER (cpu, "R%i = %#x", num2, result);
|
||||
cpu->regs[num2] = result;
|
||||
example_cpu->regs[num2] = result;
|
||||
|
||||
pc += 8;
|
||||
}
|
||||
@@ -258,7 +260,7 @@ void step_once (SIM_CPU *cpu)
|
||||
32768, result);
|
||||
|
||||
TRACE_REGISTER (cpu, "R%i = %#x", num2, result);
|
||||
cpu->regs[num2] = result;
|
||||
example_cpu->regs[num2] = result;
|
||||
|
||||
pc += 8;
|
||||
}
|
||||
@@ -281,7 +283,7 @@ void step_once (SIM_CPU *cpu)
|
||||
32768, result);
|
||||
|
||||
TRACE_REGISTER (cpu, "R%i = %#x", num2, result);
|
||||
cpu->regs[num2] = result;
|
||||
example_cpu->regs[num2] = result;
|
||||
|
||||
pc += 8;
|
||||
}
|
||||
@@ -302,7 +304,7 @@ void step_once (SIM_CPU *cpu)
|
||||
TRACE_DECODE (cpu, "R%i = %#x %% %#x = %#x", num2, num3, num4, result);
|
||||
|
||||
TRACE_REGISTER (cpu, "R%i = %#x", num2, result);
|
||||
cpu->regs[num2] = result;
|
||||
example_cpu->regs[num2] = result;
|
||||
|
||||
pc += 8;
|
||||
}
|
||||
@@ -323,7 +325,7 @@ void step_once (SIM_CPU *cpu)
|
||||
TRACE_DECODE (cpu, "R%i = %#x & %#x = %#x", num2, num3, num4, result);
|
||||
|
||||
TRACE_REGISTER (cpu, "R%i = %#x", num2, result);
|
||||
cpu->regs[num2] = result;
|
||||
example_cpu->regs[num2] = result;
|
||||
|
||||
pc += 8;
|
||||
}
|
||||
@@ -344,7 +346,7 @@ void step_once (SIM_CPU *cpu)
|
||||
TRACE_DECODE (cpu, "R%i = %#x | %#x = %#x", num2, num3, num4, result);
|
||||
|
||||
TRACE_REGISTER (cpu, "R%i = %#x", num2, result);
|
||||
cpu->regs[num2] = result;
|
||||
example_cpu->regs[num2] = result;
|
||||
|
||||
pc += 8;
|
||||
}
|
||||
@@ -363,7 +365,7 @@ void step_once (SIM_CPU *cpu)
|
||||
TRACE_DECODE (cpu, "R%i = (~%#x) & 0x7fff = %#x", num2, num3, result);
|
||||
|
||||
TRACE_REGISTER (cpu, "R%i = %#x", num2, result);
|
||||
cpu->regs[num2] = result;
|
||||
example_cpu->regs[num2] = result;
|
||||
|
||||
pc += 6;
|
||||
}
|
||||
@@ -385,7 +387,7 @@ void step_once (SIM_CPU *cpu)
|
||||
result = sim_core_read_aligned_2 (cpu, pc, read_map, num3);
|
||||
|
||||
TRACE_REGISTER (cpu, "R%i = %#x", num2, result);
|
||||
cpu->regs[num2] = result;
|
||||
example_cpu->regs[num2] = result;
|
||||
|
||||
pc += 6;
|
||||
}
|
||||
@@ -422,9 +424,9 @@ void step_once (SIM_CPU *cpu)
|
||||
TRACE_INSN (cpu, "CALL %#x", num2);
|
||||
|
||||
TRACE_MEMORY (cpu, "pushing %#x onto stack", (pc + 4) >> 1);
|
||||
sim_core_write_aligned_2 (cpu, pc, write_map, cpu->sp, (pc + 4) >> 1);
|
||||
cpu->sp -= 2;
|
||||
TRACE_REGISTER (cpu, "SP = %#x", cpu->sp);
|
||||
sim_core_write_aligned_2 (cpu, pc, write_map, example_cpu->sp, (pc + 4) >> 1);
|
||||
example_cpu->sp -= 2;
|
||||
TRACE_REGISTER (cpu, "SP = %#x", example_cpu->sp);
|
||||
|
||||
pc = num2;
|
||||
TRACE_BRANCH (cpu, "CALL %#x", pc);
|
||||
@@ -436,9 +438,9 @@ void step_once (SIM_CPU *cpu)
|
||||
uint16_t result;
|
||||
|
||||
TRACE_INSN (cpu, "RET");
|
||||
cpu->sp += 2;
|
||||
TRACE_REGISTER (cpu, "SP = %#x", cpu->sp);
|
||||
result = sim_core_read_aligned_2 (cpu, pc, read_map, cpu->sp);
|
||||
example_cpu->sp += 2;
|
||||
TRACE_REGISTER (cpu, "SP = %#x", example_cpu->sp);
|
||||
result = sim_core_read_aligned_2 (cpu, pc, read_map, example_cpu->sp);
|
||||
TRACE_MEMORY (cpu, "popping %#x off of stack", result << 1);
|
||||
|
||||
pc = result << 1;
|
||||
@@ -485,7 +487,7 @@ void step_once (SIM_CPU *cpu)
|
||||
}
|
||||
|
||||
TRACE_REGISTER (cpu, "R%i = %#x", iw2 & 0xf, c);
|
||||
cpu->regs[iw2 & 0xf] = c;
|
||||
example_cpu->regs[iw2 & 0xf] = c;
|
||||
|
||||
pc += 4;
|
||||
}
|
||||
@@ -507,14 +509,18 @@ void step_once (SIM_CPU *cpu)
|
||||
static sim_cia
|
||||
pc_get (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->pc;
|
||||
struct example_sim_cpu *example_cpu = EXAMPLE_SIM_CPU (cpu);
|
||||
|
||||
return example_cpu->pc;
|
||||
}
|
||||
|
||||
/* Set the program counter for this cpu to the new pc value. */
|
||||
static void
|
||||
pc_set (sim_cpu *cpu, sim_cia pc)
|
||||
{
|
||||
cpu->pc = pc;
|
||||
struct example_sim_cpu *example_cpu = EXAMPLE_SIM_CPU (cpu);
|
||||
|
||||
example_cpu->pc = pc;
|
||||
}
|
||||
|
||||
/* Initialize the state for a single cpu. Usuaully this involves clearing all
|
||||
@@ -522,10 +528,12 @@ pc_set (sim_cpu *cpu, sim_cia pc)
|
||||
helper functions too. */
|
||||
void initialize_cpu (SIM_DESC sd, SIM_CPU *cpu)
|
||||
{
|
||||
memset (cpu->regs, 0, sizeof (cpu->regs));
|
||||
cpu->pc = 0;
|
||||
struct example_sim_cpu *example_cpu = EXAMPLE_SIM_CPU (cpu);
|
||||
|
||||
memset (example_cpu->regs, 0, sizeof (example_cpu->regs));
|
||||
example_cpu->pc = 0;
|
||||
/* Make sure it's initialized outside of the 16-bit address space. */
|
||||
cpu->sp = 0x80000;
|
||||
example_cpu->sp = 0x80000;
|
||||
|
||||
CPU_PC_FETCH (cpu) = pc_get;
|
||||
CPU_PC_STORE (cpu) = pc_set;
|
||||
|
||||
@@ -24,18 +24,17 @@
|
||||
#include "sim-basics.h"
|
||||
#include "sim-base.h"
|
||||
|
||||
struct _sim_cpu {
|
||||
/* ... simulator specific members ... */
|
||||
struct example_sim_cpu {
|
||||
uint16_t regs[8];
|
||||
sim_cia pc;
|
||||
|
||||
/* This isn't a real register, and the stack is not directly addressable,
|
||||
so use memory outside of the 16-bit address space. */
|
||||
uint32_t sp;
|
||||
|
||||
sim_cpu_base base;
|
||||
};
|
||||
|
||||
#define EXAMPLE_SIM_CPU(cpu) ((struct example_sim_cpu *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
extern void step_once (SIM_CPU *);
|
||||
extern void initialize_cpu (SIM_DESC, SIM_CPU *);
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ frvbf_h_spr_set_handler (current_cpu, (index), (x));\
|
||||
#define GET_H_CCCR(a1) CPU (h_cccr)[a1]
|
||||
#define SET_H_CCCR(a1, x) (CPU (h_cccr)[a1] = (x))
|
||||
} hardware;
|
||||
#define CPU_CGEN_HW(cpu) (& (cpu)->cpu_data.hardware)
|
||||
#define CPU_CGEN_HW(cpu) (& FRV_SIM_CPU (cpu)->cpu_data.hardware)
|
||||
} FRVBF_CPU_DATA;
|
||||
|
||||
/* Virtual regs. */
|
||||
|
||||
@@ -65,7 +65,7 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback, bfd *abfd,
|
||||
current_target_byte_order = BFD_ENDIAN_BIG;
|
||||
|
||||
/* The cpu data is kept in a separately allocated chunk of memory. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct frv_sim_cpu)) != SIM_RC_OK)
|
||||
{
|
||||
free_state (sd);
|
||||
return 0;
|
||||
|
||||
@@ -51,15 +51,7 @@ void frv_sim_engine_halt_hook (SIM_DESC, SIM_CPU *, sim_cia);
|
||||
extern void frv_sim_close (SIM_DESC sd, int quitting);
|
||||
#define SIM_CLOSE_HOOK(...) frv_sim_close (__VA_ARGS__)
|
||||
|
||||
/* The _sim_cpu struct. */
|
||||
|
||||
struct _sim_cpu {
|
||||
/* sim/common cpu base. */
|
||||
sim_cpu_base base;
|
||||
|
||||
/* Static parts of cgen. */
|
||||
CGEN_CPU cgen_cpu;
|
||||
|
||||
struct frv_sim_cpu {
|
||||
/* CPU specific parts go here.
|
||||
Note that in files that don't need to access these pieces WANT_CPU_FOO
|
||||
won't be defined and thus these parts won't appear. This is ok in the
|
||||
@@ -72,40 +64,41 @@ struct _sim_cpu {
|
||||
|
||||
/* Control information for registers */
|
||||
FRV_REGISTER_CONTROL register_control;
|
||||
#define CPU_REGISTER_CONTROL(cpu) (& (cpu)->register_control)
|
||||
#define CPU_REGISTER_CONTROL(cpu) (& FRV_SIM_CPU (cpu)->register_control)
|
||||
|
||||
FRV_VLIW vliw;
|
||||
#define CPU_VLIW(cpu) (& (cpu)->vliw)
|
||||
#define CPU_VLIW(cpu) (& FRV_SIM_CPU (cpu)->vliw)
|
||||
|
||||
FRV_CACHE insn_cache;
|
||||
#define CPU_INSN_CACHE(cpu) (& (cpu)->insn_cache)
|
||||
#define CPU_INSN_CACHE(cpu) (& FRV_SIM_CPU (cpu)->insn_cache)
|
||||
|
||||
FRV_CACHE data_cache;
|
||||
#define CPU_DATA_CACHE(cpu) (& (cpu)->data_cache)
|
||||
#define CPU_DATA_CACHE(cpu) (& FRV_SIM_CPU (cpu)->data_cache)
|
||||
|
||||
FRV_PROFILE_STATE profile_state;
|
||||
#define CPU_PROFILE_STATE(cpu) (& (cpu)->profile_state)
|
||||
#define CPU_PROFILE_STATE(cpu) (& FRV_SIM_CPU (cpu)->profile_state)
|
||||
|
||||
int debug_state;
|
||||
#define CPU_DEBUG_STATE(cpu) ((cpu)->debug_state)
|
||||
#define CPU_DEBUG_STATE(cpu) (FRV_SIM_CPU (cpu)->debug_state)
|
||||
|
||||
SI load_address;
|
||||
#define CPU_LOAD_ADDRESS(cpu) ((cpu)->load_address)
|
||||
#define CPU_LOAD_ADDRESS(cpu) (FRV_SIM_CPU (cpu)->load_address)
|
||||
|
||||
SI load_length;
|
||||
#define CPU_LOAD_LENGTH(cpu) ((cpu)->load_length)
|
||||
#define CPU_LOAD_LENGTH(cpu) (FRV_SIM_CPU (cpu)->load_length)
|
||||
|
||||
SI load_flag;
|
||||
#define CPU_LOAD_SIGNED(cpu) ((cpu)->load_flag)
|
||||
#define CPU_LOAD_LOCK(cpu) ((cpu)->load_flag)
|
||||
#define CPU_LOAD_SIGNED(cpu) (FRV_SIM_CPU (cpu)->load_flag)
|
||||
#define CPU_LOAD_LOCK(cpu) (FRV_SIM_CPU (cpu)->load_flag)
|
||||
|
||||
SI store_flag;
|
||||
#define CPU_RSTR_INVALIDATE(cpu) ((cpu)->store_flag)
|
||||
#define CPU_RSTR_INVALIDATE(cpu) (FRV_SIM_CPU (cpu)->store_flag)
|
||||
|
||||
unsigned long elf_flags;
|
||||
#define CPU_ELF_FLAGS(cpu) ((cpu)->elf_flags)
|
||||
#define CPU_ELF_FLAGS(cpu) (FRV_SIM_CPU (cpu)->elf_flags)
|
||||
#endif /* defined (WANT_CPU_FRVBF) */
|
||||
};
|
||||
#define FRV_SIM_CPU(cpu) ((struct frv_sim_cpu *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
/* Misc. */
|
||||
|
||||
|
||||
@@ -747,7 +747,7 @@ frvbf_check_acc_range (SIM_CPU *current_cpu, SI regno)
|
||||
/* Only applicable to fr550 */
|
||||
SIM_DESC sd = CPU_STATE (current_cpu);
|
||||
if (STATE_ARCHITECTURE (sd)->mach != bfd_mach_fr550)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
/* On the fr550, media insns in slots 0 and 2 can only access
|
||||
accumulators acc0-acc3. Insns in slots 1 and 3 can only access
|
||||
|
||||
@@ -40,4 +40,6 @@ struct ft32_cpu_state {
|
||||
int exception;
|
||||
};
|
||||
|
||||
#define FT32_SIM_CPU(cpu) ((struct ft32_cpu_state *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
#endif /* _FT32_SIM_H_ */
|
||||
|
||||
@@ -162,7 +162,8 @@ ft32_write_item (SIM_DESC sd, int dw, uint32_t ea, uint32_t v)
|
||||
static uint32_t cpu_mem_read (SIM_DESC sd, uint32_t dw, uint32_t ea)
|
||||
{
|
||||
sim_cpu *cpu = STATE_CPU (sd, 0);
|
||||
uint32_t insnpc = cpu->state.pc;
|
||||
struct ft32_cpu_state *ft32_cpu = FT32_SIM_CPU (cpu);
|
||||
uint32_t insnpc = ft32_cpu->pc;
|
||||
uint32_t r;
|
||||
uint8_t byte[4];
|
||||
|
||||
@@ -176,7 +177,7 @@ static uint32_t cpu_mem_read (SIM_DESC sd, uint32_t dw, uint32_t ea)
|
||||
return getchar ();
|
||||
case 0x1fff4:
|
||||
/* Read the simulator cycle timer. */
|
||||
return cpu->state.cycles / 100;
|
||||
return ft32_cpu->cycles / 100;
|
||||
default:
|
||||
sim_io_eprintf (sd, "Illegal IO read address %08x, pc %#x\n",
|
||||
ea, insnpc);
|
||||
@@ -189,6 +190,7 @@ static uint32_t cpu_mem_read (SIM_DESC sd, uint32_t dw, uint32_t ea)
|
||||
static void cpu_mem_write (SIM_DESC sd, uint32_t dw, uint32_t ea, uint32_t d)
|
||||
{
|
||||
sim_cpu *cpu = STATE_CPU (sd, 0);
|
||||
struct ft32_cpu_state *ft32_cpu = FT32_SIM_CPU (cpu);
|
||||
ea &= 0x1ffff;
|
||||
if (ea & 0x10000)
|
||||
{
|
||||
@@ -201,23 +203,23 @@ static void cpu_mem_write (SIM_DESC sd, uint32_t dw, uint32_t ea, uint32_t d)
|
||||
break;
|
||||
case 0x1fc80:
|
||||
/* Unlock the PM write port */
|
||||
cpu->state.pm_unlock = (d == 0x1337f7d1);
|
||||
ft32_cpu->pm_unlock = (d == 0x1337f7d1);
|
||||
break;
|
||||
case 0x1fc84:
|
||||
/* Set the PM write address register */
|
||||
cpu->state.pm_addr = d;
|
||||
ft32_cpu->pm_addr = d;
|
||||
break;
|
||||
case 0x1fc88:
|
||||
if (cpu->state.pm_unlock)
|
||||
if (ft32_cpu->pm_unlock)
|
||||
{
|
||||
/* Write to PM. */
|
||||
ft32_write_item (sd, dw, cpu->state.pm_addr, d);
|
||||
cpu->state.pm_addr += 4;
|
||||
ft32_write_item (sd, dw, ft32_cpu->pm_addr, d);
|
||||
ft32_cpu->pm_addr += 4;
|
||||
}
|
||||
break;
|
||||
case 0x1fffc:
|
||||
/* Normal exit. */
|
||||
sim_engine_halt (sd, cpu, NULL, cpu->state.pc, sim_exited, cpu->state.regs[0]);
|
||||
sim_engine_halt (sd, cpu, NULL, ft32_cpu->pc, sim_exited, ft32_cpu->regs[0]);
|
||||
break;
|
||||
case 0x1fff8:
|
||||
sim_io_printf (sd, "Debug write %08x\n", d);
|
||||
@@ -239,17 +241,19 @@ static void cpu_mem_write (SIM_DESC sd, uint32_t dw, uint32_t ea, uint32_t d)
|
||||
static void ft32_push (SIM_DESC sd, uint32_t v)
|
||||
{
|
||||
sim_cpu *cpu = STATE_CPU (sd, 0);
|
||||
cpu->state.regs[FT32_HARD_SP] -= 4;
|
||||
cpu->state.regs[FT32_HARD_SP] &= 0xffff;
|
||||
cpu_mem_write (sd, 2, cpu->state.regs[FT32_HARD_SP], v);
|
||||
struct ft32_cpu_state *ft32_cpu = FT32_SIM_CPU (cpu);
|
||||
ft32_cpu->regs[FT32_HARD_SP] -= 4;
|
||||
ft32_cpu->regs[FT32_HARD_SP] &= 0xffff;
|
||||
cpu_mem_write (sd, 2, ft32_cpu->regs[FT32_HARD_SP], v);
|
||||
}
|
||||
|
||||
static uint32_t ft32_pop (SIM_DESC sd)
|
||||
{
|
||||
sim_cpu *cpu = STATE_CPU (sd, 0);
|
||||
uint32_t r = cpu_mem_read (sd, 2, cpu->state.regs[FT32_HARD_SP]);
|
||||
cpu->state.regs[FT32_HARD_SP] += 4;
|
||||
cpu->state.regs[FT32_HARD_SP] &= 0xffff;
|
||||
struct ft32_cpu_state *ft32_cpu = FT32_SIM_CPU (cpu);
|
||||
uint32_t r = cpu_mem_read (sd, 2, ft32_cpu->regs[FT32_HARD_SP]);
|
||||
ft32_cpu->regs[FT32_HARD_SP] += 4;
|
||||
ft32_cpu->regs[FT32_HARD_SP] &= 0xffff;
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -320,6 +324,7 @@ static void
|
||||
step_once (SIM_DESC sd)
|
||||
{
|
||||
sim_cpu *cpu = STATE_CPU (sd, 0);
|
||||
struct ft32_cpu_state *ft32_cpu = FT32_SIM_CPU (cpu);
|
||||
address_word cia = CPU_PC_GET (cpu);
|
||||
uint32_t inst;
|
||||
uint32_t dw;
|
||||
@@ -346,13 +351,13 @@ step_once (SIM_DESC sd)
|
||||
unsigned int sc[2];
|
||||
int isize;
|
||||
|
||||
inst = ft32_read_item (sd, 2, cpu->state.pc);
|
||||
cpu->state.cycles += 1;
|
||||
inst = ft32_read_item (sd, 2, ft32_cpu->pc);
|
||||
ft32_cpu->cycles += 1;
|
||||
|
||||
if ((STATE_ARCHITECTURE (sd)->mach == bfd_mach_ft32b)
|
||||
&& ft32_decode_shortcode (cpu->state.pc, inst, sc))
|
||||
&& ft32_decode_shortcode (ft32_cpu->pc, inst, sc))
|
||||
{
|
||||
if ((cpu->state.pc & 3) == 0)
|
||||
if ((ft32_cpu->pc & 3) == 0)
|
||||
inst = sc[0];
|
||||
else
|
||||
inst = sc[1];
|
||||
@@ -365,7 +370,7 @@ step_once (SIM_DESC sd)
|
||||
if (inst == 0x00340002)
|
||||
{
|
||||
sim_engine_halt (sd, cpu, NULL,
|
||||
cpu->state.pc,
|
||||
ft32_cpu->pc,
|
||||
sim_stopped, SIM_SIGTRAP);
|
||||
goto escape;
|
||||
}
|
||||
@@ -390,8 +395,8 @@ step_once (SIM_DESC sd)
|
||||
k15 -= 0x8000;
|
||||
al = (inst >> FT32_FLD_AL_BIT) & LSBS (FT32_FLD_AL_SIZ);
|
||||
|
||||
r_1v = cpu->state.regs[r_1];
|
||||
rimmv = (rimm & 0x400) ? nsigned (10, rimm) : cpu->state.regs[rimm & 0x1f];
|
||||
r_1v = ft32_cpu->regs[r_1];
|
||||
rimmv = (rimm & 0x400) ? nsigned (10, rimm) : ft32_cpu->regs[rimm & 0x1f];
|
||||
|
||||
bit_pos = rimmv & 31;
|
||||
bit_len = 0xf & (rimmv >> 5);
|
||||
@@ -400,24 +405,24 @@ step_once (SIM_DESC sd)
|
||||
|
||||
upper = (inst >> 27);
|
||||
|
||||
insnpc = cpu->state.pc;
|
||||
cpu->state.pc += isize;
|
||||
insnpc = ft32_cpu->pc;
|
||||
ft32_cpu->pc += isize;
|
||||
switch (upper)
|
||||
{
|
||||
case FT32_PAT_TOC:
|
||||
case FT32_PAT_TOCI:
|
||||
{
|
||||
int take = (cr == 3) || ((1 & (cpu->state.regs[28 + cr] >> cb)) == cv);
|
||||
int take = (cr == 3) || ((1 & (ft32_cpu->regs[28 + cr] >> cb)) == cv);
|
||||
if (take)
|
||||
{
|
||||
cpu->state.cycles += 1;
|
||||
ft32_cpu->cycles += 1;
|
||||
if (bt)
|
||||
ft32_push (sd, cpu->state.pc); /* this is a call. */
|
||||
ft32_push (sd, ft32_cpu->pc); /* this is a call. */
|
||||
if (upper == FT32_PAT_TOC)
|
||||
cpu->state.pc = pa << 2;
|
||||
ft32_cpu->pc = pa << 2;
|
||||
else
|
||||
cpu->state.pc = cpu->state.regs[r_2];
|
||||
if (cpu->state.pc == 0x8)
|
||||
ft32_cpu->pc = ft32_cpu->regs[r_2];
|
||||
if (ft32_cpu->pc == 0x8)
|
||||
goto escape;
|
||||
}
|
||||
}
|
||||
@@ -449,7 +454,7 @@ step_once (SIM_DESC sd)
|
||||
ILLEGAL ();
|
||||
}
|
||||
if (upper == FT32_PAT_ALUOP)
|
||||
cpu->state.regs[r_d] = result;
|
||||
ft32_cpu->regs[r_d] = result;
|
||||
else
|
||||
{
|
||||
uint32_t dwmask = 0;
|
||||
@@ -492,7 +497,7 @@ step_once (SIM_DESC sd)
|
||||
greater = (sign == overflow) & !zero;
|
||||
greatereq = (sign == overflow);
|
||||
|
||||
cpu->state.regs[r_d] = (
|
||||
ft32_cpu->regs[r_d] = (
|
||||
(above << 6) |
|
||||
(greater << 5) |
|
||||
(greatereq << 4) |
|
||||
@@ -505,54 +510,54 @@ step_once (SIM_DESC sd)
|
||||
break;
|
||||
|
||||
case FT32_PAT_LDK:
|
||||
cpu->state.regs[r_d] = k20;
|
||||
ft32_cpu->regs[r_d] = k20;
|
||||
break;
|
||||
|
||||
case FT32_PAT_LPM:
|
||||
cpu->state.regs[r_d] = ft32_read_item (sd, dw, pa << 2);
|
||||
cpu->state.cycles += 1;
|
||||
ft32_cpu->regs[r_d] = ft32_read_item (sd, dw, pa << 2);
|
||||
ft32_cpu->cycles += 1;
|
||||
break;
|
||||
|
||||
case FT32_PAT_LPMI:
|
||||
cpu->state.regs[r_d] = ft32_read_item (sd, dw, cpu->state.regs[r_1] + k15);
|
||||
cpu->state.cycles += 1;
|
||||
ft32_cpu->regs[r_d] = ft32_read_item (sd, dw, ft32_cpu->regs[r_1] + k15);
|
||||
ft32_cpu->cycles += 1;
|
||||
break;
|
||||
|
||||
case FT32_PAT_STA:
|
||||
cpu_mem_write (sd, dw, aa, cpu->state.regs[r_d]);
|
||||
cpu_mem_write (sd, dw, aa, ft32_cpu->regs[r_d]);
|
||||
break;
|
||||
|
||||
case FT32_PAT_STI:
|
||||
cpu_mem_write (sd, dw, cpu->state.regs[r_d] + k15, cpu->state.regs[r_1]);
|
||||
cpu_mem_write (sd, dw, ft32_cpu->regs[r_d] + k15, ft32_cpu->regs[r_1]);
|
||||
break;
|
||||
|
||||
case FT32_PAT_LDA:
|
||||
cpu->state.regs[r_d] = cpu_mem_read (sd, dw, aa);
|
||||
cpu->state.cycles += 1;
|
||||
ft32_cpu->regs[r_d] = cpu_mem_read (sd, dw, aa);
|
||||
ft32_cpu->cycles += 1;
|
||||
break;
|
||||
|
||||
case FT32_PAT_LDI:
|
||||
cpu->state.regs[r_d] = cpu_mem_read (sd, dw, cpu->state.regs[r_1] + k15);
|
||||
cpu->state.cycles += 1;
|
||||
ft32_cpu->regs[r_d] = cpu_mem_read (sd, dw, ft32_cpu->regs[r_1] + k15);
|
||||
ft32_cpu->cycles += 1;
|
||||
break;
|
||||
|
||||
case FT32_PAT_EXA:
|
||||
{
|
||||
uint32_t tmp;
|
||||
tmp = cpu_mem_read (sd, dw, aa);
|
||||
cpu_mem_write (sd, dw, aa, cpu->state.regs[r_d]);
|
||||
cpu->state.regs[r_d] = tmp;
|
||||
cpu->state.cycles += 1;
|
||||
cpu_mem_write (sd, dw, aa, ft32_cpu->regs[r_d]);
|
||||
ft32_cpu->regs[r_d] = tmp;
|
||||
ft32_cpu->cycles += 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case FT32_PAT_EXI:
|
||||
{
|
||||
uint32_t tmp;
|
||||
tmp = cpu_mem_read (sd, dw, cpu->state.regs[r_1] + k15);
|
||||
cpu_mem_write (sd, dw, cpu->state.regs[r_1] + k15, cpu->state.regs[r_d]);
|
||||
cpu->state.regs[r_d] = tmp;
|
||||
cpu->state.cycles += 1;
|
||||
tmp = cpu_mem_read (sd, dw, ft32_cpu->regs[r_1] + k15);
|
||||
cpu_mem_write (sd, dw, ft32_cpu->regs[r_1] + k15, ft32_cpu->regs[r_d]);
|
||||
ft32_cpu->regs[r_d] = tmp;
|
||||
ft32_cpu->cycles += 1;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -561,41 +566,41 @@ step_once (SIM_DESC sd)
|
||||
break;
|
||||
|
||||
case FT32_PAT_LINK:
|
||||
ft32_push (sd, cpu->state.regs[r_d]);
|
||||
cpu->state.regs[r_d] = cpu->state.regs[FT32_HARD_SP];
|
||||
cpu->state.regs[FT32_HARD_SP] -= k16;
|
||||
cpu->state.regs[FT32_HARD_SP] &= 0xffff;
|
||||
ft32_push (sd, ft32_cpu->regs[r_d]);
|
||||
ft32_cpu->regs[r_d] = ft32_cpu->regs[FT32_HARD_SP];
|
||||
ft32_cpu->regs[FT32_HARD_SP] -= k16;
|
||||
ft32_cpu->regs[FT32_HARD_SP] &= 0xffff;
|
||||
break;
|
||||
|
||||
case FT32_PAT_UNLINK:
|
||||
cpu->state.regs[FT32_HARD_SP] = cpu->state.regs[r_d];
|
||||
cpu->state.regs[FT32_HARD_SP] &= 0xffff;
|
||||
cpu->state.regs[r_d] = ft32_pop (sd);
|
||||
ft32_cpu->regs[FT32_HARD_SP] = ft32_cpu->regs[r_d];
|
||||
ft32_cpu->regs[FT32_HARD_SP] &= 0xffff;
|
||||
ft32_cpu->regs[r_d] = ft32_pop (sd);
|
||||
break;
|
||||
|
||||
case FT32_PAT_POP:
|
||||
cpu->state.cycles += 1;
|
||||
cpu->state.regs[r_d] = ft32_pop (sd);
|
||||
ft32_cpu->cycles += 1;
|
||||
ft32_cpu->regs[r_d] = ft32_pop (sd);
|
||||
break;
|
||||
|
||||
case FT32_PAT_RETURN:
|
||||
cpu->state.pc = ft32_pop (sd);
|
||||
ft32_cpu->pc = ft32_pop (sd);
|
||||
break;
|
||||
|
||||
case FT32_PAT_FFUOP:
|
||||
switch (al)
|
||||
{
|
||||
case 0x0:
|
||||
cpu->state.regs[r_d] = r_1v / rimmv;
|
||||
ft32_cpu->regs[r_d] = r_1v / rimmv;
|
||||
break;
|
||||
case 0x1:
|
||||
cpu->state.regs[r_d] = r_1v % rimmv;
|
||||
ft32_cpu->regs[r_d] = r_1v % rimmv;
|
||||
break;
|
||||
case 0x2:
|
||||
cpu->state.regs[r_d] = ft32sdiv (r_1v, rimmv);
|
||||
ft32_cpu->regs[r_d] = ft32sdiv (r_1v, rimmv);
|
||||
break;
|
||||
case 0x3:
|
||||
cpu->state.regs[r_d] = ft32smod (r_1v, rimmv);
|
||||
ft32_cpu->regs[r_d] = ft32smod (r_1v, rimmv);
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
@@ -607,7 +612,7 @@ step_once (SIM_DESC sd)
|
||||
while ((GET_BYTE (a + i) != 0) &&
|
||||
(GET_BYTE (a + i) == GET_BYTE (b + i)))
|
||||
i++;
|
||||
cpu->state.regs[r_d] = GET_BYTE (a + i) - GET_BYTE (b + i);
|
||||
ft32_cpu->regs[r_d] = GET_BYTE (a + i) - GET_BYTE (b + i);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -615,7 +620,7 @@ step_once (SIM_DESC sd)
|
||||
{
|
||||
/* memcpy instruction. */
|
||||
uint32_t src = r_1v;
|
||||
uint32_t dst = cpu->state.regs[r_d];
|
||||
uint32_t dst = ft32_cpu->regs[r_d];
|
||||
uint32_t i;
|
||||
for (i = 0; i < (rimmv & 0x7fff); i++)
|
||||
PUT_BYTE (dst + i, GET_BYTE (src + i));
|
||||
@@ -628,46 +633,46 @@ step_once (SIM_DESC sd)
|
||||
uint32_t i;
|
||||
for (i = 0; GET_BYTE (src + i) != 0; i++)
|
||||
;
|
||||
cpu->state.regs[r_d] = i;
|
||||
ft32_cpu->regs[r_d] = i;
|
||||
}
|
||||
break;
|
||||
case 0x7:
|
||||
{
|
||||
/* memset instruction. */
|
||||
uint32_t dst = cpu->state.regs[r_d];
|
||||
uint32_t dst = ft32_cpu->regs[r_d];
|
||||
uint32_t i;
|
||||
for (i = 0; i < (rimmv & 0x7fff); i++)
|
||||
PUT_BYTE (dst + i, r_1v);
|
||||
}
|
||||
break;
|
||||
case 0x8:
|
||||
cpu->state.regs[r_d] = r_1v * rimmv;
|
||||
ft32_cpu->regs[r_d] = r_1v * rimmv;
|
||||
break;
|
||||
case 0x9:
|
||||
cpu->state.regs[r_d] = ((uint64_t)r_1v * (uint64_t)rimmv) >> 32;
|
||||
ft32_cpu->regs[r_d] = ((uint64_t)r_1v * (uint64_t)rimmv) >> 32;
|
||||
break;
|
||||
case 0xa:
|
||||
{
|
||||
/* stpcpy instruction. */
|
||||
uint32_t src = r_1v;
|
||||
uint32_t dst = cpu->state.regs[r_d];
|
||||
uint32_t dst = ft32_cpu->regs[r_d];
|
||||
uint32_t i;
|
||||
for (i = 0; GET_BYTE (src + i) != 0; i++)
|
||||
PUT_BYTE (dst + i, GET_BYTE (src + i));
|
||||
PUT_BYTE (dst + i, 0);
|
||||
cpu->state.regs[r_d] = dst + i;
|
||||
ft32_cpu->regs[r_d] = dst + i;
|
||||
}
|
||||
break;
|
||||
case 0xe:
|
||||
{
|
||||
/* streamout instruction. */
|
||||
uint32_t i;
|
||||
uint32_t src = cpu->state.regs[r_1];
|
||||
uint32_t src = ft32_cpu->regs[r_1];
|
||||
for (i = 0; i < rimmv; i += (1 << dw))
|
||||
{
|
||||
cpu_mem_write (sd,
|
||||
dw,
|
||||
cpu->state.regs[r_d],
|
||||
ft32_cpu->regs[r_d],
|
||||
cpu_mem_read (sd, dw, src));
|
||||
src += (1 << dw);
|
||||
}
|
||||
@@ -683,7 +688,7 @@ step_once (SIM_DESC sd)
|
||||
sim_io_eprintf (sd, "Unhandled pattern %d at %08x\n", upper, insnpc);
|
||||
ILLEGAL ();
|
||||
}
|
||||
cpu->state.num_i++;
|
||||
ft32_cpu->num_i++;
|
||||
|
||||
escape:
|
||||
;
|
||||
@@ -721,6 +726,8 @@ ft32_lookup_register (SIM_CPU *cpu, int nr)
|
||||
* 31 - cc
|
||||
*/
|
||||
|
||||
struct ft32_cpu_state *ft32_cpu = FT32_SIM_CPU (cpu);
|
||||
|
||||
if ((nr < 0) || (nr > 32))
|
||||
{
|
||||
sim_io_eprintf (CPU_STATE (cpu), "unknown register %i\n", nr);
|
||||
@@ -730,15 +737,15 @@ ft32_lookup_register (SIM_CPU *cpu, int nr)
|
||||
switch (nr)
|
||||
{
|
||||
case FT32_FP_REGNUM:
|
||||
return &cpu->state.regs[FT32_HARD_FP];
|
||||
return &ft32_cpu->regs[FT32_HARD_FP];
|
||||
case FT32_SP_REGNUM:
|
||||
return &cpu->state.regs[FT32_HARD_SP];
|
||||
return &ft32_cpu->regs[FT32_HARD_SP];
|
||||
case FT32_CC_REGNUM:
|
||||
return &cpu->state.regs[FT32_HARD_CC];
|
||||
return &ft32_cpu->regs[FT32_HARD_CC];
|
||||
case FT32_PC_REGNUM:
|
||||
return &cpu->state.pc;
|
||||
return &ft32_cpu->pc;
|
||||
default:
|
||||
return &cpu->state.regs[nr - 2];
|
||||
return &ft32_cpu->regs[nr - 2];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -779,13 +786,13 @@ ft32_reg_fetch (SIM_CPU *cpu,
|
||||
static sim_cia
|
||||
ft32_pc_get (SIM_CPU *cpu)
|
||||
{
|
||||
return cpu->state.pc;
|
||||
return FT32_SIM_CPU (cpu)->pc;
|
||||
}
|
||||
|
||||
static void
|
||||
ft32_pc_set (SIM_CPU *cpu, sim_cia newpc)
|
||||
{
|
||||
cpu->state.pc = newpc;
|
||||
FT32_SIM_CPU (cpu)->pc = newpc;
|
||||
}
|
||||
|
||||
/* Cover function of sim_state_free to free the cpu buffers as well. */
|
||||
@@ -814,7 +821,8 @@ sim_open (SIM_OPEN_KIND kind,
|
||||
current_target_byte_order = BFD_ENDIAN_LITTLE;
|
||||
|
||||
/* The cpu data is kept in a separately allocated chunk of memory. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct ft32_cpu_state))
|
||||
!= SIM_RC_OK)
|
||||
{
|
||||
free_state (sd);
|
||||
return 0;
|
||||
@@ -884,6 +892,7 @@ sim_create_inferior (SIM_DESC sd,
|
||||
{
|
||||
uint32_t addr;
|
||||
sim_cpu *cpu = STATE_CPU (sd, 0);
|
||||
struct ft32_cpu_state *ft32_cpu = FT32_SIM_CPU (cpu);
|
||||
host_callback *cb = STATE_CALLBACK (sd);
|
||||
|
||||
/* Set the PC. */
|
||||
@@ -911,10 +920,10 @@ sim_create_inferior (SIM_DESC sd,
|
||||
cb->argv = STATE_PROG_ARGV (sd);
|
||||
cb->envp = STATE_PROG_ENVP (sd);
|
||||
|
||||
cpu->state.regs[FT32_HARD_SP] = addr;
|
||||
cpu->state.num_i = 0;
|
||||
cpu->state.cycles = 0;
|
||||
cpu->state.next_tick_cycle = 100000;
|
||||
ft32_cpu->regs[FT32_HARD_SP] = addr;
|
||||
ft32_cpu->num_i = 0;
|
||||
ft32_cpu->cycles = 0;
|
||||
ft32_cpu->next_tick_cycle = 100000;
|
||||
|
||||
return SIM_RC_OK;
|
||||
}
|
||||
|
||||
@@ -27,13 +27,4 @@
|
||||
|
||||
#include "ft32-sim.h"
|
||||
|
||||
struct _sim_cpu {
|
||||
|
||||
/* The following are internal simulator state variables: */
|
||||
|
||||
struct ft32_cpu_state state;
|
||||
|
||||
sim_cpu_base base;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -57,13 +57,13 @@ static int memory_size;
|
||||
static unsigned int
|
||||
h8_get_reg (sim_cpu *cpu, int regnum)
|
||||
{
|
||||
return cpu->regs[regnum];
|
||||
return H8300_SIM_CPU (cpu)->regs[regnum];
|
||||
}
|
||||
|
||||
static void
|
||||
h8_set_reg (sim_cpu *cpu, int regnum, int val)
|
||||
{
|
||||
cpu->regs[regnum] = val;
|
||||
H8300_SIM_CPU (cpu)->regs[regnum] = val;
|
||||
}
|
||||
|
||||
#define h8_get_ccr(cpu) h8_get_reg (cpu, CCR_REGNUM)
|
||||
@@ -88,25 +88,25 @@ h8_set_reg (sim_cpu *cpu, int regnum, int val)
|
||||
static int
|
||||
h8_get_mask (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->mask;
|
||||
return H8300_SIM_CPU (cpu)->mask;
|
||||
}
|
||||
|
||||
static void
|
||||
h8_set_mask (sim_cpu *cpu, int val)
|
||||
{
|
||||
cpu->mask = val;
|
||||
H8300_SIM_CPU (cpu)->mask = val;
|
||||
}
|
||||
#if 0
|
||||
static int
|
||||
h8_get_exception (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->exception;
|
||||
return H8300_SIM_CPU (cpu)->exception;
|
||||
}
|
||||
|
||||
static void
|
||||
h8_set_exception (sim_cpu *cpu, int val)
|
||||
{
|
||||
cpu->exception = val;
|
||||
H8300_SIM_CPU (cpu)->exception = val;
|
||||
}
|
||||
|
||||
static enum h8300_sim_state
|
||||
@@ -125,7 +125,7 @@ h8_set_state (SIM_DESC sd, enum h8300_sim_state val)
|
||||
static unsigned int *
|
||||
h8_get_reg_buf (sim_cpu *cpu)
|
||||
{
|
||||
return &cpu->regs[0];
|
||||
return &H8300_SIM_CPU (cpu)->regs[0];
|
||||
}
|
||||
|
||||
#ifdef ADEBUG
|
||||
@@ -145,77 +145,77 @@ h8_increment_stats (SIM_DESC sd, int idx)
|
||||
static unsigned char *
|
||||
h8_get_memory_buf (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->memory;
|
||||
return H8300_SIM_CPU (cpu)->memory;
|
||||
}
|
||||
|
||||
static void
|
||||
h8_set_memory_buf (sim_cpu *cpu, unsigned char *ptr)
|
||||
{
|
||||
cpu->memory = ptr;
|
||||
H8300_SIM_CPU (cpu)->memory = ptr;
|
||||
}
|
||||
|
||||
static unsigned char
|
||||
h8_get_memory (sim_cpu *cpu, int idx)
|
||||
{
|
||||
ASSERT (idx < memory_size);
|
||||
return cpu->memory[idx];
|
||||
return H8300_SIM_CPU (cpu)->memory[idx];
|
||||
}
|
||||
|
||||
static void
|
||||
h8_set_memory (sim_cpu *cpu, int idx, unsigned int val)
|
||||
{
|
||||
ASSERT (idx < memory_size);
|
||||
cpu->memory[idx] = (unsigned char) val;
|
||||
H8300_SIM_CPU (cpu)->memory[idx] = (unsigned char) val;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
h8_get_delayed_branch (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->delayed_branch;
|
||||
return H8300_SIM_CPU (cpu)->delayed_branch;
|
||||
}
|
||||
|
||||
static void
|
||||
h8_set_delayed_branch (sim_cpu *cpu, unsigned int dest)
|
||||
{
|
||||
cpu->delayed_branch = dest;
|
||||
H8300_SIM_CPU (cpu)->delayed_branch = dest;
|
||||
}
|
||||
|
||||
static char **
|
||||
h8_get_command_line (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->command_line;
|
||||
return H8300_SIM_CPU (cpu)->command_line;
|
||||
}
|
||||
|
||||
static void
|
||||
h8_set_command_line (sim_cpu *cpu, char ** val)
|
||||
{
|
||||
cpu->command_line = val;
|
||||
H8300_SIM_CPU (cpu)->command_line = val;
|
||||
}
|
||||
|
||||
static char *
|
||||
h8_get_cmdline_arg (sim_cpu *cpu, int index)
|
||||
{
|
||||
return cpu->command_line[index];
|
||||
return H8300_SIM_CPU (cpu)->command_line[index];
|
||||
}
|
||||
|
||||
static void
|
||||
h8_set_cmdline_arg (sim_cpu *cpu, int index, char * val)
|
||||
{
|
||||
cpu->command_line[index] = val;
|
||||
H8300_SIM_CPU (cpu)->command_line[index] = val;
|
||||
}
|
||||
|
||||
/* MAC Saturation Mode */
|
||||
static int
|
||||
h8_get_macS (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->macS;
|
||||
return H8300_SIM_CPU (cpu)->macS;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
h8_set_macS (sim_cpu *cpu, int val)
|
||||
{
|
||||
cpu->macS = (val != 0);
|
||||
H8300_SIM_CPU (cpu)->macS = (val != 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -223,39 +223,39 @@ h8_set_macS (sim_cpu *cpu, int val)
|
||||
static int
|
||||
h8_get_macZ (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->macZ;
|
||||
return H8300_SIM_CPU (cpu)->macZ;
|
||||
}
|
||||
|
||||
static void
|
||||
h8_set_macZ (sim_cpu *cpu, int val)
|
||||
{
|
||||
cpu->macZ = (val != 0);
|
||||
H8300_SIM_CPU (cpu)->macZ = (val != 0);
|
||||
}
|
||||
|
||||
/* MAC Negative Flag */
|
||||
static int
|
||||
h8_get_macN (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->macN;
|
||||
return H8300_SIM_CPU (cpu)->macN;
|
||||
}
|
||||
|
||||
static void
|
||||
h8_set_macN (sim_cpu *cpu, int val)
|
||||
{
|
||||
cpu->macN = (val != 0);
|
||||
H8300_SIM_CPU (cpu)->macN = (val != 0);
|
||||
}
|
||||
|
||||
/* MAC Overflow Flag */
|
||||
static int
|
||||
h8_get_macV (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->macV;
|
||||
return H8300_SIM_CPU (cpu)->macV;
|
||||
}
|
||||
|
||||
static void
|
||||
h8_set_macV (sim_cpu *cpu, int val)
|
||||
{
|
||||
cpu->macV = (val != 0);
|
||||
H8300_SIM_CPU (cpu)->macV = (val != 0);
|
||||
}
|
||||
|
||||
/* End CPU data object. */
|
||||
@@ -1593,7 +1593,7 @@ init_pointers (SIM_DESC sd)
|
||||
|
||||
h8_set_mask (cpu, memory_size - 1);
|
||||
|
||||
memset (h8_get_reg_buf (cpu), 0, sizeof (cpu->regs));
|
||||
memset (h8_get_reg_buf (cpu), 0, sizeof (H8300_SIM_CPU (cpu)->regs));
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
@@ -4592,13 +4592,13 @@ static const OPTION h8300_options[] =
|
||||
static sim_cia
|
||||
h8300_pc_get (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->pc;
|
||||
return H8300_SIM_CPU (cpu)->pc;
|
||||
}
|
||||
|
||||
static void
|
||||
h8300_pc_set (sim_cpu *cpu, sim_cia pc)
|
||||
{
|
||||
cpu->pc = pc;
|
||||
H8300_SIM_CPU (cpu)->pc = pc;
|
||||
}
|
||||
|
||||
/* Cover function of sim_state_free to free the cpu buffers as well. */
|
||||
@@ -4629,7 +4629,8 @@ sim_open (SIM_OPEN_KIND kind,
|
||||
current_target_byte_order = BFD_ENDIAN_BIG;
|
||||
|
||||
/* The cpu data is kept in a separately allocated chunk of memory. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct h8300_sim_cpu))
|
||||
!= SIM_RC_OK)
|
||||
{
|
||||
free_state (sd);
|
||||
return 0;
|
||||
|
||||
@@ -114,7 +114,7 @@ typedef struct
|
||||
#endif
|
||||
} decoded_inst;
|
||||
|
||||
struct _sim_cpu {
|
||||
struct h8300_sim_cpu {
|
||||
unsigned int regs[20]; /* 8 GR's plus ZERO, SBR, and VBR. */
|
||||
unsigned int pc;
|
||||
|
||||
@@ -128,9 +128,8 @@ struct _sim_cpu {
|
||||
|
||||
unsigned char *memory;
|
||||
int mask;
|
||||
|
||||
sim_cpu_base base;
|
||||
};
|
||||
#define H8300_SIM_CPU(sd) ((struct h8300_sim_cpu *) CPU_ARCH_DATA (sd))
|
||||
|
||||
struct h8300_sim_state {
|
||||
unsigned long memory_size;
|
||||
@@ -142,8 +141,8 @@ struct h8300_sim_state {
|
||||
|
||||
/* The current state of the processor; registers, memory, etc. */
|
||||
|
||||
#define cpu_set_pc(CPU, VAL) (((CPU)->pc) = (VAL))
|
||||
#define cpu_get_pc(CPU) (((CPU)->pc))
|
||||
#define cpu_set_pc(cpu, val) (H8300_SIM_CPU (cpu)->pc = (val))
|
||||
#define cpu_get_pc(cpu) (H8300_SIM_CPU (cpu)->pc)
|
||||
|
||||
/* Magic numbers used to distinguish an exit from a breakpoint. */
|
||||
#define LIBC_EXIT_MAGIC1 0xdead
|
||||
|
||||
@@ -61,7 +61,7 @@ CPU (h_gr[(index)]) = (x);\
|
||||
}\
|
||||
;} while (0)
|
||||
} hardware;
|
||||
#define CPU_CGEN_HW(cpu) (& (cpu)->cpu_data.hardware)
|
||||
#define CPU_CGEN_HW(cpu) (& IQ2000_SIM_CPU (cpu)->cpu_data.hardware)
|
||||
} IQ2000BF_CPU_DATA;
|
||||
|
||||
/* Cover fns for register access. */
|
||||
|
||||
@@ -70,7 +70,8 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback, struct bfd *abfd,
|
||||
current_target_byte_order = BFD_ENDIAN_BIG;
|
||||
|
||||
/* The cpu data is kept in a separately allocated chunk of memory. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct iq2000_sim_cpu))
|
||||
!= SIM_RC_OK)
|
||||
{
|
||||
free_state (sd);
|
||||
return 0;
|
||||
|
||||
@@ -22,15 +22,7 @@
|
||||
#include "sim-base.h"
|
||||
#include "cgen-sim.h"
|
||||
|
||||
/* The _sim_cpu struct. */
|
||||
|
||||
struct _sim_cpu {
|
||||
/* sim/common cpu base. */
|
||||
sim_cpu_base base;
|
||||
|
||||
/* Static parts of cgen. */
|
||||
CGEN_CPU cgen_cpu;
|
||||
|
||||
struct iq2000_sim_cpu {
|
||||
/* CPU specific parts go here.
|
||||
Note that in files that don't need to access these pieces WANT_CPU_FOO
|
||||
won't be defined and thus these parts won't appear. This is ok in the
|
||||
@@ -42,6 +34,7 @@ struct _sim_cpu {
|
||||
IQ2000BF_CPU_DATA cpu_data;
|
||||
#endif
|
||||
};
|
||||
#define IQ2000_SIM_CPU(cpu) ((struct iq2000_sim_cpu *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
/* Misc. */
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ typedef struct {
|
||||
#define GET_H_CSR(a1) CPU (h_csr)[a1]
|
||||
#define SET_H_CSR(a1, x) (CPU (h_csr)[a1] = (x))
|
||||
} hardware;
|
||||
#define CPU_CGEN_HW(cpu) (& (cpu)->cpu_data.hardware)
|
||||
#define CPU_CGEN_HW(cpu) (& LM32_SIM_CPU (cpu)->cpu_data.hardware)
|
||||
} LM32BF_CPU_DATA;
|
||||
|
||||
/* Cover fns for register access. */
|
||||
|
||||
@@ -101,7 +101,8 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback, struct bfd *abfd,
|
||||
current_target_byte_order = BFD_ENDIAN_BIG;
|
||||
|
||||
/* The cpu data is kept in a separately allocated chunk of memory. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct lm32_sim_cpu))
|
||||
!= SIM_RC_OK)
|
||||
{
|
||||
free_state (sd);
|
||||
return 0;
|
||||
|
||||
@@ -36,16 +36,8 @@
|
||||
#include "lm32-sim.h"
|
||||
#include "opcode/cgen.h"
|
||||
|
||||
/* The _sim_cpu struct. */
|
||||
|
||||
struct _sim_cpu
|
||||
struct lm32_sim_cpu
|
||||
{
|
||||
/* sim/common cpu base. */
|
||||
sim_cpu_base base;
|
||||
|
||||
/* Static parts of cgen. */
|
||||
CGEN_CPU cgen_cpu;
|
||||
|
||||
/* CPU specific parts go here.
|
||||
Note that in files that don't need to access these pieces WANT_CPU_FOO
|
||||
won't be defined and thus these parts won't appear. This is ok in the
|
||||
@@ -56,8 +48,8 @@ struct _sim_cpu
|
||||
#if defined (WANT_CPU_LM32BF)
|
||||
LM32BF_CPU_DATA cpu_data;
|
||||
#endif
|
||||
|
||||
};
|
||||
#define LM32_SIM_CPU(cpu) ((struct lm32_sim_cpu *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
/* Misc. */
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ m32rbf_h_psw_set_handler (current_cpu, (x));\
|
||||
#define GET_H_LOCK() CPU (h_lock)
|
||||
#define SET_H_LOCK(x) (CPU (h_lock) = (x))
|
||||
} hardware;
|
||||
#define CPU_CGEN_HW(cpu) (& (cpu)->cpu_data.hardware)
|
||||
#define CPU_CGEN_HW(cpu) (& M32R_SIM_CPU (cpu)->cpu_data.hardware)
|
||||
} M32RBF_CPU_DATA;
|
||||
|
||||
/* Cover fns for register access. */
|
||||
|
||||
@@ -94,7 +94,7 @@ m32r2f_h_psw_set_handler (current_cpu, (x));\
|
||||
#define GET_H_LOCK() CPU (h_lock)
|
||||
#define SET_H_LOCK(x) (CPU (h_lock) = (x))
|
||||
} hardware;
|
||||
#define CPU_CGEN_HW(cpu) (& (cpu)->cpu_data.hardware)
|
||||
#define CPU_CGEN_HW(cpu) (& M32R_SIM_CPU (cpu)->cpu_data.hardware)
|
||||
} M32R2F_CPU_DATA;
|
||||
|
||||
/* Cover fns for register access. */
|
||||
|
||||
@@ -94,7 +94,7 @@ m32rxf_h_psw_set_handler (current_cpu, (x));\
|
||||
#define GET_H_LOCK() CPU (h_lock)
|
||||
#define SET_H_LOCK(x) (CPU (h_lock) = (x))
|
||||
} hardware;
|
||||
#define CPU_CGEN_HW(cpu) (& (cpu)->cpu_data.hardware)
|
||||
#define CPU_CGEN_HW(cpu) (& M32R_SIM_CPU (cpu)->cpu_data.hardware)
|
||||
} M32RXF_CPU_DATA;
|
||||
|
||||
/* Cover fns for register access. */
|
||||
|
||||
@@ -66,7 +66,8 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback, struct bfd *abfd,
|
||||
current_target_byte_order = BFD_ENDIAN_BIG;
|
||||
|
||||
/* The cpu data is kept in a separately allocated chunk of memory. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct m32r_sim_cpu))
|
||||
!= SIM_RC_OK)
|
||||
{
|
||||
free_state (sd);
|
||||
return 0;
|
||||
|
||||
@@ -19,17 +19,9 @@
|
||||
#include "m32r-sim.h"
|
||||
#include "opcode/cgen.h"
|
||||
|
||||
/* The _sim_cpu struct. */
|
||||
|
||||
struct _sim_cpu {
|
||||
/* sim/common cpu base. */
|
||||
sim_cpu_base base;
|
||||
|
||||
/* Static parts of cgen. */
|
||||
CGEN_CPU cgen_cpu;
|
||||
|
||||
struct m32r_sim_cpu {
|
||||
M32R_MISC_PROFILE m32r_misc_profile;
|
||||
#define CPU_M32R_MISC_PROFILE(cpu) (& (cpu)->m32r_misc_profile)
|
||||
#define CPU_M32R_MISC_PROFILE(cpu) (& M32R_SIM_CPU (cpu)->m32r_misc_profile)
|
||||
|
||||
/* CPU specific parts go here.
|
||||
Note that in files that don't need to access these pieces WANT_CPU_FOO
|
||||
@@ -47,6 +39,7 @@ struct _sim_cpu {
|
||||
M32R2F_CPU_DATA cpu_data;
|
||||
#endif
|
||||
};
|
||||
#define M32R_SIM_CPU(cpu) ((struct m32r_sim_cpu *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
/* Misc. */
|
||||
|
||||
|
||||
@@ -286,6 +286,7 @@ attach_m68hc11_regs (struct hw *me,
|
||||
{
|
||||
SIM_DESC sd;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
reg_property_spec reg;
|
||||
const char *cpu_mode;
|
||||
|
||||
@@ -314,20 +315,21 @@ attach_m68hc11_regs (struct hw *me,
|
||||
/* Get cpu frequency. */
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
if (hw_find_property (me, "clock") != NULL)
|
||||
{
|
||||
cpu->cpu_frequency = hw_find_integer_property (me, "clock");
|
||||
m68hc11_cpu->cpu_frequency = hw_find_integer_property (me, "clock");
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu->cpu_frequency = 8*1000*1000;
|
||||
m68hc11_cpu->cpu_frequency = 8*1000*1000;
|
||||
}
|
||||
|
||||
if (hw_find_property (me, "use_bank") != NULL)
|
||||
hw_attach_address (hw_parent (me), 0,
|
||||
exec_map,
|
||||
cpu->bank_start,
|
||||
cpu->bank_end - cpu->bank_start,
|
||||
m68hc11_cpu->bank_start,
|
||||
m68hc11_cpu->bank_end - m68hc11_cpu->bank_start,
|
||||
me);
|
||||
|
||||
cpu_mode = "expanded";
|
||||
@@ -335,13 +337,13 @@ attach_m68hc11_regs (struct hw *me,
|
||||
cpu_mode = hw_find_string_property (me, "mode");
|
||||
|
||||
if (strcmp (cpu_mode, "test") == 0)
|
||||
cpu->cpu_mode = M6811_MDA | M6811_SMOD;
|
||||
m68hc11_cpu->cpu_mode = M6811_MDA | M6811_SMOD;
|
||||
else if (strcmp (cpu_mode, "bootstrap") == 0)
|
||||
cpu->cpu_mode = M6811_SMOD;
|
||||
m68hc11_cpu->cpu_mode = M6811_SMOD;
|
||||
else if (strcmp (cpu_mode, "single") == 0)
|
||||
cpu->cpu_mode = 0;
|
||||
m68hc11_cpu->cpu_mode = 0;
|
||||
else
|
||||
cpu->cpu_mode = M6811_MDA;
|
||||
m68hc11_cpu->cpu_mode = M6811_MDA;
|
||||
|
||||
controller->last_oscillator = 0;
|
||||
|
||||
@@ -445,15 +447,17 @@ oscillator_handler (struct hw *me, void *data)
|
||||
struct input_osc *osc = (struct input_osc*) data;
|
||||
SIM_DESC sd;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
int64_t dt;
|
||||
uint8_t val;
|
||||
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
|
||||
/* Change the input bit. */
|
||||
osc->value ^= osc->mask;
|
||||
val = cpu->ios[osc->addr] & ~osc->mask;
|
||||
val = m68hc11_cpu->ios[osc->addr] & ~osc->mask;
|
||||
val |= osc->value;
|
||||
m68hc11cpu_set_port (me, cpu, osc->addr, val);
|
||||
|
||||
@@ -595,19 +599,21 @@ m68hc11_info (struct hw *me)
|
||||
SIM_DESC sd;
|
||||
uint16_t base = 0;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
struct m68hc11sio *controller;
|
||||
uint8_t val;
|
||||
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
controller = hw_data (me);
|
||||
|
||||
base = cpu_get_io_base (cpu);
|
||||
sim_io_printf (sd, "M68HC11:\n");
|
||||
|
||||
val = cpu->ios[M6811_HPRIO];
|
||||
val = m68hc11_cpu->ios[M6811_HPRIO];
|
||||
print_io_byte (sd, "HPRIO ", hprio_desc, val, base + M6811_HPRIO);
|
||||
switch (cpu->cpu_mode)
|
||||
switch (m68hc11_cpu->cpu_mode)
|
||||
{
|
||||
case M6811_MDA | M6811_SMOD:
|
||||
sim_io_printf (sd, "[test]\n");
|
||||
@@ -623,15 +629,15 @@ m68hc11_info (struct hw *me)
|
||||
break;
|
||||
}
|
||||
|
||||
val = cpu->ios[M6811_CONFIG];
|
||||
val = m68hc11_cpu->ios[M6811_CONFIG];
|
||||
print_io_byte (sd, "CONFIG", config_desc, val, base + M6811_CONFIG);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
val = cpu->ios[M6811_OPTION];
|
||||
val = m68hc11_cpu->ios[M6811_OPTION];
|
||||
print_io_byte (sd, "OPTION", option_desc, val, base + M6811_OPTION);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
val = cpu->ios[M6811_INIT];
|
||||
val = m68hc11_cpu->ios[M6811_INIT];
|
||||
print_io_byte (sd, "INIT ", 0, val, base + M6811_INIT);
|
||||
sim_io_printf (sd, "Ram = 0x%04x IO = 0x%04x\n",
|
||||
(((uint16_t) (val & 0xF0)) << 8),
|
||||
@@ -639,7 +645,7 @@ m68hc11_info (struct hw *me)
|
||||
|
||||
|
||||
cpu_info (sd, cpu);
|
||||
interrupts_info (sd, &cpu->cpu_interrupts);
|
||||
interrupts_info (sd, &m68hc11_cpu->cpu_interrupts);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -665,33 +671,35 @@ m68hc11cpu_set_oscillator (SIM_DESC sd, const char *port,
|
||||
double ton, double toff, int64_t repeat)
|
||||
{
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
struct input_osc *osc;
|
||||
double f;
|
||||
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
|
||||
/* Find oscillator that corresponds to the input port. */
|
||||
osc = find_oscillator (hw_data (cpu->hw_cpu), port);
|
||||
osc = find_oscillator (hw_data (m68hc11_cpu->hw_cpu), port);
|
||||
if (osc == 0)
|
||||
return -1;
|
||||
|
||||
/* Compute the ON time in cpu cycles. */
|
||||
f = (double) (cpu->cpu_frequency) * ton;
|
||||
f = (double) (m68hc11_cpu->cpu_frequency) * ton;
|
||||
osc->on_time = (int64_t) (f / 4.0);
|
||||
if (osc->on_time < 1)
|
||||
osc->on_time = 1;
|
||||
|
||||
/* Compute the OFF time in cpu cycles. */
|
||||
f = (double) (cpu->cpu_frequency) * toff;
|
||||
f = (double) (m68hc11_cpu->cpu_frequency) * toff;
|
||||
osc->off_time = (int64_t) (f / 4.0);
|
||||
if (osc->off_time < 1)
|
||||
osc->off_time = 1;
|
||||
|
||||
osc->repeat = repeat;
|
||||
if (osc->event)
|
||||
hw_event_queue_deschedule (cpu->hw_cpu, osc->event);
|
||||
hw_event_queue_deschedule (m68hc11_cpu->hw_cpu, osc->event);
|
||||
|
||||
osc->event = hw_event_queue_schedule (cpu->hw_cpu,
|
||||
osc->event = hw_event_queue_schedule (m68hc11_cpu->hw_cpu,
|
||||
osc->value ? osc->on_time
|
||||
: osc->off_time,
|
||||
oscillator_handler, osc);
|
||||
@@ -703,15 +711,17 @@ int
|
||||
m68hc11cpu_clear_oscillator (SIM_DESC sd, const char *port)
|
||||
{
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
struct input_osc *osc;
|
||||
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
osc = find_oscillator (hw_data (cpu->hw_cpu), port);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
osc = find_oscillator (hw_data (m68hc11_cpu->hw_cpu), port);
|
||||
if (osc == 0)
|
||||
return -1;
|
||||
|
||||
if (osc->event)
|
||||
hw_event_queue_deschedule (cpu->hw_cpu, osc->event);
|
||||
hw_event_queue_deschedule (m68hc11_cpu->hw_cpu, osc->event);
|
||||
osc->event = 0;
|
||||
osc->repeat = 0;
|
||||
return 0;
|
||||
@@ -742,6 +752,7 @@ static SIM_RC
|
||||
m68hc11_option_handler (SIM_DESC sd, sim_cpu *cpu,
|
||||
int opt, char *arg, int is_command)
|
||||
{
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
struct m68hc11cpu *controller;
|
||||
double f;
|
||||
char *p;
|
||||
@@ -750,8 +761,9 @@ m68hc11_option_handler (SIM_DESC sd, sim_cpu *cpu,
|
||||
|
||||
if (cpu == 0)
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
|
||||
controller = hw_data (cpu->hw_cpu);
|
||||
controller = hw_data (m68hc11_cpu->hw_cpu);
|
||||
switch (opt)
|
||||
{
|
||||
case OPTION_OSC_SET:
|
||||
@@ -796,8 +808,8 @@ m68hc11_option_handler (SIM_DESC sd, sim_cpu *cpu,
|
||||
}
|
||||
|
||||
f = (double) (osc->on_time + osc->off_time);
|
||||
f = (double) (cpu->cpu_frequency / 4) / f;
|
||||
t = hw_event_remain_time (cpu->hw_cpu, osc->event);
|
||||
f = (double) (m68hc11_cpu->cpu_frequency / 4) / f;
|
||||
t = hw_event_remain_time (m68hc11_cpu->hw_cpu, osc->event);
|
||||
|
||||
if (f > 10000.0)
|
||||
sprintf (freq, "%6.2f", f / 1000.0);
|
||||
@@ -839,6 +851,7 @@ m68hc11cpu_io_read_buffer (struct hw *me,
|
||||
SIM_DESC sd;
|
||||
struct m68hc11cpu *controller = hw_data (me);
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
unsigned byte = 0;
|
||||
int result;
|
||||
|
||||
@@ -846,8 +859,9 @@ m68hc11cpu_io_read_buffer (struct hw *me,
|
||||
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
|
||||
if (base >= cpu->bank_start && base < cpu->bank_end)
|
||||
if (base >= m68hc11_cpu->bank_start && base < m68hc11_cpu->bank_end)
|
||||
{
|
||||
address_word virt_addr = phys_to_virt (cpu, base);
|
||||
if (virt_addr != base)
|
||||
@@ -867,7 +881,7 @@ m68hc11cpu_io_read_buffer (struct hw *me,
|
||||
if (base >= controller->attach_size)
|
||||
break;
|
||||
|
||||
memcpy (dest, &cpu->ios[base], 1);
|
||||
memcpy (dest, &m68hc11_cpu->ios[base], 1);
|
||||
dest = (char*) dest + 1;
|
||||
base++;
|
||||
byte++;
|
||||
@@ -880,6 +894,7 @@ void
|
||||
m68hc11cpu_set_port (struct hw *me, sim_cpu *cpu,
|
||||
unsigned addr, uint8_t val)
|
||||
{
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
uint8_t mask;
|
||||
uint8_t delta;
|
||||
int check_interrupts = 0;
|
||||
@@ -888,35 +903,35 @@ m68hc11cpu_set_port (struct hw *me, sim_cpu *cpu,
|
||||
switch (addr)
|
||||
{
|
||||
case M6811_PORTA:
|
||||
if (cpu->ios[M6811_PACTL] & M6811_DDRA7)
|
||||
if (m68hc11_cpu->ios[M6811_PACTL] & M6811_DDRA7)
|
||||
mask = 3;
|
||||
else
|
||||
mask = 0x83;
|
||||
|
||||
val = val & mask;
|
||||
val |= cpu->ios[M6811_PORTA] & ~mask;
|
||||
delta = val ^ cpu->ios[M6811_PORTA];
|
||||
cpu->ios[M6811_PORTA] = val;
|
||||
val |= m68hc11_cpu->ios[M6811_PORTA] & ~mask;
|
||||
delta = val ^ m68hc11_cpu->ios[M6811_PORTA];
|
||||
m68hc11_cpu->ios[M6811_PORTA] = val;
|
||||
if (delta & 0x80)
|
||||
{
|
||||
/* Pulse accumulator is enabled. */
|
||||
if ((cpu->ios[M6811_PACTL] & M6811_PAEN)
|
||||
&& !(cpu->ios[M6811_PACTL] & M6811_PAMOD))
|
||||
if ((m68hc11_cpu->ios[M6811_PACTL] & M6811_PAEN)
|
||||
&& !(m68hc11_cpu->ios[M6811_PACTL] & M6811_PAMOD))
|
||||
{
|
||||
int inc;
|
||||
|
||||
/* Increment event counter according to rising/falling edge. */
|
||||
if (cpu->ios[M6811_PACTL] & M6811_PEDGE)
|
||||
if (m68hc11_cpu->ios[M6811_PACTL] & M6811_PEDGE)
|
||||
inc = (val & 0x80) ? 1 : 0;
|
||||
else
|
||||
inc = (val & 0x80) ? 0 : 1;
|
||||
|
||||
cpu->ios[M6811_PACNT] += inc;
|
||||
m68hc11_cpu->ios[M6811_PACNT] += inc;
|
||||
|
||||
/* Event counter overflowed. */
|
||||
if (inc && cpu->ios[M6811_PACNT] == 0)
|
||||
if (inc && m68hc11_cpu->ios[M6811_PACNT] == 0)
|
||||
{
|
||||
cpu->ios[M6811_TFLG2] |= M6811_PAOVI;
|
||||
m68hc11_cpu->ios[M6811_TFLG2] |= M6811_PAOVI;
|
||||
check_interrupts = 1;
|
||||
}
|
||||
}
|
||||
@@ -932,7 +947,7 @@ m68hc11cpu_set_port (struct hw *me, sim_cpu *cpu,
|
||||
uint8_t edge;
|
||||
int captured;
|
||||
|
||||
edge = cpu->ios[M6811_TCTL2];
|
||||
edge = m68hc11_cpu->ios[M6811_TCTL2];
|
||||
edge = (edge >> (2 * i)) & 0x3;
|
||||
switch (edge)
|
||||
{
|
||||
@@ -951,7 +966,7 @@ m68hc11cpu_set_port (struct hw *me, sim_cpu *cpu,
|
||||
}
|
||||
if (captured)
|
||||
{
|
||||
cpu->ios[M6811_TFLG1] |= (1 << i);
|
||||
m68hc11_cpu->ios[M6811_TFLG1] |= (1 << i);
|
||||
hw_port_event (me, CAPTURE, M6811_TIC1 + 3 - i);
|
||||
check_interrupts = 1;
|
||||
}
|
||||
@@ -960,17 +975,17 @@ m68hc11cpu_set_port (struct hw *me, sim_cpu *cpu,
|
||||
break;
|
||||
|
||||
case M6811_PORTC:
|
||||
mask = cpu->ios[M6811_DDRC];
|
||||
mask = m68hc11_cpu->ios[M6811_DDRC];
|
||||
val = val & mask;
|
||||
val |= cpu->ios[M6811_PORTC] & ~mask;
|
||||
cpu->ios[M6811_PORTC] = val;
|
||||
val |= m68hc11_cpu->ios[M6811_PORTC] & ~mask;
|
||||
m68hc11_cpu->ios[M6811_PORTC] = val;
|
||||
break;
|
||||
|
||||
case M6811_PORTD:
|
||||
mask = cpu->ios[M6811_DDRD];
|
||||
mask = m68hc11_cpu->ios[M6811_DDRD];
|
||||
val = val & mask;
|
||||
val |= cpu->ios[M6811_PORTD] & ~mask;
|
||||
cpu->ios[M6811_PORTD] = val;
|
||||
val |= m68hc11_cpu->ios[M6811_PORTD] & ~mask;
|
||||
m68hc11_cpu->ios[M6811_PORTD] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -978,13 +993,15 @@ m68hc11cpu_set_port (struct hw *me, sim_cpu *cpu,
|
||||
}
|
||||
|
||||
if (check_interrupts)
|
||||
interrupts_update_pending (&cpu->cpu_interrupts);
|
||||
interrupts_update_pending (&m68hc11_cpu->cpu_interrupts);
|
||||
}
|
||||
|
||||
static void
|
||||
m68hc11cpu_io_write (struct hw *me, sim_cpu *cpu,
|
||||
unsigned_word addr, uint8_t val)
|
||||
{
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case M6811_PORTA:
|
||||
@@ -1022,9 +1039,9 @@ m68hc11cpu_io_write (struct hw *me, sim_cpu *cpu,
|
||||
/* Change the RAM and I/O mapping. */
|
||||
case M6811_INIT:
|
||||
{
|
||||
uint8_t old_bank = cpu->ios[M6811_INIT];
|
||||
uint8_t old_bank = m68hc11_cpu->ios[M6811_INIT];
|
||||
|
||||
cpu->ios[M6811_INIT] = val;
|
||||
m68hc11_cpu->ios[M6811_INIT] = val;
|
||||
|
||||
/* Update IO mapping. Detach from the old address
|
||||
and attach to the new one. */
|
||||
@@ -1063,7 +1080,7 @@ m68hc11cpu_io_write (struct hw *me, sim_cpu *cpu,
|
||||
|
||||
/* COP reset. */
|
||||
case M6811_COPRST:
|
||||
if (val == 0xAA && cpu->ios[addr] == 0x55)
|
||||
if (val == 0xAA && m68hc11_cpu->ios[addr] == 0x55)
|
||||
{
|
||||
val = 0;
|
||||
/* COP reset here. */
|
||||
@@ -1074,7 +1091,7 @@ m68hc11cpu_io_write (struct hw *me, sim_cpu *cpu,
|
||||
break;
|
||||
|
||||
}
|
||||
cpu->ios[addr] = val;
|
||||
m68hc11_cpu->ios[addr] = val;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
@@ -1088,14 +1105,16 @@ m68hc11cpu_io_write_buffer (struct hw *me,
|
||||
struct m68hc11cpu *controller = hw_data (me);
|
||||
unsigned byte;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
int result;
|
||||
|
||||
HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));
|
||||
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
|
||||
if (base >= cpu->bank_start && base < cpu->bank_end)
|
||||
if (base >= m68hc11_cpu->bank_start && base < m68hc11_cpu->bank_end)
|
||||
{
|
||||
address_word virt_addr = phys_to_virt (cpu, base);
|
||||
if (virt_addr != base)
|
||||
|
||||
@@ -241,10 +241,12 @@ m68hc11eepr_port_event (struct hw *me,
|
||||
SIM_DESC sd;
|
||||
struct m68hc11eepr *controller;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
|
||||
controller = hw_data (me);
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
switch (my_port)
|
||||
{
|
||||
case RESET_PORT:
|
||||
@@ -258,11 +260,11 @@ m68hc11eepr_port_event (struct hw *me,
|
||||
|
||||
/* Reset the state of EEPROM programmer. The CONFIG register
|
||||
is also initialized from the EEPROM/file content. */
|
||||
cpu->ios[M6811_PPROG] = 0;
|
||||
if (cpu->cpu_use_local_config)
|
||||
cpu->ios[M6811_CONFIG] = cpu->cpu_config;
|
||||
m68hc11_cpu->ios[M6811_PPROG] = 0;
|
||||
if (m68hc11_cpu->cpu_use_local_config)
|
||||
m68hc11_cpu->ios[M6811_CONFIG] = m68hc11_cpu->cpu_config;
|
||||
else
|
||||
cpu->ios[M6811_CONFIG] = controller->eeprom[controller->size-1];
|
||||
m68hc11_cpu->ios[M6811_CONFIG] = controller->eeprom[controller->size-1];
|
||||
controller->eeprom_wmode = 0;
|
||||
controller->eeprom_waddr = 0;
|
||||
controller->eeprom_wbyte = 0;
|
||||
@@ -271,7 +273,7 @@ m68hc11eepr_port_event (struct hw *me,
|
||||
The EEPROM CONFIG register is still enabled and can be programmed
|
||||
for a next configuration (taken into account only after a reset,
|
||||
see Motorola spec). */
|
||||
if (!(cpu->ios[M6811_CONFIG] & M6811_EEON))
|
||||
if (!(m68hc11_cpu->ios[M6811_CONFIG] & M6811_EEON))
|
||||
{
|
||||
if (controller->mapped)
|
||||
hw_detach_address (hw_parent (me), M6811_EEPROM_LEVEL,
|
||||
@@ -341,21 +343,23 @@ m68hc11eepr_info (struct hw *me)
|
||||
SIM_DESC sd;
|
||||
uint16_t base = 0;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
struct m68hc11eepr *controller;
|
||||
uint8_t val;
|
||||
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
controller = hw_data (me);
|
||||
base = cpu_get_io_base (cpu);
|
||||
|
||||
sim_io_printf (sd, "M68HC11 EEprom:\n");
|
||||
|
||||
val = cpu->ios[M6811_PPROG];
|
||||
val = m68hc11_cpu->ios[M6811_PPROG];
|
||||
print_io_byte (sd, "PPROG ", pprog_desc, val, base + M6811_PPROG);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
val = cpu->ios[M6811_CONFIG];
|
||||
val = m68hc11_cpu->ios[M6811_CONFIG];
|
||||
print_io_byte (sd, "CONFIG ", config_desc, val, base + M6811_CONFIG);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
@@ -401,12 +405,14 @@ m68hc11eepr_io_read_buffer (struct hw *me,
|
||||
SIM_DESC sd;
|
||||
struct m68hc11eepr *controller;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
|
||||
HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
|
||||
|
||||
sd = hw_system (me);
|
||||
controller = hw_data (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
|
||||
if (space == io_map)
|
||||
{
|
||||
@@ -418,7 +424,7 @@ m68hc11eepr_io_read_buffer (struct hw *me,
|
||||
{
|
||||
case M6811_PPROG:
|
||||
case M6811_CONFIG:
|
||||
*((uint8_t*) dest) = cpu->ios[base];
|
||||
*((uint8_t*) dest) = m68hc11_cpu->ios[base];
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -433,7 +439,7 @@ m68hc11eepr_io_read_buffer (struct hw *me,
|
||||
}
|
||||
|
||||
/* In theory, we can't read the EEPROM when it's being programmed. */
|
||||
if ((cpu->ios[M6811_PPROG] & M6811_EELAT) != 0
|
||||
if ((m68hc11_cpu->ios[M6811_PPROG] & M6811_EELAT) != 0
|
||||
&& cpu_is_running (cpu))
|
||||
{
|
||||
sim_memory_error (cpu, SIM_SIGBUS, base,
|
||||
@@ -456,6 +462,7 @@ m68hc11eepr_io_write_buffer (struct hw *me,
|
||||
SIM_DESC sd;
|
||||
struct m68hc11eepr *controller;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
uint8_t val;
|
||||
|
||||
HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));
|
||||
@@ -463,6 +470,7 @@ m68hc11eepr_io_write_buffer (struct hw *me,
|
||||
sd = hw_system (me);
|
||||
controller = hw_data (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
|
||||
/* Programming several bytes at a time is not possible. */
|
||||
if (space != io_map && nr_bytes != 1)
|
||||
@@ -487,7 +495,7 @@ m68hc11eepr_io_write_buffer (struct hw *me,
|
||||
|
||||
/* Setting EELAT and EEPGM at the same time is an error.
|
||||
Clearing them both is ok. */
|
||||
wrong_bits = (cpu->ios[M6811_PPROG] ^ val) & val;
|
||||
wrong_bits = (m68hc11_cpu->ios[M6811_PPROG] ^ val) & val;
|
||||
wrong_bits &= (M6811_EELAT | M6811_EEPGM);
|
||||
|
||||
if (wrong_bits == (M6811_EEPGM|M6811_EELAT))
|
||||
@@ -501,7 +509,7 @@ m68hc11eepr_io_write_buffer (struct hw *me,
|
||||
{
|
||||
val = 0;
|
||||
}
|
||||
if ((val & M6811_EEPGM) && !(cpu->ios[M6811_PPROG] & M6811_EELAT))
|
||||
if ((val & M6811_EEPGM) && !(m68hc11_cpu->ios[M6811_PPROG] & M6811_EELAT))
|
||||
{
|
||||
sim_memory_error (cpu, SIM_SIGBUS, addr,
|
||||
"EEProm high voltage applied after EELAT");
|
||||
@@ -515,7 +523,7 @@ m68hc11eepr_io_write_buffer (struct hw *me,
|
||||
{
|
||||
controller->eeprom_wcycle = cpu_current_cycle (cpu);
|
||||
}
|
||||
else if (cpu->ios[M6811_PPROG] & M6811_PPROG)
|
||||
else if (m68hc11_cpu->ios[M6811_PPROG] & M6811_PPROG)
|
||||
{
|
||||
int i;
|
||||
unsigned long t = cpu_current_cycle (cpu);
|
||||
@@ -529,7 +537,7 @@ m68hc11eepr_io_write_buffer (struct hw *me,
|
||||
}
|
||||
|
||||
/* Program the byte by clearing some bits. */
|
||||
if (!(cpu->ios[M6811_PPROG] & M6811_ERASE))
|
||||
if (!(m68hc11_cpu->ios[M6811_PPROG] & M6811_ERASE))
|
||||
{
|
||||
controller->eeprom[controller->eeprom_waddr]
|
||||
&= controller->eeprom_wbyte;
|
||||
@@ -538,12 +546,12 @@ m68hc11eepr_io_write_buffer (struct hw *me,
|
||||
/* Erase a byte, row or the complete eeprom. Erased value is 0xFF.
|
||||
Ignore row or complete eeprom erase when we are programming the
|
||||
CONFIG register (last EEPROM byte). */
|
||||
else if ((cpu->ios[M6811_PPROG] & M6811_BYTE)
|
||||
else if ((m68hc11_cpu->ios[M6811_PPROG] & M6811_BYTE)
|
||||
|| controller->eeprom_waddr == controller->size - 1)
|
||||
{
|
||||
controller->eeprom[controller->eeprom_waddr] = 0xff;
|
||||
}
|
||||
else if (cpu->ios[M6811_BYTE] & M6811_ROW)
|
||||
else if (m68hc11_cpu->ios[M6811_BYTE] & M6811_ROW)
|
||||
{
|
||||
size_t max_size;
|
||||
|
||||
@@ -578,7 +586,7 @@ m68hc11eepr_io_write_buffer (struct hw *me,
|
||||
}
|
||||
controller->eeprom_wmode = 0;
|
||||
}
|
||||
cpu->ios[M6811_PPROG] = val;
|
||||
m68hc11_cpu->ios[M6811_PPROG] = val;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -597,7 +605,7 @@ m68hc11eepr_io_write_buffer (struct hw *me,
|
||||
(cpu not running). */
|
||||
if (cpu_is_running (cpu))
|
||||
{
|
||||
if ((cpu->ios[M6811_PPROG] & M6811_EELAT) == 0)
|
||||
if ((m68hc11_cpu->ios[M6811_PPROG] & M6811_EELAT) == 0)
|
||||
{
|
||||
sim_memory_error (cpu, SIM_SIGSEGV, base,
|
||||
"EEprom not configured for writing");
|
||||
|
||||
@@ -184,11 +184,13 @@ m68hc11sio_port_event (struct hw *me,
|
||||
SIM_DESC sd;
|
||||
struct m68hc11sio *controller;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
uint8_t val;
|
||||
|
||||
controller = hw_data (me);
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
switch (my_port)
|
||||
{
|
||||
case RESET_PORT:
|
||||
@@ -204,7 +206,7 @@ m68hc11sio_port_event (struct hw *me,
|
||||
m68hc11sio_io_write_buffer (me, &val, io_map,
|
||||
(unsigned_word) M6811_SCCR2, 1);
|
||||
|
||||
cpu->ios[M6811_SCSR] = M6811_TC | M6811_TDRE;
|
||||
m68hc11_cpu->ios[M6811_SCSR] = M6811_TC | M6811_TDRE;
|
||||
controller->rx_char = 0;
|
||||
controller->tx_char = 0;
|
||||
controller->tx_has_char = 0;
|
||||
@@ -222,7 +224,7 @@ m68hc11sio_port_event (struct hw *me,
|
||||
|
||||
/* In bootstrap mode, initialize the SCI to 1200 bauds to
|
||||
simulate some initial setup by the internal rom. */
|
||||
if (((cpu->ios[M6811_HPRIO]) & (M6811_SMOD | M6811_MDA)) == M6811_SMOD)
|
||||
if (((m68hc11_cpu->ios[M6811_HPRIO]) & (M6811_SMOD | M6811_MDA)) == M6811_SMOD)
|
||||
{
|
||||
unsigned char val = 0x33;
|
||||
|
||||
@@ -248,6 +250,7 @@ m68hc11sio_rx_poll (struct hw *me, void *data)
|
||||
SIM_DESC sd;
|
||||
struct m68hc11sio *controller;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
char cc;
|
||||
int cnt;
|
||||
int check_interrupt = 0;
|
||||
@@ -255,6 +258,7 @@ m68hc11sio_rx_poll (struct hw *me, void *data)
|
||||
controller = hw_data (me);
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
switch (controller->backend)
|
||||
{
|
||||
case sio_tcp:
|
||||
@@ -278,10 +282,10 @@ m68hc11sio_rx_poll (struct hw *me, void *data)
|
||||
if (cnt == 1)
|
||||
{
|
||||
/* Raise the overrun flag if the previous character was not read. */
|
||||
if (cpu->ios[M6811_SCSR] & M6811_RDRF)
|
||||
cpu->ios[M6811_SCSR] |= M6811_OR;
|
||||
if (m68hc11_cpu->ios[M6811_SCSR] & M6811_RDRF)
|
||||
m68hc11_cpu->ios[M6811_SCSR] |= M6811_OR;
|
||||
|
||||
cpu->ios[M6811_SCSR] |= M6811_RDRF;
|
||||
m68hc11_cpu->ios[M6811_SCSR] |= M6811_RDRF;
|
||||
controller->rx_char = cc;
|
||||
controller->rx_clear_scsr = 0;
|
||||
check_interrupt = 1;
|
||||
@@ -298,7 +302,7 @@ m68hc11sio_rx_poll (struct hw *me, void *data)
|
||||
controller->rx_poll_event = 0;
|
||||
}
|
||||
|
||||
if (cpu->ios[M6811_SCCR2] & M6811_RE)
|
||||
if (m68hc11_cpu->ios[M6811_SCCR2] & M6811_RE)
|
||||
{
|
||||
unsigned long clock_cycle;
|
||||
|
||||
@@ -311,7 +315,7 @@ m68hc11sio_rx_poll (struct hw *me, void *data)
|
||||
}
|
||||
|
||||
if (check_interrupt)
|
||||
interrupts_update_pending (&cpu->cpu_interrupts);
|
||||
interrupts_update_pending (&m68hc11_cpu->cpu_interrupts);
|
||||
}
|
||||
|
||||
|
||||
@@ -321,19 +325,21 @@ m68hc11sio_tx_poll (struct hw *me, void *data)
|
||||
SIM_DESC sd;
|
||||
struct m68hc11sio *controller;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
|
||||
controller = hw_data (me);
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
|
||||
cpu->ios[M6811_SCSR] |= M6811_TDRE;
|
||||
cpu->ios[M6811_SCSR] |= M6811_TC;
|
||||
m68hc11_cpu->ios[M6811_SCSR] |= M6811_TDRE;
|
||||
m68hc11_cpu->ios[M6811_SCSR] |= M6811_TC;
|
||||
|
||||
/* Transmitter is enabled and we have something to send. */
|
||||
if ((cpu->ios[M6811_SCCR2] & M6811_TE) && controller->tx_has_char)
|
||||
if ((m68hc11_cpu->ios[M6811_SCCR2] & M6811_TE) && controller->tx_has_char)
|
||||
{
|
||||
cpu->ios[M6811_SCSR] &= ~M6811_TDRE;
|
||||
cpu->ios[M6811_SCSR] &= ~M6811_TC;
|
||||
m68hc11_cpu->ios[M6811_SCSR] &= ~M6811_TDRE;
|
||||
m68hc11_cpu->ios[M6811_SCSR] &= ~M6811_TC;
|
||||
controller->tx_has_char = 0;
|
||||
switch (controller->backend)
|
||||
{
|
||||
@@ -357,8 +363,8 @@ m68hc11sio_tx_poll (struct hw *me, void *data)
|
||||
controller->tx_poll_event = 0;
|
||||
}
|
||||
|
||||
if ((cpu->ios[M6811_SCCR2] & M6811_TE)
|
||||
&& ((cpu->ios[M6811_SCSR] & M6811_TC) == 0))
|
||||
if ((m68hc11_cpu->ios[M6811_SCCR2] & M6811_TE)
|
||||
&& ((m68hc11_cpu->ios[M6811_SCSR] & M6811_TC) == 0))
|
||||
{
|
||||
unsigned long clock_cycle;
|
||||
|
||||
@@ -370,7 +376,7 @@ m68hc11sio_tx_poll (struct hw *me, void *data)
|
||||
NULL);
|
||||
}
|
||||
|
||||
interrupts_update_pending (&cpu->cpu_interrupts);
|
||||
interrupts_update_pending (&m68hc11_cpu->cpu_interrupts);
|
||||
}
|
||||
|
||||
/* Descriptions of the SIO I/O ports. These descriptions are only used to
|
||||
@@ -423,33 +429,35 @@ m68hc11sio_info (struct hw *me)
|
||||
SIM_DESC sd;
|
||||
uint16_t base = 0;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
struct m68hc11sio *controller;
|
||||
uint8_t val;
|
||||
long clock_cycle;
|
||||
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
controller = hw_data (me);
|
||||
|
||||
sim_io_printf (sd, "M68HC11 SIO:\n");
|
||||
|
||||
base = cpu_get_io_base (cpu);
|
||||
|
||||
val = cpu->ios[M6811_BAUD];
|
||||
val = m68hc11_cpu->ios[M6811_BAUD];
|
||||
print_io_byte (sd, "BAUD ", baud_desc, val, base + M6811_BAUD);
|
||||
sim_io_printf (sd, " (%ld baud)\n",
|
||||
(cpu->cpu_frequency / 4) / controller->baud_cycle);
|
||||
(m68hc11_cpu->cpu_frequency / 4) / controller->baud_cycle);
|
||||
|
||||
val = cpu->ios[M6811_SCCR1];
|
||||
val = m68hc11_cpu->ios[M6811_SCCR1];
|
||||
print_io_byte (sd, "SCCR1", sccr1_desc, val, base + M6811_SCCR1);
|
||||
sim_io_printf (sd, " (%d bits) (%dN1)\n",
|
||||
controller->data_length, controller->data_length - 2);
|
||||
|
||||
val = cpu->ios[M6811_SCCR2];
|
||||
val = m68hc11_cpu->ios[M6811_SCCR2];
|
||||
print_io_byte (sd, "SCCR2", sccr2_desc, val, base + M6811_SCCR2);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
val = cpu->ios[M6811_SCSR];
|
||||
val = m68hc11_cpu->ios[M6811_SCSR];
|
||||
print_io_byte (sd, "SCSR ", scsr_desc, val, base + M6811_SCSR);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
@@ -499,30 +507,32 @@ m68hc11sio_io_read_buffer (struct hw *me,
|
||||
SIM_DESC sd;
|
||||
struct m68hc11sio *controller;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
uint8_t val;
|
||||
|
||||
HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
|
||||
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
controller = hw_data (me);
|
||||
|
||||
switch (base)
|
||||
{
|
||||
case M6811_SCSR:
|
||||
controller->rx_clear_scsr = cpu->ios[M6811_SCSR]
|
||||
controller->rx_clear_scsr = m68hc11_cpu->ios[M6811_SCSR]
|
||||
& (M6811_RDRF | M6811_IDLE | M6811_OR | M6811_NF | M6811_FE);
|
||||
|
||||
case M6811_BAUD:
|
||||
case M6811_SCCR1:
|
||||
case M6811_SCCR2:
|
||||
val = cpu->ios[base];
|
||||
val = m68hc11_cpu->ios[base];
|
||||
break;
|
||||
|
||||
case M6811_SCDR:
|
||||
if (controller->rx_clear_scsr)
|
||||
{
|
||||
cpu->ios[M6811_SCSR] &= ~controller->rx_clear_scsr;
|
||||
m68hc11_cpu->ios[M6811_SCSR] &= ~controller->rx_clear_scsr;
|
||||
}
|
||||
val = controller->rx_char;
|
||||
break;
|
||||
@@ -544,12 +554,14 @@ m68hc11sio_io_write_buffer (struct hw *me,
|
||||
SIM_DESC sd;
|
||||
struct m68hc11sio *controller;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
uint8_t val;
|
||||
|
||||
HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));
|
||||
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
controller = hw_data (me);
|
||||
|
||||
val = *((const uint8_t*) source);
|
||||
@@ -560,7 +572,7 @@ m68hc11sio_io_write_buffer (struct hw *me,
|
||||
long divisor;
|
||||
long baud;
|
||||
|
||||
cpu->ios[M6811_BAUD] = val;
|
||||
m68hc11_cpu->ios[M6811_BAUD] = val;
|
||||
switch (val & (M6811_SCP1|M6811_SCP0))
|
||||
{
|
||||
case M6811_BAUD_DIV_1:
|
||||
@@ -583,7 +595,7 @@ m68hc11sio_io_write_buffer (struct hw *me,
|
||||
val &= (M6811_SCR2|M6811_SCR1|M6811_SCR0);
|
||||
divisor *= (1 << val);
|
||||
|
||||
baud = (cpu->cpu_frequency / 4) / divisor;
|
||||
baud = (m68hc11_cpu->cpu_frequency / 4) / divisor;
|
||||
|
||||
HW_TRACE ((me, "divide rate %ld, baud rate %ld",
|
||||
divisor, baud));
|
||||
@@ -599,7 +611,7 @@ m68hc11sio_io_write_buffer (struct hw *me,
|
||||
else
|
||||
controller->data_length = 10;
|
||||
|
||||
cpu->ios[M6811_SCCR1] = val;
|
||||
m68hc11_cpu->ios[M6811_SCCR1] = val;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -607,9 +619,9 @@ m68hc11sio_io_write_buffer (struct hw *me,
|
||||
if ((val & M6811_RE) == 0)
|
||||
{
|
||||
val &= ~(M6811_RDRF|M6811_IDLE|M6811_OR|M6811_NF|M6811_NF);
|
||||
val |= (cpu->ios[M6811_SCCR2]
|
||||
val |= (m68hc11_cpu->ios[M6811_SCCR2]
|
||||
& (M6811_RDRF|M6811_IDLE|M6811_OR|M6811_NF|M6811_NF));
|
||||
cpu->ios[M6811_SCCR2] = val;
|
||||
m68hc11_cpu->ios[M6811_SCCR2] = val;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -625,8 +637,8 @@ m68hc11sio_io_write_buffer (struct hw *me,
|
||||
m68hc11sio_rx_poll,
|
||||
NULL);
|
||||
}
|
||||
cpu->ios[M6811_SCCR2] = val;
|
||||
interrupts_update_pending (&cpu->cpu_interrupts);
|
||||
m68hc11_cpu->ios[M6811_SCCR2] = val;
|
||||
interrupts_update_pending (&m68hc11_cpu->cpu_interrupts);
|
||||
break;
|
||||
|
||||
/* No effect. */
|
||||
@@ -634,14 +646,14 @@ m68hc11sio_io_write_buffer (struct hw *me,
|
||||
return 1;
|
||||
|
||||
case M6811_SCDR:
|
||||
if (!(cpu->ios[M6811_SCSR] & M6811_TDRE))
|
||||
if (!(m68hc11_cpu->ios[M6811_SCSR] & M6811_TDRE))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
controller->tx_char = val;
|
||||
controller->tx_has_char = 1;
|
||||
if ((cpu->ios[M6811_SCCR2] & M6811_TE)
|
||||
if ((m68hc11_cpu->ios[M6811_SCCR2] & M6811_TE)
|
||||
&& controller->tx_poll_event == 0)
|
||||
{
|
||||
m68hc11sio_tx_poll (me, NULL);
|
||||
|
||||
@@ -193,12 +193,13 @@ m68hc11spi_port_event (struct hw *me,
|
||||
static void
|
||||
set_bit_port (struct hw *me, sim_cpu *cpu, int port, int mask, int value)
|
||||
{
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
uint8_t val;
|
||||
|
||||
if (value)
|
||||
val = cpu->ios[port] | mask;
|
||||
val = m68hc11_cpu->ios[port] | mask;
|
||||
else
|
||||
val = cpu->ios[port] & ~mask;
|
||||
val = m68hc11_cpu->ios[port] & ~mask;
|
||||
|
||||
/* Set the new value and post an event to inform other devices
|
||||
that pin 'port' changed. */
|
||||
@@ -242,11 +243,13 @@ m68hc11spi_clock (struct hw *me, void *data)
|
||||
SIM_DESC sd;
|
||||
struct m68hc11spi* controller;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
int check_interrupt = 0;
|
||||
|
||||
controller = hw_data (me);
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
|
||||
/* Cleanup current event. */
|
||||
if (controller->spi_event)
|
||||
@@ -289,8 +292,8 @@ m68hc11spi_clock (struct hw *me, void *data)
|
||||
if (controller->mode == SPI_START_BIT && controller->tx_bit < 0)
|
||||
{
|
||||
controller->rx_clear_scsr = 0;
|
||||
cpu->ios[M6811_SPSR] |= M6811_SPIF;
|
||||
if (cpu->ios[M6811_SPCR] & M6811_SPIE)
|
||||
m68hc11_cpu->ios[M6811_SPSR] |= M6811_SPIF;
|
||||
if (m68hc11_cpu->ios[M6811_SPCR] & M6811_SPIE)
|
||||
check_interrupt = 1;
|
||||
}
|
||||
else
|
||||
@@ -301,7 +304,7 @@ m68hc11spi_clock (struct hw *me, void *data)
|
||||
}
|
||||
|
||||
if (check_interrupt)
|
||||
interrupts_update_pending (&cpu->cpu_interrupts);
|
||||
interrupts_update_pending (&m68hc11_cpu->cpu_interrupts);
|
||||
}
|
||||
|
||||
/* Flags of the SPCR register. */
|
||||
@@ -332,22 +335,24 @@ m68hc11spi_info (struct hw *me)
|
||||
SIM_DESC sd;
|
||||
uint16_t base = 0;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
struct m68hc11spi *controller;
|
||||
uint8_t val;
|
||||
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
controller = hw_data (me);
|
||||
|
||||
sim_io_printf (sd, "M68HC11 SPI:\n");
|
||||
|
||||
base = cpu_get_io_base (cpu);
|
||||
|
||||
val = cpu->ios[M6811_SPCR];
|
||||
val = m68hc11_cpu->ios[M6811_SPCR];
|
||||
print_io_byte (sd, "SPCR", spcr_desc, val, base + M6811_SPCR);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
val = cpu->ios[M6811_SPSR];
|
||||
val = m68hc11_cpu->ios[M6811_SPSR];
|
||||
print_io_byte (sd, "SPSR", spsr_desc, val, base + M6811_SPSR);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
@@ -388,30 +393,32 @@ m68hc11spi_io_read_buffer (struct hw *me,
|
||||
SIM_DESC sd;
|
||||
struct m68hc11spi *controller;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
uint8_t val;
|
||||
|
||||
HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
|
||||
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
controller = hw_data (me);
|
||||
|
||||
switch (base)
|
||||
{
|
||||
case M6811_SPSR:
|
||||
controller->rx_clear_scsr = cpu->ios[M6811_SCSR]
|
||||
controller->rx_clear_scsr = m68hc11_cpu->ios[M6811_SCSR]
|
||||
& (M6811_SPIF | M6811_WCOL | M6811_MODF);
|
||||
|
||||
case M6811_SPCR:
|
||||
val = cpu->ios[base];
|
||||
val = m68hc11_cpu->ios[base];
|
||||
break;
|
||||
|
||||
case M6811_SPDR:
|
||||
if (controller->rx_clear_scsr)
|
||||
{
|
||||
cpu->ios[M6811_SPSR] &= ~controller->rx_clear_scsr;
|
||||
m68hc11_cpu->ios[M6811_SPSR] &= ~controller->rx_clear_scsr;
|
||||
controller->rx_clear_scsr = 0;
|
||||
interrupts_update_pending (&cpu->cpu_interrupts);
|
||||
interrupts_update_pending (&m68hc11_cpu->cpu_interrupts);
|
||||
}
|
||||
val = controller->rx_char;
|
||||
break;
|
||||
@@ -433,19 +440,21 @@ m68hc11spi_io_write_buffer (struct hw *me,
|
||||
SIM_DESC sd;
|
||||
struct m68hc11spi *controller;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
uint8_t val;
|
||||
|
||||
HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));
|
||||
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
controller = hw_data (me);
|
||||
|
||||
val = *((const uint8_t*) source);
|
||||
switch (base)
|
||||
{
|
||||
case M6811_SPCR:
|
||||
cpu->ios[M6811_SPCR] = val;
|
||||
m68hc11_cpu->ios[M6811_SPCR] = val;
|
||||
|
||||
/* The SPI clock rate is 2, 4, 16, 32 of the internal CPU clock.
|
||||
We have to drive the clock pin and need a 2x faster clock. */
|
||||
@@ -484,23 +493,23 @@ m68hc11spi_io_write_buffer (struct hw *me,
|
||||
break;
|
||||
|
||||
case M6811_SPDR:
|
||||
if (!(cpu->ios[M6811_SPCR] & M6811_SPE))
|
||||
if (!(m68hc11_cpu->ios[M6811_SPCR] & M6811_SPE))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (controller->rx_clear_scsr)
|
||||
{
|
||||
cpu->ios[M6811_SPSR] &= ~controller->rx_clear_scsr;
|
||||
m68hc11_cpu->ios[M6811_SPSR] &= ~controller->rx_clear_scsr;
|
||||
controller->rx_clear_scsr = 0;
|
||||
interrupts_update_pending (&cpu->cpu_interrupts);
|
||||
interrupts_update_pending (&m68hc11_cpu->cpu_interrupts);
|
||||
}
|
||||
|
||||
/* If transfer is taking place, a write to SPDR
|
||||
generates a collision. */
|
||||
if (controller->spi_event)
|
||||
{
|
||||
cpu->ios[M6811_SPSR] |= M6811_WCOL;
|
||||
m68hc11_cpu->ios[M6811_SPSR] |= M6811_WCOL;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -513,10 +522,10 @@ m68hc11spi_io_write_buffer (struct hw *me,
|
||||
|
||||
/* Toggle clock pin internal value when CPHA is 0 so that
|
||||
it will really change in the middle of a bit. */
|
||||
if (!(cpu->ios[M6811_SPCR] & M6811_CPHA))
|
||||
if (!(m68hc11_cpu->ios[M6811_SPCR] & M6811_CPHA))
|
||||
controller->clk_pin = ~controller->clk_pin;
|
||||
|
||||
cpu->ios[M6811_SPDR] = val;
|
||||
m68hc11_cpu->ios[M6811_SPDR] = val;
|
||||
|
||||
/* Activate transmission. */
|
||||
m68hc11spi_clock (me, NULL);
|
||||
|
||||
@@ -158,12 +158,14 @@ m68hc11tim_port_event (struct hw *me,
|
||||
SIM_DESC sd;
|
||||
struct m68hc11tim *controller;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
uint8_t val;
|
||||
uint16_t tcnt;
|
||||
|
||||
controller = hw_data (me);
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
switch (my_port)
|
||||
{
|
||||
case RESET_PORT:
|
||||
@@ -198,7 +200,7 @@ m68hc11tim_port_event (struct hw *me,
|
||||
the timer events (overflow and RTI clock). The pending
|
||||
flags (TFLG2) must be cleared explicitly here. */
|
||||
val = 0;
|
||||
cpu->ios[M6811_TFLG2] = 0;
|
||||
m68hc11_cpu->ios[M6811_TFLG2] = 0;
|
||||
m68hc11tim_io_write_buffer (me, &val, io_map,
|
||||
(unsigned_word) M6811_TMSK2, 1);
|
||||
m68hc11tim_io_write_buffer (me, &val, io_map,
|
||||
@@ -207,15 +209,15 @@ m68hc11tim_port_event (struct hw *me,
|
||||
}
|
||||
|
||||
case CAPTURE:
|
||||
tcnt = (uint16_t) ((cpu->cpu_absolute_cycle - controller->tcnt_adjust)
|
||||
tcnt = (uint16_t) ((m68hc11_cpu->cpu_absolute_cycle - controller->tcnt_adjust)
|
||||
/ controller->clock_prescaler);
|
||||
switch (level)
|
||||
{
|
||||
case M6811_TIC1:
|
||||
case M6811_TIC2:
|
||||
case M6811_TIC3:
|
||||
cpu->ios[level] = tcnt >> 8;
|
||||
cpu->ios[level + 1] = tcnt;
|
||||
m68hc11_cpu->ios[level] = tcnt >> 8;
|
||||
m68hc11_cpu->ios[level + 1] = tcnt;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -244,6 +246,7 @@ m68hc11tim_timer_event (struct hw *me, void *data)
|
||||
SIM_DESC sd;
|
||||
struct m68hc11tim *controller;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
enum event_type type;
|
||||
unsigned long delay;
|
||||
struct hw_event **eventp;
|
||||
@@ -260,6 +263,7 @@ m68hc11tim_timer_event (struct hw *me, void *data)
|
||||
controller = hw_data (me);
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
type = (enum event_type) ((uintptr_t) data) & 0x0FF;
|
||||
events = STATE_EVENTS (sd);
|
||||
|
||||
@@ -271,7 +275,7 @@ m68hc11tim_timer_event (struct hw *me, void *data)
|
||||
delay = controller->cop_delay;
|
||||
delay = controller->cop_prev_interrupt + controller->cop_delay;
|
||||
controller->cop_prev_interrupt = delay;
|
||||
delay = delay - cpu->cpu_absolute_cycle;
|
||||
delay = delay - m68hc11_cpu->cpu_absolute_cycle;
|
||||
check_interrupt = 1;
|
||||
delay += events->nr_ticks_to_process;
|
||||
break;
|
||||
@@ -282,18 +286,18 @@ m68hc11tim_timer_event (struct hw *me, void *data)
|
||||
|
||||
if (((uintptr_t) data & 0x0100) == 0)
|
||||
{
|
||||
cpu->ios[M6811_TFLG2] |= M6811_RTIF;
|
||||
m68hc11_cpu->ios[M6811_TFLG2] |= M6811_RTIF;
|
||||
check_interrupt = 1;
|
||||
controller->rti_prev_interrupt = delay;
|
||||
delay += controller->rti_delay;
|
||||
}
|
||||
delay = delay - cpu->cpu_absolute_cycle;
|
||||
delay = delay - m68hc11_cpu->cpu_absolute_cycle;
|
||||
delay += events->nr_ticks_to_process;
|
||||
break;
|
||||
|
||||
case OVERFLOW_EVENT:
|
||||
/* Compute the 68HC11 internal free running counter. */
|
||||
tcnt_internal = (cpu->cpu_absolute_cycle - controller->tcnt_adjust);
|
||||
tcnt_internal = (m68hc11_cpu->cpu_absolute_cycle - controller->tcnt_adjust);
|
||||
|
||||
/* We must take into account the prescaler that comes
|
||||
before the counter (it's a power of 2). */
|
||||
@@ -310,7 +314,7 @@ m68hc11tim_timer_event (struct hw *me, void *data)
|
||||
eventp = &controller->tof_timer_event;
|
||||
if (((uintptr_t) data & 0x100) == 0)
|
||||
{
|
||||
cpu->ios[M6811_TFLG2] |= M6811_TOF;
|
||||
m68hc11_cpu->ios[M6811_TFLG2] |= M6811_TOF;
|
||||
check_interrupt = 1;
|
||||
}
|
||||
break;
|
||||
@@ -318,8 +322,8 @@ m68hc11tim_timer_event (struct hw *me, void *data)
|
||||
case COMPARE_EVENT:
|
||||
/* Compute value of TCNT register (64-bit precision) at beginning
|
||||
and end of instruction. */
|
||||
tcnt_insn_end = (cpu->cpu_absolute_cycle - controller->tcnt_adjust);
|
||||
tcnt_insn_start = (tcnt_insn_end - cpu->cpu_current_cycle);
|
||||
tcnt_insn_end = (m68hc11_cpu->cpu_absolute_cycle - controller->tcnt_adjust);
|
||||
tcnt_insn_start = (tcnt_insn_end - m68hc11_cpu->cpu_current_cycle);
|
||||
|
||||
/* TCNT value at beginning of current instruction. */
|
||||
tcnt_prev = (tcnt_insn_start / controller->clock_prescaler) & 0x0ffff;
|
||||
@@ -332,7 +336,7 @@ m68hc11tim_timer_event (struct hw *me, void *data)
|
||||
tcnt_internal = tcnt_insn_end;
|
||||
tcnt_internal &= 0x0ffff * controller->clock_prescaler;
|
||||
|
||||
flags = cpu->ios[M6811_TMSK1];
|
||||
flags = m68hc11_cpu->ios[M6811_TMSK1];
|
||||
mask = 0x80;
|
||||
delay = 65536 * controller->clock_prescaler;
|
||||
|
||||
@@ -343,7 +347,7 @@ m68hc11tim_timer_event (struct hw *me, void *data)
|
||||
{
|
||||
unsigned long compare;
|
||||
|
||||
compare = (cpu->ios[i] << 8) + cpu->ios[i + 1];
|
||||
compare = (m68hc11_cpu->ios[i] << 8) + m68hc11_cpu->ios[i + 1];
|
||||
|
||||
/* See if compare is reached; handle wrap arround. */
|
||||
if ((compare >= tcnt_prev && compare <= tcnt && tcnt_prev < tcnt)
|
||||
@@ -357,13 +361,13 @@ m68hc11tim_timer_event (struct hw *me, void *data)
|
||||
else
|
||||
dt = tcnt - compare;
|
||||
|
||||
cpu->ios[M6811_TFLG1] |= mask;
|
||||
m68hc11_cpu->ios[M6811_TFLG1] |= mask;
|
||||
|
||||
/* Raise interrupt now at the correct CPU cycle so that
|
||||
we can find the interrupt latency. */
|
||||
cpu->cpu_absolute_cycle -= dt;
|
||||
interrupts_update_pending (&cpu->cpu_interrupts);
|
||||
cpu->cpu_absolute_cycle += dt;
|
||||
m68hc11_cpu->cpu_absolute_cycle -= dt;
|
||||
interrupts_update_pending (&m68hc11_cpu->cpu_interrupts);
|
||||
m68hc11_cpu->cpu_absolute_cycle += dt;
|
||||
}
|
||||
|
||||
/* Compute how many times for the next match.
|
||||
@@ -408,7 +412,7 @@ m68hc11tim_timer_event (struct hw *me, void *data)
|
||||
}
|
||||
|
||||
if (check_interrupt)
|
||||
interrupts_update_pending (&cpu->cpu_interrupts);
|
||||
interrupts_update_pending (&m68hc11_cpu->cpu_interrupts);
|
||||
}
|
||||
|
||||
|
||||
@@ -473,7 +477,7 @@ io_reg_desc pactl_desc[] = {
|
||||
static double
|
||||
to_realtime (sim_cpu *cpu, int64_t t)
|
||||
{
|
||||
return (double) (t) / (double) (cpu->cpu_frequency / 4);
|
||||
return (double) (t) / (double) (M68HC11_SIM_CPU (cpu)->cpu_frequency / 4);
|
||||
}
|
||||
|
||||
const char*
|
||||
@@ -537,12 +541,14 @@ m68hc11tim_info (struct hw *me)
|
||||
SIM_DESC sd;
|
||||
uint16_t base = 0;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
struct m68hc11tim *controller;
|
||||
uint8_t val;
|
||||
uint16_t val16;
|
||||
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
controller = hw_data (me);
|
||||
|
||||
sim_io_printf (sd, "M68HC11 Timer:\n");
|
||||
@@ -550,68 +556,68 @@ m68hc11tim_info (struct hw *me)
|
||||
base = cpu_get_io_base (cpu);
|
||||
|
||||
/* Info for TIC1 */
|
||||
val16 = (cpu->ios[M6811_TIC1_H] << 8) + cpu->ios[M6811_TIC1_L];
|
||||
val16 = (m68hc11_cpu->ios[M6811_TIC1_H] << 8) + m68hc11_cpu->ios[M6811_TIC1_L];
|
||||
print_io_word (sd, "TIC1 ", 0, val16, base + M6811_TIC1);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
/* Info for TIC2 */
|
||||
val16 = (cpu->ios[M6811_TIC2_H] << 8) + cpu->ios[M6811_TIC2_L];
|
||||
val16 = (m68hc11_cpu->ios[M6811_TIC2_H] << 8) + m68hc11_cpu->ios[M6811_TIC2_L];
|
||||
print_io_word (sd, "TIC2 ", 0, val16, base + M6811_TIC2);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
/* Info for TIC3 */
|
||||
val16 = (cpu->ios[M6811_TIC3_H] << 8) + cpu->ios[M6811_TIC3_L];
|
||||
val16 = (m68hc11_cpu->ios[M6811_TIC3_H] << 8) + m68hc11_cpu->ios[M6811_TIC3_L];
|
||||
print_io_word (sd, "TIC3 ", 0, val16, base + M6811_TIC3);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
/* Info for TOC1 */
|
||||
val16 = (cpu->ios[M6811_TOC1_H] << 8) + cpu->ios[M6811_TOC1_L];
|
||||
val16 = (m68hc11_cpu->ios[M6811_TOC1_H] << 8) + m68hc11_cpu->ios[M6811_TOC1_L];
|
||||
print_io_word (sd, "TOC1 ", 0, val16, base + M6811_TOC1);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
/* Info for TOC2 */
|
||||
val16 = (cpu->ios[M6811_TOC2_H] << 8) + cpu->ios[M6811_TOC2_L];
|
||||
val16 = (m68hc11_cpu->ios[M6811_TOC2_H] << 8) + m68hc11_cpu->ios[M6811_TOC2_L];
|
||||
print_io_word (sd, "TOC2 ", 0, val16, base + M6811_TOC2);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
/* Info for TOC3 */
|
||||
val16 = (cpu->ios[M6811_TOC3_H] << 8) + cpu->ios[M6811_TOC3_L];
|
||||
val16 = (m68hc11_cpu->ios[M6811_TOC3_H] << 8) + m68hc11_cpu->ios[M6811_TOC3_L];
|
||||
print_io_word (sd, "TOC3 ", 0, val16, base + M6811_TOC3);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
/* Info for TOC4 */
|
||||
val16 = (cpu->ios[M6811_TOC4_H] << 8) + cpu->ios[M6811_TOC4_L];
|
||||
val16 = (m68hc11_cpu->ios[M6811_TOC4_H] << 8) + m68hc11_cpu->ios[M6811_TOC4_L];
|
||||
print_io_word (sd, "TOC4 ", 0, val16, base + M6811_TOC4);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
/* Info for TOC5 */
|
||||
val16 = (cpu->ios[M6811_TOC5_H] << 8) + cpu->ios[M6811_TOC5_L];
|
||||
val16 = (m68hc11_cpu->ios[M6811_TOC5_H] << 8) + m68hc11_cpu->ios[M6811_TOC5_L];
|
||||
print_io_word (sd, "TOC5 ", 0, val16, base + M6811_TOC5);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
/* Info for TMSK1 */
|
||||
val = cpu->ios[M6811_TMSK1];
|
||||
val = m68hc11_cpu->ios[M6811_TMSK1];
|
||||
print_io_byte (sd, "TMSK1 ", tmsk1_desc, val, base + M6811_TMSK1);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
/* Info for TFLG1 */
|
||||
val = cpu->ios[M6811_TFLG1];
|
||||
val = m68hc11_cpu->ios[M6811_TFLG1];
|
||||
print_io_byte (sd, "TFLG1", tflg1_desc, val, base + M6811_TFLG1);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
val = cpu->ios[M6811_TMSK2];
|
||||
val = m68hc11_cpu->ios[M6811_TMSK2];
|
||||
print_io_byte (sd, "TMSK2 ", tmsk2_desc, val, base + M6811_TMSK2);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
val = cpu->ios[M6811_TFLG2];
|
||||
val = m68hc11_cpu->ios[M6811_TFLG2];
|
||||
print_io_byte (sd, "TFLG2", tflg2_desc, val, base + M6811_TFLG2);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
val = cpu->ios[M6811_PACTL];
|
||||
val = m68hc11_cpu->ios[M6811_PACTL];
|
||||
print_io_byte (sd, "PACTL", pactl_desc, val, base + M6811_PACTL);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
val = cpu->ios[M6811_PACNT];
|
||||
val = m68hc11_cpu->ios[M6811_PACNT];
|
||||
print_io_byte (sd, "PACNT", 0, val, base + M6811_PACNT);
|
||||
sim_io_printf (sd, "\n");
|
||||
|
||||
@@ -643,6 +649,7 @@ m68hc11tim_io_read_buffer (struct hw *me,
|
||||
SIM_DESC sd;
|
||||
struct m68hc11tim *controller;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
uint8_t val;
|
||||
unsigned cnt = 0;
|
||||
|
||||
@@ -650,6 +657,7 @@ m68hc11tim_io_read_buffer (struct hw *me,
|
||||
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
controller = hw_data (me);
|
||||
|
||||
while (nr_bytes)
|
||||
@@ -660,17 +668,17 @@ m68hc11tim_io_read_buffer (struct hw *me,
|
||||
Reading in a 16-bit register will be split in two accesses
|
||||
but this will be atomic within the simulator. */
|
||||
case M6811_TCTN_H:
|
||||
val = (uint8_t) ((cpu->cpu_absolute_cycle - controller->tcnt_adjust)
|
||||
/ (controller->clock_prescaler * 256));
|
||||
val = (uint8_t) ((m68hc11_cpu->cpu_absolute_cycle - controller->tcnt_adjust)
|
||||
/ (controller->clock_prescaler * 256));
|
||||
break;
|
||||
|
||||
case M6811_TCTN_L:
|
||||
val = (uint8_t) ((cpu->cpu_absolute_cycle - controller->tcnt_adjust)
|
||||
/ controller->clock_prescaler);
|
||||
val = (uint8_t) ((m68hc11_cpu->cpu_absolute_cycle - controller->tcnt_adjust)
|
||||
/ controller->clock_prescaler);
|
||||
break;
|
||||
|
||||
default:
|
||||
val = cpu->ios[base];
|
||||
val = m68hc11_cpu->ios[base];
|
||||
break;
|
||||
}
|
||||
*((uint8_t*) dest) = val;
|
||||
@@ -692,6 +700,7 @@ m68hc11tim_io_write_buffer (struct hw *me,
|
||||
SIM_DESC sd;
|
||||
struct m68hc11tim *controller;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
uint8_t val, n;
|
||||
int64_t adj;
|
||||
int reset_compare = 0;
|
||||
@@ -702,6 +711,7 @@ m68hc11tim_io_write_buffer (struct hw *me,
|
||||
|
||||
sd = hw_system (me);
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
controller = hw_data (me);
|
||||
|
||||
while (nr_bytes)
|
||||
@@ -714,9 +724,9 @@ m68hc11tim_io_write_buffer (struct hw *me,
|
||||
to obtain the timer current value. Computation must be made
|
||||
in 64-bit to avoid overflow problems. */
|
||||
case M6811_TCTN_L:
|
||||
adj = ((cpu->cpu_absolute_cycle - controller->tcnt_adjust)
|
||||
adj = ((m68hc11_cpu->cpu_absolute_cycle - controller->tcnt_adjust)
|
||||
/ (controller->clock_prescaler * (int64_t) 256)) & 0x0FF;
|
||||
adj = cpu->cpu_absolute_cycle
|
||||
adj = m68hc11_cpu->cpu_absolute_cycle
|
||||
- (adj * controller->clock_prescaler * (int64_t) 256)
|
||||
- ((int64_t) adj * controller->clock_prescaler);
|
||||
controller->tcnt_adjust = adj;
|
||||
@@ -725,9 +735,9 @@ m68hc11tim_io_write_buffer (struct hw *me,
|
||||
break;
|
||||
|
||||
case M6811_TCTN_H:
|
||||
adj = ((cpu->cpu_absolute_cycle - controller->tcnt_adjust)
|
||||
adj = ((m68hc11_cpu->cpu_absolute_cycle - controller->tcnt_adjust)
|
||||
/ controller->clock_prescaler) & 0x0ff;
|
||||
adj = cpu->cpu_absolute_cycle
|
||||
adj = m68hc11_cpu->cpu_absolute_cycle
|
||||
- ((int64_t) val * controller->clock_prescaler * (int64_t) 256)
|
||||
- (adj * controller->clock_prescaler);
|
||||
controller->tcnt_adjust = adj;
|
||||
@@ -738,10 +748,10 @@ m68hc11tim_io_write_buffer (struct hw *me,
|
||||
case M6811_TMSK2:
|
||||
|
||||
/* Timer prescaler cannot be changed after 64 bus cycles. */
|
||||
if (cpu->cpu_absolute_cycle >= 64)
|
||||
if (m68hc11_cpu->cpu_absolute_cycle >= 64)
|
||||
{
|
||||
val &= ~(M6811_PR1 | M6811_PR0);
|
||||
val |= cpu->ios[M6811_TMSK2] & (M6811_PR1 | M6811_PR0);
|
||||
val |= m68hc11_cpu->ios[M6811_TMSK2] & (M6811_PR1 | M6811_PR0);
|
||||
}
|
||||
switch (val & (M6811_PR1 | M6811_PR0))
|
||||
{
|
||||
@@ -759,39 +769,39 @@ m68hc11tim_io_write_buffer (struct hw *me,
|
||||
n = 16;
|
||||
break;
|
||||
}
|
||||
if (cpu->cpu_absolute_cycle < 64)
|
||||
if (m68hc11_cpu->cpu_absolute_cycle < 64)
|
||||
{
|
||||
reset_overflow = 1;
|
||||
controller->clock_prescaler = n;
|
||||
}
|
||||
cpu->ios[base] = val;
|
||||
interrupts_update_pending (&cpu->cpu_interrupts);
|
||||
m68hc11_cpu->ios[base] = val;
|
||||
interrupts_update_pending (&m68hc11_cpu->cpu_interrupts);
|
||||
break;
|
||||
|
||||
case M6811_PACTL:
|
||||
n = (1 << ((val & (M6811_RTR1 | M6811_RTR0))));
|
||||
cpu->ios[base] = val;
|
||||
m68hc11_cpu->ios[base] = val;
|
||||
|
||||
controller->rti_delay = (long) (n) * 8192;
|
||||
m68hc11tim_timer_event (me, (void*) (RTI_EVENT| 0x100));
|
||||
break;
|
||||
|
||||
case M6811_TFLG2:
|
||||
val &= cpu->ios[M6811_TFLG2];
|
||||
cpu->ios[M6811_TFLG2] &= ~val;
|
||||
interrupts_update_pending (&cpu->cpu_interrupts);
|
||||
val &= m68hc11_cpu->ios[M6811_TFLG2];
|
||||
m68hc11_cpu->ios[M6811_TFLG2] &= ~val;
|
||||
interrupts_update_pending (&m68hc11_cpu->cpu_interrupts);
|
||||
break;
|
||||
|
||||
case M6811_TMSK1:
|
||||
cpu->ios[M6811_TMSK1] = val;
|
||||
interrupts_update_pending (&cpu->cpu_interrupts);
|
||||
m68hc11_cpu->ios[M6811_TMSK1] = val;
|
||||
interrupts_update_pending (&m68hc11_cpu->cpu_interrupts);
|
||||
reset_compare = 1;
|
||||
break;
|
||||
|
||||
case M6811_TFLG1:
|
||||
val &= cpu->ios[M6811_TFLG1];
|
||||
cpu->ios[M6811_TFLG1] &= ~val;
|
||||
interrupts_update_pending (&cpu->cpu_interrupts);
|
||||
val &= m68hc11_cpu->ios[M6811_TFLG1];
|
||||
m68hc11_cpu->ios[M6811_TFLG1] &= ~val;
|
||||
interrupts_update_pending (&m68hc11_cpu->cpu_interrupts);
|
||||
break;
|
||||
|
||||
case M6811_TOC1:
|
||||
@@ -799,17 +809,17 @@ m68hc11tim_io_write_buffer (struct hw *me,
|
||||
case M6811_TOC3:
|
||||
case M6811_TOC4:
|
||||
case M6811_TOC5:
|
||||
cpu->ios[base] = val;
|
||||
m68hc11_cpu->ios[base] = val;
|
||||
reset_compare = 1;
|
||||
break;
|
||||
|
||||
case M6811_TCTL1:
|
||||
case M6811_TCTL2:
|
||||
cpu->ios[base] = val;
|
||||
m68hc11_cpu->ios[base] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
cpu->ios[base] = val;
|
||||
m68hc11_cpu->ios[base] = val;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ emul_write (sim_cpu *cpu)
|
||||
if (addr + size > 0x0FFFF) {
|
||||
size = 0x0FFFF - addr;
|
||||
}
|
||||
cpu->cpu_running = 0;
|
||||
M68HC11_SIM_CPU (cpu)->cpu_running = 0;
|
||||
while (size)
|
||||
{
|
||||
uint8_t val = memory_read8 (cpu, addr);
|
||||
@@ -132,7 +132,7 @@ emul_exit (sim_cpu *cpu)
|
||||
void
|
||||
emul_os (int code, sim_cpu *cpu)
|
||||
{
|
||||
cpu->cpu_current_cycle = 8;
|
||||
M68HC11_SIM_CPU (cpu)->cpu_current_cycle = 8;
|
||||
switch (code)
|
||||
{
|
||||
case 0x0:
|
||||
|
||||
@@ -114,7 +114,7 @@ sim_get_info (SIM_DESC sd, char *cmd)
|
||||
}
|
||||
|
||||
cpu_info (sd, cpu);
|
||||
interrupts_info (sd, &cpu->cpu_interrupts);
|
||||
interrupts_info (sd, &M68HC11_SIM_CPU (cpu)->cpu_interrupts);
|
||||
}
|
||||
|
||||
|
||||
@@ -123,21 +123,23 @@ sim_board_reset (SIM_DESC sd)
|
||||
{
|
||||
struct hw *hw_cpu;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
const struct bfd_arch_info *arch;
|
||||
const char *cpu_type;
|
||||
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
arch = STATE_ARCHITECTURE (sd);
|
||||
|
||||
/* hw_cpu = sim_hw_parse (sd, "/"); */
|
||||
if (arch->arch == bfd_arch_m68hc11)
|
||||
{
|
||||
cpu->cpu_type = CPU_M6811;
|
||||
m68hc11_cpu->cpu_type = CPU_M6811;
|
||||
cpu_type = "/m68hc11";
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu->cpu_type = CPU_M6812;
|
||||
m68hc11_cpu->cpu_type = CPU_M6812;
|
||||
cpu_type = "/m68hc12";
|
||||
}
|
||||
|
||||
@@ -159,17 +161,19 @@ sim_hw_configure (SIM_DESC sd)
|
||||
const struct bfd_arch_info *arch;
|
||||
struct hw *device_tree;
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
|
||||
arch = STATE_ARCHITECTURE (sd);
|
||||
if (arch == 0)
|
||||
return 0;
|
||||
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
cpu->cpu_configured_arch = arch;
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
m68hc11_cpu->cpu_configured_arch = arch;
|
||||
device_tree = sim_hw_parse (sd, "/");
|
||||
if (arch->arch == bfd_arch_m68hc11)
|
||||
{
|
||||
cpu->cpu_interpretor = cpu_interp_m6811;
|
||||
m68hc11_cpu->cpu_interpretor = cpu_interp_m6811;
|
||||
if (hw_tree_find_property (device_tree, "/m68hc11/reg") == 0)
|
||||
{
|
||||
/* Allocate core managed memory */
|
||||
@@ -181,16 +185,16 @@ sim_hw_configure (SIM_DESC sd)
|
||||
sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
|
||||
M6811_RAM_LEVEL);
|
||||
sim_hw_parse (sd, "/m68hc11/reg 0x1000 0x03F");
|
||||
if (cpu->bank_start < cpu->bank_end)
|
||||
if (m68hc11_cpu->bank_start < m68hc11_cpu->bank_end)
|
||||
{
|
||||
sim_do_commandf (sd, "memory region 0x%x@%d,0x100000",
|
||||
cpu->bank_virtual, M6811_RAM_LEVEL);
|
||||
m68hc11_cpu->bank_virtual, M6811_RAM_LEVEL);
|
||||
sim_hw_parse (sd, "/m68hc11/use_bank 1");
|
||||
}
|
||||
}
|
||||
if (cpu->cpu_start_mode)
|
||||
if (m68hc11_cpu->cpu_start_mode)
|
||||
{
|
||||
sim_hw_parse (sd, "/m68hc11/mode %s", cpu->cpu_start_mode);
|
||||
sim_hw_parse (sd, "/m68hc11/mode %s", m68hc11_cpu->cpu_start_mode);
|
||||
}
|
||||
if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11sio/reg") == 0)
|
||||
{
|
||||
@@ -229,11 +233,11 @@ sim_hw_configure (SIM_DESC sd)
|
||||
sim_hw_parse (sd, "/m68hc11 > port-b cpu-write-port /m68hc11");
|
||||
sim_hw_parse (sd, "/m68hc11 > port-c cpu-write-port /m68hc11");
|
||||
sim_hw_parse (sd, "/m68hc11 > port-d cpu-write-port /m68hc11");
|
||||
cpu->hw_cpu = sim_hw_parse (sd, "/m68hc11");
|
||||
m68hc11_cpu->hw_cpu = sim_hw_parse (sd, "/m68hc11");
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu->cpu_interpretor = cpu_interp_m6812;
|
||||
m68hc11_cpu->cpu_interpretor = cpu_interp_m6812;
|
||||
if (hw_tree_find_property (device_tree, "/m68hc12/reg") == 0)
|
||||
{
|
||||
/* Allocate core external memory. */
|
||||
@@ -241,10 +245,10 @@ sim_hw_configure (SIM_DESC sd)
|
||||
0x8000, M6811_RAM_LEVEL, 0x8000);
|
||||
sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
|
||||
M6811_RAM_LEVEL);
|
||||
if (cpu->bank_start < cpu->bank_end)
|
||||
if (m68hc11_cpu->bank_start < m68hc11_cpu->bank_end)
|
||||
{
|
||||
sim_do_commandf (sd, "memory region 0x%x@%d,0x100000",
|
||||
cpu->bank_virtual, M6811_RAM_LEVEL);
|
||||
m68hc11_cpu->bank_virtual, M6811_RAM_LEVEL);
|
||||
sim_hw_parse (sd, "/m68hc12/use_bank 1");
|
||||
}
|
||||
sim_hw_parse (sd, "/m68hc12/reg 0x0 0x3FF");
|
||||
@@ -287,7 +291,7 @@ sim_hw_configure (SIM_DESC sd)
|
||||
sim_hw_parse (sd, "/m68hc12 > port-b cpu-write-port /m68hc12");
|
||||
sim_hw_parse (sd, "/m68hc12 > port-c cpu-write-port /m68hc12");
|
||||
sim_hw_parse (sd, "/m68hc12 > port-d cpu-write-port /m68hc12");
|
||||
cpu->hw_cpu = sim_hw_parse (sd, "/m68hc12");
|
||||
m68hc11_cpu->hw_cpu = sim_hw_parse (sd, "/m68hc12");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -298,14 +302,16 @@ static int
|
||||
sim_get_bank_parameters (SIM_DESC sd)
|
||||
{
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
unsigned size;
|
||||
bfd_vma addr;
|
||||
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
|
||||
addr = trace_sym_value (sd, BFD_M68HC11_BANK_START_NAME);
|
||||
if (addr != -1)
|
||||
cpu->bank_start = addr;
|
||||
m68hc11_cpu->bank_start = addr;
|
||||
|
||||
size = trace_sym_value (sd, BFD_M68HC11_BANK_SIZE_NAME);
|
||||
if (size == -1)
|
||||
@@ -313,12 +319,12 @@ sim_get_bank_parameters (SIM_DESC sd)
|
||||
|
||||
addr = trace_sym_value (sd, BFD_M68HC11_BANK_VIRTUAL_NAME);
|
||||
if (addr != -1)
|
||||
cpu->bank_virtual = addr;
|
||||
m68hc11_cpu->bank_virtual = addr;
|
||||
|
||||
cpu->bank_end = cpu->bank_start + size;
|
||||
cpu->bank_shift = 0;
|
||||
m68hc11_cpu->bank_end = m68hc11_cpu->bank_start + size;
|
||||
m68hc11_cpu->bank_shift = 0;
|
||||
for (; size > 1; size >>= 1)
|
||||
cpu->bank_shift++;
|
||||
m68hc11_cpu->bank_shift++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -327,9 +333,11 @@ static int
|
||||
sim_prepare_for_program (SIM_DESC sd, bfd* abfd)
|
||||
{
|
||||
sim_cpu *cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu;
|
||||
int elf_flags = 0;
|
||||
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
|
||||
if (abfd != NULL)
|
||||
{
|
||||
@@ -338,10 +346,10 @@ sim_prepare_for_program (SIM_DESC sd, bfd* abfd)
|
||||
if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
|
||||
elf_flags = elf_elfheader (abfd)->e_flags;
|
||||
|
||||
cpu->cpu_elf_start = bfd_get_start_address (abfd);
|
||||
m68hc11_cpu->cpu_elf_start = bfd_get_start_address (abfd);
|
||||
/* See if any section sets the reset address */
|
||||
cpu->cpu_use_elf_start = 1;
|
||||
for (s = abfd->sections; s && cpu->cpu_use_elf_start; s = s->next)
|
||||
m68hc11_cpu->cpu_use_elf_start = 1;
|
||||
for (s = abfd->sections; s && m68hc11_cpu->cpu_use_elf_start; s = s->next)
|
||||
{
|
||||
if (s->flags & SEC_LOAD)
|
||||
{
|
||||
@@ -358,7 +366,7 @@ sim_prepare_for_program (SIM_DESC sd, bfd* abfd)
|
||||
lma = bfd_section_vma (s);
|
||||
|
||||
if (lma <= 0xFFFE && lma+size >= 0x10000)
|
||||
cpu->cpu_use_elf_start = 0;
|
||||
m68hc11_cpu->cpu_use_elf_start = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -410,7 +418,8 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback,
|
||||
current_target_byte_order = BFD_ENDIAN_BIG;
|
||||
|
||||
/* The cpu data is kept in a separately allocated chunk of memory. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct m68hc11_sim_cpu))
|
||||
!= SIM_RC_OK)
|
||||
{
|
||||
free_state (sd);
|
||||
return 0;
|
||||
@@ -494,7 +503,7 @@ sim_engine_run (SIM_DESC sd,
|
||||
cpu_single_step (cpu);
|
||||
|
||||
/* process any events */
|
||||
if (sim_events_tickn (sd, cpu->cpu_current_cycle))
|
||||
if (sim_events_tickn (sd, M68HC11_SIM_CPU (cpu)->cpu_current_cycle))
|
||||
{
|
||||
sim_events_process (sd);
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ static const OPTION interrupt_options[] =
|
||||
void
|
||||
interrupts_initialize (SIM_DESC sd, sim_cpu *cpu)
|
||||
{
|
||||
struct interrupts *interrupts = &cpu->cpu_interrupts;
|
||||
struct interrupts *interrupts = &M68HC11_SIM_CPU (cpu)->cpu_interrupts;
|
||||
|
||||
interrupts->cpu = cpu;
|
||||
|
||||
@@ -139,10 +139,12 @@ interrupts_initialize (SIM_DESC sd, sim_cpu *cpu)
|
||||
void
|
||||
interrupts_reset (struct interrupts *interrupts)
|
||||
{
|
||||
sim_cpu *cpu = interrupts->cpu;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
int i;
|
||||
|
||||
interrupts->pending_mask = 0;
|
||||
if (interrupts->cpu->cpu_mode & M6811_SMOD)
|
||||
if (m68hc11_cpu->cpu_mode & M6811_SMOD)
|
||||
interrupts->vectors_addr = 0xbfc0;
|
||||
else
|
||||
interrupts->vectors_addr = 0xffc0;
|
||||
@@ -171,13 +173,13 @@ interrupts_reset (struct interrupts *interrupts)
|
||||
|
||||
/* In bootstrap mode, initialize the vector table to point
|
||||
to the RAM location. */
|
||||
if (interrupts->cpu->cpu_mode == M6811_SMOD)
|
||||
if (m68hc11_cpu->cpu_mode == M6811_SMOD)
|
||||
{
|
||||
bfd_vma addr = interrupts->vectors_addr;
|
||||
uint16_t vector = 0x0100 - 3 * (M6811_INT_NUMBER - 1);
|
||||
for (i = 0; i < M6811_INT_NUMBER; i++)
|
||||
{
|
||||
memory_write16 (interrupts->cpu, addr, vector);
|
||||
memory_write16 (cpu, addr, vector);
|
||||
addr += 2;
|
||||
vector += 3;
|
||||
}
|
||||
@@ -209,7 +211,7 @@ interrupt_option_handler (SIM_DESC sd, sim_cpu *cpu,
|
||||
if (cpu == 0)
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
|
||||
interrupts = &cpu->cpu_interrupts;
|
||||
interrupts = &M68HC11_SIM_CPU (cpu)->cpu_interrupts;
|
||||
switch (opt)
|
||||
{
|
||||
case OPTION_INTERRUPT_INFO:
|
||||
@@ -291,7 +293,7 @@ interrupts_update_pending (struct interrupts *interrupts)
|
||||
|
||||
clear_mask = 0;
|
||||
set_mask = 0;
|
||||
ioregs = &interrupts->cpu->ios[0];
|
||||
ioregs = &M68HC11_SIM_CPU (interrupts->cpu)->ios[0];
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (idefs); i++)
|
||||
{
|
||||
|
||||
@@ -64,6 +64,7 @@ static SIM_RC
|
||||
cpu_option_handler (SIM_DESC sd, sim_cpu *cpu,
|
||||
int opt, char *arg, int is_command)
|
||||
{
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
int val;
|
||||
|
||||
cpu = STATE_CPU (sd, 0);
|
||||
@@ -74,22 +75,22 @@ cpu_option_handler (SIM_DESC sd, sim_cpu *cpu,
|
||||
break;
|
||||
|
||||
case OPTION_EMUL_OS:
|
||||
cpu->cpu_emul_syscall = 1;
|
||||
m68hc11_cpu->cpu_emul_syscall = 1;
|
||||
break;
|
||||
|
||||
case OPTION_CPU_CONFIG:
|
||||
if (sscanf(arg, "0x%x", &val) == 1
|
||||
|| sscanf(arg, "%d", &val) == 1)
|
||||
{
|
||||
cpu->cpu_config = val;
|
||||
cpu->cpu_use_local_config = 1;
|
||||
m68hc11_cpu->cpu_config = val;
|
||||
m68hc11_cpu->cpu_use_local_config = 1;
|
||||
}
|
||||
else
|
||||
cpu->cpu_use_local_config = 0;
|
||||
m68hc11_cpu->cpu_use_local_config = 0;
|
||||
break;
|
||||
|
||||
case OPTION_CPU_BOOTSTRAP:
|
||||
cpu->cpu_start_mode = "bootstrap";
|
||||
m68hc11_cpu->cpu_start_mode = "bootstrap";
|
||||
break;
|
||||
|
||||
case OPTION_CPU_MODE:
|
||||
@@ -116,7 +117,7 @@ cpu_return (sim_cpu *cpu)
|
||||
void
|
||||
cpu_set_sp (sim_cpu *cpu, uint16_t val)
|
||||
{
|
||||
cpu->cpu_regs.sp = val;
|
||||
M68HC11_SIM_CPU (cpu)->cpu_regs.sp = val;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
@@ -465,27 +466,28 @@ cpu_move16 (sim_cpu *cpu, uint8_t code)
|
||||
int
|
||||
cpu_initialize (SIM_DESC sd, sim_cpu *cpu)
|
||||
{
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
sim_add_option_table (sd, 0, cpu_options);
|
||||
|
||||
memset (&cpu->cpu_regs, 0, sizeof(cpu->cpu_regs));
|
||||
memset (&m68hc11_cpu->cpu_regs, 0, sizeof(m68hc11_cpu->cpu_regs));
|
||||
|
||||
cpu->cpu_absolute_cycle = 0;
|
||||
cpu->cpu_current_cycle = 0;
|
||||
cpu->cpu_emul_syscall = 1;
|
||||
cpu->cpu_running = 1;
|
||||
cpu->cpu_stop_on_interrupt = 0;
|
||||
cpu->cpu_frequency = 8 * 1000 * 1000;
|
||||
cpu->cpu_use_elf_start = 0;
|
||||
cpu->cpu_elf_start = 0;
|
||||
cpu->cpu_use_local_config = 0;
|
||||
cpu->bank_start = 0;
|
||||
cpu->bank_end = 0;
|
||||
cpu->bank_shift = 0;
|
||||
cpu->cpu_config = M6811_NOSEC | M6811_NOCOP | M6811_ROMON |
|
||||
m68hc11_cpu->cpu_absolute_cycle = 0;
|
||||
m68hc11_cpu->cpu_current_cycle = 0;
|
||||
m68hc11_cpu->cpu_emul_syscall = 1;
|
||||
m68hc11_cpu->cpu_running = 1;
|
||||
m68hc11_cpu->cpu_stop_on_interrupt = 0;
|
||||
m68hc11_cpu->cpu_frequency = 8 * 1000 * 1000;
|
||||
m68hc11_cpu->cpu_use_elf_start = 0;
|
||||
m68hc11_cpu->cpu_elf_start = 0;
|
||||
m68hc11_cpu->cpu_use_local_config = 0;
|
||||
m68hc11_cpu->bank_start = 0;
|
||||
m68hc11_cpu->bank_end = 0;
|
||||
m68hc11_cpu->bank_shift = 0;
|
||||
m68hc11_cpu->cpu_config = M6811_NOSEC | M6811_NOCOP | M6811_ROMON |
|
||||
M6811_EEON;
|
||||
interrupts_initialize (sd, cpu);
|
||||
|
||||
cpu->cpu_is_initialized = 1;
|
||||
m68hc11_cpu->cpu_is_initialized = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -494,35 +496,37 @@ cpu_initialize (SIM_DESC sd, sim_cpu *cpu)
|
||||
int
|
||||
cpu_reset (sim_cpu *cpu)
|
||||
{
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
|
||||
/* Initialize the config register.
|
||||
It is only initialized at reset time. */
|
||||
memset (cpu->ios, 0, sizeof (cpu->ios));
|
||||
if (cpu->cpu_configured_arch->arch == bfd_arch_m68hc11)
|
||||
cpu->ios[M6811_INIT] = 0x1;
|
||||
memset (m68hc11_cpu->ios, 0, sizeof (m68hc11_cpu->ios));
|
||||
if (m68hc11_cpu->cpu_configured_arch->arch == bfd_arch_m68hc11)
|
||||
m68hc11_cpu->ios[M6811_INIT] = 0x1;
|
||||
else
|
||||
cpu->ios[M6811_INIT] = 0;
|
||||
m68hc11_cpu->ios[M6811_INIT] = 0;
|
||||
|
||||
/* Output compare registers set to 0xFFFF. */
|
||||
cpu->ios[M6811_TOC1_H] = 0xFF;
|
||||
cpu->ios[M6811_TOC1_L] = 0xFF;
|
||||
cpu->ios[M6811_TOC2_H] = 0xFF;
|
||||
cpu->ios[M6811_TOC2_L] = 0xFF;
|
||||
cpu->ios[M6811_TOC3_H] = 0xFF;
|
||||
cpu->ios[M6811_TOC4_L] = 0xFF;
|
||||
cpu->ios[M6811_TOC5_H] = 0xFF;
|
||||
cpu->ios[M6811_TOC5_L] = 0xFF;
|
||||
m68hc11_cpu->ios[M6811_TOC1_H] = 0xFF;
|
||||
m68hc11_cpu->ios[M6811_TOC1_L] = 0xFF;
|
||||
m68hc11_cpu->ios[M6811_TOC2_H] = 0xFF;
|
||||
m68hc11_cpu->ios[M6811_TOC2_L] = 0xFF;
|
||||
m68hc11_cpu->ios[M6811_TOC3_H] = 0xFF;
|
||||
m68hc11_cpu->ios[M6811_TOC4_L] = 0xFF;
|
||||
m68hc11_cpu->ios[M6811_TOC5_H] = 0xFF;
|
||||
m68hc11_cpu->ios[M6811_TOC5_L] = 0xFF;
|
||||
|
||||
/* Setup the processor registers. */
|
||||
memset (&cpu->cpu_regs, 0, sizeof(cpu->cpu_regs));
|
||||
cpu->cpu_absolute_cycle = 0;
|
||||
cpu->cpu_current_cycle = 0;
|
||||
cpu->cpu_is_initialized = 0;
|
||||
memset (&m68hc11_cpu->cpu_regs, 0, sizeof(m68hc11_cpu->cpu_regs));
|
||||
m68hc11_cpu->cpu_absolute_cycle = 0;
|
||||
m68hc11_cpu->cpu_current_cycle = 0;
|
||||
m68hc11_cpu->cpu_is_initialized = 0;
|
||||
|
||||
/* Reset interrupts. */
|
||||
interrupts_reset (&cpu->cpu_interrupts);
|
||||
interrupts_reset (&m68hc11_cpu->cpu_interrupts);
|
||||
|
||||
/* Reinitialize the CPU operating mode. */
|
||||
cpu->ios[M6811_HPRIO] = cpu->cpu_mode;
|
||||
m68hc11_cpu->ios[M6811_HPRIO] = m68hc11_cpu->cpu_mode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -530,12 +534,13 @@ cpu_reset (sim_cpu *cpu)
|
||||
int
|
||||
cpu_restart (sim_cpu *cpu)
|
||||
{
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
uint16_t addr;
|
||||
|
||||
/* Get CPU starting address depending on the CPU mode. */
|
||||
if (cpu->cpu_use_elf_start == 0)
|
||||
if (m68hc11_cpu->cpu_use_elf_start == 0)
|
||||
{
|
||||
switch ((cpu->ios[M6811_HPRIO]) & (M6811_SMOD | M6811_MDA))
|
||||
switch ((m68hc11_cpu->ios[M6811_HPRIO]) & (M6811_SMOD | M6811_MDA))
|
||||
{
|
||||
/* Single Chip */
|
||||
default:
|
||||
@@ -561,16 +566,16 @@ cpu_restart (sim_cpu *cpu)
|
||||
}
|
||||
else
|
||||
{
|
||||
addr = cpu->cpu_elf_start;
|
||||
addr = m68hc11_cpu->cpu_elf_start;
|
||||
}
|
||||
|
||||
/* Setup the processor registers. */
|
||||
cpu->cpu_insn_pc = addr;
|
||||
cpu->cpu_regs.pc = addr;
|
||||
cpu->cpu_regs.ccr = M6811_X_BIT | M6811_I_BIT | M6811_S_BIT;
|
||||
cpu->cpu_absolute_cycle = 0;
|
||||
cpu->cpu_is_initialized = 1;
|
||||
cpu->cpu_current_cycle = 0;
|
||||
m68hc11_cpu->cpu_insn_pc = addr;
|
||||
m68hc11_cpu->cpu_regs.pc = addr;
|
||||
m68hc11_cpu->cpu_regs.ccr = M6811_X_BIT | M6811_I_BIT | M6811_S_BIT;
|
||||
m68hc11_cpu->cpu_absolute_cycle = 0;
|
||||
m68hc11_cpu->cpu_is_initialized = 1;
|
||||
m68hc11_cpu->cpu_current_cycle = 0;
|
||||
|
||||
cpu_call (cpu, addr);
|
||||
|
||||
@@ -625,7 +630,7 @@ cpu_fetch_relbranch (sim_cpu *cpu)
|
||||
{
|
||||
addr |= 0xFF00;
|
||||
}
|
||||
addr += cpu->cpu_regs.pc;
|
||||
addr += M68HC11_SIM_CPU (cpu)->cpu_regs.pc;
|
||||
return addr;
|
||||
}
|
||||
|
||||
@@ -634,7 +639,7 @@ cpu_fetch_relbranch16 (sim_cpu *cpu)
|
||||
{
|
||||
uint16_t addr = cpu_fetch16 (cpu);
|
||||
|
||||
addr += cpu->cpu_regs.pc;
|
||||
addr += M68HC11_SIM_CPU (cpu)->cpu_regs.pc;
|
||||
return addr;
|
||||
}
|
||||
|
||||
@@ -642,21 +647,23 @@ cpu_fetch_relbranch16 (sim_cpu *cpu)
|
||||
void
|
||||
cpu_push_all (sim_cpu *cpu)
|
||||
{
|
||||
if (cpu->cpu_configured_arch->arch == bfd_arch_m68hc11)
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
|
||||
if (m68hc11_cpu->cpu_configured_arch->arch == bfd_arch_m68hc11)
|
||||
{
|
||||
cpu_m68hc11_push_uint16 (cpu, cpu->cpu_regs.pc);
|
||||
cpu_m68hc11_push_uint16 (cpu, cpu->cpu_regs.iy);
|
||||
cpu_m68hc11_push_uint16 (cpu, cpu->cpu_regs.ix);
|
||||
cpu_m68hc11_push_uint16 (cpu, cpu->cpu_regs.d);
|
||||
cpu_m68hc11_push_uint8 (cpu, cpu->cpu_regs.ccr);
|
||||
cpu_m68hc11_push_uint16 (cpu, m68hc11_cpu->cpu_regs.pc);
|
||||
cpu_m68hc11_push_uint16 (cpu, m68hc11_cpu->cpu_regs.iy);
|
||||
cpu_m68hc11_push_uint16 (cpu, m68hc11_cpu->cpu_regs.ix);
|
||||
cpu_m68hc11_push_uint16 (cpu, m68hc11_cpu->cpu_regs.d);
|
||||
cpu_m68hc11_push_uint8 (cpu, m68hc11_cpu->cpu_regs.ccr);
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu_m68hc12_push_uint16 (cpu, cpu->cpu_regs.pc);
|
||||
cpu_m68hc12_push_uint16 (cpu, cpu->cpu_regs.iy);
|
||||
cpu_m68hc12_push_uint16 (cpu, cpu->cpu_regs.ix);
|
||||
cpu_m68hc12_push_uint16 (cpu, cpu->cpu_regs.d);
|
||||
cpu_m68hc12_push_uint8 (cpu, cpu->cpu_regs.ccr);
|
||||
cpu_m68hc12_push_uint16 (cpu, m68hc11_cpu->cpu_regs.pc);
|
||||
cpu_m68hc12_push_uint16 (cpu, m68hc11_cpu->cpu_regs.iy);
|
||||
cpu_m68hc12_push_uint16 (cpu, m68hc11_cpu->cpu_regs.ix);
|
||||
cpu_m68hc12_push_uint16 (cpu, m68hc11_cpu->cpu_regs.d);
|
||||
cpu_m68hc12_push_uint8 (cpu, m68hc11_cpu->cpu_regs.ccr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -737,6 +744,8 @@ cpu_exg (sim_cpu *cpu, uint8_t code)
|
||||
void
|
||||
cpu_special (sim_cpu *cpu, enum M6811_Special special)
|
||||
{
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
|
||||
switch (special)
|
||||
{
|
||||
case M6811_RTI:
|
||||
@@ -770,9 +779,9 @@ cpu_special (sim_cpu *cpu, enum M6811_Special special)
|
||||
case M6811_WAI:
|
||||
/* In the ELF-start mode, we are in a special mode where
|
||||
the WAI corresponds to an exit. */
|
||||
if (cpu->cpu_use_elf_start)
|
||||
if (m68hc11_cpu->cpu_use_elf_start)
|
||||
{
|
||||
cpu_set_pc (cpu, cpu->cpu_insn_pc);
|
||||
cpu_set_pc (cpu, m68hc11_cpu->cpu_insn_pc);
|
||||
sim_engine_halt (CPU_STATE (cpu), cpu,
|
||||
NULL, NULL_CIA, sim_exited,
|
||||
cpu_get_d (cpu));
|
||||
@@ -783,19 +792,19 @@ cpu_special (sim_cpu *cpu, enum M6811_Special special)
|
||||
break;
|
||||
|
||||
case M6811_SWI:
|
||||
interrupts_raise (&cpu->cpu_interrupts, M6811_INT_SWI);
|
||||
interrupts_process (&cpu->cpu_interrupts);
|
||||
interrupts_raise (&m68hc11_cpu->cpu_interrupts, M6811_INT_SWI);
|
||||
interrupts_process (&m68hc11_cpu->cpu_interrupts);
|
||||
break;
|
||||
|
||||
case M6811_EMUL_SYSCALL:
|
||||
case M6811_ILLEGAL:
|
||||
if (cpu->cpu_emul_syscall)
|
||||
if (m68hc11_cpu->cpu_emul_syscall)
|
||||
{
|
||||
uint8_t op = memory_read8 (cpu,
|
||||
cpu_get_pc (cpu) - 1);
|
||||
if (op == 0x41)
|
||||
{
|
||||
cpu_set_pc (cpu, cpu->cpu_insn_pc);
|
||||
cpu_set_pc (cpu, m68hc11_cpu->cpu_insn_pc);
|
||||
sim_engine_halt (CPU_STATE (cpu), cpu,
|
||||
NULL, NULL_CIA, sim_exited,
|
||||
cpu_get_d (cpu));
|
||||
@@ -808,8 +817,8 @@ cpu_special (sim_cpu *cpu, enum M6811_Special special)
|
||||
return;
|
||||
}
|
||||
|
||||
interrupts_raise (&cpu->cpu_interrupts, M6811_INT_ILLEGAL);
|
||||
interrupts_process (&cpu->cpu_interrupts);
|
||||
interrupts_raise (&m68hc11_cpu->cpu_interrupts, M6811_INT_ILLEGAL);
|
||||
interrupts_process (&m68hc11_cpu->cpu_interrupts);
|
||||
break;
|
||||
|
||||
case M6811_TEST:
|
||||
@@ -822,7 +831,7 @@ cpu_special (sim_cpu *cpu, enum M6811_Special special)
|
||||
/* Breakpoint instruction if we are under gdb. */
|
||||
if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
|
||||
{
|
||||
cpu->cpu_regs.pc --;
|
||||
m68hc11_cpu->cpu_regs.pc --;
|
||||
sim_engine_halt (CPU_STATE (cpu), cpu,
|
||||
0, cpu_get_pc (cpu), sim_stopped,
|
||||
SIM_SIGTRAP);
|
||||
@@ -1000,20 +1009,22 @@ cpu_special (sim_cpu *cpu, enum M6811_Special special)
|
||||
void
|
||||
cpu_single_step (sim_cpu *cpu)
|
||||
{
|
||||
cpu->cpu_current_cycle = 0;
|
||||
cpu->cpu_insn_pc = cpu_get_pc (cpu);
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
|
||||
m68hc11_cpu->cpu_current_cycle = 0;
|
||||
m68hc11_cpu->cpu_insn_pc = cpu_get_pc (cpu);
|
||||
|
||||
/* Handle the pending interrupts. If an interrupt is handled,
|
||||
treat this as an single step. */
|
||||
if (interrupts_process (&cpu->cpu_interrupts))
|
||||
if (interrupts_process (&m68hc11_cpu->cpu_interrupts))
|
||||
{
|
||||
cpu->cpu_absolute_cycle += cpu->cpu_current_cycle;
|
||||
m68hc11_cpu->cpu_absolute_cycle += m68hc11_cpu->cpu_current_cycle;
|
||||
return;
|
||||
}
|
||||
|
||||
/* printf("PC = 0x%04x\n", cpu_get_pc (cpu));*/
|
||||
cpu->cpu_interpretor (cpu);
|
||||
cpu->cpu_absolute_cycle += cpu->cpu_current_cycle;
|
||||
m68hc11_cpu->cpu_interpretor (cpu);
|
||||
m68hc11_cpu->cpu_absolute_cycle += m68hc11_cpu->cpu_current_cycle;
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
@@ -1037,40 +1048,44 @@ void
|
||||
cpu_memory_exception (sim_cpu *cpu, SIM_SIGNAL excep,
|
||||
uint16_t addr, const char *message)
|
||||
{
|
||||
if (cpu->cpu_running == 0)
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
|
||||
if (m68hc11_cpu->cpu_running == 0)
|
||||
return;
|
||||
|
||||
cpu_set_pc (cpu, cpu->cpu_insn_pc);
|
||||
cpu_set_pc (cpu, m68hc11_cpu->cpu_insn_pc);
|
||||
sim_engine_halt (CPU_STATE (cpu), cpu, NULL,
|
||||
cpu_get_pc (cpu), sim_stopped, excep);
|
||||
|
||||
#if 0
|
||||
cpu->mem_exception = excep;
|
||||
cpu->fault_addr = addr;
|
||||
cpu->fault_msg = strdup (message);
|
||||
m68hc11_cpu->mem_exception = excep;
|
||||
m68hc11_cpu->fault_addr = addr;
|
||||
m68hc11_cpu->fault_msg = strdup (message);
|
||||
|
||||
if (cpu->cpu_use_handler)
|
||||
if (m68hc11_cpu->cpu_use_handler)
|
||||
{
|
||||
longjmp (&cpu->cpu_exception_handler, 1);
|
||||
longjmp (&m68hc11_cpu->cpu_exception_handler, 1);
|
||||
}
|
||||
(* cpu->callback->printf_filtered)
|
||||
(cpu->callback, "Fault at 0x%04x: %s\n", addr, message);
|
||||
(* m68hc11_cpu->callback->printf_filtered)
|
||||
(m68hc11_cpu->callback, "Fault at 0x%04x: %s\n", addr, message);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
cpu_info (SIM_DESC sd, sim_cpu *cpu)
|
||||
{
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
|
||||
sim_io_printf (sd, "CPU info:\n");
|
||||
sim_io_printf (sd, " Absolute cycle: %s\n",
|
||||
cycle_to_string (cpu, cpu->cpu_absolute_cycle,
|
||||
cycle_to_string (cpu, m68hc11_cpu->cpu_absolute_cycle,
|
||||
PRINT_TIME | PRINT_CYCLE));
|
||||
|
||||
sim_io_printf (sd, " Syscall emulation: %s\n",
|
||||
cpu->cpu_emul_syscall ? "yes, via 0xcd <n>" : "no");
|
||||
m68hc11_cpu->cpu_emul_syscall ? "yes, via 0xcd <n>" : "no");
|
||||
sim_io_printf (sd, " Memory errors detection: %s\n",
|
||||
cpu->cpu_check_memory ? "yes" : "no");
|
||||
m68hc11_cpu->cpu_check_memory ? "yes" : "no");
|
||||
sim_io_printf (sd, " Stop on interrupt: %s\n",
|
||||
cpu->cpu_stop_on_interrupt ? "yes" : "no");
|
||||
m68hc11_cpu->cpu_stop_on_interrupt ? "yes" : "no");
|
||||
}
|
||||
|
||||
|
||||
@@ -32,8 +32,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include "sim-signal.h"
|
||||
#include "sim-types.h"
|
||||
|
||||
struct _sim_cpu;
|
||||
|
||||
#include "interrupts.h"
|
||||
#include <setjmp.h>
|
||||
|
||||
@@ -133,11 +131,9 @@ enum M6811_Special
|
||||
#define M6812_MAX_PORTS (0x3ff+1)
|
||||
#define MAX_PORTS (M6812_MAX_PORTS)
|
||||
|
||||
struct _sim_cpu;
|
||||
typedef void (* cpu_interp) (sim_cpu *);
|
||||
|
||||
typedef void (* cpu_interp) (struct _sim_cpu*);
|
||||
|
||||
struct _sim_cpu {
|
||||
struct m68hc11_sim_cpu {
|
||||
/* CPU registers. */
|
||||
struct m6811_regs cpu_regs;
|
||||
|
||||
@@ -203,42 +199,40 @@ struct _sim_cpu {
|
||||
|
||||
|
||||
struct hw *hw_cpu;
|
||||
|
||||
/* ... base type ... */
|
||||
sim_cpu_base base;
|
||||
};
|
||||
#define M68HC11_SIM_CPU(cpu) ((struct m68hc11_sim_cpu *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
/* Returns the cpu absolute cycle time (A virtual counter incremented
|
||||
at each 68HC11 E clock). */
|
||||
#define cpu_current_cycle(cpu) ((cpu)->cpu_absolute_cycle)
|
||||
#define cpu_add_cycles(cpu, T) ((cpu)->cpu_current_cycle += (int64_t) (T))
|
||||
#define cpu_is_running(cpu) ((cpu)->cpu_running)
|
||||
#define cpu_current_cycle(cpu) (M68HC11_SIM_CPU (cpu)->cpu_absolute_cycle)
|
||||
#define cpu_add_cycles(cpu, T) (M68HC11_SIM_CPU (cpu)->cpu_current_cycle += (int64_t) (T))
|
||||
#define cpu_is_running(cpu) (M68HC11_SIM_CPU (cpu)->cpu_running)
|
||||
|
||||
/* Get the IO/RAM base addresses depending on the M6811_INIT register. */
|
||||
#define cpu_get_io_base(cpu) \
|
||||
(((uint16_t)(((cpu)->ios[M6811_INIT]) & 0x0F)) << 12)
|
||||
(((uint16_t)((M68HC11_SIM_CPU (cpu)->ios[M6811_INIT]) & 0x0F)) << 12)
|
||||
#define cpu_get_reg_base(cpu) \
|
||||
(((uint16_t)(((cpu)->ios[M6811_INIT]) & 0xF0)) << 8)
|
||||
(((uint16_t)((M68HC11_SIM_CPU (cpu)->ios[M6811_INIT]) & 0xF0)) << 8)
|
||||
|
||||
/* Returns the different CPU registers. */
|
||||
#define cpu_get_ccr(cpu) ((cpu)->cpu_regs.ccr)
|
||||
#define cpu_get_pc(cpu) ((cpu)->cpu_regs.pc)
|
||||
#define cpu_get_d(cpu) ((cpu)->cpu_regs.d)
|
||||
#define cpu_get_x(cpu) ((cpu)->cpu_regs.ix)
|
||||
#define cpu_get_y(cpu) ((cpu)->cpu_regs.iy)
|
||||
#define cpu_get_sp(cpu) ((cpu)->cpu_regs.sp)
|
||||
#define cpu_get_a(cpu) (((cpu)->cpu_regs.d >> 8) & 0x0FF)
|
||||
#define cpu_get_b(cpu) ((cpu)->cpu_regs.d & 0x0FF)
|
||||
#define cpu_get_page(cpu) ((cpu)->cpu_regs.page)
|
||||
#define cpu_get_ccr(cpu) (M68HC11_SIM_CPU (cpu)->cpu_regs.ccr)
|
||||
#define cpu_get_pc(cpu) (M68HC11_SIM_CPU (cpu)->cpu_regs.pc)
|
||||
#define cpu_get_d(cpu) (M68HC11_SIM_CPU (cpu)->cpu_regs.d)
|
||||
#define cpu_get_x(cpu) (M68HC11_SIM_CPU (cpu)->cpu_regs.ix)
|
||||
#define cpu_get_y(cpu) (M68HC11_SIM_CPU (cpu)->cpu_regs.iy)
|
||||
#define cpu_get_sp(cpu) (M68HC11_SIM_CPU (cpu)->cpu_regs.sp)
|
||||
#define cpu_get_a(cpu) ((M68HC11_SIM_CPU (cpu)->cpu_regs.d >> 8) & 0x0FF)
|
||||
#define cpu_get_b(cpu) (M68HC11_SIM_CPU (cpu)->cpu_regs.d & 0x0FF)
|
||||
#define cpu_get_page(cpu) (M68HC11_SIM_CPU (cpu)->cpu_regs.page)
|
||||
|
||||
/* 68HC12 specific and Motorola internal registers. */
|
||||
#define cpu_get_tmp3(cpu) (0)
|
||||
#define cpu_get_tmp2(cpu) (0)
|
||||
|
||||
#define cpu_set_d(cpu, val) ((cpu)->cpu_regs.d = (val))
|
||||
#define cpu_set_x(cpu, val) ((cpu)->cpu_regs.ix = (val))
|
||||
#define cpu_set_y(cpu, val) ((cpu)->cpu_regs.iy = (val))
|
||||
#define cpu_set_page(cpu, val) ((cpu)->cpu_regs.page = (val))
|
||||
#define cpu_set_d(cpu, val) (M68HC11_SIM_CPU (cpu)->cpu_regs.d = (val))
|
||||
#define cpu_set_x(cpu, val) (M68HC11_SIM_CPU (cpu)->cpu_regs.ix = (val))
|
||||
#define cpu_set_y(cpu, val) (M68HC11_SIM_CPU (cpu)->cpu_regs.iy = (val))
|
||||
#define cpu_set_page(cpu, val) (M68HC11_SIM_CPU (cpu)->cpu_regs.page = (val))
|
||||
|
||||
/* 68HC12 specific and Motorola internal registers. */
|
||||
#define cpu_set_tmp3(cpu, val) (0)
|
||||
@@ -246,17 +240,17 @@ struct _sim_cpu {
|
||||
|
||||
#if 0
|
||||
/* This is a function in m68hc11_sim.c to keep track of the frame. */
|
||||
#define cpu_set_sp(cpu, val) ((cpu)->cpu_regs.sp = (val))
|
||||
#define cpu_set_sp(cpu, val) (M68HC11_SIM_CPU (cpu)->cpu_regs.sp = (val))
|
||||
#endif
|
||||
|
||||
#define cpu_set_pc(cpu, val) ((cpu)->cpu_regs.pc = (val))
|
||||
#define cpu_set_pc(cpu, val) (M68HC11_SIM_CPU (cpu)->cpu_regs.pc = (val))
|
||||
|
||||
#define cpu_set_a(cpu, val) \
|
||||
cpu_set_d(cpu, ((val) << 8) | cpu_get_b (cpu))
|
||||
#define cpu_set_b(cpu, val) \
|
||||
cpu_set_d(cpu, ((cpu_get_a (cpu)) << 8) | ((val) & 0x0FF))
|
||||
|
||||
#define cpu_set_ccr(cpu, val) ((cpu)->cpu_regs.ccr = (val))
|
||||
#define cpu_set_ccr(cpu, val) (M68HC11_SIM_CPU (cpu)->cpu_regs.ccr = (val))
|
||||
#define cpu_get_ccr_H(cpu) ((cpu_get_ccr (cpu) & M6811_H_BIT) ? 1 : 0)
|
||||
#define cpu_get_ccr_X(cpu) ((cpu_get_ccr (cpu) & M6811_X_BIT) ? 1 : 0)
|
||||
#define cpu_get_ccr_S(cpu) ((cpu_get_ccr (cpu) & M6811_S_BIT) ? 1 : 0)
|
||||
@@ -286,10 +280,12 @@ extern void cpu_memory_exception (sim_cpu *cpu,
|
||||
STATIC_INLINE UNUSED address_word
|
||||
phys_to_virt (sim_cpu *cpu, address_word addr)
|
||||
{
|
||||
if (addr >= cpu->bank_start && addr < cpu->bank_end)
|
||||
return ((address_word) (addr - cpu->bank_start)
|
||||
+ (((address_word) cpu->cpu_regs.page) << cpu->bank_shift)
|
||||
+ cpu->bank_virtual);
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
|
||||
if (addr >= m68hc11_cpu->bank_start && addr < m68hc11_cpu->bank_end)
|
||||
return ((address_word) (addr - m68hc11_cpu->bank_start)
|
||||
+ (((address_word) m68hc11_cpu->cpu_regs.page) << m68hc11_cpu->bank_shift)
|
||||
+ m68hc11_cpu->bank_virtual);
|
||||
else
|
||||
return (address_word) (addr);
|
||||
}
|
||||
@@ -411,40 +407,44 @@ cpu_ccr_update_sub16 (sim_cpu *cpu, uint16_t r, uint16_t a, uint16_t b)
|
||||
STATIC_INLINE UNUSED void
|
||||
cpu_m68hc11_push_uint8 (sim_cpu *cpu, uint8_t val)
|
||||
{
|
||||
uint16_t addr = cpu->cpu_regs.sp;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
uint16_t addr = m68hc11_cpu->cpu_regs.sp;
|
||||
|
||||
memory_write8 (cpu, addr, val);
|
||||
cpu->cpu_regs.sp = addr - 1;
|
||||
m68hc11_cpu->cpu_regs.sp = addr - 1;
|
||||
}
|
||||
|
||||
STATIC_INLINE UNUSED void
|
||||
cpu_m68hc11_push_uint16 (sim_cpu *cpu, uint16_t val)
|
||||
{
|
||||
uint16_t addr = cpu->cpu_regs.sp - 1;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
uint16_t addr = m68hc11_cpu->cpu_regs.sp - 1;
|
||||
|
||||
memory_write16 (cpu, addr, val);
|
||||
cpu->cpu_regs.sp = addr - 1;
|
||||
m68hc11_cpu->cpu_regs.sp = addr - 1;
|
||||
}
|
||||
|
||||
STATIC_INLINE UNUSED uint8_t
|
||||
cpu_m68hc11_pop_uint8 (sim_cpu *cpu)
|
||||
{
|
||||
uint16_t addr = cpu->cpu_regs.sp;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
uint16_t addr = m68hc11_cpu->cpu_regs.sp;
|
||||
uint8_t val;
|
||||
|
||||
val = memory_read8 (cpu, addr + 1);
|
||||
cpu->cpu_regs.sp = addr + 1;
|
||||
m68hc11_cpu->cpu_regs.sp = addr + 1;
|
||||
return val;
|
||||
}
|
||||
|
||||
STATIC_INLINE UNUSED uint16_t
|
||||
cpu_m68hc11_pop_uint16 (sim_cpu *cpu)
|
||||
{
|
||||
uint16_t addr = cpu->cpu_regs.sp;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
uint16_t addr = m68hc11_cpu->cpu_regs.sp;
|
||||
uint16_t val;
|
||||
|
||||
val = memory_read16 (cpu, addr + 1);
|
||||
cpu->cpu_regs.sp = addr + 2;
|
||||
m68hc11_cpu->cpu_regs.sp = addr + 2;
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -452,42 +452,46 @@ cpu_m68hc11_pop_uint16 (sim_cpu *cpu)
|
||||
STATIC_INLINE UNUSED void
|
||||
cpu_m68hc12_push_uint8 (sim_cpu *cpu, uint8_t val)
|
||||
{
|
||||
uint16_t addr = cpu->cpu_regs.sp;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
uint16_t addr = m68hc11_cpu->cpu_regs.sp;
|
||||
|
||||
addr --;
|
||||
memory_write8 (cpu, addr, val);
|
||||
cpu->cpu_regs.sp = addr;
|
||||
m68hc11_cpu->cpu_regs.sp = addr;
|
||||
}
|
||||
|
||||
STATIC_INLINE UNUSED void
|
||||
cpu_m68hc12_push_uint16 (sim_cpu *cpu, uint16_t val)
|
||||
{
|
||||
uint16_t addr = cpu->cpu_regs.sp;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
uint16_t addr = m68hc11_cpu->cpu_regs.sp;
|
||||
|
||||
addr -= 2;
|
||||
memory_write16 (cpu, addr, val);
|
||||
cpu->cpu_regs.sp = addr;
|
||||
m68hc11_cpu->cpu_regs.sp = addr;
|
||||
}
|
||||
|
||||
STATIC_INLINE UNUSED uint8_t
|
||||
cpu_m68hc12_pop_uint8 (sim_cpu *cpu)
|
||||
{
|
||||
uint16_t addr = cpu->cpu_regs.sp;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
uint16_t addr = m68hc11_cpu->cpu_regs.sp;
|
||||
uint8_t val;
|
||||
|
||||
val = memory_read8 (cpu, addr);
|
||||
cpu->cpu_regs.sp = addr + 1;
|
||||
m68hc11_cpu->cpu_regs.sp = addr + 1;
|
||||
return val;
|
||||
}
|
||||
|
||||
STATIC_INLINE UNUSED uint16_t
|
||||
cpu_m68hc12_pop_uint16 (sim_cpu *cpu)
|
||||
{
|
||||
uint16_t addr = cpu->cpu_regs.sp;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
uint16_t addr = m68hc11_cpu->cpu_regs.sp;
|
||||
uint16_t val;
|
||||
|
||||
val = memory_read16 (cpu, addr);
|
||||
cpu->cpu_regs.sp = addr + 2;
|
||||
m68hc11_cpu->cpu_regs.sp = addr + 2;
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -495,22 +499,24 @@ cpu_m68hc12_pop_uint16 (sim_cpu *cpu)
|
||||
STATIC_INLINE UNUSED uint8_t
|
||||
cpu_fetch8 (sim_cpu *cpu)
|
||||
{
|
||||
uint16_t addr = cpu->cpu_regs.pc;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
uint16_t addr = m68hc11_cpu->cpu_regs.pc;
|
||||
uint8_t val;
|
||||
|
||||
val = memory_read8 (cpu, addr);
|
||||
cpu->cpu_regs.pc = addr + 1;
|
||||
m68hc11_cpu->cpu_regs.pc = addr + 1;
|
||||
return val;
|
||||
}
|
||||
|
||||
STATIC_INLINE UNUSED uint16_t
|
||||
cpu_fetch16 (sim_cpu *cpu)
|
||||
{
|
||||
uint16_t addr = cpu->cpu_regs.pc;
|
||||
struct m68hc11_sim_cpu *m68hc11_cpu = M68HC11_SIM_CPU (cpu);
|
||||
uint16_t addr = m68hc11_cpu->cpu_regs.pc;
|
||||
uint16_t val;
|
||||
|
||||
val = memory_read16 (cpu, addr);
|
||||
cpu->cpu_regs.pc = addr + 2;
|
||||
m68hc11_cpu->cpu_regs.pc = addr + 2;
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
@@ -98,8 +98,8 @@ mcore_store_unsigned_integer (unsigned char *addr, int len, unsigned long val)
|
||||
|
||||
static int memcycles = 1;
|
||||
|
||||
#define gr cpu->active_gregs
|
||||
#define cr cpu->regs.cregs
|
||||
#define gr MCORE_SIM_CPU (cpu)->active_gregs
|
||||
#define cr MCORE_SIM_CPU (cpu)->regs.cregs
|
||||
#define sr cr[0]
|
||||
#define vbr cr[1]
|
||||
#define esr cr[2]
|
||||
@@ -125,10 +125,12 @@ static int memcycles = 1;
|
||||
#define SR_AF() ((sr >> 1) & 1)
|
||||
static void set_active_regs (SIM_CPU *cpu)
|
||||
{
|
||||
struct mcore_sim_cpu *mcore_cpu = MCORE_SIM_CPU (cpu);
|
||||
|
||||
if (SR_AF())
|
||||
cpu->active_gregs = cpu->regs.alt_gregs;
|
||||
mcore_cpu->active_gregs = mcore_cpu->regs.alt_gregs;
|
||||
else
|
||||
cpu->active_gregs = cpu->regs.gregs;
|
||||
mcore_cpu->active_gregs = mcore_cpu->regs.gregs;
|
||||
}
|
||||
|
||||
#define TRAPCODE 1 /* r1 holds which function we want */
|
||||
@@ -144,13 +146,15 @@ static void set_active_regs (SIM_CPU *cpu)
|
||||
static void
|
||||
set_initial_gprs (SIM_CPU *cpu)
|
||||
{
|
||||
struct mcore_sim_cpu *mcore_cpu = MCORE_SIM_CPU (cpu);
|
||||
|
||||
/* Set up machine just out of reset. */
|
||||
CPU_PC_SET (cpu, 0);
|
||||
sr = 0;
|
||||
|
||||
/* Clean out the GPRs and alternate GPRs. */
|
||||
memset (&cpu->regs.gregs, 0, sizeof(cpu->regs.gregs));
|
||||
memset (&cpu->regs.alt_gregs, 0, sizeof(cpu->regs.alt_gregs));
|
||||
memset (&mcore_cpu->regs.gregs, 0, sizeof(mcore_cpu->regs.gregs));
|
||||
memset (&mcore_cpu->regs.alt_gregs, 0, sizeof(mcore_cpu->regs.alt_gregs));
|
||||
|
||||
/* Make our register set point to the right place. */
|
||||
set_active_regs (cpu);
|
||||
@@ -203,10 +207,12 @@ process_stub (SIM_DESC sd, SIM_CPU *cpu, int what)
|
||||
static void
|
||||
util (SIM_DESC sd, SIM_CPU *cpu, unsigned what)
|
||||
{
|
||||
struct mcore_sim_cpu *mcore_cpu = MCORE_SIM_CPU (cpu);
|
||||
|
||||
switch (what)
|
||||
{
|
||||
case 0: /* exit */
|
||||
sim_engine_halt (sd, cpu, NULL, cpu->regs.pc, sim_exited, gr[PARM1]);
|
||||
sim_engine_halt (sd, cpu, NULL, mcore_cpu->regs.pc, sim_exited, gr[PARM1]);
|
||||
break;
|
||||
|
||||
case 1: /* printf */
|
||||
@@ -220,7 +226,7 @@ util (SIM_DESC sd, SIM_CPU *cpu, unsigned what)
|
||||
break;
|
||||
|
||||
case 3: /* utime */
|
||||
gr[RET1] = cpu->insts;
|
||||
gr[RET1] = mcore_cpu->insts;
|
||||
break;
|
||||
|
||||
case 0xFF:
|
||||
@@ -287,6 +293,7 @@ static int tracing = 0;
|
||||
static void
|
||||
step_once (SIM_DESC sd, SIM_CPU *cpu)
|
||||
{
|
||||
struct mcore_sim_cpu *mcore_cpu = MCORE_SIM_CPU (cpu);
|
||||
int needfetch;
|
||||
word ibuf;
|
||||
word pc;
|
||||
@@ -349,7 +356,7 @@ step_once (SIM_DESC sd, SIM_CPU *cpu)
|
||||
|
||||
if ((WLincyc == 1) && (pc == WLendpc))
|
||||
{
|
||||
cycs = (cpu->cycles + (insts + bonus_cycles +
|
||||
cycs = (mcore_cpu->cycles + (insts + bonus_cycles +
|
||||
(memops * memcycles)) - WLbcyc);
|
||||
|
||||
if (WLcnts[WLW] == 1)
|
||||
@@ -384,7 +391,7 @@ step_once (SIM_DESC sd, SIM_CPU *cpu)
|
||||
if (pc == WL[w])
|
||||
{
|
||||
WLcnts[w]++;
|
||||
WLbcyc = cpu->cycles + insts
|
||||
WLbcyc = mcore_cpu->cycles + insts
|
||||
+ bonus_cycles + (memops * memcycles);
|
||||
WLendpc = gr[15];
|
||||
WLincyc = 1;
|
||||
@@ -1215,10 +1222,10 @@ step_once (SIM_DESC sd, SIM_CPU *cpu)
|
||||
|
||||
/* Hide away the things we've cached while executing. */
|
||||
CPU_PC_SET (cpu, pc);
|
||||
cpu->insts += insts; /* instructions done ... */
|
||||
cpu->cycles += insts; /* and each takes a cycle */
|
||||
cpu->cycles += bonus_cycles; /* and extra cycles for branches */
|
||||
cpu->cycles += memops * memcycles; /* and memop cycle delays */
|
||||
mcore_cpu->insts += insts; /* instructions done ... */
|
||||
mcore_cpu->cycles += insts; /* and each takes a cycle */
|
||||
mcore_cpu->cycles += bonus_cycles; /* and extra cycles for branches */
|
||||
mcore_cpu->cycles += memops * memcycles; /* and memop cycle delays */
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1244,6 +1251,8 @@ sim_engine_run (SIM_DESC sd,
|
||||
static int
|
||||
mcore_reg_store (SIM_CPU *cpu, int rn, const void *memory, int length)
|
||||
{
|
||||
struct mcore_sim_cpu *mcore_cpu = MCORE_SIM_CPU (cpu);
|
||||
|
||||
if (rn < NUM_MCORE_REGS && rn >= 0)
|
||||
{
|
||||
if (length == 4)
|
||||
@@ -1252,7 +1261,7 @@ mcore_reg_store (SIM_CPU *cpu, int rn, const void *memory, int length)
|
||||
|
||||
/* misalignment safe */
|
||||
ival = mcore_extract_unsigned_integer (memory, 4);
|
||||
cpu->asints[rn] = ival;
|
||||
mcore_cpu->asints[rn] = ival;
|
||||
}
|
||||
|
||||
return 4;
|
||||
@@ -1264,11 +1273,13 @@ mcore_reg_store (SIM_CPU *cpu, int rn, const void *memory, int length)
|
||||
static int
|
||||
mcore_reg_fetch (SIM_CPU *cpu, int rn, void *memory, int length)
|
||||
{
|
||||
struct mcore_sim_cpu *mcore_cpu = MCORE_SIM_CPU (cpu);
|
||||
|
||||
if (rn < NUM_MCORE_REGS && rn >= 0)
|
||||
{
|
||||
if (length == 4)
|
||||
{
|
||||
long ival = cpu->asints[rn];
|
||||
long ival = mcore_cpu->asints[rn];
|
||||
|
||||
/* misalignment-safe */
|
||||
mcore_store_unsigned_integer (memory, 4, ival);
|
||||
@@ -1284,18 +1295,19 @@ void
|
||||
sim_info (SIM_DESC sd, int verbose)
|
||||
{
|
||||
SIM_CPU *cpu = STATE_CPU (sd, 0);
|
||||
struct mcore_sim_cpu *mcore_cpu = MCORE_SIM_CPU (cpu);
|
||||
#ifdef WATCHFUNCTIONS
|
||||
int w, wcyc;
|
||||
#endif
|
||||
double virttime = cpu->cycles / 36.0e6;
|
||||
double virttime = mcore_cpu->cycles / 36.0e6;
|
||||
host_callback *callback = STATE_CALLBACK (sd);
|
||||
|
||||
callback->printf_filtered (callback, "\n\n# instructions executed %10d\n",
|
||||
cpu->insts);
|
||||
mcore_cpu->insts);
|
||||
callback->printf_filtered (callback, "# cycles %10d\n",
|
||||
cpu->cycles);
|
||||
mcore_cpu->cycles);
|
||||
callback->printf_filtered (callback, "# pipeline stalls %10d\n",
|
||||
cpu->stalls);
|
||||
mcore_cpu->stalls);
|
||||
callback->printf_filtered (callback, "# virtual time taken %10.4f\n",
|
||||
virttime);
|
||||
|
||||
@@ -1326,13 +1338,13 @@ sim_info (SIM_DESC sd, int verbose)
|
||||
static sim_cia
|
||||
mcore_pc_get (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->regs.pc;
|
||||
return MCORE_SIM_CPU (cpu)->regs.pc;
|
||||
}
|
||||
|
||||
static void
|
||||
mcore_pc_set (sim_cpu *cpu, sim_cia pc)
|
||||
{
|
||||
cpu->regs.pc = pc;
|
||||
MCORE_SIM_CPU (cpu)->regs.pc = pc;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1356,7 +1368,8 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb,
|
||||
cb->syscall_map = cb_mcore_syscall_map;
|
||||
|
||||
/* The cpu data is kept in a separately allocated chunk of memory. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct mcore_sim_cpu))
|
||||
!= SIM_RC_OK)
|
||||
{
|
||||
free_state (sd);
|
||||
return 0;
|
||||
|
||||
@@ -48,8 +48,7 @@ struct mcore_regset
|
||||
#define LAST_VALID_CREG 32 /* only 0..12 implemented */
|
||||
#define NUM_MCORE_REGS (16 + 16 + LAST_VALID_CREG + 1)
|
||||
|
||||
struct _sim_cpu {
|
||||
|
||||
struct mcore_sim_cpu {
|
||||
union
|
||||
{
|
||||
struct mcore_regset regs;
|
||||
@@ -64,9 +63,9 @@ struct _sim_cpu {
|
||||
int stalls;
|
||||
int cycles;
|
||||
int insts;
|
||||
|
||||
sim_cpu_base base;
|
||||
};
|
||||
|
||||
#define MCORE_SIM_CPU(cpu) ((struct mcore_sim_cpu *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -382,13 +382,13 @@ sim_info (SIM_DESC sd, int verbose)
|
||||
static sim_cia
|
||||
microblaze_pc_get (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->microblaze_cpu.spregs[0];
|
||||
return MICROBLAZE_SIM_CPU (cpu)->spregs[0];
|
||||
}
|
||||
|
||||
static void
|
||||
microblaze_pc_set (sim_cpu *cpu, sim_cia pc)
|
||||
{
|
||||
cpu->microblaze_cpu.spregs[0] = pc;
|
||||
MICROBLAZE_SIM_CPU (cpu)->spregs[0] = pc;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -409,7 +409,8 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb,
|
||||
SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
|
||||
|
||||
/* The cpu data is kept in a separately allocated chunk of memory. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct microblaze_regset))
|
||||
!= SIM_RC_OK)
|
||||
{
|
||||
free_state (sd);
|
||||
return 0;
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#define GET_RA ((inst & RA_MASK) >> RA_LOW)
|
||||
#define GET_RB ((inst & RB_MASK) >> RB_LOW)
|
||||
|
||||
#define CPU cpu->microblaze_cpu
|
||||
#define CPU (*MICROBLAZE_SIM_CPU (cpu))
|
||||
|
||||
#define RD CPU.regs[rd]
|
||||
#define RA CPU.regs[ra]
|
||||
|
||||
@@ -43,9 +43,6 @@
|
||||
signed_2 imm_high;
|
||||
};
|
||||
|
||||
struct _sim_cpu {
|
||||
struct microblaze_regset microblaze_cpu;
|
||||
sim_cpu_base base;
|
||||
};
|
||||
#define MICROBLAZE_SIM_CPU(cpu) ((struct microblaze_regset *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
#endif /* MICROBLAZE_SIM_MAIN */
|
||||
|
||||
@@ -351,7 +351,8 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb,
|
||||
SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
|
||||
|
||||
/* The cpu data is kept in a separately allocated chunk of memory. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct mips_sim_cpu))
|
||||
!= SIM_RC_OK)
|
||||
return 0;
|
||||
|
||||
cpu = STATE_CPU (sd, 0); /* FIXME */
|
||||
@@ -666,19 +667,21 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb,
|
||||
int rn;
|
||||
for (rn = 0; (rn < (LAST_EMBED_REGNUM + 1)); rn++)
|
||||
{
|
||||
struct mips_sim_cpu *mips_cpu = MIPS_SIM_CPU (cpu);
|
||||
|
||||
if (rn < 32)
|
||||
cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
|
||||
mips_cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
|
||||
else if ((rn >= FGR_BASE) && (rn < (FGR_BASE + NR_FGR)))
|
||||
cpu->register_widths[rn] = WITH_TARGET_FLOATING_POINT_BITSIZE;
|
||||
mips_cpu->register_widths[rn] = WITH_TARGET_FLOATING_POINT_BITSIZE;
|
||||
else if ((rn >= 33) && (rn <= 37))
|
||||
cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
|
||||
mips_cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
|
||||
else if ((rn == SRIDX)
|
||||
|| (rn == FCR0IDX)
|
||||
|| (rn == FCR31IDX)
|
||||
|| ((rn >= 72) && (rn <= 89)))
|
||||
cpu->register_widths[rn] = 32;
|
||||
mips_cpu->register_widths[rn] = 32;
|
||||
else
|
||||
cpu->register_widths[rn] = 0;
|
||||
mips_cpu->register_widths[rn] = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -855,7 +858,9 @@ mips_reg_store (SIM_CPU *cpu, int rn, const void *memory, int length)
|
||||
numbering one. We need to know what the width of each logical
|
||||
register number is for the architecture being simulated. */
|
||||
|
||||
if (cpu->register_widths[rn] == 0)
|
||||
struct mips_sim_cpu *mips_cpu = MIPS_SIM_CPU (cpu);
|
||||
|
||||
if (mips_cpu->register_widths[rn] == 0)
|
||||
{
|
||||
sim_io_eprintf (CPU_STATE (cpu), "Invalid register width for %d (register store ignored)\n", rn);
|
||||
return 0;
|
||||
@@ -863,18 +868,18 @@ mips_reg_store (SIM_CPU *cpu, int rn, const void *memory, int length)
|
||||
|
||||
if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
|
||||
{
|
||||
cpu->fpr_state[rn - FGR_BASE] = fmt_uninterpreted;
|
||||
if (cpu->register_widths[rn] == 32)
|
||||
mips_cpu->fpr_state[rn - FGR_BASE] = fmt_uninterpreted;
|
||||
if (mips_cpu->register_widths[rn] == 32)
|
||||
{
|
||||
if (length == 8)
|
||||
{
|
||||
cpu->fgr[rn - FGR_BASE] =
|
||||
mips_cpu->fgr[rn - FGR_BASE] =
|
||||
(uint32_t) T2H_8 (*(uint64_t*)memory);
|
||||
return 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu->fgr[rn - FGR_BASE] = T2H_4 (*(uint32_t*)memory);
|
||||
mips_cpu->fgr[rn - FGR_BASE] = T2H_4 (*(uint32_t*)memory);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
@@ -882,28 +887,28 @@ mips_reg_store (SIM_CPU *cpu, int rn, const void *memory, int length)
|
||||
{
|
||||
if (length == 8)
|
||||
{
|
||||
cpu->fgr[rn - FGR_BASE] = T2H_8 (*(uint64_t*)memory);
|
||||
mips_cpu->fgr[rn - FGR_BASE] = T2H_8 (*(uint64_t*)memory);
|
||||
return 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu->fgr[rn - FGR_BASE] = T2H_4 (*(uint32_t*)memory);
|
||||
mips_cpu->fgr[rn - FGR_BASE] = T2H_4 (*(uint32_t*)memory);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cpu->register_widths[rn] == 32)
|
||||
if (mips_cpu->register_widths[rn] == 32)
|
||||
{
|
||||
if (length == 8)
|
||||
{
|
||||
cpu->registers[rn] =
|
||||
mips_cpu->registers[rn] =
|
||||
(uint32_t) T2H_8 (*(uint64_t*)memory);
|
||||
return 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu->registers[rn] = T2H_4 (*(uint32_t*)memory);
|
||||
mips_cpu->registers[rn] = T2H_4 (*(uint32_t*)memory);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
@@ -911,12 +916,12 @@ mips_reg_store (SIM_CPU *cpu, int rn, const void *memory, int length)
|
||||
{
|
||||
if (length == 8)
|
||||
{
|
||||
cpu->registers[rn] = T2H_8 (*(uint64_t*)memory);
|
||||
mips_cpu->registers[rn] = T2H_8 (*(uint64_t*)memory);
|
||||
return 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu->registers[rn] = (int32_t) T2H_4(*(uint32_t*)memory);
|
||||
mips_cpu->registers[rn] = (int32_t) T2H_4(*(uint32_t*)memory);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
@@ -930,7 +935,9 @@ mips_reg_fetch (SIM_CPU *cpu, int rn, void *memory, int length)
|
||||
/* NOTE: gdb (the client) stores registers in target byte order
|
||||
while the simulator uses host byte order */
|
||||
|
||||
if (cpu->register_widths[rn] == 0)
|
||||
struct mips_sim_cpu *mips_cpu = MIPS_SIM_CPU (cpu);
|
||||
|
||||
if (mips_cpu->register_widths[rn] == 0)
|
||||
{
|
||||
sim_io_eprintf (CPU_STATE (cpu), "Invalid register width for %d (register fetch ignored)\n", rn);
|
||||
return 0;
|
||||
@@ -939,17 +946,17 @@ mips_reg_fetch (SIM_CPU *cpu, int rn, void *memory, int length)
|
||||
/* Any floating point register */
|
||||
if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
|
||||
{
|
||||
if (cpu->register_widths[rn] == 32)
|
||||
if (mips_cpu->register_widths[rn] == 32)
|
||||
{
|
||||
if (length == 8)
|
||||
{
|
||||
*(uint64_t*)memory =
|
||||
H2T_8 ((uint32_t) (cpu->fgr[rn - FGR_BASE]));
|
||||
H2T_8 ((uint32_t) (mips_cpu->fgr[rn - FGR_BASE]));
|
||||
return 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(uint32_t*)memory = H2T_4 (cpu->fgr[rn - FGR_BASE]);
|
||||
*(uint32_t*)memory = H2T_4 (mips_cpu->fgr[rn - FGR_BASE]);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
@@ -957,28 +964,28 @@ mips_reg_fetch (SIM_CPU *cpu, int rn, void *memory, int length)
|
||||
{
|
||||
if (length == 8)
|
||||
{
|
||||
*(uint64_t*)memory = H2T_8 (cpu->fgr[rn - FGR_BASE]);
|
||||
*(uint64_t*)memory = H2T_8 (mips_cpu->fgr[rn - FGR_BASE]);
|
||||
return 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(uint32_t*)memory = H2T_4 ((uint32_t)(cpu->fgr[rn - FGR_BASE]));
|
||||
*(uint32_t*)memory = H2T_4 ((uint32_t)(mips_cpu->fgr[rn - FGR_BASE]));
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cpu->register_widths[rn] == 32)
|
||||
if (mips_cpu->register_widths[rn] == 32)
|
||||
{
|
||||
if (length == 8)
|
||||
{
|
||||
*(uint64_t*)memory =
|
||||
H2T_8 ((uint32_t) (cpu->registers[rn]));
|
||||
H2T_8 ((uint32_t) (mips_cpu->registers[rn]));
|
||||
return 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(uint32_t*)memory = H2T_4 ((uint32_t)(cpu->registers[rn]));
|
||||
*(uint32_t*)memory = H2T_4 ((uint32_t)(mips_cpu->registers[rn]));
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
@@ -987,12 +994,12 @@ mips_reg_fetch (SIM_CPU *cpu, int rn, void *memory, int length)
|
||||
if (length == 8)
|
||||
{
|
||||
*(uint64_t*)memory =
|
||||
H2T_8 ((uint64_t) (cpu->registers[rn]));
|
||||
H2T_8 ((uint64_t) (mips_cpu->registers[rn]));
|
||||
return 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(uint32_t*)memory = H2T_4 ((uint32_t)(cpu->registers[rn]));
|
||||
*(uint32_t*)memory = H2T_4 ((uint32_t)(mips_cpu->registers[rn]));
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
@@ -2532,55 +2539,66 @@ mips_core_signal (SIM_DESC sd,
|
||||
void
|
||||
mips_cpu_exception_trigger(SIM_DESC sd, sim_cpu* cpu, address_word cia)
|
||||
{
|
||||
struct mips_sim_cpu *mips_cpu = MIPS_SIM_CPU (cpu);
|
||||
|
||||
ASSERT(cpu != NULL);
|
||||
|
||||
if (cpu->exc_suspended > 0)
|
||||
sim_io_eprintf(sd, "Warning, nested exception triggered (%d)\n", cpu->exc_suspended);
|
||||
if (mips_cpu->exc_suspended > 0)
|
||||
sim_io_eprintf (sd, "Warning, nested exception triggered (%d)\n",
|
||||
mips_cpu->exc_suspended);
|
||||
|
||||
PC = cia;
|
||||
memcpy(cpu->exc_trigger_registers, cpu->registers, sizeof(cpu->exc_trigger_registers));
|
||||
cpu->exc_suspended = 0;
|
||||
memcpy (mips_cpu->exc_trigger_registers, mips_cpu->registers,
|
||||
sizeof (mips_cpu->exc_trigger_registers));
|
||||
mips_cpu->exc_suspended = 0;
|
||||
}
|
||||
|
||||
void
|
||||
mips_cpu_exception_suspend(SIM_DESC sd, sim_cpu* cpu, int exception)
|
||||
{
|
||||
struct mips_sim_cpu *mips_cpu = MIPS_SIM_CPU (cpu);
|
||||
|
||||
ASSERT(cpu != NULL);
|
||||
|
||||
if (cpu->exc_suspended > 0)
|
||||
if (mips_cpu->exc_suspended > 0)
|
||||
sim_io_eprintf(sd, "Warning, nested exception signal (%d then %d)\n",
|
||||
cpu->exc_suspended, exception);
|
||||
mips_cpu->exc_suspended, exception);
|
||||
|
||||
memcpy(cpu->exc_suspend_registers, cpu->registers, sizeof(cpu->exc_suspend_registers));
|
||||
memcpy(cpu->registers, cpu->exc_trigger_registers, sizeof(cpu->registers));
|
||||
cpu->exc_suspended = exception;
|
||||
memcpy (mips_cpu->exc_suspend_registers, mips_cpu->registers,
|
||||
sizeof (mips_cpu->exc_suspend_registers));
|
||||
memcpy (mips_cpu->registers, mips_cpu->exc_trigger_registers,
|
||||
sizeof (mips_cpu->registers));
|
||||
mips_cpu->exc_suspended = exception;
|
||||
}
|
||||
|
||||
void
|
||||
mips_cpu_exception_resume(SIM_DESC sd, sim_cpu* cpu, int exception)
|
||||
{
|
||||
struct mips_sim_cpu *mips_cpu = MIPS_SIM_CPU (cpu);
|
||||
|
||||
ASSERT(cpu != NULL);
|
||||
|
||||
if (exception == 0 && cpu->exc_suspended > 0)
|
||||
if (exception == 0 && mips_cpu->exc_suspended > 0)
|
||||
{
|
||||
/* warn not for breakpoints */
|
||||
if (cpu->exc_suspended != sim_signal_to_host(sd, SIM_SIGTRAP))
|
||||
if (mips_cpu->exc_suspended != sim_signal_to_host(sd, SIM_SIGTRAP))
|
||||
sim_io_eprintf(sd, "Warning, resuming but ignoring pending exception signal (%d)\n",
|
||||
cpu->exc_suspended);
|
||||
mips_cpu->exc_suspended);
|
||||
}
|
||||
else if (exception != 0 && cpu->exc_suspended > 0)
|
||||
else if (exception != 0 && mips_cpu->exc_suspended > 0)
|
||||
{
|
||||
if (exception != cpu->exc_suspended)
|
||||
if (exception != mips_cpu->exc_suspended)
|
||||
sim_io_eprintf(sd, "Warning, resuming with mismatched exception signal (%d vs %d)\n",
|
||||
cpu->exc_suspended, exception);
|
||||
mips_cpu->exc_suspended, exception);
|
||||
|
||||
memcpy(cpu->registers, cpu->exc_suspend_registers, sizeof(cpu->registers));
|
||||
memcpy (mips_cpu->registers, mips_cpu->exc_suspend_registers,
|
||||
sizeof (mips_cpu->registers));
|
||||
}
|
||||
else if (exception != 0 && cpu->exc_suspended == 0)
|
||||
else if (exception != 0 && mips_cpu->exc_suspended == 0)
|
||||
{
|
||||
sim_io_eprintf(sd, "Warning, ignoring spontanous exception signal (%d)\n", exception);
|
||||
}
|
||||
cpu->exc_suspended = 0;
|
||||
mips_cpu->exc_suspended = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -171,20 +171,20 @@ typedef struct _pending_write_queue {
|
||||
#ifndef PENDING_TRACE
|
||||
#define PENDING_TRACE 0
|
||||
#endif
|
||||
#define PENDING_IN ((CPU)->pending.in)
|
||||
#define PENDING_OUT ((CPU)->pending.out)
|
||||
#define PENDING_TOTAL ((CPU)->pending.total)
|
||||
#define PENDING_SLOT_SIZE ((CPU)->pending.slot_size)
|
||||
#define PENDING_SLOT_BIT ((CPU)->pending.slot_bit)
|
||||
#define PENDING_SLOT_DELAY ((CPU)->pending.slot_delay)
|
||||
#define PENDING_SLOT_DEST ((CPU)->pending.slot_dest)
|
||||
#define PENDING_SLOT_VALUE ((CPU)->pending.slot_value)
|
||||
#define PENDING_IN (MIPS_SIM_CPU (CPU)->pending.in)
|
||||
#define PENDING_OUT (MIPS_SIM_CPU (CPU)->pending.out)
|
||||
#define PENDING_TOTAL (MIPS_SIM_CPU (CPU)->pending.total)
|
||||
#define PENDING_SLOT_SIZE (MIPS_SIM_CPU (CPU)->pending.slot_size)
|
||||
#define PENDING_SLOT_BIT (MIPS_SIM_CPU (CPU)->pending.slot_bit)
|
||||
#define PENDING_SLOT_DELAY (MIPS_SIM_CPU (CPU)->pending.slot_delay)
|
||||
#define PENDING_SLOT_DEST (MIPS_SIM_CPU (CPU)->pending.slot_dest)
|
||||
#define PENDING_SLOT_VALUE (MIPS_SIM_CPU (CPU)->pending.slot_value)
|
||||
|
||||
/* Invalidate the pending write queue, all pending writes are
|
||||
discarded. */
|
||||
|
||||
#define PENDING_INVALIDATE() \
|
||||
memset (&(CPU)->pending, 0, sizeof ((CPU)->pending))
|
||||
memset (&MIPS_SIM_CPU (CPU)->pending, 0, sizeof (MIPS_SIM_CPU (CPU)->pending))
|
||||
|
||||
/* Schedule a write to DEST for N cycles time. For 64 bit
|
||||
destinations, schedule two writes. For floating point registers,
|
||||
@@ -258,12 +258,11 @@ typedef union {
|
||||
#define SIM_STATE sim_cpu *cpu, address_word cia
|
||||
#define SIM_ARGS CPU, cia
|
||||
|
||||
struct _sim_cpu {
|
||||
|
||||
struct mips_sim_cpu {
|
||||
|
||||
/* The following are internal simulator state variables: */
|
||||
address_word dspc; /* delay-slot PC */
|
||||
#define DSPC ((CPU)->dspc)
|
||||
#define DSPC (MIPS_SIM_CPU (CPU)->dspc)
|
||||
|
||||
#define DELAY_SLOT(TARGET) NIA = delayslot32 (SD_, (TARGET))
|
||||
#define FORBIDDEN_SLOT() { NIA = forbiddenslot32 (SD_); }
|
||||
@@ -273,8 +272,8 @@ struct _sim_cpu {
|
||||
/* State of the simulator */
|
||||
unsigned int state;
|
||||
unsigned int dsstate;
|
||||
#define STATE ((CPU)->state)
|
||||
#define DSSTATE ((CPU)->dsstate)
|
||||
#define STATE (MIPS_SIM_CPU (CPU)->state)
|
||||
#define DSSTATE (MIPS_SIM_CPU (CPU)->dsstate)
|
||||
|
||||
/* Flags in the "state" variable: */
|
||||
#define simHALTEX (1 << 2) /* 0 = run; 1 = halt on exception */
|
||||
@@ -331,7 +330,7 @@ struct _sim_cpu {
|
||||
unsigned_word registers[LAST_EMBED_REGNUM + 1];
|
||||
|
||||
int register_widths[NUM_REGS];
|
||||
#define REGISTERS ((CPU)->registers)
|
||||
#define REGISTERS (MIPS_SIM_CPU (CPU)->registers)
|
||||
|
||||
#define GPR (®ISTERS[0])
|
||||
#define GPR_SET(N,VAL) (REGISTERS[(N)] = (VAL))
|
||||
@@ -409,7 +408,7 @@ struct _sim_cpu {
|
||||
#define SIM_CPU_EXCEPTION_RESUME(SD,CPU,EXC) mips_cpu_exception_resume(SD,CPU,EXC)
|
||||
|
||||
unsigned_word c0_config_reg;
|
||||
#define C0_CONFIG ((CPU)->c0_config_reg)
|
||||
#define C0_CONFIG (MIPS_SIM_CPU (CPU)->c0_config_reg)
|
||||
|
||||
/* The following are pseudonyms for standard registers */
|
||||
#define ZERO (REGISTERS[0])
|
||||
@@ -431,7 +430,7 @@ struct _sim_cpu {
|
||||
|
||||
#define NR_COP0_GPR 32
|
||||
unsigned_word cop0_gpr[NR_COP0_GPR];
|
||||
#define COP0_GPR ((CPU)->cop0_gpr)
|
||||
#define COP0_GPR (MIPS_SIM_CPU (CPU)->cop0_gpr)
|
||||
#define COP0_BADVADDR (COP0_GPR[8])
|
||||
|
||||
/* While space is allocated for the floating point registers in the
|
||||
@@ -441,17 +440,17 @@ struct _sim_cpu {
|
||||
#define NR_FGR (32)
|
||||
#define FGR_BASE FP0_REGNUM
|
||||
fp_word fgr[NR_FGR];
|
||||
#define FGR ((CPU)->fgr)
|
||||
#define FGR (MIPS_SIM_CPU (CPU)->fgr)
|
||||
|
||||
/* Keep the current format state for each register: */
|
||||
FP_formats fpr_state[32];
|
||||
#define FPR_STATE ((CPU)->fpr_state)
|
||||
#define FPR_STATE (MIPS_SIM_CPU (CPU)->fpr_state)
|
||||
|
||||
pending_write_queue pending;
|
||||
|
||||
/* The MDMX accumulator (used only for MDMX ASE). */
|
||||
MDMX_accumulator acc;
|
||||
#define ACC ((CPU)->acc)
|
||||
#define ACC (MIPS_SIM_CPU (CPU)->acc)
|
||||
|
||||
/* LLBIT = Load-Linked bit. A bit of "virtual" state used by atomic
|
||||
read-write instructions. It is set when a linked load occurs. It
|
||||
@@ -460,7 +459,7 @@ struct _sim_cpu {
|
||||
no longer be atomic. In particular, it is cleared by exception
|
||||
return instructions. */
|
||||
int llbit;
|
||||
#define LLBIT ((CPU)->llbit)
|
||||
#define LLBIT (MIPS_SIM_CPU (CPU)->llbit)
|
||||
|
||||
|
||||
/* The HIHISTORY and LOHISTORY timestamps are used to ensure that
|
||||
@@ -468,13 +467,11 @@ struct _sim_cpu {
|
||||
following operation is spotted. See mips.igen for more details. */
|
||||
|
||||
hilo_history hi_history;
|
||||
#define HIHISTORY (&(CPU)->hi_history)
|
||||
#define HIHISTORY (&MIPS_SIM_CPU (CPU)->hi_history)
|
||||
hilo_history lo_history;
|
||||
#define LOHISTORY (&(CPU)->lo_history)
|
||||
|
||||
|
||||
sim_cpu_base base;
|
||||
#define LOHISTORY (&MIPS_SIM_CPU (CPU)->lo_history)
|
||||
};
|
||||
#define MIPS_SIM_CPU(cpu) ((struct mips_sim_cpu *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
extern void mips_sim_close (SIM_DESC sd, int quitting);
|
||||
#define SIM_CLOSE_HOOK(...) mips_sim_close (__VA_ARGS__)
|
||||
|
||||
@@ -53,17 +53,6 @@ mn10300_core_signal ((SD), (CPU), (CIA), (MAP), (NR_BYTES), (ADDR), (TRANSFER),
|
||||
#define IMEM8_IMMED(EA, N) \
|
||||
(sim_core_read_aligned_1(STATE_CPU(sd, 0), EA, exec_map, (EA) + (N)))
|
||||
|
||||
|
||||
/* FIXME: For moment, save/restore PC value found in struct State.
|
||||
Struct State will one day go away, being placed in the sim_cpu
|
||||
state. */
|
||||
|
||||
struct _sim_cpu {
|
||||
sim_event *pending_nmi;
|
||||
sim_cia cia;
|
||||
sim_cpu_base base;
|
||||
};
|
||||
|
||||
/* For compatibility, until all functions converted to passing
|
||||
SIM_DESC as an argument */
|
||||
extern SIM_DESC simulator;
|
||||
|
||||
@@ -127,7 +127,7 @@ struct moxie_regset
|
||||
#define CC_GTU 1<<3
|
||||
#define CC_LTU 1<<4
|
||||
|
||||
/* TODO: This should be moved to sim-main.h:_sim_cpu. */
|
||||
/* TODO: This should be moved to sim-main.h:moxie_sim_cpu. */
|
||||
union
|
||||
{
|
||||
struct moxie_regset asregs;
|
||||
@@ -1173,13 +1173,13 @@ moxie_reg_fetch (SIM_CPU *scpu, int rn, void *memory, int length)
|
||||
static sim_cia
|
||||
moxie_pc_get (sim_cpu *cpu)
|
||||
{
|
||||
return cpu->registers[PCIDX];
|
||||
return MOXIE_SIM_CPU (cpu)->registers[PCIDX];
|
||||
}
|
||||
|
||||
static void
|
||||
moxie_pc_set (sim_cpu *cpu, sim_cia pc)
|
||||
{
|
||||
cpu->registers[PCIDX] = pc;
|
||||
MOXIE_SIM_CPU (cpu)->registers[PCIDX] = pc;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1203,7 +1203,8 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb,
|
||||
current_target_byte_order = BFD_ENDIAN_BIG;
|
||||
|
||||
/* The cpu data is kept in a separately allocated chunk of memory. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct moxie_sim_cpu))
|
||||
!= SIM_RC_OK)
|
||||
{
|
||||
free_state (sd);
|
||||
return 0;
|
||||
|
||||
@@ -26,17 +26,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define PCIDX 17
|
||||
|
||||
struct _sim_cpu {
|
||||
|
||||
/* The following are internal simulator state variables: */
|
||||
|
||||
/* To keep this default simulator simple, and fast, we use a direct
|
||||
vector of registers. The internal simulator engine then uses
|
||||
manifests to access the correct slot. */
|
||||
|
||||
struct moxie_sim_cpu {
|
||||
/* To keep this default simulator simple, and fast, we use a direct
|
||||
vector of registers. The internal simulator engine then uses
|
||||
manifests to access the correct slot. */
|
||||
unsigned_word registers[19];
|
||||
|
||||
sim_cpu_base base;
|
||||
};
|
||||
|
||||
#define MOXIE_SIM_CPU(cpu) ((struct moxie_sim_cpu *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
#endif
|
||||
|
||||
@@ -36,32 +36,37 @@
|
||||
static sim_cia
|
||||
msp430_pc_fetch (SIM_CPU *cpu)
|
||||
{
|
||||
return cpu->state.regs[0];
|
||||
struct msp430_cpu_state *msp430_cpu = MSP430_SIM_CPU (cpu);
|
||||
|
||||
return msp430_cpu->regs[0];
|
||||
}
|
||||
|
||||
static void
|
||||
msp430_pc_store (SIM_CPU *cpu, sim_cia newpc)
|
||||
{
|
||||
cpu->state.regs[0] = newpc;
|
||||
struct msp430_cpu_state *msp430_cpu = MSP430_SIM_CPU (cpu);
|
||||
|
||||
msp430_cpu->regs[0] = newpc;
|
||||
}
|
||||
|
||||
static int
|
||||
msp430_reg_fetch (SIM_CPU *cpu, int regno, void *buf, int len)
|
||||
{
|
||||
struct msp430_cpu_state *msp430_cpu = MSP430_SIM_CPU (cpu);
|
||||
unsigned char *memory = buf;
|
||||
|
||||
if (0 <= regno && regno < 16)
|
||||
{
|
||||
if (len == 2)
|
||||
{
|
||||
int val = cpu->state.regs[regno];
|
||||
int val = msp430_cpu->regs[regno];
|
||||
memory[0] = val & 0xff;
|
||||
memory[1] = (val >> 8) & 0xff;
|
||||
return 0;
|
||||
}
|
||||
else if (len == 4)
|
||||
{
|
||||
int val = cpu->state.regs[regno];
|
||||
int val = msp430_cpu->regs[regno];
|
||||
memory[0] = val & 0xff;
|
||||
memory[1] = (val >> 8) & 0xff;
|
||||
memory[2] = (val >> 16) & 0x0f; /* Registers are only 20 bits wide. */
|
||||
@@ -78,20 +83,21 @@ msp430_reg_fetch (SIM_CPU *cpu, int regno, void *buf, int len)
|
||||
static int
|
||||
msp430_reg_store (SIM_CPU *cpu, int regno, const void *buf, int len)
|
||||
{
|
||||
struct msp430_cpu_state *msp430_cpu = MSP430_SIM_CPU (cpu);
|
||||
const unsigned char *memory = buf;
|
||||
|
||||
if (0 <= regno && regno < 16)
|
||||
{
|
||||
if (len == 2)
|
||||
{
|
||||
cpu->state.regs[regno] = (memory[1] << 8) | memory[0];
|
||||
msp430_cpu->regs[regno] = (memory[1] << 8) | memory[0];
|
||||
return len;
|
||||
}
|
||||
|
||||
if (len == 4)
|
||||
{
|
||||
cpu->state.regs[regno] = ((memory[2] << 16) & 0xf0000)
|
||||
| (memory[1] << 8) | memory[0];
|
||||
msp430_cpu->regs[regno] = ((memory[2] << 16) & 0xf0000)
|
||||
| (memory[1] << 8) | memory[0];
|
||||
return len;
|
||||
}
|
||||
}
|
||||
@@ -99,12 +105,6 @@ msp430_reg_store (SIM_CPU *cpu, int regno, const void *buf, int len)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
msp430_initialize_cpu (SIM_DESC sd, SIM_CPU *cpu)
|
||||
{
|
||||
memset (&cpu->state, 0, sizeof (cpu->state));
|
||||
}
|
||||
|
||||
SIM_DESC
|
||||
sim_open (SIM_OPEN_KIND kind,
|
||||
struct host_callback_struct *callback,
|
||||
@@ -112,6 +112,7 @@ sim_open (SIM_OPEN_KIND kind,
|
||||
char * const *argv)
|
||||
{
|
||||
SIM_DESC sd = sim_state_alloc (kind, callback);
|
||||
struct msp430_cpu_state *msp430_cpu;
|
||||
char c;
|
||||
|
||||
/* Initialise the simulator. */
|
||||
@@ -119,7 +120,8 @@ sim_open (SIM_OPEN_KIND kind,
|
||||
/* Set default options before parsing user options. */
|
||||
current_target_byte_order = BFD_ENDIAN_LITTLE;
|
||||
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct msp430_cpu_state))
|
||||
!= SIM_RC_OK)
|
||||
{
|
||||
sim_state_free (sd);
|
||||
return 0;
|
||||
@@ -137,22 +139,22 @@ sim_open (SIM_OPEN_KIND kind,
|
||||
return 0;
|
||||
}
|
||||
|
||||
CPU_PC_FETCH (MSP430_CPU (sd)) = msp430_pc_fetch;
|
||||
CPU_PC_STORE (MSP430_CPU (sd)) = msp430_pc_store;
|
||||
CPU_REG_FETCH (MSP430_CPU (sd)) = msp430_reg_fetch;
|
||||
CPU_REG_STORE (MSP430_CPU (sd)) = msp430_reg_store;
|
||||
CPU_PC_FETCH (STATE_CPU (sd, 0)) = msp430_pc_fetch;
|
||||
CPU_PC_STORE (STATE_CPU (sd, 0)) = msp430_pc_store;
|
||||
CPU_REG_FETCH (STATE_CPU (sd, 0)) = msp430_reg_fetch;
|
||||
CPU_REG_STORE (STATE_CPU (sd, 0)) = msp430_reg_store;
|
||||
|
||||
/* Allocate memory if none specified by user.
|
||||
Note - these values match the memory regions in the libgloss/msp430/msp430[xl]-sim.ld scripts. */
|
||||
if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x2, 1) == 0)
|
||||
if (sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, &c, 0x2, 1) == 0)
|
||||
sim_do_commandf (sd, "memory-region 0,0x20"); /* Needed by the GDB testsuite. */
|
||||
if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x500, 1) == 0)
|
||||
if (sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, &c, 0x500, 1) == 0)
|
||||
sim_do_commandf (sd, "memory-region 0x500,0xfac0"); /* RAM and/or ROM */
|
||||
if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0xfffe, 1) == 0)
|
||||
if (sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, &c, 0xfffe, 1) == 0)
|
||||
sim_do_commandf (sd, "memory-region 0xffc0,0x40"); /* VECTORS. */
|
||||
if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x10000, 1) == 0)
|
||||
if (sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, &c, 0x10000, 1) == 0)
|
||||
sim_do_commandf (sd, "memory-region 0x10000,0x80000"); /* HIGH FLASH RAM. */
|
||||
if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x90000, 1) == 0)
|
||||
if (sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, &c, 0x90000, 1) == 0)
|
||||
sim_do_commandf (sd, "memory-region 0x90000,0x70000"); /* HIGH ROM. */
|
||||
|
||||
/* Check for/establish the a reference program image. */
|
||||
@@ -177,12 +179,12 @@ sim_open (SIM_OPEN_KIND kind,
|
||||
|
||||
/* CPU specific initialization. */
|
||||
assert (MAX_NR_PROCESSORS == 1);
|
||||
msp430_initialize_cpu (sd, MSP430_CPU (sd));
|
||||
|
||||
MSP430_CPU (sd)->state.cio_breakpoint = trace_sym_value (sd, "C$$IO$$");
|
||||
MSP430_CPU (sd)->state.cio_buffer = trace_sym_value (sd, "__CIOBUF__");
|
||||
if (MSP430_CPU (sd)->state.cio_buffer == -1)
|
||||
MSP430_CPU (sd)->state.cio_buffer = trace_sym_value (sd, "_CIOBUF_");
|
||||
msp430_cpu = MSP430_SIM_CPU (STATE_CPU (sd, 0));
|
||||
msp430_cpu->cio_breakpoint = trace_sym_value (sd, "C$$IO$$");
|
||||
msp430_cpu->cio_buffer = trace_sym_value (sd, "__CIOBUF__");
|
||||
if (msp430_cpu->cio_buffer == -1)
|
||||
msp430_cpu->cio_buffer = trace_sym_value (sd, "_CIOBUF_");
|
||||
|
||||
return sd;
|
||||
}
|
||||
@@ -198,15 +200,15 @@ sim_create_inferior (SIM_DESC sd,
|
||||
int new_pc;
|
||||
|
||||
/* Set the PC to the default reset vector if available. */
|
||||
c = sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, resetv, 0xfffe, 2);
|
||||
c = sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, resetv, 0xfffe, 2);
|
||||
new_pc = resetv[0] + 256 * resetv[1];
|
||||
|
||||
/* If the reset vector isn't initialized, then use the ELF entry. */
|
||||
if (abfd != NULL && !new_pc)
|
||||
new_pc = bfd_get_start_address (abfd);
|
||||
|
||||
sim_pc_set (MSP430_CPU (sd), new_pc);
|
||||
msp430_pc_store (MSP430_CPU (sd), new_pc);
|
||||
sim_pc_set (STATE_CPU (sd, 0), new_pc);
|
||||
msp430_pc_store (STATE_CPU (sd, 0), new_pc);
|
||||
|
||||
return SIM_RC_OK;
|
||||
}
|
||||
@@ -224,12 +226,12 @@ msp430_getbyte (void *vld)
|
||||
char buf[1];
|
||||
SIM_DESC sd = ld->sd;
|
||||
|
||||
sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, ld->gb_addr, 1);
|
||||
sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, buf, ld->gb_addr, 1);
|
||||
ld->gb_addr ++;
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
#define REG(N) MSP430_CPU (sd)->state.regs[(N)]
|
||||
#define REG(N) MSP430_SIM_CPU (STATE_CPU (sd, 0))->regs[N]
|
||||
#define PC REG(MSR_PC)
|
||||
#define SP REG(MSR_SP)
|
||||
#define SR REG(MSR_SR)
|
||||
@@ -244,14 +246,14 @@ register_names[] =
|
||||
static void
|
||||
trace_reg_put (SIM_DESC sd, int n, unsigned int v)
|
||||
{
|
||||
TRACE_REGISTER (MSP430_CPU (sd), "PUT: %#x -> %s", v, register_names[n]);
|
||||
TRACE_REGISTER (STATE_CPU (sd, 0), "PUT: %#x -> %s", v, register_names[n]);
|
||||
REG (n) = v;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
trace_reg_get (SIM_DESC sd, int n)
|
||||
{
|
||||
TRACE_REGISTER (MSP430_CPU (sd), "GET: %s -> %#x", register_names[n], REG (n));
|
||||
TRACE_REGISTER (STATE_CPU (sd, 0), "GET: %s -> %#x", register_names[n], REG (n));
|
||||
return REG (n);
|
||||
}
|
||||
|
||||
@@ -326,16 +328,16 @@ get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n)
|
||||
switch (opc->size)
|
||||
{
|
||||
case 8:
|
||||
sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 1);
|
||||
sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, buf, addr, 1);
|
||||
rv = buf[0];
|
||||
break;
|
||||
case 16:
|
||||
sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 2);
|
||||
sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, buf, addr, 2);
|
||||
rv = buf[0] | (buf[1] << 8);
|
||||
break;
|
||||
case 20:
|
||||
case 32:
|
||||
sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 4);
|
||||
sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, buf, addr, 4);
|
||||
rv = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
|
||||
break;
|
||||
default:
|
||||
@@ -432,7 +434,7 @@ get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n)
|
||||
}
|
||||
}
|
||||
|
||||
TRACE_MEMORY (MSP430_CPU (sd), "GET: [%#x].%d -> %#x", addr, opc->size,
|
||||
TRACE_MEMORY (STATE_CPU (sd, 0), "GET: [%#x].%d -> %#x", addr, opc->size,
|
||||
rv);
|
||||
break;
|
||||
|
||||
@@ -525,7 +527,7 @@ put_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n, int val)
|
||||
}
|
||||
addr &= 0xfffff;
|
||||
|
||||
TRACE_MEMORY (MSP430_CPU (sd), "PUT: [%#x].%d <- %#x", addr, opc->size,
|
||||
TRACE_MEMORY (STATE_CPU (sd, 0), "PUT: [%#x].%d <- %#x", addr, opc->size,
|
||||
val);
|
||||
#if 0
|
||||
/* Hack - MSP430X5438 serial port transmit register. */
|
||||
@@ -685,12 +687,12 @@ put_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n, int val)
|
||||
{
|
||||
case 8:
|
||||
buf[0] = val;
|
||||
sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 1);
|
||||
sim_core_write_buffer (sd, STATE_CPU (sd, 0), write_map, buf, addr, 1);
|
||||
break;
|
||||
case 16:
|
||||
buf[0] = val;
|
||||
buf[1] = val >> 8;
|
||||
sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 2);
|
||||
sim_core_write_buffer (sd, STATE_CPU (sd, 0), write_map, buf, addr, 2);
|
||||
break;
|
||||
case 20:
|
||||
case 32:
|
||||
@@ -698,7 +700,7 @@ put_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n, int val)
|
||||
buf[1] = val >> 8;
|
||||
buf[2] = val >> 16;
|
||||
buf[3] = val >> 24;
|
||||
sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 4);
|
||||
sim_core_write_buffer (sd, STATE_CPU (sd, 0), write_map, buf, addr, 4);
|
||||
break;
|
||||
default:
|
||||
assert (! opc->size);
|
||||
@@ -787,7 +789,8 @@ msp430_cio (SIM_DESC sd)
|
||||
{
|
||||
/* A block of data at __CIOBUF__ describes the I/O operation to
|
||||
perform. */
|
||||
|
||||
sim_cpu *cpu = STATE_CPU (sd, 0);
|
||||
struct msp430_cpu_state *msp430_cpu = MSP430_SIM_CPU (cpu);
|
||||
unsigned char raw_parms[13];
|
||||
unsigned char parms[8];
|
||||
long length;
|
||||
@@ -796,16 +799,12 @@ msp430_cio (SIM_DESC sd)
|
||||
long ret_buflen = 0;
|
||||
long fd, addr, len, rv;
|
||||
|
||||
sim_core_read_buffer (sd, MSP430_CPU (sd), 0, parms,
|
||||
MSP430_CPU (sd)->state.cio_buffer, 5);
|
||||
sim_core_read_buffer (sd, cpu, 0, parms, msp430_cpu->cio_buffer, 5);
|
||||
length = CIO_I (0);
|
||||
command = parms[2];
|
||||
|
||||
sim_core_read_buffer (sd, MSP430_CPU (sd), 0, parms,
|
||||
MSP430_CPU (sd)->state.cio_buffer + 3, 8);
|
||||
|
||||
sim_core_read_buffer (sd, MSP430_CPU (sd), 0, buffer,
|
||||
MSP430_CPU (sd)->state.cio_buffer + 11, length);
|
||||
sim_core_read_buffer (sd, cpu, 0, parms, msp430_cpu->cio_buffer + 3, 8);
|
||||
sim_core_read_buffer (sd, cpu, 0, buffer, msp430_cpu->cio_buffer + 11, length);
|
||||
|
||||
switch (command)
|
||||
{
|
||||
@@ -820,11 +819,10 @@ msp430_cio (SIM_DESC sd)
|
||||
break;
|
||||
}
|
||||
|
||||
sim_core_write_buffer (sd, MSP430_CPU (sd), 0, parms,
|
||||
MSP430_CPU (sd)->state.cio_buffer + 4, 8);
|
||||
sim_core_write_buffer (sd, cpu, 0, parms, msp430_cpu->cio_buffer + 4, 8);
|
||||
if (ret_buflen)
|
||||
sim_core_write_buffer (sd, MSP430_CPU (sd), 0, buffer,
|
||||
MSP430_CPU (sd)->state.cio_buffer + 12, ret_buflen);
|
||||
sim_core_write_buffer (sd, cpu, 0, buffer, msp430_cpu->cio_buffer + 12,
|
||||
ret_buflen);
|
||||
}
|
||||
|
||||
#define SRC get_op (sd, opcode, 1)
|
||||
@@ -836,7 +834,7 @@ msp430_cio (SIM_DESC sd)
|
||||
int s1 = DSRC; \
|
||||
int s2 = SRC; \
|
||||
int result = s1 OP s2 MORE; \
|
||||
TRACE_ALU (MSP430_CPU (sd), "ALU: %#x %s %#x %s = %#x", s1, SOP, \
|
||||
TRACE_ALU (STATE_CPU (sd, 0), "ALU: %#x %s %#x %s = %#x", s1, SOP, \
|
||||
s2, #MORE, result); \
|
||||
DEST (result); \
|
||||
}
|
||||
@@ -900,10 +898,10 @@ do_flags (SIM_DESC sd,
|
||||
|
||||
new_f = f | (new_f & opcode->flags_set);
|
||||
if (SR != new_f)
|
||||
TRACE_ALU (MSP430_CPU (sd), "FLAGS: %s -> %s", flags2string (SR),
|
||||
TRACE_ALU (STATE_CPU (sd, 0), "FLAGS: %s -> %s", flags2string (SR),
|
||||
flags2string (new_f));
|
||||
else
|
||||
TRACE_ALU (MSP430_CPU (sd), "FLAGS: %s", flags2string (new_f));
|
||||
TRACE_ALU (STATE_CPU (sd, 0), "FLAGS: %s", flags2string (new_f));
|
||||
SR = new_f;
|
||||
}
|
||||
|
||||
@@ -966,6 +964,9 @@ cond_string (int cond)
|
||||
static int
|
||||
maybe_perform_syscall (SIM_DESC sd, int call_addr)
|
||||
{
|
||||
sim_cpu *cpu = STATE_CPU (sd, 0);
|
||||
struct msp430_cpu_state *msp430_cpu = MSP430_SIM_CPU (cpu);
|
||||
|
||||
if (call_addr == 0x00160)
|
||||
{
|
||||
int i;
|
||||
@@ -974,13 +975,13 @@ maybe_perform_syscall (SIM_DESC sd, int call_addr)
|
||||
{
|
||||
if (i % 4 == 0)
|
||||
fprintf (stderr, "\t");
|
||||
fprintf (stderr, "R%-2d %05x ", i, MSP430_CPU (sd)->state.regs[i]);
|
||||
fprintf (stderr, "R%-2d %05x ", i, msp430_cpu->regs[i]);
|
||||
if (i % 4 == 3)
|
||||
{
|
||||
int sp = SP + (3 - (i / 4)) * 2;
|
||||
unsigned char buf[2];
|
||||
|
||||
sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, sp, 2);
|
||||
sim_core_read_buffer (sd, cpu, read_map, buf, sp, 2);
|
||||
|
||||
fprintf (stderr, "\tSP%+d: %04x", sp - SP,
|
||||
buf[0] + buf[1] * 256);
|
||||
@@ -1012,22 +1013,21 @@ maybe_perform_syscall (SIM_DESC sd, int call_addr)
|
||||
See slaa534.pdf distributed by TI. */
|
||||
if (syscall_num == 2)
|
||||
{
|
||||
arg1 = MSP430_CPU (sd)->state.regs[12];
|
||||
arg1 = msp430_cpu->regs[12];
|
||||
arg2 = mem_get_val (sd, SP, 16);
|
||||
arg3 = mem_get_val (sd, SP + 2, 16);
|
||||
arg4 = mem_get_val (sd, SP + 4, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
arg1 = MSP430_CPU (sd)->state.regs[12];
|
||||
arg2 = MSP430_CPU (sd)->state.regs[13];
|
||||
arg3 = MSP430_CPU (sd)->state.regs[14];
|
||||
arg4 = MSP430_CPU (sd)->state.regs[15];
|
||||
arg1 = msp430_cpu->regs[12];
|
||||
arg2 = msp430_cpu->regs[13];
|
||||
arg3 = msp430_cpu->regs[14];
|
||||
arg4 = msp430_cpu->regs[15];
|
||||
}
|
||||
|
||||
MSP430_CPU (sd)->state.regs[12] = sim_syscall (MSP430_CPU (sd),
|
||||
syscall_num, arg1, arg2,
|
||||
arg3, arg4);
|
||||
msp430_cpu->regs[12] = sim_syscall (cpu, syscall_num, arg1, arg2, arg3,
|
||||
arg4);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1037,6 +1037,8 @@ maybe_perform_syscall (SIM_DESC sd, int call_addr)
|
||||
static void
|
||||
msp430_step_once (SIM_DESC sd)
|
||||
{
|
||||
sim_cpu *cpu = STATE_CPU (sd, 0);
|
||||
struct msp430_cpu_state *msp430_cpu = MSP430_SIM_CPU (cpu);
|
||||
Get_Byte_Local_Data ld;
|
||||
unsigned char buf[100];
|
||||
int i;
|
||||
@@ -1059,32 +1061,27 @@ msp430_step_once (SIM_DESC sd)
|
||||
if (opcode_pc < 0x10)
|
||||
{
|
||||
fprintf (stderr, "Fault: PC(%#x) is less than 0x10\n", opcode_pc);
|
||||
sim_engine_halt (sd, MSP430_CPU (sd), NULL,
|
||||
MSP430_CPU (sd)->state.regs[0],
|
||||
sim_exited, -1);
|
||||
sim_engine_halt (sd, cpu, NULL, msp430_cpu->regs[0], sim_exited, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (PC == MSP430_CPU (sd)->state.cio_breakpoint
|
||||
&& STATE_OPEN_KIND (sd) != SIM_OPEN_DEBUG)
|
||||
if (PC == msp430_cpu->cio_breakpoint && STATE_OPEN_KIND (sd) != SIM_OPEN_DEBUG)
|
||||
msp430_cio (sd);
|
||||
|
||||
ld.sd = sd;
|
||||
ld.gb_addr = PC;
|
||||
opsize = msp430_decode_opcode (MSP430_CPU (sd)->state.regs[0],
|
||||
opcode, msp430_getbyte, &ld);
|
||||
opsize = msp430_decode_opcode (msp430_cpu->regs[0], opcode, msp430_getbyte,
|
||||
&ld);
|
||||
PC += opsize;
|
||||
if (opsize <= 0)
|
||||
{
|
||||
fprintf (stderr, "Fault: undecodable opcode at %#x\n", opcode_pc);
|
||||
sim_engine_halt (sd, MSP430_CPU (sd), NULL,
|
||||
MSP430_CPU (sd)->state.regs[0],
|
||||
sim_exited, -1);
|
||||
sim_engine_halt (sd, cpu, NULL, msp430_cpu->regs[0], sim_exited, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (opcode->repeat_reg)
|
||||
n_repeats = (MSP430_CPU (sd)->state.regs[opcode->repeats] & 0x000f) + 1;
|
||||
n_repeats = (msp430_cpu->regs[opcode->repeats] & 0x000f) + 1;
|
||||
else
|
||||
n_repeats = opcode->repeats + 1;
|
||||
|
||||
@@ -1103,11 +1100,11 @@ msp430_step_once (SIM_DESC sd)
|
||||
break;
|
||||
}
|
||||
|
||||
if (TRACE_ANY_P (MSP430_CPU (sd)))
|
||||
trace_prefix (sd, MSP430_CPU (sd), NULL_CIA, opcode_pc,
|
||||
TRACE_LINENUM_P (MSP430_CPU (sd)), NULL, 0, " ");
|
||||
if (TRACE_ANY_P (cpu))
|
||||
trace_prefix (sd, cpu, NULL_CIA, opcode_pc, TRACE_LINENUM_P (cpu), NULL,
|
||||
0, " ");
|
||||
|
||||
TRACE_DISASM (MSP430_CPU (sd), opcode_pc);
|
||||
TRACE_DISASM (cpu, opcode_pc);
|
||||
|
||||
carry_to_use = 0;
|
||||
switch (opcode->id)
|
||||
@@ -1127,10 +1124,8 @@ msp430_step_once (SIM_DESC sd)
|
||||
{
|
||||
/* This is the designated software breakpoint instruction. */
|
||||
PC -= opsize;
|
||||
sim_engine_halt (sd, MSP430_CPU (sd), NULL,
|
||||
MSP430_CPU (sd)->state.regs[0],
|
||||
sim_stopped, SIM_SIGTRAP);
|
||||
|
||||
sim_engine_halt (sd, cpu, NULL, msp430_cpu->regs[0], sim_stopped,
|
||||
SIM_SIGTRAP);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1152,7 +1147,7 @@ msp430_step_once (SIM_DESC sd)
|
||||
s2 = SX (u2);
|
||||
uresult = u1 + u2 + carry_to_use;
|
||||
result = s1 + s2 + carry_to_use;
|
||||
TRACE_ALU (MSP430_CPU (sd), "ADDC: %#x + %#x + %d = %#x",
|
||||
TRACE_ALU (cpu, "ADDC: %#x + %#x + %d = %#x",
|
||||
u1, u2, carry_to_use, uresult);
|
||||
DEST (result);
|
||||
FLAGS (result, uresult != ZX (uresult));
|
||||
@@ -1168,8 +1163,7 @@ msp430_step_once (SIM_DESC sd)
|
||||
s2 = SX (u2);
|
||||
uresult = u1 + u2;
|
||||
result = s1 + s2;
|
||||
TRACE_ALU (MSP430_CPU (sd), "ADD: %#x + %#x = %#x",
|
||||
u1, u2, uresult);
|
||||
TRACE_ALU (cpu, "ADD: %#x + %#x = %#x", u1, u2, uresult);
|
||||
DEST (result);
|
||||
FLAGS (result, uresult != ZX (uresult));
|
||||
}
|
||||
@@ -1185,7 +1179,7 @@ msp430_step_once (SIM_DESC sd)
|
||||
s2 = SX (u2);
|
||||
uresult = ZX (~u2) + u1 + carry_to_use;
|
||||
result = s1 - s2 + (carry_to_use - 1);
|
||||
TRACE_ALU (MSP430_CPU (sd), "SUBC: %#x - %#x + %d = %#x",
|
||||
TRACE_ALU (cpu, "SUBC: %#x - %#x + %d = %#x",
|
||||
u1, u2, carry_to_use, uresult);
|
||||
DEST (result);
|
||||
FLAGS (result, uresult != ZX (uresult));
|
||||
@@ -1201,7 +1195,7 @@ msp430_step_once (SIM_DESC sd)
|
||||
s2 = SX (u2);
|
||||
uresult = ZX (~u2) + u1 + 1;
|
||||
result = SX (uresult);
|
||||
TRACE_ALU (MSP430_CPU (sd), "SUB: %#x - %#x = %#x",
|
||||
TRACE_ALU (cpu, "SUB: %#x - %#x = %#x",
|
||||
u1, u2, uresult);
|
||||
DEST (result);
|
||||
FLAGS (result, uresult != ZX (uresult));
|
||||
@@ -1217,7 +1211,7 @@ msp430_step_once (SIM_DESC sd)
|
||||
s2 = SX (u2);
|
||||
uresult = ZX (~u2) + u1 + 1;
|
||||
result = s1 - s2;
|
||||
TRACE_ALU (MSP430_CPU (sd), "CMP: %#x - %#x = %x",
|
||||
TRACE_ALU (cpu, "CMP: %#x - %#x = %x",
|
||||
u1, u2, uresult);
|
||||
FLAGS (result, uresult != ZX (uresult));
|
||||
}
|
||||
@@ -1231,7 +1225,7 @@ msp430_step_once (SIM_DESC sd)
|
||||
u2 = SRC;
|
||||
uresult = bcd_to_binary (u1) + bcd_to_binary (u2) + carry_to_use;
|
||||
result = binary_to_bcd (uresult);
|
||||
TRACE_ALU (MSP430_CPU (sd), "DADD: %#x + %#x + %d = %#x",
|
||||
TRACE_ALU (cpu, "DADD: %#x + %#x + %d = %#x",
|
||||
u1, u2, carry_to_use, result);
|
||||
DEST (result);
|
||||
FLAGS (result, uresult > ((opcode->size == 8) ? 99 : 9999));
|
||||
@@ -1244,7 +1238,7 @@ msp430_step_once (SIM_DESC sd)
|
||||
u1 = DSRC;
|
||||
u2 = SRC;
|
||||
uresult = u1 & u2;
|
||||
TRACE_ALU (MSP430_CPU (sd), "AND: %#x & %#x = %#x",
|
||||
TRACE_ALU (cpu, "AND: %#x & %#x = %#x",
|
||||
u1, u2, uresult);
|
||||
DEST (uresult);
|
||||
FLAGS (uresult, uresult != 0);
|
||||
@@ -1257,7 +1251,7 @@ msp430_step_once (SIM_DESC sd)
|
||||
u1 = DSRC;
|
||||
u2 = SRC;
|
||||
uresult = u1 & u2;
|
||||
TRACE_ALU (MSP430_CPU (sd), "BIT: %#x & %#x -> %#x",
|
||||
TRACE_ALU (cpu, "BIT: %#x & %#x -> %#x",
|
||||
u1, u2, uresult);
|
||||
FLAGS (uresult, uresult != 0);
|
||||
}
|
||||
@@ -1269,7 +1263,7 @@ msp430_step_once (SIM_DESC sd)
|
||||
u1 = DSRC;
|
||||
u2 = SRC;
|
||||
uresult = u1 & ~ u2;
|
||||
TRACE_ALU (MSP430_CPU (sd), "BIC: %#x & ~ %#x = %#x",
|
||||
TRACE_ALU (cpu, "BIC: %#x & ~ %#x = %#x",
|
||||
u1, u2, uresult);
|
||||
DEST (uresult);
|
||||
}
|
||||
@@ -1281,7 +1275,7 @@ msp430_step_once (SIM_DESC sd)
|
||||
u1 = DSRC;
|
||||
u2 = SRC;
|
||||
uresult = u1 | u2;
|
||||
TRACE_ALU (MSP430_CPU (sd), "BIS: %#x | %#x = %#x",
|
||||
TRACE_ALU (cpu, "BIS: %#x | %#x = %#x",
|
||||
u1, u2, uresult);
|
||||
DEST (uresult);
|
||||
}
|
||||
@@ -1294,7 +1288,7 @@ msp430_step_once (SIM_DESC sd)
|
||||
u1 = DSRC;
|
||||
u2 = SRC;
|
||||
uresult = u1 ^ u2;
|
||||
TRACE_ALU (MSP430_CPU (sd), "XOR: %#x & %#x = %#x",
|
||||
TRACE_ALU (cpu, "XOR: %#x & %#x = %#x",
|
||||
u1, u2, uresult);
|
||||
DEST (uresult);
|
||||
FLAGSV (uresult, uresult != 0, (u1 & s1) && (u2 & s1));
|
||||
@@ -1314,7 +1308,7 @@ msp430_step_once (SIM_DESC sd)
|
||||
RRUX, so the carry bit must be ignored. */
|
||||
if (opcode->zc == 0 && (SR & MSP430_FLAG_C))
|
||||
uresult |= (1 << (opcode->size - 1));
|
||||
TRACE_ALU (MSP430_CPU (sd), "RRC: %#x >>= %#x",
|
||||
TRACE_ALU (cpu, "RRC: %#x >>= %#x",
|
||||
u1, uresult);
|
||||
DEST (uresult);
|
||||
FLAGS (uresult, carry_to_use);
|
||||
@@ -1326,7 +1320,7 @@ msp430_step_once (SIM_DESC sd)
|
||||
{
|
||||
u1 = SRC;
|
||||
uresult = ((u1 >> 8) & 0x00ff) | ((u1 << 8) & 0xff00);
|
||||
TRACE_ALU (MSP430_CPU (sd), "SWPB: %#x -> %#x",
|
||||
TRACE_ALU (cpu, "SWPB: %#x -> %#x",
|
||||
u1, uresult);
|
||||
DEST (uresult);
|
||||
}
|
||||
@@ -1339,7 +1333,7 @@ msp430_step_once (SIM_DESC sd)
|
||||
c = u1 & 1;
|
||||
s1 = 1 << (opcode->size - 1);
|
||||
uresult = (u1 >> 1) | (u1 & s1);
|
||||
TRACE_ALU (MSP430_CPU (sd), "RRA: %#x >>= %#x",
|
||||
TRACE_ALU (cpu, "RRA: %#x >>= %#x",
|
||||
u1, uresult);
|
||||
DEST (uresult);
|
||||
FLAGS (uresult, c);
|
||||
@@ -1352,7 +1346,7 @@ msp430_step_once (SIM_DESC sd)
|
||||
u1 = SRC;
|
||||
c = u1 & 1;
|
||||
uresult = (u1 >> 1);
|
||||
TRACE_ALU (MSP430_CPU (sd), "RRU: %#x >>= %#x",
|
||||
TRACE_ALU (cpu, "RRU: %#x >>= %#x",
|
||||
u1, uresult);
|
||||
DEST (uresult);
|
||||
FLAGS (uresult, c);
|
||||
@@ -1367,8 +1361,7 @@ msp430_step_once (SIM_DESC sd)
|
||||
uresult = u1 | 0xfff00;
|
||||
else
|
||||
uresult = u1 & 0x000ff;
|
||||
TRACE_ALU (MSP430_CPU (sd), "SXT: %#x -> %#x",
|
||||
u1, uresult);
|
||||
TRACE_ALU (cpu, "SXT: %#x -> %#x", u1, uresult);
|
||||
DEST (uresult);
|
||||
FLAGS (uresult, c);
|
||||
}
|
||||
@@ -1416,7 +1409,7 @@ msp430_step_once (SIM_DESC sd)
|
||||
|
||||
REG_PUT (MSR_SP, REG_GET (MSR_SP) - op_bytes);
|
||||
mem_put_val (sd, SP, PC, op_bits);
|
||||
TRACE_ALU (MSP430_CPU (sd), "CALL: func %#x ret %#x, sp %#x",
|
||||
TRACE_ALU (cpu, "CALL: func %#x ret %#x, sp %#x",
|
||||
u1, PC, SP);
|
||||
REG_PUT (MSR_PC, u1);
|
||||
break;
|
||||
@@ -1432,8 +1425,7 @@ msp430_step_once (SIM_DESC sd)
|
||||
8-bits of SR will have been written to the stack here, and will
|
||||
have been read as 0. */
|
||||
PC |= (u1 & 0xF000) << 4;
|
||||
TRACE_ALU (MSP430_CPU (sd), "RETI: pc %#x sr %#x",
|
||||
PC, SR);
|
||||
TRACE_ALU (cpu, "RETI: pc %#x sr %#x", PC, SR);
|
||||
break;
|
||||
|
||||
/* Jumps. */
|
||||
@@ -1470,14 +1462,14 @@ msp430_step_once (SIM_DESC sd)
|
||||
|
||||
if (u1)
|
||||
{
|
||||
TRACE_BRANCH (MSP430_CPU (sd), "J%s: pc %#x -> %#x sr %#x, taken",
|
||||
TRACE_BRANCH (cpu, "J%s: pc %#x -> %#x sr %#x, taken",
|
||||
cond_string (opcode->cond), PC, i, SR);
|
||||
PC = i;
|
||||
if (PC == opcode_pc)
|
||||
exit (0);
|
||||
}
|
||||
else
|
||||
TRACE_BRANCH (MSP430_CPU (sd), "J%s: pc %#x to %#x sr %#x, not taken",
|
||||
TRACE_BRANCH (cpu, "J%s: pc %#x to %#x sr %#x, not taken",
|
||||
cond_string (opcode->cond), PC, i, SR);
|
||||
break;
|
||||
|
||||
|
||||
@@ -44,6 +44,6 @@ struct msp430_cpu_state
|
||||
uint64_t hw32mult_result;
|
||||
};
|
||||
|
||||
#define HWMULT(SD, FIELD) MSP430_CPU (SD)->state.FIELD
|
||||
#define HWMULT(sd, field) MSP430_SIM_CPU (STATE_CPU (sd, 0))->field
|
||||
|
||||
#endif
|
||||
|
||||
@@ -25,15 +25,7 @@
|
||||
#include "msp430-sim.h"
|
||||
#include "sim-base.h"
|
||||
|
||||
struct _sim_cpu
|
||||
{
|
||||
/* Simulator specific members. */
|
||||
struct msp430_cpu_state state;
|
||||
sim_cpu_base base;
|
||||
};
|
||||
|
||||
#define MSP430_CPU(sd) (STATE_CPU ((sd), 0))
|
||||
#define MSP430_CPU_STATE(sd) (MSP430_CPU ((sd)->state))
|
||||
#define MSP430_SIM_CPU(cpu) ((struct msp430_cpu_state *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
#include "sim-config.h"
|
||||
#include "sim-types.h"
|
||||
|
||||
@@ -72,7 +72,7 @@ SET_H_SPR ((((index)) + (ORSI (SLLSI (SPR_GROUP_SYS, 11), SPR_INDEX_SYS_GPR0))),
|
||||
#define GET_H_ROFF1() CPU (h_roff1)
|
||||
#define SET_H_ROFF1(x) (CPU (h_roff1) = (x))
|
||||
} hardware;
|
||||
#define CPU_CGEN_HW(cpu) (& (cpu)->cpu_data.hardware)
|
||||
#define CPU_CGEN_HW(cpu) (& OR1K_SIM_CPU (cpu)->cpu_data.hardware)
|
||||
} OR1K32BF_CPU_DATA;
|
||||
|
||||
/* Virtual regs. */
|
||||
|
||||
@@ -104,32 +104,40 @@ USI
|
||||
or1k32bf_h_spr_get_raw (sim_cpu *current_cpu, USI addr)
|
||||
{
|
||||
SIM_DESC sd = CPU_STATE (current_cpu);
|
||||
struct or1k_sim_cpu *or1k_cpu = OR1K_SIM_CPU (current_cpu);
|
||||
|
||||
SIM_ASSERT (addr < NUM_SPR);
|
||||
return current_cpu->spr[addr];
|
||||
return or1k_cpu->spr[addr];
|
||||
}
|
||||
|
||||
void
|
||||
or1k32bf_h_spr_set_raw (sim_cpu *current_cpu, USI addr, USI val)
|
||||
{
|
||||
SIM_DESC sd = CPU_STATE (current_cpu);
|
||||
struct or1k_sim_cpu *or1k_cpu = OR1K_SIM_CPU (current_cpu);
|
||||
|
||||
SIM_ASSERT (addr < NUM_SPR);
|
||||
current_cpu->spr[addr] = val;
|
||||
or1k_cpu->spr[addr] = val;
|
||||
}
|
||||
|
||||
USI
|
||||
or1k32bf_h_spr_field_get_raw (sim_cpu *current_cpu, USI addr, int msb, int lsb)
|
||||
{
|
||||
SIM_DESC sd = CPU_STATE (current_cpu);
|
||||
struct or1k_sim_cpu *or1k_cpu = OR1K_SIM_CPU (current_cpu);
|
||||
|
||||
SIM_ASSERT (addr < NUM_SPR);
|
||||
return LSEXTRACTED (current_cpu->spr[addr], msb, lsb);
|
||||
return LSEXTRACTED (or1k_cpu->spr[addr], msb, lsb);
|
||||
}
|
||||
|
||||
void
|
||||
or1k32bf_h_spr_field_set_raw (sim_cpu *current_cpu, USI addr, int msb, int lsb,
|
||||
USI val)
|
||||
{
|
||||
current_cpu->spr[addr] &= ~LSMASK32 (msb, lsb);
|
||||
current_cpu->spr[addr] |= LSINSERTED (val, msb, lsb);
|
||||
struct or1k_sim_cpu *or1k_cpu = OR1K_SIM_CPU (current_cpu);
|
||||
|
||||
or1k_cpu->spr[addr] &= ~LSMASK32 (msb, lsb);
|
||||
or1k_cpu->spr[addr] |= LSINSERTED (val, msb, lsb);
|
||||
}
|
||||
|
||||
/* Initialize a sim cpu object. */
|
||||
@@ -137,6 +145,8 @@ void
|
||||
or1k_cpu_init (SIM_DESC sd, sim_cpu *current_cpu, const USI or1k_vr,
|
||||
const USI or1k_upr, const USI or1k_cpucfgr)
|
||||
{
|
||||
struct or1k_sim_cpu *or1k_cpu = OR1K_SIM_CPU (current_cpu);
|
||||
|
||||
/* Set the configuration registers passed from the user. */
|
||||
SET_H_SYS_VR (or1k_vr);
|
||||
SET_H_SYS_UPR (or1k_upr);
|
||||
@@ -153,8 +163,8 @@ or1k_cpu_init (SIM_DESC sd, sim_cpu *current_cpu, const USI or1k_vr,
|
||||
} while (0)
|
||||
|
||||
/* Set flags indicating if we are in a delay slot or not. */
|
||||
current_cpu->next_delay_slot = 0;
|
||||
current_cpu->delay_slot = 0;
|
||||
or1k_cpu->next_delay_slot = 0;
|
||||
or1k_cpu->delay_slot = 0;
|
||||
|
||||
/* Verify any user passed fields and warn on configurations we don't
|
||||
support. */
|
||||
@@ -202,11 +212,12 @@ void
|
||||
or1k32bf_insn_before (sim_cpu *current_cpu, SEM_PC vpc, const IDESC *idesc)
|
||||
{
|
||||
SIM_DESC sd = CPU_STATE (current_cpu);
|
||||
struct or1k_sim_cpu *or1k_cpu = OR1K_SIM_CPU (current_cpu);
|
||||
|
||||
current_cpu->delay_slot = current_cpu->next_delay_slot;
|
||||
current_cpu->next_delay_slot = 0;
|
||||
or1k_cpu->delay_slot = or1k_cpu->next_delay_slot;
|
||||
or1k_cpu->next_delay_slot = 0;
|
||||
|
||||
if (current_cpu->delay_slot &&
|
||||
if (or1k_cpu->delay_slot &&
|
||||
CGEN_ATTR_BOOLS (CGEN_INSN_ATTRS ((idesc)->idata)) &
|
||||
CGEN_ATTR_MASK (CGEN_INSN_NOT_IN_DELAY_SLOT))
|
||||
{
|
||||
@@ -226,6 +237,7 @@ void
|
||||
or1k32bf_insn_after (sim_cpu *current_cpu, SEM_PC vpc, const IDESC *idesc)
|
||||
{
|
||||
SIM_DESC sd = CPU_STATE (current_cpu);
|
||||
struct or1k_sim_cpu *or1k_cpu = OR1K_SIM_CPU (current_cpu);
|
||||
USI ppc;
|
||||
|
||||
#ifdef WITH_SCACHE
|
||||
@@ -240,8 +252,8 @@ or1k32bf_insn_after (sim_cpu *current_cpu, SEM_PC vpc, const IDESC *idesc)
|
||||
CGEN_ATTR_BOOLS (CGEN_INSN_ATTRS ((idesc)->idata)) &
|
||||
CGEN_ATTR_MASK (CGEN_INSN_DELAYED_CTI))
|
||||
{
|
||||
SIM_ASSERT (!current_cpu->delay_slot);
|
||||
current_cpu->next_delay_slot = 1;
|
||||
SIM_ASSERT (!or1k_cpu->delay_slot);
|
||||
or1k_cpu->next_delay_slot = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -168,7 +168,8 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback, struct bfd *abfd,
|
||||
current_target_byte_order = BFD_ENDIAN_BIG;
|
||||
|
||||
/* The cpu data is kept in a separately allocated chunk of memory. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct or1k_sim_cpu))
|
||||
!= SIM_RC_OK)
|
||||
{
|
||||
free_state (sd);
|
||||
return 0;
|
||||
|
||||
@@ -35,17 +35,10 @@
|
||||
|
||||
#define OR1K_DEFAULT_MEM_SIZE 0x800000 /* 8M */
|
||||
|
||||
/* The _sim_cpu struct. */
|
||||
struct _sim_cpu
|
||||
struct or1k_sim_cpu
|
||||
{
|
||||
/* sim/common cpu base. */
|
||||
sim_cpu_base base;
|
||||
|
||||
/* Static parts of cgen. */
|
||||
CGEN_CPU cgen_cpu;
|
||||
|
||||
OR1K_MISC_PROFILE or1k_misc_profile;
|
||||
#define CPU_OR1K_MISC_PROFILE(cpu) (& (cpu)->or1k_misc_profile)
|
||||
#define CPU_OR1K_MISC_PROFILE(cpu) (& OR1K_SIM_CPU (cpu)->or1k_misc_profile)
|
||||
|
||||
/* CPU specific parts go here.
|
||||
Note that in files that don't need to access these pieces WANT_CPU_FOO
|
||||
@@ -65,5 +58,6 @@ struct _sim_cpu
|
||||
OR1K32BF_CPU_DATA cpu_data;
|
||||
#endif
|
||||
};
|
||||
#define OR1K_SIM_CPU(cpu) ((struct or1k_sim_cpu *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
#endif /* SIM_MAIN_H */
|
||||
|
||||
@@ -123,6 +123,7 @@ void
|
||||
or1k32bf_exception (sim_cpu *current_cpu, USI pc, USI exnum)
|
||||
{
|
||||
SIM_DESC sd = CPU_STATE (current_cpu);
|
||||
struct or1k_sim_cpu *or1k_cpu = OR1K_SIM_CPU (current_cpu);
|
||||
|
||||
if (exnum == EXCEPT_TRAP)
|
||||
{
|
||||
@@ -142,14 +143,14 @@ or1k32bf_exception (sim_cpu *current_cpu, USI pc, USI exnum)
|
||||
|
||||
case EXCEPT_FPE:
|
||||
case EXCEPT_SYSCALL:
|
||||
SET_H_SYS_EPCR0 (pc + 4 - (current_cpu->delay_slot ? 4 : 0));
|
||||
SET_H_SYS_EPCR0 (pc + 4 - (or1k_cpu->delay_slot ? 4 : 0));
|
||||
break;
|
||||
|
||||
case EXCEPT_BUSERR:
|
||||
case EXCEPT_ALIGN:
|
||||
case EXCEPT_ILLEGAL:
|
||||
case EXCEPT_RANGE:
|
||||
SET_H_SYS_EPCR0 (pc - (current_cpu->delay_slot ? 4 : 0));
|
||||
SET_H_SYS_EPCR0 (pc - (or1k_cpu->delay_slot ? 4 : 0));
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -162,9 +163,9 @@ or1k32bf_exception (sim_cpu *current_cpu, USI pc, USI exnum)
|
||||
SET_H_SYS_ESR0 (GET_H_SYS_SR ());
|
||||
|
||||
/* Indicate in SR if the failed instruction is in delay slot or not. */
|
||||
SET_H_SYS_SR_DSX (current_cpu->delay_slot);
|
||||
SET_H_SYS_SR_DSX (or1k_cpu->delay_slot);
|
||||
|
||||
current_cpu->next_delay_slot = 0;
|
||||
or1k_cpu->next_delay_slot = 0;
|
||||
|
||||
/* Jump program counter into handler. */
|
||||
handler_pc =
|
||||
@@ -180,10 +181,12 @@ or1k32bf_exception (sim_cpu *current_cpu, USI pc, USI exnum)
|
||||
void
|
||||
or1k32bf_rfe (sim_cpu *current_cpu)
|
||||
{
|
||||
struct or1k_sim_cpu *or1k_cpu = OR1K_SIM_CPU (current_cpu);
|
||||
|
||||
SET_H_SYS_SR (GET_H_SYS_ESR0 ());
|
||||
SET_H_SYS_SR_FO (1);
|
||||
|
||||
current_cpu->next_delay_slot = 0;
|
||||
or1k_cpu->next_delay_slot = 0;
|
||||
|
||||
sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL,
|
||||
GET_H_SYS_EPCR0 ());
|
||||
@@ -246,6 +249,7 @@ void
|
||||
or1k32bf_mtspr (sim_cpu *current_cpu, USI addr, USI val)
|
||||
{
|
||||
SIM_DESC sd = CPU_STATE (current_cpu);
|
||||
struct or1k_sim_cpu *or1k_cpu = OR1K_SIM_CPU (current_cpu);
|
||||
|
||||
if (!GET_H_SYS_SR_SM () && !GET_H_SYS_SR_SUMRA ())
|
||||
{
|
||||
@@ -275,9 +279,9 @@ or1k32bf_mtspr (sim_cpu *current_cpu, USI addr, USI val)
|
||||
break;
|
||||
|
||||
case SPR_ADDR (SYS, NPC):
|
||||
current_cpu->next_delay_slot = 0;
|
||||
or1k_cpu->next_delay_slot = 0;
|
||||
|
||||
sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL, val);
|
||||
sim_engine_restart (sd, current_cpu, NULL, val);
|
||||
break;
|
||||
|
||||
case SPR_ADDR (TICK, TTMR):
|
||||
|
||||
@@ -130,6 +130,8 @@ write_regval (uint32_t val, uint32_t *reg, uint32_t regsel)
|
||||
static uint32_t
|
||||
imem_wordaddr_to_byteaddr (SIM_CPU *cpu, uint16_t wa)
|
||||
{
|
||||
struct pru_regset *pru_cpu = PRU_SIM_CPU (cpu);
|
||||
|
||||
return (((uint32_t) wa << 2) & IMEM_ADDR_MASK) | PC_ADDR_SPACE_MARKER;
|
||||
}
|
||||
|
||||
@@ -147,6 +149,7 @@ static inline void
|
||||
pru_reg2dmem (SIM_CPU *cpu, uint32_t addr, unsigned int nbytes,
|
||||
int regn, int regb)
|
||||
{
|
||||
struct pru_regset *pru_cpu = PRU_SIM_CPU (cpu);
|
||||
/* GDB assumes unconditional access to all memories, so enable additional
|
||||
checks only in standalone mode. */
|
||||
bool standalone = (STATE_OPEN_KIND (CPU_STATE (cpu)) == SIM_OPEN_STANDALONE);
|
||||
@@ -196,6 +199,7 @@ static inline void
|
||||
pru_dmem2reg (SIM_CPU *cpu, uint32_t addr, unsigned int nbytes,
|
||||
int regn, int regb)
|
||||
{
|
||||
struct pru_regset *pru_cpu = PRU_SIM_CPU (cpu);
|
||||
/* GDB assumes unconditional access to all memories, so enable additional
|
||||
checks only in standalone mode. */
|
||||
bool standalone = (STATE_OPEN_KIND (CPU_STATE (cpu)) == SIM_OPEN_STANDALONE);
|
||||
@@ -247,6 +251,7 @@ pru_dmem2reg (SIM_CPU *cpu, uint32_t addr, unsigned int nbytes,
|
||||
static void
|
||||
set_initial_gprs (SIM_CPU *cpu)
|
||||
{
|
||||
struct pru_regset *pru_cpu = PRU_SIM_CPU (cpu);
|
||||
int i;
|
||||
|
||||
/* Set up machine just out of reset. */
|
||||
@@ -325,6 +330,8 @@ static void
|
||||
pru_sim_xin_mac (SIM_DESC sd, SIM_CPU *cpu, unsigned int rd_regn,
|
||||
unsigned int rdb, unsigned int length)
|
||||
{
|
||||
struct pru_regset *pru_cpu = PRU_SIM_CPU (cpu);
|
||||
|
||||
if (rd_regn < 25 || (rd_regn * 4 + rdb + length) > (27 + 1) * 4)
|
||||
sim_io_error (sd, "XIN MAC: invalid transfer regn=%u.%u, length=%u\n",
|
||||
rd_regn, rdb, length);
|
||||
@@ -348,6 +355,8 @@ static void
|
||||
pru_sim_xin (SIM_DESC sd, SIM_CPU *cpu, unsigned int wba,
|
||||
unsigned int rd_regn, unsigned int rdb, unsigned int length)
|
||||
{
|
||||
struct pru_regset *pru_cpu = PRU_SIM_CPU (cpu);
|
||||
|
||||
if (wba == 0)
|
||||
{
|
||||
pru_sim_xin_mac (sd, cpu, rd_regn, rdb, length);
|
||||
@@ -393,6 +402,7 @@ static void
|
||||
pru_sim_xout_mac (SIM_DESC sd, SIM_CPU *cpu, unsigned int rd_regn,
|
||||
unsigned int rdb, unsigned int length)
|
||||
{
|
||||
struct pru_regset *pru_cpu = PRU_SIM_CPU (cpu);
|
||||
const int modereg_accessed = (rd_regn == 25);
|
||||
|
||||
/* Multiple Accumulate. */
|
||||
@@ -453,6 +463,8 @@ static void
|
||||
pru_sim_xout (SIM_DESC sd, SIM_CPU *cpu, unsigned int wba,
|
||||
unsigned int rd_regn, unsigned int rdb, unsigned int length)
|
||||
{
|
||||
struct pru_regset *pru_cpu = PRU_SIM_CPU (cpu);
|
||||
|
||||
if (wba == 0)
|
||||
{
|
||||
pru_sim_xout_mac (sd, cpu, rd_regn, rdb, length);
|
||||
@@ -482,6 +494,8 @@ static void
|
||||
pru_sim_xchg (SIM_DESC sd, SIM_CPU *cpu, unsigned int wba,
|
||||
unsigned int rd_regn, unsigned int rdb, unsigned int length)
|
||||
{
|
||||
struct pru_regset *pru_cpu = PRU_SIM_CPU (cpu);
|
||||
|
||||
if (wba == XFRID_SCRATCH_BANK_0 || wba == XFRID_SCRATCH_BANK_1
|
||||
|| wba == XFRID_SCRATCH_BANK_2 || wba == XFRID_SCRATCH_BANK_PEER)
|
||||
{
|
||||
@@ -508,6 +522,7 @@ pru_sim_xchg (SIM_DESC sd, SIM_CPU *cpu, unsigned int wba,
|
||||
static void
|
||||
pru_sim_syscall (SIM_DESC sd, SIM_CPU *cpu)
|
||||
{
|
||||
struct pru_regset *pru_cpu = PRU_SIM_CPU (cpu);
|
||||
/* If someday TI confirms that the "reserved" HALT opcode fields
|
||||
can be used for extra arguments, then maybe we can embed
|
||||
the syscall number there. Until then, let's use R1. */
|
||||
@@ -525,6 +540,7 @@ static void
|
||||
sim_step_once (SIM_DESC sd)
|
||||
{
|
||||
SIM_CPU *cpu = STATE_CPU (sd, 0);
|
||||
struct pru_regset *pru_cpu = PRU_SIM_CPU (cpu);
|
||||
const struct pru_opcode *op;
|
||||
uint32_t inst;
|
||||
uint32_t _RDVAL, OP2; /* intermediate values. */
|
||||
@@ -635,16 +651,20 @@ sim_engine_run (SIM_DESC sd,
|
||||
static sim_cia
|
||||
pru_pc_get (sim_cpu *cpu)
|
||||
{
|
||||
struct pru_regset *pru_cpu = PRU_SIM_CPU (cpu);
|
||||
|
||||
/* Present PC as byte address. */
|
||||
return imem_wordaddr_to_byteaddr (cpu, cpu->pru_cpu.pc);
|
||||
return imem_wordaddr_to_byteaddr (cpu, pru_cpu->pc);
|
||||
}
|
||||
|
||||
/* Implement callback for standard CPU_PC_STORE routine. */
|
||||
static void
|
||||
pru_pc_set (sim_cpu *cpu, sim_cia pc)
|
||||
{
|
||||
struct pru_regset *pru_cpu = PRU_SIM_CPU (cpu);
|
||||
|
||||
/* PC given as byte address. */
|
||||
cpu->pru_cpu.pc = imem_byteaddr_to_wordaddr (cpu, pc);
|
||||
pru_cpu->pc = imem_byteaddr_to_wordaddr (cpu, pc);
|
||||
}
|
||||
|
||||
|
||||
@@ -652,6 +672,8 @@ pru_pc_set (sim_cpu *cpu, sim_cia pc)
|
||||
static int
|
||||
pru_store_register (SIM_CPU *cpu, int rn, const void *memory, int length)
|
||||
{
|
||||
struct pru_regset *pru_cpu = PRU_SIM_CPU (cpu);
|
||||
|
||||
if (rn < NUM_REGS && rn >= 0)
|
||||
{
|
||||
if (length == 4)
|
||||
@@ -675,6 +697,7 @@ pru_store_register (SIM_CPU *cpu, int rn, const void *memory, int length)
|
||||
static int
|
||||
pru_fetch_register (SIM_CPU *cpu, int rn, void *memory, int length)
|
||||
{
|
||||
struct pru_regset *pru_cpu = PRU_SIM_CPU (cpu);
|
||||
long ival;
|
||||
|
||||
if (rn < NUM_REGS && rn >= 0)
|
||||
@@ -751,7 +774,7 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb,
|
||||
current_target_byte_order = BFD_ENDIAN_LITTLE;
|
||||
|
||||
/* The cpu data is kept in a separately allocated chunk of memory. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct pru_regset)) != SIM_RC_OK)
|
||||
{
|
||||
free_state (sd);
|
||||
return 0;
|
||||
@@ -831,6 +854,7 @@ sim_create_inferior (SIM_DESC sd, struct bfd *prog_bfd,
|
||||
char * const *argv, char * const *env)
|
||||
{
|
||||
SIM_CPU *cpu = STATE_CPU (sd, 0);
|
||||
struct pru_regset *pru_cpu = PRU_SIM_CPU (cpu);
|
||||
host_callback *cb = STATE_CALLBACK (sd);
|
||||
SIM_ADDR addr;
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
#define XFRID_SCRATCH_BANK_PEER 14
|
||||
#define XFRID_MAX 255
|
||||
|
||||
#define CPU (cpu->pru_cpu)
|
||||
#define CPU (*pru_cpu)
|
||||
|
||||
#define PC (CPU.pc)
|
||||
#define PC_byteaddr ((PC << 2) | PC_ADDR_SPACE_MARKER)
|
||||
|
||||
@@ -78,9 +78,6 @@ struct pru_regset
|
||||
int insts;
|
||||
};
|
||||
|
||||
struct _sim_cpu {
|
||||
struct pru_regset pru_cpu;
|
||||
sim_cpu_base base;
|
||||
};
|
||||
#define PRU_SIM_CPU(cpu) ((struct pru_regset *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
#endif /* PRU_SIM_MAIN */
|
||||
|
||||
@@ -73,7 +73,8 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback,
|
||||
callback->syscall_map = cb_riscv_syscall_map;
|
||||
|
||||
/* The cpu data is kept in a separately allocated chunk of memory. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct riscv_sim_cpu))
|
||||
!= SIM_RC_OK)
|
||||
{
|
||||
free_state (sd);
|
||||
return 0;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,7 +25,7 @@
|
||||
#include "machs.h"
|
||||
#include "sim-base.h"
|
||||
|
||||
struct _sim_cpu {
|
||||
struct riscv_sim_cpu {
|
||||
union {
|
||||
unsigned_word regs[32];
|
||||
struct {
|
||||
@@ -56,9 +56,8 @@ struct _sim_cpu {
|
||||
#include "opcode/riscv-opc.h"
|
||||
#undef DECLARE_CSR
|
||||
} csr;
|
||||
|
||||
sim_cpu_base base;
|
||||
};
|
||||
#define RISCV_SIM_CPU(cpu) ((struct riscv_sim_cpu *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
struct atomic_mem_reserved_list;
|
||||
struct atomic_mem_reserved_list {
|
||||
|
||||
@@ -118,9 +118,4 @@ typedef union
|
||||
/* TODO: Move into sim_cpu. */
|
||||
extern saved_state_type saved_state;
|
||||
|
||||
struct _sim_cpu {
|
||||
|
||||
sim_cpu_base base;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -50,6 +50,8 @@ const char *interrupt_names[] =
|
||||
static void
|
||||
do_interrupt (SIM_DESC sd, void *data)
|
||||
{
|
||||
sim_cpu *cpu = STATE_CPU (sd, 0);
|
||||
struct v850_sim_cpu *v850_cpu = V850_SIM_CPU (cpu);
|
||||
const char **interrupt_name = (const char**)data;
|
||||
enum interrupt_type inttype;
|
||||
inttype = (interrupt_name - STATE_WATCHPOINTS (sd)->interrupt_names);
|
||||
@@ -74,9 +76,9 @@ do_interrupt (SIM_DESC sd, void *data)
|
||||
ignores subsequent NMIs, so we don't need to count them.
|
||||
Just keep re-scheduling a single NMI until it manages to
|
||||
be delivered */
|
||||
if (STATE_CPU (sd, 0)->pending_nmi != NULL)
|
||||
sim_events_deschedule (sd, STATE_CPU (sd, 0)->pending_nmi);
|
||||
STATE_CPU (sd, 0)->pending_nmi =
|
||||
if (v850_cpu->pending_nmi != NULL)
|
||||
sim_events_deschedule (sd, v850_cpu->pending_nmi);
|
||||
v850_cpu->pending_nmi =
|
||||
sim_events_schedule (sd, 1, do_interrupt, data);
|
||||
return;
|
||||
}
|
||||
@@ -204,7 +206,8 @@ sim_open (SIM_OPEN_KIND kind,
|
||||
cb->syscall_map = cb_v850_syscall_map;
|
||||
|
||||
/* The cpu data is kept in a separately allocated chunk of memory. */
|
||||
if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
|
||||
if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct v850_sim_cpu))
|
||||
!= SIM_RC_OK)
|
||||
return 0;
|
||||
|
||||
/* for compatibility */
|
||||
@@ -281,8 +284,8 @@ sim_open (SIM_OPEN_KIND kind,
|
||||
case bfd_mach_v850e2:
|
||||
case bfd_mach_v850e2v3:
|
||||
case bfd_mach_v850e3v5:
|
||||
STATE_CPU (sd, 0)->psw_mask = (PSW_NP | PSW_EP | PSW_ID | PSW_SAT
|
||||
| PSW_CY | PSW_OV | PSW_S | PSW_Z);
|
||||
V850_SIM_CPU (STATE_CPU (sd, 0))->psw_mask =
|
||||
(PSW_NP | PSW_EP | PSW_ID | PSW_SAT | PSW_CY | PSW_OV | PSW_S | PSW_Z);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,16 +32,14 @@ typedef struct _v850_regs {
|
||||
reg64_t vregs[32]; /* vector registers. */
|
||||
} v850_regs;
|
||||
|
||||
struct _sim_cpu
|
||||
{
|
||||
/* ... simulator specific members ... */
|
||||
struct v850_sim_cpu {
|
||||
v850_regs reg;
|
||||
reg_t psw_mask; /* only allow non-reserved bits to be set */
|
||||
sim_event *pending_nmi;
|
||||
/* ... base type ... */
|
||||
sim_cpu_base base;
|
||||
};
|
||||
|
||||
#define V850_SIM_CPU(cpu) ((struct v850_sim_cpu *) CPU_ARCH_DATA (cpu))
|
||||
|
||||
/* For compatibility, until all functions converted to passing
|
||||
SIM_DESC as an argument */
|
||||
extern SIM_DESC simulator;
|
||||
@@ -90,15 +88,15 @@ nia = PC
|
||||
|
||||
|
||||
/* new */
|
||||
#define GR ((CPU)->reg.regs)
|
||||
#define SR ((CPU)->reg.sregs)
|
||||
#define VR ((CPU)->reg.vregs)
|
||||
#define MPU0_SR ((STATE_CPU (sd, 0))->reg.mpu0_sregs)
|
||||
#define MPU1_SR ((STATE_CPU (sd, 0))->reg.mpu1_sregs)
|
||||
#define FPU_SR ((STATE_CPU (sd, 0))->reg.fpu_sregs)
|
||||
#define GR (V850_SIM_CPU (CPU)->reg.regs)
|
||||
#define SR (V850_SIM_CPU (CPU)->reg.sregs)
|
||||
#define VR (V850_SIM_CPU (CPU)->reg.vregs)
|
||||
#define MPU0_SR (V850_SIM_CPU (STATE_CPU (sd, 0))->reg.mpu0_sregs)
|
||||
#define MPU1_SR (V850_SIM_CPU (STATE_CPU (sd, 0))->reg.mpu1_sregs)
|
||||
#define FPU_SR (V850_SIM_CPU (STATE_CPU (sd, 0))->reg.fpu_sregs)
|
||||
|
||||
/* old */
|
||||
#define State (STATE_CPU (simulator, 0)->reg)
|
||||
#define State (V850_SIM_CPU (STATE_CPU (simulator, 0))->reg)
|
||||
#define PC (State.pc)
|
||||
#define SP_REGNO 3
|
||||
#define SP (State.regs[SP_REGNO])
|
||||
|
||||
@@ -370,7 +370,7 @@ rrrrr,111111,RRRRR + 0000000011100100:IX:::clr1
|
||||
"ctret"
|
||||
{
|
||||
nia = (CTPC & ~1);
|
||||
PSW = (CTPSW & (CPU)->psw_mask);
|
||||
PSW = (CTPSW & V850_SIM_CPU (CPU)->psw_mask);
|
||||
TRACE_BRANCH1 (PSW);
|
||||
}
|
||||
|
||||
@@ -954,7 +954,7 @@ regID,111111,RRRRR + selID,00000100000:IX:::ldsr
|
||||
/* FIXME: For now we ignore the selID. */
|
||||
if (idecode_issue == idecode_v850e3v5_issue && selID != 0)
|
||||
{
|
||||
(CPU)->reg.selID_sregs[selID][regID] = sreg;
|
||||
V850_SIM_CPU (CPU)->reg.selID_sregs[selID][regID] = sreg;
|
||||
}
|
||||
else if (( idecode_issue == idecode_v850e2_issue
|
||||
|| idecode_issue == idecode_v850e3v5_issue
|
||||
|
||||
Reference in New Issue
Block a user