diff mbox

sim: avr: move global state to sim/cpu state [committed]

Message ID 1448172788-2315-1-git-send-email-vapier@gentoo.org
State Committed
Delegated to: Mike Frysinger
Headers show

Commit Message

Mike Frysinger Nov. 22, 2015, 6:13 a.m. UTC
We don't want global variables in the sim as all state should be in the
sim state or in the cpu state.  This pushes down all that logic for avr.
---
 sim/avr/ChangeLog  |  17 ++++
 sim/avr/interp.c   | 263 +++++++++++++++++++++++++++--------------------------
 sim/avr/sim-main.h |  11 ++-
 3 files changed, 157 insertions(+), 134 deletions(-)
diff mbox

Patch

diff --git a/sim/avr/ChangeLog b/sim/avr/ChangeLog
index 410caca..e72bcf4 100644
--- a/sim/avr/ChangeLog
+++ b/sim/avr/ChangeLog
@@ -1,5 +1,22 @@ 
 2015-11-21  Mike Frysinger  <vapier@gentoo.org>
 
+	* interp.c (pc, cycles, avr_pc22): Delete.
+	(do_call): Add cpu to arguments.  Declare sd.  Change pc to cpu->pc,
+	avr_pc22 to sd->avr_pc22, and cycles to cpu->cycles.
+	(gen_mul): Add cpu to arguments.  Change cycles to cpu->cycles.
+	(step_once): Change pc to cpu->pc, avr_pc22 to sd->avr_pc22, and
+	cycles to cpu->cycles.  Pass cpu to do_call and gen_mul calls.
+	(avr_reg_store, avr_reg_fetch, avr_pc_get, avr_pc_set): Change pc
+	to cpu->pc.
+	(sim_open): Likewise.  Declare cpu.
+	(sim_create_inferior): Declare cpu and addr.  Change pc to addr and
+	call sim_pc_set.  Change avr_pc22 to sd->avr_pc22.
+	* sim-main.h (pc): Delete.
+	(struct _sim_cpu): Add pc and cycles.
+	(struct sim_state): Add avr_pc22.
+
+2015-11-21  Mike Frysinger  <vapier@gentoo.org>
+
 	* interp.c (sim_store_register): Rename to ...
 	(avr_reg_store): ... this.  Adjust signature.
 	(sim_fetch_register): Rename to ...
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;
 }
diff --git a/sim/avr/sim-main.h b/sim/avr/sim-main.h
index e0cac22..d317bf8 100644
--- a/sim/avr/sim-main.h
+++ b/sim/avr/sim-main.h
@@ -21,19 +21,24 @@  along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "sim-basics.h"
 
-extern unsigned int pc;
-
 #include "sim-base.h"
 
 struct _sim_cpu {
+  /* The only real register.  */
+  uint32_t pc;
+
+  /* We update a cycle counter.  */
+  uint32_t cycles;
 
   sim_cpu_base base;
 };
 
 struct sim_state {
-
   sim_cpu *cpu[MAX_NR_PROCESSORS];
 
+  /* If true, the pc needs more than 2 bytes.  */
+  int avr_pc22;
+
   sim_state_base base;
 };