aboutsummaryrefslogtreecommitdiff
path: root/sim/avr/interp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sim/avr/interp.c')
-rw-r--r--sim/avr/interp.c263
1 files changed, 132 insertions, 131 deletions
diff --git a/sim/avr/interp.c b/sim/avr/interp.c
index 48d2195..ca50474 100644
--- a/sim/avr/interp.c
+++ b/sim/avr/interp.c
@@ -36,15 +36,6 @@ typedef signed short int sword;
typedef unsigned char byte;
typedef signed char sbyte;
-/* The only real register. */
-unsigned int pc;
-
-/* We update a cycle counter. */
-static unsigned int cycles = 0;
-
-/* If true, the pc needs more than 2 bytes. */
-static int avr_pc22;
-
/* Max size of I space (which is always flash on avr). */
#define MAX_AVR_FLASH (128 * 1024)
#define PC_MASK (MAX_AVR_FLASH - 1)
@@ -734,21 +725,22 @@ decode (unsigned int pc)
}
static void
-do_call (unsigned int npc)
+do_call (SIM_CPU *cpu, unsigned int npc)
{
+ SIM_DESC sd = CPU_STATE (cpu);
unsigned int sp = read_word (REG_SP);
/* Big endian! */
- sram[sp--] = pc;
- sram[sp--] = pc >> 8;
- if (avr_pc22)
+ sram[sp--] = cpu->pc;
+ sram[sp--] = cpu->pc >> 8;
+ if (sd->avr_pc22)
{
- sram[sp--] = pc >> 16;
- cycles++;
+ sram[sp--] = cpu->pc >> 16;
+ cpu->cycles++;
}
write_word (REG_SP, sp);
- pc = npc & PC_MASK;
- cycles += 3;
+ cpu->pc = npc & PC_MASK;
+ cpu->cycles += 3;
}
static int
@@ -780,7 +772,7 @@ get_lpm (unsigned int addr)
}
static void
-gen_mul (unsigned int res)
+gen_mul (SIM_CPU *cpu, unsigned int res)
{
write_word (0, res);
sram[SREG] &= ~(SREG_Z | SREG_C);
@@ -788,7 +780,7 @@ gen_mul (unsigned int res)
sram[SREG] |= SREG_Z;
if (res & 0x8000)
sram[SREG] |= SREG_C;
- cycles++;
+ cpu->cycles++;
}
static void
@@ -802,8 +794,8 @@ step_once (SIM_CPU *cpu)
byte r, d, vd;
again:
- code = flash[pc].code;
- op = flash[pc].op;
+ code = flash[cpu->pc].code;
+ op = flash[cpu->pc].op;
#if 0
if (tracing && code != OP_unknown)
@@ -836,27 +828,27 @@ step_once (SIM_CPU *cpu)
}
if (!tracing)
- sim_cb_eprintf (callback, "%06x: %04x\n", 2 * pc, flash[pc].op);
+ sim_cb_eprintf (callback, "%06x: %04x\n", 2 * cpu->pc, flash[cpu->pc].op);
else
{
sim_cb_eprintf (callback, "pc=0x%06x insn=0x%04x code=%d r=%d\n",
- 2 * pc, flash[pc].op, code, flash[pc].r);
- disassemble_insn (CPU_STATE (cpu), pc);
+ 2 * cpu->pc, flash[cpu->pc].op, code, flash[cpu->pc].r);
+ disassemble_insn (CPU_STATE (cpu), cpu->pc);
sim_cb_eprintf (callback, "\n");
}
}
#endif
- ipc = pc;
- pc = (pc + 1) & PC_MASK;
- cycles++;
+ ipc = cpu->pc;
+ cpu->pc = (cpu->pc + 1) & PC_MASK;
+ cpu->cycles++;
switch (code)
{
case OP_unknown:
flash[ipc].code = decode(ipc);
- pc = ipc;
- cycles--;
+ cpu->pc = ipc;
+ cpu->cycles--;
goto again;
case OP_nop:
@@ -864,36 +856,36 @@ step_once (SIM_CPU *cpu)
case OP_jmp:
/* 2 words instruction, but we don't care about the pc. */
- pc = ((flash[ipc].r << 16) | flash[ipc + 1].op) & PC_MASK;
- cycles += 2;
+ cpu->pc = ((flash[ipc].r << 16) | flash[ipc + 1].op) & PC_MASK;
+ cpu->cycles += 2;
break;
case OP_eijmp:
- pc = ((sram[EIND] << 16) | read_word (REGZ)) & PC_MASK;
- cycles += 2;
+ cpu->pc = ((sram[EIND] << 16) | read_word (REGZ)) & PC_MASK;
+ cpu->cycles += 2;
break;
case OP_ijmp:
- pc = read_word (REGZ) & PC_MASK;
- cycles += 1;
+ cpu->pc = read_word (REGZ) & PC_MASK;
+ cpu->cycles += 1;
break;
case OP_call:
/* 2 words instruction. */
- pc++;
- do_call ((flash[ipc].r << 16) | flash[ipc + 1].op);
+ cpu->pc++;
+ do_call (cpu, (flash[ipc].r << 16) | flash[ipc + 1].op);
break;
case OP_eicall:
- do_call ((sram[EIND] << 16) | read_word (REGZ));
+ do_call (cpu, (sram[EIND] << 16) | read_word (REGZ));
break;
case OP_icall:
- do_call (read_word (REGZ));
+ do_call (cpu, read_word (REGZ));
break;
case OP_rcall:
- do_call (pc + sign_ext (op & 0xfff, 12));
+ do_call (cpu, cpu->pc + sign_ext (op & 0xfff, 12));
break;
case OP_reti:
@@ -901,25 +893,26 @@ step_once (SIM_CPU *cpu)
/* Fall through */
case OP_ret:
{
+ SIM_DESC sd = CPU_STATE (cpu);
unsigned int sp = read_word (REG_SP);
- if (avr_pc22)
+ if (sd->avr_pc22)
{
- pc = sram[++sp] << 16;
- cycles++;
+ cpu->pc = sram[++sp] << 16;
+ cpu->cycles++;
}
else
- pc = 0;
- pc |= sram[++sp] << 8;
- pc |= sram[++sp];
+ cpu->pc = 0;
+ cpu->pc |= sram[++sp] << 8;
+ cpu->pc |= sram[++sp];
write_word (REG_SP, sp);
}
- cycles += 3;
+ cpu->cycles += 3;
break;
case OP_break:
/* Stop on this address. */
- sim_engine_halt (CPU_STATE (cpu), cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
- pc = ipc;
+ sim_engine_halt (CPU_STATE (cpu), cpu, NULL, cpu->pc, sim_stopped, SIM_SIGTRAP);
+ cpu->pc = ipc;
break;
case OP_bld:
@@ -942,9 +935,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(pc);
- pc += l;
- cycles += l;
+ int l = get_insn_length (cpu->pc);
+ cpu->pc += l;
+ cpu->cycles += l;
}
break;
@@ -954,7 +947,7 @@ step_once (SIM_CPU *cpu)
sram[sp--] = sram[get_d (op)];
write_word (REG_SP, sp);
}
- cycles++;
+ cpu->cycles++;
break;
case OP_pop:
@@ -963,7 +956,7 @@ step_once (SIM_CPU *cpu)
sram[get_d (op)] = sram[++sp];
write_word (REG_SP, sp);
}
- cycles++;
+ cpu->cycles++;
break;
case OP_bclr:
@@ -975,8 +968,8 @@ step_once (SIM_CPU *cpu)
break;
case OP_rjmp:
- pc = (pc + sign_ext (op & 0xfff, 12)) & PC_MASK;
- cycles++;
+ cpu->pc = (cpu->pc + sign_ext (op & 0xfff, 12)) & PC_MASK;
+ cpu->cycles++;
break;
case OP_eor:
@@ -1106,32 +1099,32 @@ step_once (SIM_CPU *cpu)
break;
case OP_mul:
- gen_mul ((word)sram[get_r (op)] * (word)sram[get_d (op)]);
+ gen_mul (cpu, (word)sram[get_r (op)] * (word)sram[get_d (op)]);
break;
case OP_muls:
- gen_mul ((sword)(sbyte)sram[get_r16 (op)]
- * (sword)(sbyte)sram[get_d16 (op)]);
+ gen_mul (cpu, (sword)(sbyte)sram[get_r16 (op)]
+ * (sword)(sbyte)sram[get_d16 (op)]);
break;
case OP_mulsu:
- gen_mul ((sword)(word)sram[get_r16_23 (op)]
- * (sword)(sbyte)sram[get_d16_23 (op)]);
+ gen_mul (cpu, (sword)(word)sram[get_r16_23 (op)]
+ * (sword)(sbyte)sram[get_d16_23 (op)]);
break;
case OP_fmul:
- gen_mul (((word)sram[get_r16_23 (op)]
- * (word)sram[get_d16_23 (op)]) << 1);
+ gen_mul (cpu, ((word)sram[get_r16_23 (op)]
+ * (word)sram[get_d16_23 (op)]) << 1);
break;
case OP_fmuls:
- gen_mul (((sword)(sbyte)sram[get_r16_23 (op)]
- * (sword)(sbyte)sram[get_d16_23 (op)]) << 1);
+ gen_mul (cpu, ((sword)(sbyte)sram[get_r16_23 (op)]
+ * (sword)(sbyte)sram[get_d16_23 (op)]) << 1);
break;
case OP_fmulsu:
- gen_mul (((sword)(word)sram[get_r16_23 (op)]
- * (sword)(sbyte)sram[get_d16_23 (op)]) << 1);
+ gen_mul (cpu, ((sword)(word)sram[get_r16_23 (op)]
+ * (sword)(sbyte)sram[get_d16_23 (op)]) << 1);
break;
case OP_adc:
@@ -1213,9 +1206,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, pc, sim_exited, 0);
+ sim_engine_halt (CPU_STATE (cpu), cpu, NULL, cpu->pc, sim_exited, 0);
else if (d == ABORT_PORT)
- sim_engine_halt (CPU_STATE (cpu), cpu, NULL, pc, sim_exited, 1);
+ sim_engine_halt (CPU_STATE (cpu), cpu, NULL, cpu->pc, sim_exited, 1);
break;
case OP_in:
@@ -1236,18 +1229,18 @@ step_once (SIM_CPU *cpu)
case OP_sbic:
if (!(sram[get_biA (op) + 0x20] & 1 << get_b(op)))
{
- int l = get_insn_length(pc);
- pc += l;
- cycles += l;
+ int l = get_insn_length (cpu->pc);
+ cpu->pc += l;
+ cpu->cycles += l;
}
break;
case OP_sbis:
if (sram[get_biA (op) + 0x20] & 1 << get_b(op))
{
- int l = get_insn_length(pc);
- pc += l;
- cycles += l;
+ int l = get_insn_length (cpu->pc);
+ cpu->pc += l;
+ cpu->cycles += l;
}
break;
@@ -1258,23 +1251,23 @@ step_once (SIM_CPU *cpu)
break;
case OP_lds:
- sram[get_d (op)] = sram[flash[pc].op];
- pc++;
- cycles++;
+ sram[get_d (op)] = sram[flash[cpu->pc].op];
+ cpu->pc++;
+ cpu->cycles++;
break;
case OP_sts:
- sram[flash[pc].op] = sram[get_d (op)];
- pc++;
- cycles++;
+ sram[flash[cpu->pc].op] = sram[get_d (op)];
+ cpu->pc++;
+ cpu->cycles++;
break;
case OP_cpse:
if (sram[get_r (op)] == sram[get_d (op)])
{
- int l = get_insn_length(pc);
- pc += l;
- cycles += l;
+ int l = get_insn_length (cpu->pc);
+ cpu->pc += l;
+ cpu->cycles += l;
}
break;
@@ -1311,42 +1304,42 @@ step_once (SIM_CPU *cpu)
case OP_brbc:
if (!(sram[SREG] & flash[ipc].r))
{
- pc = (pc + get_k (op)) & PC_MASK;
- cycles++;
+ cpu->pc = (cpu->pc + get_k (op)) & PC_MASK;
+ cpu->cycles++;
}
break;
case OP_brbs:
if (sram[SREG] & flash[ipc].r)
{
- pc = (pc + get_k (op)) & PC_MASK;
- cycles++;
+ cpu->pc = (cpu->pc + get_k (op)) & PC_MASK;
+ cpu->cycles++;
}
break;
case OP_lpm:
sram[0] = get_lpm (read_word (REGZ));
- cycles += 2;
+ cpu->cycles += 2;
break;
case OP_lpm_Z:
sram[get_d (op)] = get_lpm (read_word (REGZ));
- cycles += 2;
+ cpu->cycles += 2;
break;
case OP_lpm_inc_Z:
sram[get_d (op)] = get_lpm (read_word_post_inc (REGZ));
- cycles += 2;
+ cpu->cycles += 2;
break;
case OP_elpm:
sram[0] = get_lpm (get_z ());
- cycles += 2;
+ cpu->cycles += 2;
break;
case OP_elpm_Z:
sram[get_d (op)] = get_lpm (get_z ());
- cycles += 2;
+ cpu->cycles += 2;
break;
case OP_elpm_inc_Z:
@@ -1359,97 +1352,97 @@ step_once (SIM_CPU *cpu)
sram[REGZ_HI] = z >> 8;
sram[RAMPZ] = z >> 16;
}
- cycles += 2;
+ cpu->cycles += 2;
break;
case OP_ld_Z_inc:
sram[get_d (op)] = sram[read_word_post_inc (REGZ) & SRAM_MASK];
- cycles++;
+ cpu->cycles++;
break;
case OP_ld_dec_Z:
sram[get_d (op)] = sram[read_word_pre_dec (REGZ) & SRAM_MASK];
- cycles++;
+ cpu->cycles++;
break;
case OP_ld_X_inc:
sram[get_d (op)] = sram[read_word_post_inc (REGX) & SRAM_MASK];
- cycles++;
+ cpu->cycles++;
break;
case OP_ld_dec_X:
sram[get_d (op)] = sram[read_word_pre_dec (REGX) & SRAM_MASK];
- cycles++;
+ cpu->cycles++;
break;
case OP_ld_Y_inc:
sram[get_d (op)] = sram[read_word_post_inc (REGY) & SRAM_MASK];
- cycles++;
+ cpu->cycles++;
break;
case OP_ld_dec_Y:
sram[get_d (op)] = sram[read_word_pre_dec (REGY) & SRAM_MASK];
- cycles++;
+ cpu->cycles++;
break;
case OP_st_X:
sram[read_word (REGX) & SRAM_MASK] = sram[get_d (op)];
- cycles++;
+ cpu->cycles++;
break;
case OP_st_X_inc:
sram[read_word_post_inc (REGX) & SRAM_MASK] = sram[get_d (op)];
- cycles++;
+ cpu->cycles++;
break;
case OP_st_dec_X:
sram[read_word_pre_dec (REGX) & SRAM_MASK] = sram[get_d (op)];
- cycles++;
+ cpu->cycles++;
break;
case OP_st_Z_inc:
sram[read_word_post_inc (REGZ) & SRAM_MASK] = sram[get_d (op)];
- cycles++;
+ cpu->cycles++;
break;
case OP_st_dec_Z:
sram[read_word_pre_dec (REGZ) & SRAM_MASK] = sram[get_d (op)];
- cycles++;
+ cpu->cycles++;
break;
case OP_st_Y_inc:
sram[read_word_post_inc (REGY) & SRAM_MASK] = sram[get_d (op)];
- cycles++;
+ cpu->cycles++;
break;
case OP_st_dec_Y:
sram[read_word_pre_dec (REGY) & SRAM_MASK] = sram[get_d (op)];
- cycles++;
+ cpu->cycles++;
break;
case OP_std_Y:
sram[read_word (REGY) + flash[ipc].r] = sram[get_d (op)];
- cycles++;
+ cpu->cycles++;
break;
case OP_std_Z:
sram[read_word (REGZ) + flash[ipc].r] = sram[get_d (op)];
- cycles++;
+ cpu->cycles++;
break;
case OP_ldd_Z:
sram[get_d (op)] = sram[read_word (REGZ) + flash[ipc].r];
- cycles++;
+ cpu->cycles++;
break;
case OP_ldd_Y:
sram[get_d (op)] = sram[read_word (REGY) + flash[ipc].r];
- cycles++;
+ cpu->cycles++;
break;
case OP_ld_X:
sram[get_d (op)] = sram[read_word (REGX) & SRAM_MASK];
- cycles++;
+ cpu->cycles++;
break;
case OP_sbiw:
@@ -1475,7 +1468,7 @@ step_once (SIM_CPU *cpu)
sram[SREG] |= SREG_S;
write_word (d, wres);
}
- cycles++;
+ cpu->cycles++;
break;
case OP_adiw:
@@ -1501,14 +1494,14 @@ step_once (SIM_CPU *cpu)
sram[SREG] |= SREG_S;
write_word (d, wres);
}
- cycles++;
+ cpu->cycles++;
break;
case OP_bad:
- sim_engine_halt (CPU_STATE (cpu), cpu, NULL, pc, sim_signalled, SIM_SIGILL);
+ sim_engine_halt (CPU_STATE (cpu), cpu, NULL, cpu->pc, sim_signalled, SIM_SIGILL);
default:
- sim_engine_halt (CPU_STATE (cpu), cpu, NULL, pc, sim_signalled, SIM_SIGILL);
+ sim_engine_halt (CPU_STATE (cpu), cpu, NULL, cpu->pc, sim_signalled, SIM_SIGILL);
}
}
@@ -1625,9 +1618,9 @@ avr_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
}
if (rn == AVR_PC_REGNUM && length == 4)
{
- pc = (memory[0] >> 1) | (memory[1] << 7)
- | (memory[2] << 15) | (memory[3] << 23);
- pc &= PC_MASK;
+ cpu->pc = (memory[0] >> 1) | (memory[1] << 7)
+ | (memory[2] << 15) | (memory[3] << 23);
+ cpu->pc &= PC_MASK;
return 4;
}
return 0;
@@ -1654,10 +1647,10 @@ avr_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
}
if (rn == AVR_PC_REGNUM && length == 4)
{
- memory[0] = pc << 1;
- memory[1] = pc >> 7;
- memory[2] = pc >> 15;
- memory[3] = pc >> 23;
+ memory[0] = cpu->pc << 1;
+ memory[1] = cpu->pc >> 7;
+ memory[2] = cpu->pc >> 15;
+ memory[3] = cpu->pc >> 23;
return 4;
}
return 0;
@@ -1666,13 +1659,13 @@ avr_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
static sim_cia
avr_pc_get (sim_cpu *cpu)
{
- return pc;
+ return cpu->pc;
}
static void
-avr_pc_set (sim_cpu *cpu, sim_cia _pc)
+avr_pc_set (sim_cpu *cpu, sim_cia pc)
{
- pc = _pc;
+ cpu->pc = pc;
}
static void
@@ -1698,8 +1691,12 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
return 0;
}
- STATE_WATCHPOINTS (sd)->pc = &pc;
- STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (pc);
+ {
+ /* XXX: Only first core gets profiled ? */
+ SIM_CPU *cpu = STATE_CPU (sd, 0);
+ STATE_WATCHPOINTS (sd)->pc = &cpu->pc;
+ STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (cpu->pc);
+ }
if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
{
@@ -1763,14 +1760,18 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
SIM_RC
sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
{
+ SIM_CPU *cpu = STATE_CPU (sd, 0);
+ SIM_ADDR addr;
+
/* Set the PC. */
if (abfd != NULL)
- pc = bfd_get_start_address (abfd);
+ addr = bfd_get_start_address (abfd);
else
- pc = 0;
+ addr = 0;
+ sim_pc_set (cpu, addr);
if (abfd != NULL)
- avr_pc22 = (bfd_get_mach (abfd) >= bfd_mach_avr6);
+ sd->avr_pc22 = (bfd_get_mach (abfd) >= bfd_mach_avr6);
return SIM_RC_OK;
}