aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR')
0 files changed, 0 insertions, 0 deletions
ss="hl opt">; } static enum register_status mep_pseudo_cr64_read (struct gdbarch *gdbarch, readable_regcache *regcache, int cookednum, gdb_byte *buf) { return regcache->raw_read (mep_pseudo_to_raw[cookednum], buf); } static enum register_status mep_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache, int cookednum, gdb_byte *buf) { if (IS_CSR_REGNUM (cookednum) || IS_CCR_REGNUM (cookednum)) return regcache->raw_read (mep_pseudo_to_raw[cookednum], buf); else if (IS_CR32_REGNUM (cookednum) || IS_FP_CR32_REGNUM (cookednum)) return mep_pseudo_cr32_read (gdbarch, regcache, cookednum, buf); else if (IS_CR64_REGNUM (cookednum) || IS_FP_CR64_REGNUM (cookednum)) return mep_pseudo_cr64_read (gdbarch, regcache, cookednum, buf); else gdb_assert_not_reached ("unexpected pseudo register"); } static void mep_pseudo_csr_write (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, const gdb_byte *buf) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int size = register_size (gdbarch, cookednum); struct mep_csr_register *r = &mep_csr_registers[cookednum - MEP_FIRST_CSR_REGNUM]; if (r->writeable_bits == 0) /* A completely read-only register; avoid the read-modify- write cycle, and juts ignore the entire write. */ ; else { /* A partially writeable register; do a read-modify-write cycle. */ ULONGEST old_bits; ULONGEST new_bits; ULONGEST mixed_bits; regcache_raw_read_unsigned (regcache, r->raw, &old_bits); new_bits = extract_unsigned_integer (buf, size, byte_order); mixed_bits = ((r->writeable_bits & new_bits) | (~r->writeable_bits & old_bits)); regcache_raw_write_unsigned (regcache, r->raw, mixed_bits); } } static void mep_pseudo_cr32_write (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, const gdb_byte *buf) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* Expand the 32-bit value into a 64-bit value, and write that to the pseudoregister. */ int rawnum = mep_pseudo_to_raw[cookednum]; gdb_byte buf64[8]; gdb_assert (register_type (gdbarch, rawnum)->length () == sizeof (buf64)); gdb_assert (register_type (gdbarch, cookednum)->length () == 4); /* Slow, but legible. */ store_unsigned_integer (buf64, 8, byte_order, extract_unsigned_integer (buf, 4, byte_order)); regcache->raw_write (rawnum, buf64); } static void mep_pseudo_cr64_write (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, const gdb_byte *buf) { regcache->raw_write (mep_pseudo_to_raw[cookednum], buf); } static void mep_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, const gdb_byte *buf) { if (IS_CSR_REGNUM (cookednum)) mep_pseudo_csr_write (gdbarch, regcache, cookednum, buf); else if (IS_CR32_REGNUM (cookednum) || IS_FP_CR32_REGNUM (cookednum)) mep_pseudo_cr32_write (gdbarch, regcache, cookednum, buf); else if (IS_CR64_REGNUM (cookednum) || IS_FP_CR64_REGNUM (cookednum)) mep_pseudo_cr64_write (gdbarch, regcache, cookednum, buf); else if (IS_CCR_REGNUM (cookednum)) regcache->raw_write (mep_pseudo_to_raw[cookednum], buf); else gdb_assert_not_reached ("unexpected pseudo register"); } /* Disassembly. */ static int mep_gdb_print_insn (bfd_vma pc, disassemble_info * info) { struct obj_section * s = find_pc_section (pc); info->arch = bfd_arch_mep; if (s) { /* The libopcodes disassembly code uses the section to find the BFD, the BFD to find the ELF header, the ELF header to find the me_module index, and the me_module index to select the right instructions to print. */ info->section = s->the_bfd_section; } return print_insn_mep (pc, info); } /* Prologue analysis. */ /* The MeP has two classes of instructions: "core" instructions, which are pretty normal RISC chip stuff, and "coprocessor" instructions, which are mostly concerned with moving data in and out of coprocessor registers, and branching on coprocessor condition codes. There's space in the instruction set for custom coprocessor instructions, too. Instructions can be 16 or 32 bits long; the top two bits of the first byte indicate the length. The coprocessor instructions are mixed in with the core instructions, and there's no easy way to distinguish them; you have to completely decode them to tell one from the other. The MeP also supports a "VLIW" operation mode, where instructions always occur in fixed-width bundles. The bundles are either 32 bits or 64 bits long, depending on a fixed configuration flag. You decode the first part of the bundle as normal; if it's a core instruction, and there's any space left in the bundle, the remainder of the bundle is a coprocessor instruction, which will execute in parallel with the core instruction. If the first part of the bundle is a coprocessor instruction, it occupies the entire bundle. So, here are all the cases: - 32-bit VLIW mode: Every bundle is four bytes long, and naturally aligned, and can hold one or two instructions: - 16-bit core instruction; 16-bit coprocessor instruction These execute in parallel. - 32-bit core instruction - 32-bit coprocessor instruction - 64-bit VLIW mode: Every bundle is eight bytes long, and naturally aligned, and can hold one or two instructions: - 16-bit core instruction; 48-bit (!) coprocessor instruction These execute in parallel. - 32-bit core instruction; 32-bit coprocessor instruction These execute in parallel. - 64-bit coprocessor instruction Now, the MeP manual doesn't define any 48- or 64-bit coprocessor instruction, so I don't really know what's up there; perhaps these are always the user-defined coprocessor instructions. */ /* Return non-zero if PC is in a VLIW code section, zero otherwise. */ static int mep_pc_in_vliw_section (CORE_ADDR pc) { struct obj_section *s = find_pc_section (pc); if (s) return (s->the_bfd_section->flags & SEC_MEP_VLIW); return 0; } /* Set *INSN to the next core instruction at PC, and return the address of the next instruction. The MeP instruction encoding is endian-dependent. 16- and 32-bit instructions are encoded as one or two two-byte parts, and each part is byte-swapped independently. Thus: void foo (void) { asm ("movu $1, 0x123456"); asm ("sb $1,0x5678($2)"); asm ("clip $1, 19"); } compiles to this big-endian code: 0: d1 56 12 34 movu $1,0x123456 4: c1 28 56 78 sb $1,22136($2) 8: f1 01 10 98 clip $1,0x13 c: 70 02 ret and this little-endian code: 0: 56 d1 34 12 movu $1,0x123456 4: 28 c1 78 56 sb $1,22136($2) 8: 01 f1 98 10 clip $1,0x13 c: 02 70 ret Instructions are returned in *INSN in an endian-independent form: a given instruction always appears in *INSN the same way, regardless of whether the instruction stream is big-endian or little-endian. *INSN's most significant 16 bits are the first (i.e., at lower addresses) 16 bit part of the instruction. Its least significant 16 bits are the second (i.e., higher-addressed) 16 bit part of the instruction, or zero for a 16-bit instruction. Both 16-bit parts are fetched using the current endianness. So, the *INSN values for the instruction sequence above would be the following, in either endianness: 0xd1561234 movu $1,0x123456 0xc1285678 sb $1,22136($2) 0xf1011098 clip $1,0x13 0x70020000 ret (In a sense, it would be more natural to return 16-bit instructions in the least significant 16 bits of *INSN, but that would be ambiguous. In order to tell whether you're looking at a 16- or a 32-bit instruction, you have to consult the major opcode field --- the most significant four bits of the instruction's first 16-bit part. But if we put 16-bit instructions at the least significant end of *INSN, then you don't know where to find the major opcode field until you know if it's a 16- or a 32-bit instruction --- which is where we started.) If PC points to a core / coprocessor bundle in a VLIW section, set *INSN to the core instruction, and return the address of the next bundle. This has the effect of skipping the bundled coprocessor instruction. That's okay, since coprocessor instructions aren't significant to prologue analysis --- for the time being, anyway. */ static CORE_ADDR mep_get_insn (struct gdbarch *gdbarch, CORE_ADDR pc, unsigned long *insn) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int pc_in_vliw_section; int vliw_mode; int insn_len; gdb_byte buf[2]; *insn = 0; /* Are we in a VLIW section? */ pc_in_vliw_section = mep_pc_in_vliw_section (pc); if (pc_in_vliw_section) { /* Yes, find out which bundle size. */ vliw_mode = current_options () & (MEP_OPT_VL32 | MEP_OPT_VL64); /* If PC is in a VLIW section, but the current core doesn't say that it supports either VLIW mode, then we don't have enough information to parse the instruction stream it contains. Since the "undifferentiated" standard core doesn't have either VLIW mode bit set, this could happen. But it shouldn't be an error to (say) set a breakpoint in a VLIW section, if you know you'll never reach it. (Perhaps you have a script that sets a bunch of standard breakpoints.) So we'll just return zero here, and hope for the best. */ if (! (vliw_mode & (MEP_OPT_VL32 | MEP_OPT_VL64))) return 0; /* If both VL32 and VL64 are set, that's bogus, too. */ if (vliw_mode == (MEP_OPT_VL32 | MEP_OPT_VL64)) return 0; } else vliw_mode = 0; read_memory (pc, buf, sizeof (buf)); *insn = extract_unsigned_integer (buf, 2, byte_order) << 16; /* The major opcode --- the top four bits of the first 16-bit part --- indicates whether this instruction is 16 or 32 bits long. All 32-bit instructions have a major opcode whose top two bits are 11; all the rest are 16-bit instructions. */ if ((*insn & 0xc0000000) == 0xc0000000) { /* Fetch the second 16-bit part of the instruction. */ read_memory (pc + 2, buf, sizeof (buf)); *insn = *insn | extract_unsigned_integer (buf, 2, byte_order); } /* If we're in VLIW code, then the VLIW width determines the address of the next instruction. */ if (vliw_mode) { /* In 32-bit VLIW code, all bundles are 32 bits long. We ignore the coprocessor half of a core / copro bundle. */ if (vliw_mode == MEP_OPT_VL32) insn_len = 4; /* In 64-bit VLIW code, all bundles are 64 bits long. We ignore the coprocessor half of a core / copro bundle. */ else if (vliw_mode == MEP_OPT_VL64) insn_len = 8; /* We'd better be in either core, 32-bit VLIW, or 64-bit VLIW mode. */ else gdb_assert_not_reached ("unexpected vliw mode"); } /* Otherwise, the top two bits of the major opcode are (again) what we need to check. */ else if ((*insn & 0xc0000000) == 0xc0000000) insn_len = 4; else insn_len = 2; return pc + insn_len; } /* Sign-extend the LEN-bit value N. */ #define SEXT(n, len) ((((int) (n)) ^ (1 << ((len) - 1))) - (1 << ((len) - 1))) /* Return the LEN-bit field at POS from I. */ #define FIELD(i, pos, len) (((i) >> (pos)) & ((1 << (len)) - 1)) /* Like FIELD, but sign-extend the field's value. */ #define SFIELD(i, pos, len) (SEXT (FIELD ((i), (pos), (len)), (len))) /* Macros for decoding instructions. Remember that 16-bit instructions are placed in bits 16..31 of i, not at the least significant end; this means that the major opcode field is always in the same place, regardless of the width of the instruction. As a reminder of this, we show the lower 16 bits of a 16-bit instruction as xxxx_xxxx_xxxx_xxxx. */ /* SB Rn,(Rm) 0000_nnnn_mmmm_1000 */ /* SH Rn,(Rm) 0000_nnnn_mmmm_1001 */ /* SW Rn,(Rm) 0000_nnnn_mmmm_1010 */ /* SW Rn,disp16(Rm) 1100_nnnn_mmmm_1010 dddd_dddd_dddd_dddd */ #define IS_SW(i) (((i) & 0xf00f0000) == 0xc00a0000) /* SB Rn,disp16(Rm) 1100_nnnn_mmmm_1000 dddd_dddd_dddd_dddd */ #define IS_SB(i) (((i) & 0xf00f0000) == 0xc0080000) /* SH Rn,disp16(Rm) 1100_nnnn_mmmm_1001 dddd_dddd_dddd_dddd */ #define IS_SH(i) (((i) & 0xf00f0000) == 0xc0090000) #define SWBH_32_BASE(i) (FIELD (i, 20, 4)) #define SWBH_32_SOURCE(i) (FIELD (i, 24, 4)) #define SWBH_32_OFFSET(i) (SFIELD (i, 0, 16)) /* SW Rn,disp7.align4(SP) 0100_nnnn_0ddd_dd10 xxxx_xxxx_xxxx_xxxx */ #define IS_SW_IMMD(i) (((i) & 0xf0830000) == 0x40020000) #define SW_IMMD_SOURCE(i) (FIELD (i, 24, 4)) #define SW_IMMD_OFFSET(i) (FIELD (i, 18, 5) << 2) /* SW Rn,(Rm) 0000_nnnn_mmmm_1010 xxxx_xxxx_xxxx_xxxx */ #define IS_SW_REG(i) (((i) & 0xf00f0000) == 0x000a0000) #define SW_REG_SOURCE(i) (FIELD (i, 24, 4)) #define SW_REG_BASE(i) (FIELD (i, 20, 4)) /* ADD3 Rl,Rn,Rm 1001_nnnn_mmmm_llll xxxx_xxxx_xxxx_xxxx */ #define IS_ADD3_16_REG(i) (((i) & 0xf0000000) == 0x90000000) #define ADD3_16_REG_SRC1(i) (FIELD (i, 20, 4)) /* n */ #define ADD3_16_REG_SRC2(i) (FIELD (i, 24, 4)) /* m */ /* ADD3 Rn,Rm,imm16 1100_nnnn_mmmm_0000 iiii_iiii_iiii_iiii */ #define IS_ADD3_32(i) (((i) & 0xf00f0000) == 0xc0000000) #define ADD3_32_TARGET(i) (FIELD (i, 24, 4)) #define ADD3_32_SOURCE(i) (FIELD (i, 20, 4)) #define ADD3_32_OFFSET(i) (SFIELD (i, 0, 16)) /* ADD3 Rn,SP,imm7.align4 0100_nnnn_0iii_ii00 xxxx_xxxx_xxxx_xxxx */ #define IS_ADD3_16(i) (((i) & 0xf0830000) == 0x40000000) #define ADD3_16_TARGET(i) (FIELD (i, 24, 4)) #define ADD3_16_OFFSET(i) (FIELD (i, 18, 5) << 2) /* ADD Rn,imm6 0110_nnnn_iiii_ii00 xxxx_xxxx_xxxx_xxxx */ #define IS_ADD(i) (((i) & 0xf0030000) == 0x60000000) #define ADD_TARGET(i) (FIELD (i, 24, 4)) #define ADD_OFFSET(i) (SFIELD (i, 18, 6)) /* LDC Rn,imm5 0111_nnnn_iiii_101I xxxx_xxxx_xxxx_xxxx imm5 = I||i[7:4] */ #define IS_LDC(i) (((i) & 0xf00e0000) == 0x700a0000) #define LDC_IMM(i) ((FIELD (i, 16, 1) << 4) | FIELD (i, 20, 4)) #define LDC_TARGET(i) (FIELD (i, 24, 4)) /* LW Rn,disp16(Rm) 1100_nnnn_mmmm_1110 dddd_dddd_dddd_dddd */ #define IS_LW(i) (((i) & 0xf00f0000) == 0xc00e0000) #define LW_TARGET(i) (FIELD (i, 24, 4)) #define LW_BASE(i) (FIELD (i, 20, 4)) #define LW_OFFSET(i) (SFIELD (i, 0, 16)) /* MOV Rn,Rm 0000_nnnn_mmmm_0000 xxxx_xxxx_xxxx_xxxx */ #define IS_MOV(i) (((i) & 0xf00f0000) == 0x00000000) #define MOV_TARGET(i) (FIELD (i, 24, 4)) #define MOV_SOURCE(i) (FIELD (i, 20, 4)) /* BRA disp12.align2 1011_dddd_dddd_ddd0 xxxx_xxxx_xxxx_xxxx */ #define IS_BRA(i) (((i) & 0xf0010000) == 0xb0000000) #define BRA_DISP(i) (SFIELD (i, 17, 11) << 1) /* This structure holds the results of a prologue analysis. */ struct mep_prologue { /* The architecture for which we generated this prologue info. */ struct gdbarch *gdbarch; /* The offset from the frame base to the stack pointer --- always zero or negative. Calling this a "size" is a bit misleading, but given that the stack grows downwards, using offsets for everything keeps one from going completely sign-crazy: you never change anything's sign for an ADD instruction; always change the second operand's sign for a SUB instruction; and everything takes care of itself. */ int frame_size; /* Non-zero if this function has initialized the frame pointer from the stack pointer, zero otherwise. */ int has_frame_ptr; /* If has_frame_ptr is non-zero, this is the offset from the frame base to where the frame pointer points. This is always zero or negative. */ int frame_ptr_offset; /* The address of the first instruction at which the frame has been set up and the arguments are where the debug info says they are --- as best as we can tell. */ CORE_ADDR prologue_end; /* reg_offset[R] is the offset from the CFA at which register R is saved, or 1 if register R has not been saved. (Real values are always zero or negative.) */ int reg_offset[MEP_NUM_REGS]; }; /* Return non-zero if VALUE is an incoming argument register. */ static int is_arg_reg (pv_t value) { return (value.kind == pvk_register && MEP_R1_REGNUM <= value.reg && value.reg <= MEP_R4_REGNUM && value.k == 0); } /* Return non-zero if a store of REG's current value VALUE to ADDR is probably spilling an argument register to its stack slot in STACK. Such instructions should be included in the prologue, if possible. The store is a spill if: - the value being stored is REG's original value; - the value has not already been stored somewhere in STACK; and - ADDR is a stack slot's address (e.g., relative to the original value of the SP). */ static int is_arg_spill (struct gdbarch *gdbarch, pv_t value, pv_t addr, struct pv_area *stack) { return (is_arg_reg (value) && pv_is_register (addr, MEP_SP_REGNUM) && ! stack->find_reg (gdbarch, value.reg, 0)); } /* Function for finding saved registers in a 'struct pv_area'; we pass this to pv_area::scan. If VALUE is a saved register, ADDR says it was saved at a constant offset from the frame base, and SIZE indicates that the whole register was saved, record its offset in RESULT_UNTYPED. */ static void check_for_saved (void *result_untyped, pv_t addr, CORE_ADDR size, pv_t value) { struct mep_prologue *result = (struct mep_prologue *) result_untyped; if (value.kind == pvk_register && value.k == 0 && pv_is_register (addr, MEP_SP_REGNUM) && size == register_size (result->gdbarch, value.reg)) result->reg_offset[value.reg] = addr.k; } /* Analyze a prologue starting at START_PC, going no further than LIMIT_PC. Fill in RESULT as appropriate. */ static void mep_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc, CORE_ADDR limit_pc, struct mep_prologue *result) { CORE_ADDR pc; unsigned long insn; pv_t reg[MEP_NUM_REGS]; CORE_ADDR after_last_frame_setup_insn = start_pc; memset (result, 0, sizeof (*result)); result->gdbarch = gdbarch; for (int rn = 0; rn < MEP_NUM_REGS; rn++) { reg[rn] = pv_register (rn, 0); result->reg_offset[rn] = 1; } pv_area stack (MEP_SP_REGNUM, gdbarch_addr_bit (gdbarch)); pc = start_pc; while (pc < limit_pc) { CORE_ADDR next_pc; pv_t pre_insn_fp, pre_insn_sp; next_pc = mep_get_insn (gdbarch, pc, &insn); /* A zero return from mep_get_insn means that either we weren't able to read the instruction from memory, or that we don't have enough information to be able to reliably decode it. So we'll store here and hope for the best. */ if (! next_pc) break; /* Note the current values of the SP and FP, so we can tell if this instruction changed them, below. */ pre_insn_fp = reg[MEP_FP_REGNUM]; pre_insn_sp = reg[MEP_SP_REGNUM]; if (IS_ADD (insn)) { int rn = ADD_TARGET (insn); CORE_ADDR imm6 = ADD_OFFSET (insn); reg[rn] = pv_add_constant (reg[rn], imm6); } else if (IS_ADD3_16 (insn)) { int rn = ADD3_16_TARGET (insn); int imm7 = ADD3_16_OFFSET (insn); reg[rn] = pv_add_constant (reg[MEP_SP_REGNUM], imm7); } else if (IS_ADD3_32 (insn)) { int rn = ADD3_32_TARGET (insn); int rm = ADD3_32_SOURCE (insn); int imm16 = ADD3_32_OFFSET (insn); reg[rn] = pv_add_constant (reg[rm], imm16); } else if (IS_SW_REG (insn)) { int rn = SW_REG_SOURCE (insn); int rm = SW_REG_BASE (insn); /* If simulating this store would require us to forget everything we know about the stack frame in the name of accuracy, it would be better to just quit now. */ if (stack.store_would_trash (reg[rm])) break; if (is_arg_spill (gdbarch, reg[rn], reg[rm], &stack)) after_last_frame_setup_insn = next_pc; stack.store (reg[rm], 4, reg[rn]); } else if (IS_SW_IMMD (insn)) { int rn = SW_IMMD_SOURCE (insn); int offset = SW_IMMD_OFFSET (insn); pv_t addr = pv_add_constant (reg[MEP_SP_REGNUM], offset); /* If simulating this store would require us to forget everything we know about the stack frame in the name of accuracy, it would be better to just quit now. */ if (stack.store_would_trash (addr)) break; if (is_arg_spill (gdbarch, reg[rn], addr, &stack)) after_last_frame_setup_insn = next_pc; stack.store (addr, 4, reg[rn]); } else if (IS_MOV (insn)) { int rn = MOV_TARGET (insn); int rm = MOV_SOURCE (insn); reg[rn] = reg[rm]; if (pv_is_register (reg[rm], rm) && is_arg_reg (reg[rm])) after_last_frame_setup_insn = next_pc; } else if (IS_SB (insn) || IS_SH (insn) || IS_SW (insn)) { int rn = SWBH_32_SOURCE (insn); int rm = SWBH_32_BASE (insn); int disp = SWBH_32_OFFSET (insn); int size = (IS_SB (insn) ? 1 : IS_SH (insn) ? 2 : (gdb_assert (IS_SW (insn)), 4)); pv_t addr = pv_add_constant (reg[rm], disp); if (stack.store_would_trash (addr)) break; if (is_arg_spill (gdbarch, reg[rn], addr, &stack)) after_last_frame_setup_insn = next_pc; stack.store (addr, size, reg[rn]); } else if (IS_LDC (insn)) { int rn = LDC_TARGET (insn); int cr = LDC_IMM (insn) + MEP_FIRST_CSR_REGNUM; reg[rn] = reg[cr]; } else if (IS_LW (insn)) { int rn = LW_TARGET (insn); int rm = LW_BASE (insn); int offset = LW_OFFSET (insn); pv_t addr = pv_add_constant (reg[rm], offset); reg[rn] = stack.fetch (addr, 4); } else if (IS_BRA (insn) && BRA_DISP (insn) > 0) { /* When a loop appears as the first statement of a function body, gcc 4.x will use a BRA instruction to branch to the loop condition checking code. This BRA instruction is marked as part of the prologue. We therefore set next_pc to this branch target and also stop the prologue scan. The instructions at and beyond the branch target should no longer be associated with the prologue. Note that we only consider forward branches here. We presume that a forward branch is being used to skip over a loop body. A backwards branch is covered by the default case below. If we were to encounter a backwards branch, that would most likely mean that we've scanned through a loop body. We definitely want to stop the prologue scan when this happens and that is precisely what is done by the default case below. */ next_pc = pc + BRA_DISP (insn); after_last_frame_setup_insn = next_pc; break; } else /* We've hit some instruction we don't know how to simulate. Strictly speaking, we should set every value we're tracking to "unknown". But we'll be optimistic, assume that we have enough information already, and stop analysis here. */ break; /* If this instruction changed the FP or decreased the SP (i.e., allocated more stack space), then this may be a good place to declare the prologue finished. However, there are some exceptions: - If the instruction just changed the FP back to its original value, then that's probably a restore instruction. The prologue should definitely end before that. - If the instruction increased the value of the SP (that is, shrunk the frame), then it's probably part of a frame teardown sequence, and the prologue should end before that. */ if (! pv_is_identical (reg[MEP_FP_REGNUM], pre_insn_fp)) { if (! pv_is_register_k (reg[MEP_FP_REGNUM], MEP_FP_REGNUM, 0)) after_last_frame_setup_insn = next_pc; } else if (! pv_is_identical (reg[MEP_SP_REGNUM], pre_insn_sp)) { /* The comparison of constants looks odd, there, because .k is unsigned. All it really means is that the new value is lower than it was before the instruction. */ if (pv_is_register (pre_insn_sp, MEP_SP_REGNUM) && pv_is_register (reg[MEP_SP_REGNUM], MEP_SP_REGNUM) && ((pre_insn_sp.k - reg[MEP_SP_REGNUM].k) < (reg[MEP_SP_REGNUM].k - pre_insn_sp.k))) after_last_frame_setup_insn = next_pc; } pc = next_pc; } /* Is the frame size (offset, really) a known constant? */ if (pv_is_register (reg[MEP_SP_REGNUM], MEP_SP_REGNUM)) result->frame_size = reg[MEP_SP_REGNUM].k; /* Was the frame pointer initialized? */ if (pv_is_register (reg[MEP_FP_REGNUM], MEP_SP_REGNUM)) { result->has_frame_ptr = 1; result->frame_ptr_offset = reg[MEP_FP_REGNUM].k; } /* Record where all the registers were saved. */ stack.scan (check_for_saved, (void *) result); result->prologue_end = after_last_frame_setup_insn; } static CORE_ADDR mep_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) { const char *name; CORE_ADDR func_addr, func_end; struct mep_prologue p; /* Try to find the extent of the function that contains PC. */ if (! find_pc_partial_function (pc, &name, &func_addr, &func_end)) return pc; mep_analyze_prologue (gdbarch, pc, func_end, &p); return p.prologue_end; } /* Breakpoints. */ constexpr gdb_byte mep_break_insn[] = { 0x70, 0x32 }; typedef BP_MANIPULATION (mep_break_insn) mep_breakpoint; /* Frames and frame unwinding. */ static struct mep_prologue * mep_analyze_frame_prologue (const frame_info_ptr &this_frame, void **this_prologue_cache) { if (! *this_prologue_cache) { CORE_ADDR func_start, stop_addr; *this_prologue_cache = FRAME_OBSTACK_ZALLOC (struct mep_prologue); func_start = get_frame_func (this_frame); stop_addr = get_frame_pc (this_frame); /* If we couldn't find any function containing the PC, then just initialize the prologue cache, but don't do anything. */ if (! func_start) stop_addr = func_start; mep_analyze_prologue (get_frame_arch (this_frame), func_start, stop_addr, (struct mep_prologue *) *this_prologue_cache); } return (struct mep_prologue *) *this_prologue_cache; } /* Given the next frame and a prologue cache, return this frame's base. */ static CORE_ADDR mep_frame_base (const frame_info_ptr &this_frame, void **this_prologue_cache) { struct mep_prologue *p = mep_analyze_frame_prologue (this_frame, this_prologue_cache); /* In functions that use alloca, the distance between the stack pointer and the frame base varies dynamically, so we can't use the SP plus static information like prologue analysis to find the frame base. However, such functions must have a frame pointer, to be able to restore the SP on exit. So whenever we do have a frame pointer, use that to find the base. */ if (p->has_frame_ptr) { CORE_ADDR fp = get_frame_register_unsigned (this_frame, MEP_FP_REGNUM); return fp - p->frame_ptr_offset; } else { CORE_ADDR sp = get_frame_register_unsigned (this_frame, MEP_SP_REGNUM); return sp - p->frame_size; } } static void mep_frame_this_id (const frame_info_ptr &this_frame, void **this_prologue_cache, struct frame_id *this_id) { *this_id = frame_id_build (mep_frame_base (this_frame, this_prologue_cache), get_frame_func (this_frame)); } static struct value * mep_frame_prev_register (const frame_info_ptr &this_frame, void **this_prologue_cache, int regnum) { struct mep_prologue *p = mep_analyze_frame_prologue (this_frame, this_prologue_cache); /* There are a number of complications in unwinding registers on the MeP, having to do with core functions calling VLIW functions and vice versa. The least significant bit of the link register, LP.LTOM, is the VLIW mode toggle bit: it's set if a core function called a VLIW function, or vice versa, and clear when the caller and callee were both in the same mode. So, if we're asked to unwind the PC, then we really want to unwind the LP and clear the least significant bit. (Real return addresses are always even.) And if we want to unwind the program status word (PSW), we need to toggle PSW.OM if LP.LTOM is set. Tweaking the register values we return in this way means that the bits in BUFFERP[] are not the same as the bits you'd find at ADDRP in the inferior, so we make sure lvalp is not_lval when we do this. */ if (regnum == MEP_PC_REGNUM) { struct value *value; CORE_ADDR lp; value = mep_frame_prev_register (this_frame, this_prologue_cache, MEP_LP_REGNUM); lp = value_as_long (value); release_value (value); return frame_unwind_got_constant (this_frame, regnum, lp & ~1); } else { CORE_ADDR frame_base = mep_frame_base (this_frame, this_prologue_cache); struct value *value; /* Our caller's SP is our frame base. */ if (regnum == MEP_SP_REGNUM) return frame_unwind_got_constant (this_frame, regnum, frame_base); /* If prologue analysis says we saved this register somewhere, return a description of the stack slot holding it. */ if (p->reg_offset[regnum] != 1) value = frame_unwind_got_memory (this_frame, regnum, frame_base + p->reg_offset[regnum]); /* Otherwise, presume we haven't changed the value of this register, and get it from the next frame. */ else value = frame_unwind_got_register (this_frame, regnum, regnum); /* If we need to toggle the operating mode, do so. */ if (regnum == MEP_PSW_REGNUM) { CORE_ADDR psw, lp; psw = value_as_long (value); release_value (value); /* Get the LP's value, too. */ value = get_frame_register_value (this_frame, MEP_LP_REGNUM); lp = value_as_long (value); release_value (value); /* If LP.LTOM is set, then toggle PSW.OM. */ if (lp & 0x1) psw ^= 0x1000; return frame_unwind_got_constant (this_frame, regnum, psw); } return value; } } static const struct frame_unwind_legacy mep_frame_unwind ( "mep prologue", NORMAL_FRAME, FRAME_UNWIND_ARCH, default_frame_unwind_stop_reason, mep_frame_this_id, mep_frame_prev_register, NULL, default_frame_sniffer ); /* Return values. */ static int mep_use_struct_convention (struct type *type) { return (type->length () > MEP_GPR_SIZE); } static void mep_extract_return_value (struct gdbarch *arch, struct type *type, struct regcache *regcache, gdb_byte *valbuf) { int byte_order = gdbarch_byte_order (arch); /* Values that don't occupy a full register appear at the less significant end of the value. This is the offset to where the value starts. */ int offset; /* Return values > MEP_GPR_SIZE bytes are returned in memory, pointed to by R0. */ gdb_assert (type->length () <= MEP_GPR_SIZE); if (byte_order == BFD_ENDIAN_BIG) offset = MEP_GPR_SIZE - type->length (); else offset = 0; /* Return values that do fit in a single register are returned in R0. */ regcache->cooked_read_part (MEP_R0_REGNUM, offset, type->length (), valbuf); } static void mep_store_return_value (struct gdbarch *arch, struct type *type, struct regcache *regcache, const gdb_byte *valbuf) { int byte_order = gdbarch_byte_order (arch); /* Values that fit in a single register go in R0. */ if (type->length () <= MEP_GPR_SIZE) { /* Values that don't occupy a full register appear at the least significant end of the value. This is the offset to where the value starts. */ int offset; if (byte_order == BFD_ENDIAN_BIG) offset = MEP_GPR_SIZE - type->length (); else offset = 0; regcache->cooked_write_part (MEP_R0_REGNUM, offset, type->length (), valbuf); } /* Return values larger than a single register are returned in memory, pointed to by R0. Unfortunately, we can't count on R0 pointing to the return buffer, so we raise an error here. */ else error (_("\ GDB cannot set return values larger than four bytes; the Media Processor's\n\ calling conventions do not provide enough information to do this.\n\ Try using the 'return' command with no argument.")); } static enum return_value_convention mep_return_value (struct gdbarch *gdbarch, struct value *function, struct type *type, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { if (mep_use_struct_convention (type)) { if (readbuf) { ULONGEST addr; /* Although the address of the struct buffer gets passed in R1, it's returned in R0. Fetch R0's value and then read the memory at that address. */ regcache_raw_read_unsigned (regcache, MEP_R0_REGNUM, &addr); read_memory (addr, readbuf, type->length ()); } if (writebuf) { /* Return values larger than a single register are returned in memory, pointed to by R0. Unfortunately, we can't count on R0 pointing to the return buffer, so we raise an error here. */ error (_("\ GDB cannot set return values larger than four bytes; the Media Processor's\n\ calling conventions do not provide enough information to do this.\n\ Try using the 'return' command with no argument.")); } return RETURN_VALUE_ABI_RETURNS_ADDRESS; } if (readbuf) mep_extract_return_value (gdbarch, type, regcache, readbuf); if (writebuf) mep_store_return_value (gdbarch, type, regcache, writebuf); return RETURN_VALUE_REGISTER_CONVENTION; } /* Inferior calls. */ static CORE_ADDR mep_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp) { /* Require word alignment. */ return sp & -4; } /* From "lang_spec2.txt": 4.2 Calling conventions 4.2.1 Core register conventions - Parameters should be evaluated from left to right, and they should be held in $1,$2,$3,$4 in order. The fifth parameter or after should be held in the stack. If the size is larger than 4 bytes in the first four parameters, the pointer should be held in the registers instead. If the size is larger than 4 bytes in the fifth parameter or after, the pointer should be held in the stack. - Return value of a function should be held in register $0. If the size of return value is larger than 4 bytes, $1 should hold the pointer pointing memory that would hold the return value. In this case, the first parameter should be held in $2, the second one in $3, and the third one in $4, and the forth parameter or after should be held in the stack. [This doesn't say so, but arguments shorter than four bytes are passed in the least significant end of a four-byte word when they're passed on the stack.] */ /* Traverse the list of ARGC arguments ARGV; for every ARGV[i] too large to fit in a register, save it on the stack, and place its address in COPY[i]. SP is the initial stack pointer; return the new stack pointer. */ static CORE_ADDR push_large_arguments (CORE_ADDR sp, int argc, struct value **argv, CORE_ADDR copy[]) { int i; for (i = 0; i < argc; i++) { unsigned arg_len = argv[i]->type ()->length (); if (arg_len > MEP_GPR_SIZE) { /* Reserve space for the copy, and then round the SP down, to make sure it's all aligned properly. */ sp = (sp - arg_len) & -4; write_memory (sp, argv[i]->contents ().data (), arg_len); copy[i] = sp; } } return sp; } static CORE_ADDR mep_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, int argc, struct value **argv, CORE_ADDR sp, function_call_return_method return_method, CORE_ADDR struct_addr) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR *copy = (CORE_ADDR *) alloca (argc * sizeof (copy[0])); int i; /* The number of the next register available to hold an argument. */ int arg_reg; /* The address of the next stack slot available to hold an argument. */ CORE_ADDR arg_stack; /* The address of the end of the stack area for arguments. This is just for error checking. */ CORE_ADDR arg_stack_end; sp = push_large_arguments (sp, argc, argv, copy); /* Reserve space for the stack arguments, if any. */ arg_stack_end = sp; if (argc + (struct_addr ? 1 : 0) > 4) sp -= ((argc + (struct_addr ? 1 : 0)) - 4) * MEP_GPR_SIZE; arg_reg = MEP_R1_REGNUM; arg_stack = sp; /* If we're returning a structure by value, push the pointer to the buffer as the first argument. */ if (return_method == return_method_struct) { regcache_cooked_write_unsigned (regcache, arg_reg, struct_addr); arg_reg++; } for (i = 0; i < argc; i++) { ULONGEST value; /* Arguments that fit in a GPR get expanded to fill the GPR. */ if (argv[i]->type ()->length () <= MEP_GPR_SIZE) value = extract_unsigned_integer (argv[i]->contents ().data (), argv[i]->type ()->length (), byte_order); /* Arguments too large to fit in a GPR get copied to the stack, and we pass a pointer to the copy. */ else value = copy[i]; /* We use $1 -- $4 for passing arguments, then use the stack. */ if (arg_reg <= MEP_R4_REGNUM) { regcache_cooked_write_unsigned (regcache, arg_reg, value); arg_reg++; } else { gdb_byte buf[MEP_GPR_SIZE]; store_unsigned_integer (buf, MEP_GPR_SIZE, byte_order, value); write_memory (arg_stack, buf, MEP_GPR_SIZE); arg_stack += MEP_GPR_SIZE; } } gdb_assert (arg_stack <= arg_stack_end); /* Set the return address. */ regcache_cooked_write_unsigned (regcache, MEP_LP_REGNUM, bp_addr); /* Update the stack pointer. */ regcache_cooked_write_unsigned (regcache, MEP_SP_REGNUM, sp); return sp; } /* Initialization. */ static struct gdbarch * mep_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { /* Which me_module are we building a gdbarch object for? */ CONFIG_ATTR me_module; /* If we have a BFD in hand, figure out which me_module it was built for. Otherwise, use the no-particular-me_module code. */ if (info.abfd) { /* The way to get the me_module code depends on the object file format. At the moment, we only know how to handle ELF. */ if (bfd_get_flavour (info.abfd) == bfd_target_elf_flavour) { int flag = elf_elfheader (info.abfd)->e_flags & EF_MEP_INDEX_MASK; me_module = (CONFIG_ATTR) flag; } else me_module = CONFIG_NONE; } else me_module = CONFIG_NONE; /* If we're setting the architecture from a file, check the endianness of the file against that of the me_module. */ if (info.abfd) { /* The negations on either side make the comparison treat all non-zero (true) values as equal. */ if (! bfd_big_endian (info.abfd) != ! me_module_big_endian (me_module)) { const char *module_name = me_module_name (me_module); const char *module_endianness = me_module_big_endian (me_module) ? "big" : "little"; const char *file_name = bfd_get_filename (info.abfd); const char *file_endianness = bfd_big_endian (info.abfd) ? "big" : "little"; gdb_putc ('\n', gdb_stderr); if (module_name) warning (_("the MeP module '%s' is %s-endian, but the executable\n" "%s is %s-endian."), module_name, module_endianness, file_name, file_endianness); else warning (_("the selected MeP module is %s-endian, but the " "executable\n" "%s is %s-endian."), module_endianness, file_name, file_endianness); } } /* Find a candidate among the list of architectures we've created already. info->bfd_arch_info needs to match, but we also want the right me_module: the ELF header's e_flags field needs to match as well. */ for (arches = gdbarch_list_lookup_by_info (arches, &info); arches != NULL; arches = gdbarch_list_lookup_by_info (arches->next, &info)) { mep_gdbarch_tdep *tdep = gdbarch_tdep<mep_gdbarch_tdep> (arches->gdbarch); if (tdep->me_module == me_module) return arches->gdbarch; } gdbarch *gdbarch = gdbarch_alloc (&info, gdbarch_tdep_up (new mep_gdbarch_tdep)); mep_gdbarch_tdep *tdep = gdbarch_tdep<mep_gdbarch_tdep> (gdbarch); /* Get a CGEN CPU descriptor for this architecture. */ { const char *mach_name = info.bfd_arch_info->printable_name; enum cgen_endian endian = (info.byte_order == BFD_ENDIAN_BIG ? CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE); tdep->cpu_desc = mep_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name, CGEN_CPU_OPEN_ENDIAN, endian, CGEN_CPU_OPEN_END); } tdep->me_module = me_module; /* Register set. */ set_gdbarch_num_regs (gdbarch, MEP_NUM_RAW_REGS); set_gdbarch_pc_regnum (gdbarch, MEP_PC_REGNUM); set_gdbarch_sp_regnum (gdbarch, MEP_SP_REGNUM); set_gdbarch_register_name (gdbarch, mep_register_name); set_gdbarch_register_type (gdbarch, mep_register_type); set_gdbarch_num_pseudo_regs (gdbarch, MEP_NUM_PSEUDO_REGS); set_gdbarch_pseudo_register_read (gdbarch, mep_pseudo_register_read); set_gdbarch_deprecated_pseudo_register_write (gdbarch, mep_pseudo_register_write); set_gdbarch_dwarf2_reg_to_regnum (gdbarch, mep_debug_reg_to_regnum); set_gdbarch_stab_reg_to_regnum (gdbarch, mep_debug_reg_to_regnum); set_gdbarch_register_reggroup_p (gdbarch, mep_register_reggroup_p); reggroup_add (gdbarch, mep_csr_reggroup); reggroup_add (gdbarch, mep_cr_reggroup); reggroup_add (gdbarch, mep_ccr_reggroup); /* Disassembly. */ set_gdbarch_print_insn (gdbarch, mep_gdb_print_insn); /* Breakpoints. */ set_gdbarch_breakpoint_kind_from_pc (gdbarch, mep_breakpoint::kind_from_pc); set_gdbarch_sw_breakpoint_from_kind (gdbarch, mep_breakpoint::bp_from_kind); set_gdbarch_decr_pc_after_break (gdbarch, 0); set_gdbarch_skip_prologue (gdbarch, mep_skip_prologue); /* Frames and frame unwinding. */ frame_unwind_append_unwinder (gdbarch, &mep_frame_unwind); set_gdbarch_inner_than (gdbarch, core_addr_lessthan); set_gdbarch_frame_args_skip (gdbarch, 0); /* Return values. */ set_gdbarch_return_value (gdbarch, mep_return_value); /* Inferior function calls. */ set_gdbarch_frame_align (gdbarch, mep_frame_align); set_gdbarch_push_dummy_call (gdbarch, mep_push_dummy_call); return gdbarch; } void _initialize_mep_tdep (); void _initialize_mep_tdep () { mep_csr_reggroup = reggroup_new ("csr", USER_REGGROUP); mep_cr_reggroup = reggroup_new ("cr", USER_REGGROUP); mep_ccr_reggroup = reggroup_new ("ccr", USER_REGGROUP); gdbarch_register (bfd_arch_mep, mep_gdbarch_init); mep_init_pseudoregister_maps (); }