diff options
author | James Bowman <jamesb@excamera.com> | 2017-11-01 18:34:25 -0700 |
---|---|---|
committer | James Bowman <jamesb@excamera.com> | 2017-11-01 18:36:51 -0700 |
commit | dcc31d286ad05aa93577181f9a8292009622363e (patch) | |
tree | f455afb6e8e5f4ff9c702fa00d129091f94e9be5 /gdb/ft32-tdep.c | |
parent | 89f3c4b6b9b565720f88636d966f22923c03e9cb (diff) | |
download | gdb-dcc31d286ad05aa93577181f9a8292009622363e.zip gdb-dcc31d286ad05aa93577181f9a8292009622363e.tar.gz gdb-dcc31d286ad05aa93577181f9a8292009622363e.tar.bz2 |
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.
Diffstat (limited to 'gdb/ft32-tdep.c')
-rw-r--r-- | gdb/ft32-tdep.c | 30 |
1 files changed, 24 insertions, 6 deletions
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; } } |