return ((addr) & ~(CORE_ADDR) 1);
}
+static CORE_ADDR
+make_mips16_addr (CORE_ADDR addr)
+{
+ return ((addr) | (CORE_ADDR) 1);
+}
+
/* Return the MIPS ABI associated with GDBARCH. */
enum mips_abi
mips_abi (struct gdbarch *gdbarch)
if (((elf_symbol_type *) (sym))->internal_elf_sym.st_other == STO_MIPS16)
{
MSYMBOL_TARGET_FLAG_1 (msym) = 1;
- SYMBOL_VALUE_ADDRESS (msym) |= 1;
}
}
ULONGEST pc;
int regnum = mips_regnum (get_regcache_arch (regcache))->pc;
regcache_cooked_read_signed (regcache, regnum, &pc);
+ if (is_mips16_addr (pc))
+ pc = unmake_mips16_addr (pc);
return pc;
}
static CORE_ADDR
mips_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
- return frame_unwind_register_signed
- (next_frame, gdbarch_num_regs (gdbarch) + mips_regnum (gdbarch)->pc);
+ ULONGEST pc;
+
+ pc = frame_unwind_register_signed
+ (next_frame, gdbarch_num_regs (gdbarch) + mips_regnum (gdbarch)->pc);
+ if (is_mips16_addr (pc))
+ pc = unmake_mips16_addr (pc);
+ return pc;
}
static CORE_ADDR
mips_write_pc (struct regcache *regcache, CORE_ADDR pc)
{
int regnum = mips_regnum (get_regcache_arch (regcache))->pc;
- regcache_cooked_write_unsigned (regcache, regnum, pc);
+ if (mips_pc_is_mips16 (pc))
+ regcache_cooked_write_unsigned (regcache, regnum, make_mips16_addr (pc));
+ else
+ regcache_cooked_write_unsigned (regcache, regnum, pc);
}
/* Fetch and return instruction from the specified location. If the PC
mips_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ if (is_mips16_addr (addr))
+ addr = unmake_mips16_addr (addr);
+
if (mips_mask_address_p (tdep) && (((ULONGEST) addr) >> 32 == 0xffffffffUL))
/* This hack is a work-around for existing boards using PMON, the
simulator, and any other 64-bit targets that doesn't have true
"mips_eabi_push_dummy_call: %d len=%d type=%d",
argnum + 1, len, (int) typecode);
+ /* Function pointer arguments to mips16 code need to be made into
+ mips16 pointers. */
+ if (typecode == TYPE_CODE_PTR
+ && TYPE_CODE (TYPE_TARGET_TYPE (arg_type)) == TYPE_CODE_FUNC)
+ {
+ CORE_ADDR addr = extract_signed_integer (value_contents (arg),
+ len, byte_order);
+ if (mips_pc_is_mips16 (addr))
+ {
+ store_signed_integer (valbuf, len, byte_order,
+ make_mips16_addr (addr));
+ val = valbuf;
+ }
+ else
+ val = value_contents (arg);
+ }
/* The EABI passes structures that do not fit in a register by
reference. */
- if (len > regsize
+ else if (len > regsize
&& (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
{
store_unsigned_integer (valbuf, regsize, byte_order,
for (argnum = 0; argnum < nargs; argnum++)
{
const gdb_byte *val;
+ gdb_byte valbuf[MAX_REGISTER_SIZE];
struct value *arg = args[argnum];
struct type *arg_type = check_typedef (value_type (arg));
int len = TYPE_LENGTH (arg_type);
val = value_contents (arg);
+ /* Function pointer arguments to mips16 code need to be made into
+ mips16 pointers. */
+ if (typecode == TYPE_CODE_PTR
+ && TYPE_CODE (TYPE_TARGET_TYPE (arg_type)) == TYPE_CODE_FUNC)
+ {
+ CORE_ADDR addr = extract_signed_integer (value_contents (arg),
+ len, byte_order);
+ if (mips_pc_is_mips16 (addr))
+ {
+ store_signed_integer (valbuf, len, byte_order,
+ make_mips16_addr (addr));
+ val = valbuf;
+ }
+ }
+
/* Floating point arguments passed in registers have to be
treated specially. On 32-bit architectures, doubles
are passed in register pairs; the even register gets