X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gdb%2Frl78-tdep.c;h=6966f5b5917f66141b5ad23be0650e2423f6f1e9;hb=bd30b2c856c9ae1fc3559d80fc8c8ccdf65e5fce;hp=d178a1fecfe073202f4a83e74d89387a2d293f2b;hpb=6a3a010ba62de90c4fb166550a6bcff4782542db;p=platform%2Fupstream%2Fbinutils.git diff --git a/gdb/rl78-tdep.c b/gdb/rl78-tdep.c index d178a1f..6966f5b 100644 --- a/gdb/rl78-tdep.c +++ b/gdb/rl78-tdep.c @@ -1,6 +1,6 @@ /* Target-dependent code for the Renesas RL78 for GDB, the GNU debugger. - Copyright (C) 2011-2012 Free Software Foundation, Inc. + Copyright (C) 2011-2014 Free Software Foundation, Inc. Contributed by Red Hat, Inc. @@ -94,7 +94,7 @@ enum RL78_PSW_REGNUM, /* 8 bits */ RL78_ES_REGNUM, /* 8 bits */ RL78_CS_REGNUM, /* 8 bits */ - RL78_PC_REGNUM, /* 20 bits; we'll use 32 bits for it. */ + RL78_RAW_PC_REGNUM, /* 20 bits; we'll use 32 bits for it. */ /* Fixed address SFRs (some of those above are SFRs too.) */ RL78_SPL_REGNUM, /* 8 bits; lower half of SP */ @@ -105,7 +105,8 @@ enum RL78_NUM_REGS, /* Pseudo registers. */ - RL78_SP_REGNUM = RL78_NUM_REGS, + RL78_PC_REGNUM = RL78_NUM_REGS, + RL78_SP_REGNUM, RL78_X_REGNUM, RL78_A_REGNUM, @@ -177,6 +178,29 @@ enum 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 }; @@ -243,13 +267,19 @@ rl78_register_type (struct gdbarch *gdbarch, int reg_nr) if (reg_nr == RL78_PC_REGNUM) return tdep->rl78_code_pointer; + else if (reg_nr == RL78_RAW_PC_REGNUM) + return tdep->rl78_uint32; else if (reg_nr <= RL78_MEM_REGNUM || (RL78_X_REGNUM <= reg_nr && reg_nr <= RL78_H_REGNUM) || (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. */ @@ -298,13 +328,14 @@ rl78_register_name (struct gdbarch *gdbarch, int regnr) "psw", "es", "cs", - "pc", + "", "", /* spl */ "", /* sph */ "pmc", "mem", + "pc", "sp", "x", @@ -375,7 +406,147 @@ rl78_register_name (struct gdbarch *gdbarch, int regnr) "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]; @@ -393,7 +564,12 @@ rl78_register_reggroup_p (struct gdbarch *gdbarch, int regnum, /* All other registers are saved and restored. */ if (group == save_reggroup || group == restore_reggroup) { - if (regnum < RL78_NUM_REGS) + if ((regnum < RL78_NUM_REGS + && regnum != RL78_SPL_REGNUM + && regnum != RL78_SPH_REGNUM + && regnum != RL78_RAW_PC_REGNUM) + || regnum == RL78_SP_REGNUM + || regnum == RL78_PC_REGNUM) return 1; else return 0; @@ -406,6 +582,7 @@ rl78_register_reggroup_p (struct gdbarch *gdbarch, int regnum, || regnum == RL78_SPH_REGNUM || regnum == RL78_PMC_REGNUM || regnum == RL78_MEM_REGNUM + || regnum == RL78_RAW_PC_REGNUM || (RL78_BANK0_RP0_REGNUM <= regnum && regnum <= RL78_BANK3_RP3_REGNUM)) return group == system_reggroup; @@ -455,12 +632,28 @@ rl78_pseudo_register_read (struct gdbarch *gdbarch, 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); + } else if (reg == RL78_SP_REGNUM) { status = regcache_raw_read (regcache, RL78_SPL_REGNUM, buffer); if (status == REG_VALID) status = regcache_raw_read (regcache, RL78_SPH_REGNUM, buffer + 1); } + else if (reg == RL78_PC_REGNUM) + { + gdb_byte rawbuf[4]; + + status = regcache_raw_read (regcache, RL78_RAW_PC_REGNUM, rawbuf); + memcpy (buffer, rawbuf, 3); + } else if (RL78_X_REGNUM <= reg && reg <= RL78_H_REGNUM) { ULONGEST psw; @@ -519,11 +712,27 @@ rl78_pseudo_register_write (struct gdbarch *gdbarch, 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); + } else if (reg == RL78_SP_REGNUM) { regcache_raw_write (regcache, RL78_SPL_REGNUM, buffer); regcache_raw_write (regcache, RL78_SPH_REGNUM, buffer + 1); } + else if (reg == RL78_PC_REGNUM) + { + gdb_byte rawbuf[4]; + + memcpy (rawbuf, buffer, 3); + rawbuf[3] = 0; + regcache_raw_write (regcache, RL78_RAW_PC_REGNUM, rawbuf); + } else if (RL78_X_REGNUM <= reg && reg <= RL78_H_REGNUM) { ULONGEST psw; @@ -616,7 +825,7 @@ check_for_saved (void *result_untyped, pv_t addr, CORE_ADDR size, if (value.kind == pvk_register && value.k == 0 && pv_is_register (addr, RL78_SP_REGNUM) - && size == register_size (target_gdbarch, value.reg)) + && size == register_size (target_gdbarch (), value.reg)) result->reg_offset[value.reg] = addr.k; } @@ -643,7 +852,7 @@ rl78_analyze_prologue (CORE_ADDR start_pc, result->reg_offset[rn] = 1; } - stack = make_pv_area (RL78_SP_REGNUM, gdbarch_addr_bit (target_gdbarch)); + stack = make_pv_area (RL78_SP_REGNUM, gdbarch_addr_bit (target_gdbarch ())); back_to = make_cleanup_free_pv_area (stack); /* The call instruction has saved the return address on the stack. */ @@ -901,15 +1110,24 @@ rl78_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) 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; } else if (reg == 32) return RL78_SP_REGNUM; else if (reg == 33) + return -1; /* ap */ + else if (reg == 34) + return RL78_PSW_REGNUM; + else if (reg == 35) + return RL78_ES_REGNUM; + else if (reg == 36) + return RL78_CS_REGNUM; + else if (reg == 37) return RL78_PC_REGNUM; else internal_error (__FILE__, __LINE__, @@ -941,6 +1159,7 @@ rl78_return_value (struct gdbarch *gdbarch, { 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; @@ -949,15 +1168,21 @@ rl78_return_value (struct gdbarch *gdbarch, { 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++; } } @@ -965,15 +1190,22 @@ rl78_return_value (struct gdbarch *gdbarch, { 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++; } } @@ -1021,7 +1253,6 @@ rl78_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct type *value_type = value_enclosing_type (args[i]); int len = TYPE_LENGTH (value_type); int container_len = (len + 1) & ~1; - int offset; sp -= container_len; write_memory (rl78_make_data_address (sp), @@ -1108,7 +1339,10 @@ rl78_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* 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); @@ -1126,6 +1360,7 @@ rl78_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_long_long_bit (gdbarch, 64); set_gdbarch_ptr_bit (gdbarch, 16); set_gdbarch_addr_bit (gdbarch, 32); + set_gdbarch_dwarf2_addr_size (gdbarch, 4); set_gdbarch_float_bit (gdbarch, 32); set_gdbarch_float_format (gdbarch, floatformats_ieee_single); set_gdbarch_double_bit (gdbarch, 32); @@ -1149,6 +1384,8 @@ rl78_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_unwind_pc (gdbarch, rl78_unwind_pc); set_gdbarch_unwind_sp (gdbarch, rl78_unwind_sp); set_gdbarch_frame_align (gdbarch, rl78_frame_align); + + dwarf2_append_unwinders (gdbarch); frame_unwind_append_unwinder (gdbarch, &rl78_unwind); /* Dummy frames, return values. */