X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Fcr16%2Finterp.c;h=aa03a1b23a24402ff00f54785a30d3c6f38dab5e;hb=5fd104addfddb68844fb8df67be832ee98ad9888;hp=6e31e1a51c422ed0f18804518df02745d99523fe;hpb=27b97b40bca216097d16d53fa9408a70cd281479;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/cr16/interp.c b/sim/cr16/interp.c index 6e31e1a51c..aa03a1b23a 100644 --- a/sim/cr16/interp.c +++ b/sim/cr16/interp.c @@ -1,5 +1,5 @@ /* Simulation code for the CR16 processor. - Copyright (C) 2008-2015 Free Software Foundation, Inc. + Copyright (C) 2008-2020 Free Software Foundation, Inc. Contributed by M Ranga Swami Reddy This file is part of GDB, the GNU debugger. @@ -35,14 +35,11 @@ int cr16_debug; -host_callback *cr16_callback; - uint32 OP[4]; uint32 sign_flag; -static struct hash_entry *lookup_hash (uint64 ins, int size); +static struct hash_entry *lookup_hash (SIM_DESC, SIM_CPU *, uint64 ins, int size); static void get_operands (operand_desc *s, uint64 mcode, int isize, int nops); -static INLINE uint8 *map_memory (unsigned phys_addr); #define MAX_HASH 16 @@ -73,7 +70,7 @@ hash(unsigned long long insn, int format) INLINE static struct hash_entry * -lookup_hash (uint64 ins, int size) +lookup_hash (SIM_DESC sd, SIM_CPU *cpu, uint64 ins, int size) { uint32 mask; struct hash_entry *h; @@ -92,11 +89,7 @@ lookup_hash (uint64 ins, int size) while ((ins & mask) != (BIN(h->opcode, h->mask))) { if (h->next == NULL) - { - State.exception = SIGILL; - State.pc_changed = 1; /* Don't increment the PC. */ - return NULL; - } + sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGILL); h = h->next; mask = (((1 << (32 - h->mask)) -1) << h->mask); @@ -329,28 +322,22 @@ get_operands (operand_desc *s, uint64 ins, int isize, int nops) } static int -do_run (SIM_DESC sd, uint64 mcode) +do_run (SIM_DESC sd, SIM_CPU *cpu, uint64 mcode) { - host_callback *cr16_callback = STATE_CALLBACK (sd); - struct simops *s= Simops; struct hash_entry *h; - char func[12]="\0"; - uint8 *iaddr; + #ifdef DEBUG if ((cr16_debug & DEBUG_INSTRUCTION) != 0) - (*cr16_callback->printf_filtered) (cr16_callback, "do_long 0x%x\n", mcode); + sim_io_printf (sd, "do_long 0x%x\n", mcode); #endif - - h = lookup_hash(mcode, 1); + + h = lookup_hash (sd, cpu, mcode, 1); if ((h == NULL) || (h->opcode == 0)) return 0; - if (h->size == 3) - { - iaddr = imem_addr ((uint32)PC + 2); - mcode = (mcode << 16) | get_longword( iaddr ); - } + if (h->size == 3) + mcode = (mcode << 16) | RW (PC + 4); /* Re-set OP list. */ OP[0] = OP[1] = OP[2] = OP[3] = sign_flag = 0; @@ -365,378 +352,11 @@ do_run (SIM_DESC sd, uint64 mcode) //State.ins_type = h->flags; - (h->ops->func)(); + (h->ops->func) (sd, cpu); return h->size; } -static void -sim_size (int power) -{ - int i; - for (i = 0; i < IMEM_SEGMENTS; i++) - { - if (State.mem.insn[i]) - free (State.mem.insn[i]); - } - for (i = 0; i < DMEM_SEGMENTS; i++) - { - if (State.mem.data[i]) - free (State.mem.data[i]); - } - for (i = 0; i < UMEM_SEGMENTS; i++) - { - if (State.mem.unif[i]) - free (State.mem.unif[i]); - } - /* Always allocate dmem segment 0. This contains the IMAP and DMAP - registers. */ - State.mem.data[0] = calloc (1, SEGMENT_SIZE); -} - -/* For tracing - leave info on last access around. */ -static char *last_segname = "invalid"; -static char *last_from = "invalid"; -static char *last_to = "invalid"; - -enum - { - IMAP0_OFFSET = 0xff00, - DMAP0_OFFSET = 0xff08, - DMAP2_SHADDOW = 0xff04, - DMAP2_OFFSET = 0xff0c - }; - -static unsigned long -dmap_register (void *regcache, int reg_nr) -{ - uint8 *raw = map_memory (SIM_CR16_MEMORY_DATA - + DMAP0_OFFSET + 2 * reg_nr); - return READ_16 (raw); -} - -static unsigned long -imap_register (void *regcache, int reg_nr) -{ - uint8 *raw = map_memory (SIM_CR16_MEMORY_DATA - + IMAP0_OFFSET + 2 * reg_nr); - return READ_16 (raw); -} - -/* Given a virtual address in the DMAP address space, translate it - into a physical address. */ - -unsigned long -sim_cr16_translate_dmap_addr (unsigned long offset, - int nr_bytes, - unsigned long *phys, - void *regcache, - unsigned long (*dmap_register) (void *regcache, - int reg_nr)) -{ - short map; - int regno; - last_from = "logical-data"; - if (offset >= DMAP_BLOCK_SIZE * SIM_CR16_NR_DMAP_REGS) - { - /* Logical address out side of data segments, not supported */ - return 0; - } - regno = (offset / DMAP_BLOCK_SIZE); - offset = (offset % DMAP_BLOCK_SIZE); - -#if 1 - if ((offset % DMAP_BLOCK_SIZE) + nr_bytes > DMAP_BLOCK_SIZE) - { - /* Don't cross a BLOCK boundary */ - nr_bytes = DMAP_BLOCK_SIZE - (offset % DMAP_BLOCK_SIZE); - } - map = dmap_register (regcache, regno); - if (regno == 3) - { - /* Always maps to data memory */ - int iospi = (offset / 0x1000) % 4; - int iosp = (map >> (4 * (3 - iospi))) % 0x10; - last_to = "io-space"; - *phys = (SIM_CR16_MEMORY_DATA + (iosp * 0x10000) + 0xc000 + offset); - } - else - { - int sp = ((map & 0x3000) >> 12); - int segno = (map & 0x3ff); - switch (sp) - { - case 0: /* 00: Unified memory */ - *phys = SIM_CR16_MEMORY_UNIFIED + (segno * DMAP_BLOCK_SIZE) + offset; - last_to = "unified"; - break; - case 1: /* 01: Instruction Memory */ - *phys = SIM_CR16_MEMORY_INSN + (segno * DMAP_BLOCK_SIZE) + offset; - last_to = "chip-insn"; - break; - case 2: /* 10: Internal data memory */ - *phys = SIM_CR16_MEMORY_DATA + (segno << 16) + (regno * DMAP_BLOCK_SIZE) + offset; - last_to = "chip-data"; - break; - case 3: /* 11: Reserved */ - return 0; - } - } -#endif - return nr_bytes; -} - -/* Given a virtual address in the IMAP address space, translate it - into a physical address. */ - -unsigned long -sim_cr16_translate_imap_addr (unsigned long offset, - int nr_bytes, - unsigned long *phys, - void *regcache, - unsigned long (*imap_register) (void *regcache, - int reg_nr)) -{ - short map; - int regno; - int sp; - int segno; - last_from = "logical-insn"; - if (offset >= (IMAP_BLOCK_SIZE * SIM_CR16_NR_IMAP_REGS)) - { - /* Logical address outside of IMAP segments, not supported */ - return 0; - } - regno = (offset / IMAP_BLOCK_SIZE); - offset = (offset % IMAP_BLOCK_SIZE); - if (offset + nr_bytes > IMAP_BLOCK_SIZE) - { - /* Don't cross a BLOCK boundary */ - nr_bytes = IMAP_BLOCK_SIZE - offset; - } - map = imap_register (regcache, regno); - sp = (map & 0x3000) >> 12; - segno = (map & 0x007f); - switch (sp) - { - case 0: /* 00: unified memory */ - *phys = SIM_CR16_MEMORY_UNIFIED + (segno << 17) + offset; - last_to = "unified"; - break; - case 1: /* 01: instruction memory */ - *phys = SIM_CR16_MEMORY_INSN + (IMAP_BLOCK_SIZE * regno) + offset; - last_to = "chip-insn"; - break; - case 2: /*10*/ - /* Reserved. */ - return 0; - case 3: /* 11: for testing - instruction memory */ - offset = (offset % 0x800); - *phys = SIM_CR16_MEMORY_INSN + offset; - if (offset + nr_bytes > 0x800) - /* don't cross VM boundary */ - nr_bytes = 0x800 - offset; - last_to = "test-insn"; - break; - } - return nr_bytes; -} - -unsigned long -sim_cr16_translate_addr (unsigned long memaddr, int nr_bytes, - unsigned long *targ_addr, void *regcache, - unsigned long (*dmap_register) (void *regcache, - int reg_nr), - unsigned long (*imap_register) (void *regcache, - int reg_nr)) -{ - unsigned long phys; - unsigned long seg; - unsigned long off; - - last_from = "unknown"; - last_to = "unknown"; - - seg = (memaddr >> 24); - off = (memaddr & 0xffffffL); - - switch (seg) - { - case 0x00: /* Physical unified memory */ - last_from = "phys-unified"; - last_to = "unified"; - phys = SIM_CR16_MEMORY_UNIFIED + off; - if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE) - nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE); - break; - - case 0x01: /* Physical instruction memory */ - last_from = "phys-insn"; - last_to = "chip-insn"; - phys = SIM_CR16_MEMORY_INSN + off; - if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE) - nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE); - break; - - case 0x02: /* Physical data memory segment */ - last_from = "phys-data"; - last_to = "chip-data"; - phys = SIM_CR16_MEMORY_DATA + off; - if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE) - nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE); - break; - - case 0x10: /* in logical data address segment */ - nr_bytes = sim_cr16_translate_dmap_addr (off, nr_bytes, &phys, regcache, - dmap_register); - break; - - case 0x11: /* in logical instruction address segment */ - nr_bytes = sim_cr16_translate_imap_addr (off, nr_bytes, &phys, regcache, - imap_register); - break; - - default: - return 0; - } - - *targ_addr = phys; - return nr_bytes; -} - -/* Return a pointer into the raw buffer designated by phys_addr. It - is assumed that the client has already ensured that the access - isn't going to cross a segment boundary. */ - -uint8 * -map_memory (unsigned phys_addr) -{ - uint8 **memory; - uint8 *raw; - unsigned offset; - int segment = ((phys_addr >> 24) & 0xff); - - switch (segment) - { - - case 0x00: /* Unified memory */ - { - memory = &State.mem.unif[(phys_addr / SEGMENT_SIZE) % UMEM_SEGMENTS]; - last_segname = "umem"; - break; - } - - case 0x01: /* On-chip insn memory */ - { - memory = &State.mem.insn[(phys_addr / SEGMENT_SIZE) % IMEM_SEGMENTS]; - last_segname = "imem"; - break; - } - - case 0x02: /* On-chip data memory */ - { - if ((phys_addr & 0xff00) == 0xff00) - { - phys_addr = (phys_addr & 0xffff); - if (phys_addr == DMAP2_SHADDOW) - { - phys_addr = DMAP2_OFFSET; - last_segname = "dmap"; - } - else - last_segname = "reg"; - } - else - last_segname = "dmem"; - memory = &State.mem.data[(phys_addr / SEGMENT_SIZE) % DMEM_SEGMENTS]; - break; - } - - default: - /* OOPS! */ - last_segname = "scrap"; - return State.mem.fault; - } - - if (*memory == NULL) - { - *memory = calloc (1, SEGMENT_SIZE); - if (*memory == NULL) - { - (*cr16_callback->printf_filtered) (cr16_callback, "Malloc failed.\n"); - return State.mem.fault; - } - } - - offset = (phys_addr % SEGMENT_SIZE); - raw = *memory + offset; - return raw; -} - -/* Transfer data to/from simulated memory. Since a bug in either the - simulated program or in gdb or the simulator itself may cause a - bogus address to be passed in, we need to do some sanity checking - on addresses to make sure they are within bounds. When an address - fails the bounds check, treat it as a zero length read/write rather - than aborting the entire run. */ - -static int -xfer_mem (SIM_DESC sd, SIM_ADDR virt, - unsigned char *buffer, - int size, - int write_p) -{ - host_callback *cr16_callback = STATE_CALLBACK (sd); - uint8 *memory; - unsigned long phys; - int phys_size; - phys_size = sim_cr16_translate_addr (virt, size, &phys, NULL, - dmap_register, imap_register); - if (phys_size == 0) - return 0; - - memory = map_memory (phys); - -#ifdef DEBUG - if ((cr16_debug & DEBUG_INSTRUCTION) != 0) - { - (*cr16_callback->printf_filtered) - (cr16_callback, - "sim_%s %d bytes: 0x%08lx (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n", - (write_p ? "write" : "read"), - phys_size, virt, last_from, - phys, last_to, - (long) memory, last_segname); - } -#endif - - if (write_p) - { - memcpy (memory, buffer, phys_size); - } - else - { - memcpy (buffer, memory, phys_size); - } - - return phys_size; -} - - -int -sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size) -{ - /* FIXME: this should be performing a virtual transfer */ - return xfer_mem (sd, addr, buffer, size, 1); -} - -int -sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size) -{ - /* FIXME: this should be performing a virtual transfer */ - return xfer_mem (sd, addr, buffer, size, 0); -} - static sim_cia cr16_pc_get (sim_cpu *cpu) { @@ -746,6 +366,7 @@ cr16_pc_get (sim_cpu *cpu) static void cr16_pc_set (sim_cpu *cpu, sim_cia pc) { + SIM_DESC sd = CPU_STATE (cpu); SET_PC (pc); } @@ -758,10 +379,12 @@ free_state (SIM_DESC sd) sim_state_free (sd); } -SIM_DESC trace_sd = NULL; +static int cr16_reg_fetch (SIM_CPU *, int, unsigned char *, int); +static int cr16_reg_store (SIM_CPU *, int, unsigned char *, int); SIM_DESC -sim_open (SIM_OPEN_KIND kind, struct host_callback_struct *cb, struct bfd *abfd, char **argv) +sim_open (SIM_OPEN_KIND kind, struct host_callback_struct *cb, + struct bfd *abfd, char * const *argv) { struct simops *s; struct hash_entry *h; @@ -784,9 +407,7 @@ sim_open (SIM_OPEN_KIND kind, struct host_callback_struct *cb, struct bfd *abfd, return 0; } - /* getopt will print the error message so we just have to exit if this fails. - FIXME: Hmmm... in the case of gdb we need getopt to call - print_filtered. */ + /* The parser will print an error message for us, so we silently return. */ if (sim_parse_args (sd, argv) != SIM_RC_OK) { free_state (sd); @@ -824,12 +445,19 @@ sim_open (SIM_OPEN_KIND kind, struct host_callback_struct *cb, struct bfd *abfd, { SIM_CPU *cpu = STATE_CPU (sd, i); + CPU_REG_FETCH (cpu) = cr16_reg_fetch; + CPU_REG_STORE (cpu) = cr16_reg_store; CPU_PC_FETCH (cpu) = cr16_pc_get; CPU_PC_STORE (cpu) = cr16_pc_set; } - trace_sd = sd; - cr16_callback = cb; + /* The CR16 has an interrupt controller at 0xFC00, but we don't currently + handle that. Revisit if anyone ever implements operating mode. */ + /* cr16 memory: There are three separate cr16 memory regions IMEM, + UMEM and DMEM. The IMEM and DMEM are further broken down into + blocks (very like VM pages). This might not match the hardware, + but it matches what the toolchain currently expects. Ugh. */ + sim_do_commandf (sd, "memory-size %#x", 20 * 1024 * 1024); /* put all the opcodes in the hash table. */ if (!init_p++) @@ -937,120 +565,67 @@ sim_open (SIM_OPEN_KIND kind, struct host_callback_struct *cb, struct bfd *abfd, } } - /* reset the processor state */ - if (!State.mem.data[0]) - sim_size (1); - sim_create_inferior ((SIM_DESC) 1, NULL, NULL, NULL); - return sd; } - -void -sim_close (SIM_DESC sd, int quitting) +static void +step_once (SIM_DESC sd, SIM_CPU *cpu) { - /* Nothing to do. */ -} + uint32 curr_ins_size = 0; + uint64 mcode = RLW (PC); -uint8 * -dmem_addr (uint32 offset) -{ - unsigned long phys; - uint8 *mem; - int phys_size; + State.pc_changed = 0; - /* Note: DMEM address range is 0..0x10000. Calling code can compute - things like ``0xfffe + 0x0e60 == 0x10e5d''. Since offset's type - is uint16 this is modulo'ed onto 0x0e5d. */ + curr_ins_size = do_run (sd, cpu, mcode); - phys_size = sim_cr16_translate_dmap_addr (offset, 1, &phys, NULL, - dmap_register); - if (phys_size == 0) - { - mem = State.mem.fault; - } - else - mem = map_memory (phys); -#ifdef DEBUG - if ((cr16_debug & DEBUG_MEMORY)) - { - (*cr16_callback->printf_filtered) - (cr16_callback, - "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n", - offset, last_from, - phys, phys_size, last_to, - (long) mem, last_segname); - } +#if CR16_DEBUG + sim_io_printf (sd, "INS: PC=0x%X, mcode=0x%X\n", PC, mcode); #endif - return mem; -} -uint8 * -imem_addr (uint32 offset) -{ - unsigned long phys; - uint8 *mem; - int phys_size = sim_cr16_translate_imap_addr (offset, 1, &phys, NULL, - imap_register); - if (phys_size == 0) - { - return State.mem.fault; - } - mem = map_memory (phys); -#ifdef DEBUG - if ((cr16_debug & DEBUG_MEMORY)) + if (curr_ins_size == 0) + sim_engine_halt (sd, cpu, NULL, PC, sim_exited, GPR (2)); + else if (!State.pc_changed) + SET_PC (PC + (curr_ins_size * 2)); /* For word instructions. */ + +#if 0 + /* Check for a breakpoint trap on this instruction. This + overrides any pending branches or loops */ + if (PSR_DB && PC == DBS) { - (*cr16_callback->printf_filtered) - (cr16_callback, - "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n", - offset, last_from, - phys, phys_size, last_to, - (long) mem, last_segname); + SET_BPC (PC); + SET_BPSR (PSR); + SET_PC (SDBT_VECTOR_START); } #endif - return mem; -} - -static int stop_simulator = 0; -int -sim_stop (SIM_DESC sd) -{ - stop_simulator = 1; - return 1; + /* Writeback all the DATA / PC changes */ + SLOT_FLUSH (); } - -/* Run (or resume) the program. */ void -sim_resume (SIM_DESC sd, int step, int siggnal) +sim_engine_run (SIM_DESC sd, + int next_cpu_nr, /* ignore */ + int nr_cpus, /* ignore */ + int siggnal) { - uint32 curr_ins_size = 0; - uint64 mcode = 0; - uint8 *iaddr; + sim_cpu *cpu; -#ifdef DEBUG -// (*cr16_callback->printf_filtered) (cr16_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); -#endif + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); - State.exception = 0; - if (step) - sim_stop (sd); + cpu = STATE_CPU (sd, 0); switch (siggnal) { case 0: break; -#ifdef SIGBUS - case SIGBUS: -#endif - case SIGSEGV: + case GDB_SIGNAL_BUS: + case GDB_SIGNAL_SEGV: SET_PC (PC); SET_PSR (PSR); JMP (AE_VECTOR_START); SLOT_FLUSH (); break; - case SIGILL: + case GDB_SIGNAL_ILL: SET_PC (PC); SET_PSR (PSR); SET_HW_PSR ((PSR & (PSR_C_BIT))); @@ -1062,67 +637,22 @@ sim_resume (SIM_DESC sd, int step, int siggnal) break; } - do + while (1) { - iaddr = imem_addr ((uint32)PC); - if (iaddr == State.mem.fault) - { -#ifdef SIGBUS - State.exception = SIGBUS; -#else - State.exception = SIGSEGV; -#endif - break; - } - - mcode = get_longword( iaddr ); - - State.pc_changed = 0; - - curr_ins_size = do_run(sd, mcode); - -#if CR16_DEBUG - (*cr16_callback->printf_filtered) (cr16_callback, "INS: PC=0x%X, mcode=0x%X\n",PC,mcode); -#endif - - if (!State.pc_changed) - { - if (curr_ins_size == 0) - { - State.exception = SIG_CR16_EXIT; /* exit trap */ - break; - } - else - SET_PC (PC + (curr_ins_size * 2)); /* For word instructions. */ - } - -#if 0 - /* Check for a breakpoint trap on this instruction. This - overrides any pending branches or loops */ - if (PSR_DB && PC == DBS) - { - SET_BPC (PC); - SET_BPSR (PSR); - SET_PC (SDBT_VECTOR_START); - } -#endif - - /* Writeback all the DATA / PC changes */ - SLOT_FLUSH (); + step_once (sd, cpu); + if (sim_events_tick (sd)) + sim_events_process (sd); } - while ( !State.exception && !stop_simulator); - - if (step && !State.exception) - State.exception = SIGTRAP; } SIM_RC -sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env) +sim_create_inferior (SIM_DESC sd, struct bfd *abfd, + char * const *argv, char * const *env) { bfd_vma start_address; /* reset all state information */ - memset (&State.regs, 0, (uintptr_t)&State.mem - (uintptr_t)&State.regs); + memset (&State, 0, sizeof (State)); /* There was a hack here to copy the values of argc and argv into r0 and r1. The values were also saved into some high memory that @@ -1139,55 +669,49 @@ sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env) start_address = 0x0; #ifdef DEBUG if (cr16_debug) - (*cr16_callback->printf_filtered) (cr16_callback, "sim_create_inferior: PC=0x%lx\n", (long) start_address); + sim_io_printf (sd, "sim_create_inferior: PC=0x%lx\n", (long) start_address); #endif - SET_CREG (PC_CR, start_address); + { + SIM_CPU *cpu = STATE_CPU (sd, 0); + SET_CREG (PC_CR, start_address); + } SLOT_FLUSH (); return SIM_RC_OK; } -void -sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc) +static uint32 +cr16_extract_unsigned_integer (unsigned char *addr, int len) { -/* (*cr16_callback->printf_filtered) (cr16_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */ + uint32 retval; + unsigned char * p; + unsigned char * startaddr = (unsigned char *)addr; + unsigned char * endaddr = startaddr + len; - switch (State.exception) - { - case SIG_CR16_STOP: /* stop instruction */ - *reason = sim_stopped; - *sigrc = 0; - break; + retval = 0; - case SIG_CR16_EXIT: /* exit trap */ - *reason = sim_exited; - *sigrc = GPR (2); - break; + for (p = endaddr; p > startaddr;) + retval = (retval << 8) | *--p; - case SIG_CR16_BUS: - *reason = sim_stopped; - *sigrc = GDB_SIGNAL_BUS; - break; -// -// case SIG_CR16_IAD: -// *reason = sim_stopped; -// *sigrc = GDB_SIGNAL_IAD; -// break; - - default: /* some signal */ - *reason = sim_stopped; - if (stop_simulator && !State.exception) - *sigrc = GDB_SIGNAL_INT; - else - *sigrc = State.exception; - break; - } + return retval; +} + +static void +cr16_store_unsigned_integer (unsigned char *addr, int len, uint32 val) +{ + unsigned char *p; + unsigned char *startaddr = addr; + unsigned char *endaddr = startaddr + len; - stop_simulator = 0; + for (p = startaddr; p < endaddr;) + { + *p++ = val & 0xff; + val >>= 8; + } } -int -sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length) +static int +cr16_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length) { int size; switch ((enum sim_cr16_regs) rn) @@ -1204,15 +728,14 @@ sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length) case SIM_CR16_R9_REGNUM: case SIM_CR16_R10_REGNUM: case SIM_CR16_R11_REGNUM: - WRITE_16 (memory, GPR (rn - SIM_CR16_R0_REGNUM)); + cr16_store_unsigned_integer (memory, 2, GPR (rn - SIM_CR16_R0_REGNUM)); size = 2; break; case SIM_CR16_R12_REGNUM: case SIM_CR16_R13_REGNUM: case SIM_CR16_R14_REGNUM: case SIM_CR16_R15_REGNUM: - //WRITE_32 (memory, GPR (rn - SIM_CR16_R0_REGNUM)); - write_longword (memory, GPR (rn - SIM_CR16_R0_REGNUM)); + cr16_store_unsigned_integer (memory, 4, GPR (rn - SIM_CR16_R0_REGNUM)); size = 4; break; case SIM_CR16_PC_REGNUM: @@ -1226,8 +749,7 @@ sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length) case SIM_CR16_DSR_REGNUM: case SIM_CR16_CAR0_REGNUM: case SIM_CR16_CAR1_REGNUM: - //WRITE_32 (memory, CREG (rn - SIM_CR16_PC_REGNUM)); - write_longword (memory, CREG (rn - SIM_CR16_PC_REGNUM)); + cr16_store_unsigned_integer (memory, 4, CREG (rn - SIM_CR16_PC_REGNUM)); size = 4; break; default: @@ -1236,10 +758,11 @@ sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length) } return size; } - -int -sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length) + +static int +cr16_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length) { + SIM_DESC sd = CPU_STATE (cpu); int size; switch ((enum sim_cr16_regs) rn) { @@ -1255,14 +778,14 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length) case SIM_CR16_R9_REGNUM: case SIM_CR16_R10_REGNUM: case SIM_CR16_R11_REGNUM: - SET_GPR (rn - SIM_CR16_R0_REGNUM, READ_16 (memory)); + SET_GPR (rn - SIM_CR16_R0_REGNUM, cr16_extract_unsigned_integer (memory, 2)); size = 2; break; case SIM_CR16_R12_REGNUM: case SIM_CR16_R13_REGNUM: case SIM_CR16_R14_REGNUM: case SIM_CR16_R15_REGNUM: - SET_GPR32 (rn - SIM_CR16_R0_REGNUM, get_longword (memory)); + SET_GPR32 (rn - SIM_CR16_R0_REGNUM, cr16_extract_unsigned_integer (memory, 2)); size = 4; break; case SIM_CR16_PC_REGNUM: @@ -1276,7 +799,7 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length) case SIM_CR16_DSR_REGNUM: case SIM_CR16_CAR0_REGNUM: case SIM_CR16_CAR1_REGNUM: - SET_CREG (rn - SIM_CR16_PC_REGNUM, get_longword (memory)); + SET_CREG (rn - SIM_CR16_PC_REGNUM, cr16_extract_unsigned_integer (memory, 4)); size = 4; break; default: