/* Target-dependent code for the Renesas RL78 for GDB, the GNU debugger.
- Copyright (C) 2011-2013 Free Software Foundation, Inc.
+ Copyright (C) 2011-2014 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
RL78_BANK3_RP2_REGNUM,
RL78_BANK3_RP3_REGNUM,
+ /* These are the same as the above 16 registers, but have
+ a pointer type for use as base registers in expression
+ evaluation. These are not user visible registers. */
+ RL78_BANK0_RP0_PTR_REGNUM,
+ RL78_BANK0_RP1_PTR_REGNUM,
+ RL78_BANK0_RP2_PTR_REGNUM,
+ RL78_BANK0_RP3_PTR_REGNUM,
+
+ RL78_BANK1_RP0_PTR_REGNUM,
+ RL78_BANK1_RP1_PTR_REGNUM,
+ RL78_BANK1_RP2_PTR_REGNUM,
+ RL78_BANK1_RP3_PTR_REGNUM,
+
+ RL78_BANK2_RP0_PTR_REGNUM,
+ RL78_BANK2_RP1_PTR_REGNUM,
+ RL78_BANK2_RP2_PTR_REGNUM,
+ RL78_BANK2_RP3_PTR_REGNUM,
+
+ RL78_BANK3_RP0_PTR_REGNUM,
+ RL78_BANK3_RP1_PTR_REGNUM,
+ RL78_BANK3_RP2_PTR_REGNUM,
+ RL78_BANK3_RP3_PTR_REGNUM,
+
RL78_NUM_TOTAL_REGS,
RL78_NUM_PSEUDO_REGS = RL78_NUM_TOTAL_REGS - RL78_NUM_REGS
};
|| (RL78_BANK0_R0_REGNUM <= reg_nr
&& reg_nr <= RL78_BANK3_R7_REGNUM))
return tdep->rl78_int8;
- else
+ else if (reg_nr == RL78_SP_REGNUM
+ || (RL78_BANK0_RP0_PTR_REGNUM <= reg_nr
+ && reg_nr <= RL78_BANK3_RP3_PTR_REGNUM))
return tdep->rl78_data_pointer;
+ else
+ return tdep->rl78_int16;
}
/* Implement the "register_name" gdbarch method. */
"bank3_rp0",
"bank3_rp1",
"bank3_rp2",
- "bank3_rp3"
+ "bank3_rp3",
+
+ /* The 16 register slots would be named
+ bank0_rp0_ptr_regnum ... bank3_rp3_ptr_regnum, but we don't
+ want these to be user visible registers. */
+ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
+ };
+
+ return reg_names[regnr];
+}
+
+/* Implement the "register_name" gdbarch method for the g10 variant. */
+
+static const char *
+rl78_g10_register_name (struct gdbarch *gdbarch, int regnr)
+{
+ static const char *const reg_names[] =
+ {
+ "", /* bank0_r0 */
+ "", /* bank0_r1 */
+ "", /* bank0_r2 */
+ "", /* bank0_r3 */
+ "", /* bank0_r4 */
+ "", /* bank0_r5 */
+ "", /* bank0_r6 */
+ "", /* bank0_r7 */
+
+ "", /* bank1_r0 */
+ "", /* bank1_r1 */
+ "", /* bank1_r2 */
+ "", /* bank1_r3 */
+ "", /* bank1_r4 */
+ "", /* bank1_r5 */
+ "", /* bank1_r6 */
+ "", /* bank1_r7 */
+
+ "", /* bank2_r0 */
+ "", /* bank2_r1 */
+ "", /* bank2_r2 */
+ "", /* bank2_r3 */
+ "", /* bank2_r4 */
+ "", /* bank2_r5 */
+ "", /* bank2_r6 */
+ "", /* bank2_r7 */
+
+ "", /* bank3_r0 */
+ "", /* bank3_r1 */
+ "", /* bank3_r2 */
+ "", /* bank3_r3 */
+ "", /* bank3_r4 */
+ "", /* bank3_r5 */
+ "", /* bank3_r6 */
+ "", /* bank3_r7 */
+
+ "psw",
+ "es",
+ "cs",
+ "",
+
+ "", /* spl */
+ "", /* sph */
+ "pmc",
+ "mem",
+
+ "pc",
+ "sp",
+
+ "x",
+ "a",
+ "c",
+ "b",
+ "e",
+ "d",
+ "l",
+ "h",
+
+ "ax",
+ "bc",
+ "de",
+ "hl",
+
+ "bank0_r0",
+ "bank0_r1",
+ "bank0_r2",
+ "bank0_r3",
+ "bank0_r4",
+ "bank0_r5",
+ "bank0_r6",
+ "bank0_r7",
+
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+
+ "bank0_rp0",
+ "bank0_rp1",
+ "bank0_rp2",
+ "bank0_rp3",
+
+ "",
+ "",
+ "",
+ "",
+
+ "",
+ "",
+ "",
+ "",
+
+ "",
+ "",
+ "",
+ "",
+
+ /* The 16 register slots would be named
+ bank0_rp0_ptr_regnum ... bank3_rp3_ptr_regnum, but we don't
+ want these to be user visible registers. */
+ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
};
return reg_names[regnr];
int raw_regnum = 2 * (reg - RL78_BANK0_RP0_REGNUM)
+ RL78_RAW_BANK0_R0_REGNUM;
+ status = regcache_raw_read (regcache, raw_regnum, buffer);
+ if (status == REG_VALID)
+ status = regcache_raw_read (regcache, raw_regnum + 1, buffer + 1);
+ }
+ else if (RL78_BANK0_RP0_PTR_REGNUM <= reg && reg <= RL78_BANK3_RP3_PTR_REGNUM)
+ {
+ int raw_regnum = 2 * (reg - RL78_BANK0_RP0_PTR_REGNUM)
+ + RL78_RAW_BANK0_R0_REGNUM;
+
status = regcache_raw_read (regcache, raw_regnum, buffer);
if (status == REG_VALID)
status = regcache_raw_read (regcache, raw_regnum + 1, buffer + 1);
int raw_regnum = 2 * (reg - RL78_BANK0_RP0_REGNUM)
+ RL78_RAW_BANK0_R0_REGNUM;
+ regcache_raw_write (regcache, raw_regnum, buffer);
+ regcache_raw_write (regcache, raw_regnum + 1, buffer + 1);
+ }
+ else if (RL78_BANK0_RP0_PTR_REGNUM <= reg && reg <= RL78_BANK3_RP3_PTR_REGNUM)
+ {
+ int raw_regnum = 2 * (reg - RL78_BANK0_RP0_PTR_REGNUM)
+ + RL78_RAW_BANK0_R0_REGNUM;
+
regcache_raw_write (regcache, raw_regnum, buffer);
regcache_raw_write (regcache, raw_regnum + 1, buffer + 1);
}
if (0 <= reg && reg <= 31)
{
if ((reg & 1) == 0)
- /* Map even registers to their 16-bit counterparts. This
- is usually what is required from the DWARF info. */
- return (reg >> 1) + RL78_BANK0_RP0_REGNUM;
+ /* Map even registers to their 16-bit counterparts which have a
+ pointer type. This is usually what is required from the DWARF
+ info. */
+ return (reg >> 1) + RL78_BANK0_RP0_PTR_REGNUM;
else
return reg;
}
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
ULONGEST valtype_len = TYPE_LENGTH (valtype);
+ int is_g10 = gdbarch_tdep (gdbarch)->elf_flags & E_FLAG_RL78_G10;
if (valtype_len > 8)
return RETURN_VALUE_STRUCT_CONVENTION;
{
ULONGEST u;
int argreg = RL78_RAW_BANK1_R0_REGNUM;
+ CORE_ADDR g10_raddr = 0xffec8;
int offset = 0;
while (valtype_len > 0)
{
- regcache_cooked_read_unsigned (regcache, argreg, &u);
+ if (is_g10)
+ u = read_memory_integer (g10_raddr, 1,
+ gdbarch_byte_order (gdbarch));
+ else
+ regcache_cooked_read_unsigned (regcache, argreg, &u);
store_unsigned_integer (readbuf + offset, 1, byte_order, u);
valtype_len -= 1;
offset += 1;
argreg++;
+ g10_raddr++;
}
}
{
ULONGEST u;
int argreg = RL78_RAW_BANK1_R0_REGNUM;
+ CORE_ADDR g10_raddr = 0xffec8;
int offset = 0;
while (valtype_len > 0)
{
u = extract_unsigned_integer (writebuf + offset, 1, byte_order);
- regcache_cooked_write_unsigned (regcache, argreg, u);
+ if (is_g10) {
+ gdb_byte b = u & 0xff;
+ write_memory (g10_raddr, &b, 1);
+ }
+ else
+ regcache_cooked_write_unsigned (regcache, argreg, u);
valtype_len -= 1;
offset += 1;
argreg++;
+ g10_raddr++;
}
}
/* Registers. */
set_gdbarch_num_regs (gdbarch, RL78_NUM_REGS);
set_gdbarch_num_pseudo_regs (gdbarch, RL78_NUM_PSEUDO_REGS);
- set_gdbarch_register_name (gdbarch, rl78_register_name);
+ if (tdep->elf_flags & E_FLAG_RL78_G10)
+ set_gdbarch_register_name (gdbarch, rl78_g10_register_name);
+ else
+ set_gdbarch_register_name (gdbarch, rl78_register_name);
set_gdbarch_register_type (gdbarch, rl78_register_type);
set_gdbarch_pc_regnum (gdbarch, RL78_PC_REGNUM);
set_gdbarch_sp_regnum (gdbarch, RL78_SP_REGNUM);