From dcc31d286ad05aa93577181f9a8292009622363e Mon Sep 17 00:00:00 2001 From: James Bowman Date: Wed, 1 Nov 2017 18:34:25 -0700 Subject: [PATCH] FT32: support for FT32B processor - part 2/2 FT32B is a new FT32 family member. This patch adds support for the compressed instructions to gdb and sim. gdb/ChangeLog: * ft32-tdep.c (ft32_fetch_instruction): New function. (ft32_analyze_prologue): Use ft32_fetch_instruction(). sim/ChangeLog: * ft32/interp.c (step_once): Add ft32 shortcode decoder. --- gdb/ChangeLog | 5 +++++ gdb/ft32-tdep.c | 30 ++++++++++++++++++++++++------ sim/ChangeLog | 4 ++++ sim/ft32/interp.c | 22 +++++++++++++++------- 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a1621e3f0a..f3100f48cd 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2017-11-01 James Bowman + + * ft32-tdep.c (ft32_fetch_instruction): New function. + (ft32_analyze_prologue): Use ft32_fetch_instruction(). + 2017-10-31 Simon Marchi * cli/cli-script.c (execute_control_command): Rename to ... diff --git a/gdb/ft32-tdep.c b/gdb/ft32-tdep.c index 757301a2c5..85c5dd074b 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 c39cf2d1ba..3c1a351b16 100644 --- a/sim/ChangeLog +++ b/sim/ChangeLog @@ -1,3 +1,7 @@ +2017-11-01 James Bowman + + * ft32/interp.c (step_once): Add ft32 shortcode decoder. + 2017-10-12 James Bowman * ft32/interp.c (step_once): Replace FT32_FLD_K8 with K15. diff --git a/sim/ft32/interp.c b/sim/ft32/interp.c index 3bc08ee2e4..d73d4d0118 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: -- 2.34.1