diff options
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/ft32-tdep.c | 30 | ||||
-rw-r--r-- | sim/ChangeLog | 4 | ||||
-rw-r--r-- | sim/ft32/interp.c | 22 |
4 files changed, 48 insertions, 13 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a1621e3..f3100f4 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2017-11-01 James Bowman <james.bowman@ftdichip.com> + + * ft32-tdep.c (ft32_fetch_instruction): New function. + (ft32_analyze_prologue): Use ft32_fetch_instruction(). + 2017-10-31 Simon Marchi <simon.marchi@polymtl.ca> * cli/cli-script.c (execute_control_command): Rename to ... diff --git a/gdb/ft32-tdep.c b/gdb/ft32-tdep.c index 757301a..85c5dd0 100644 --- a/gdb/ft32-tdep.c +++ b/gdb/ft32-tdep.c @@ -139,6 +139,25 @@ ft32_store_return_value (struct type *type, struct regcache *regcache, } } +/* Fetch a single 32-bit instruction from address a. If memory contains + a compressed instruction pair, return the expanded instruction. */ + +static ULONGEST +ft32_fetch_instruction (CORE_ADDR a, int *isize, + enum bfd_endian byte_order) +{ + unsigned int sc[2]; + ULONGEST inst; + + CORE_ADDR a4 = a & ~3; + inst = read_code_unsigned_integer (a4, 4, byte_order); + *isize = ft32_decode_shortcode (a4, inst, sc) ? 2 : 4; + if (*isize == 2) + return sc[1 & (a >> 1)]; + else + return inst; +} + /* Decode the instructions within the given address range. Decide when we must have reached the end of the function prologue. If a frame_info pointer is provided, fill in its saved_regs etc. @@ -153,6 +172,7 @@ ft32_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr, enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR next_addr; ULONGEST inst; + int isize = 0; int regnum, pushreg; struct bound_minimal_symbol msymbol; const int first_saved_reg = 13; /* The first saved register. */ @@ -186,16 +206,15 @@ ft32_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr, return end_addr; cache->established = 0; - for (next_addr = start_addr; next_addr < end_addr;) + for (next_addr = start_addr; next_addr < end_addr; next_addr += isize) { - inst = read_memory_unsigned_integer (next_addr, 4, byte_order); + inst = ft32_fetch_instruction (next_addr, &isize, byte_order); if (FT32_IS_PUSH (inst)) { pushreg = FT32_PUSH_REG (inst); cache->framesize += 4; cache->saved_regs[FT32_R0_REGNUM + pushreg] = cache->framesize; - next_addr += 4; } else if (FT32_IS_CALL (inst)) { @@ -210,7 +229,6 @@ ft32_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr, cache->saved_regs[FT32_R0_REGNUM + pushreg] = cache->framesize; } - next_addr += 4; } } break; @@ -229,7 +247,7 @@ ft32_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr, /* It is a LINK? */ if (next_addr < end_addr) { - inst = read_memory_unsigned_integer (next_addr, 4, byte_order); + inst = ft32_fetch_instruction (next_addr, &isize, byte_order); if (FT32_IS_LINK (inst)) { cache->established = 1; @@ -241,7 +259,7 @@ ft32_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr, cache->saved_regs[FT32_PC_REGNUM] = cache->framesize + 4; cache->saved_regs[FT32_FP_REGNUM] = 0; cache->framesize += FT32_LINK_SIZE (inst); - next_addr += 4; + next_addr += isize; } } diff --git a/sim/ChangeLog b/sim/ChangeLog index c39cf2d..3c1a351 100644 --- a/sim/ChangeLog +++ b/sim/ChangeLog @@ -1,3 +1,7 @@ +2017-11-01 James Bowman <james.bowman@ftdichip.com> + + * ft32/interp.c (step_once): Add ft32 shortcode decoder. + 2017-10-12 James Bowman <james.bowman@ftdichip.com> * ft32/interp.c (step_once): Replace FT32_FLD_K8 with K15. diff --git a/sim/ft32/interp.c b/sim/ft32/interp.c index 3bc08ee..d73d4d0 100644 --- a/sim/ft32/interp.c +++ b/sim/ft32/interp.c @@ -340,16 +340,24 @@ step_once (SIM_DESC sd) uint32_t bit_len; uint32_t upper; uint32_t insnpc; + unsigned int sc[2]; + int isize; - if (cpu->state.cycles >= cpu->state.next_tick_cycle) - { - cpu->state.next_tick_cycle += 100000; - ft32_push (sd, cpu->state.pc); - cpu->state.pc = 12; /* interrupt 1. */ - } inst = ft32_read_item (sd, 2, cpu->state.pc); cpu->state.cycles += 1; + if ((STATE_ARCHITECTURE (sd)->mach == bfd_mach_ft32b) + && ft32_decode_shortcode (cpu->state.pc, inst, sc)) + { + if ((cpu->state.pc & 3) == 0) + inst = sc[0]; + else + inst = sc[1]; + isize = 2; + } + else + isize = 4; + /* Handle "call 8" (which is FT32's "break" equivalent) here. */ if (inst == 0x00340002) { @@ -390,7 +398,7 @@ step_once (SIM_DESC sd) upper = (inst >> 27); insnpc = cpu->state.pc; - cpu->state.pc += 4; + cpu->state.pc += isize; switch (upper) { case FT32_PAT_TOC: |