Hi Yoshinori,
Looks like this fell through the cracks. Very sorry about that.
Better late and never, I hope!
On 12/21/2015 05:36 PM, Yoshinori Sato wrote:
> gdb/ChangeLog
> * features/rx.xml: New. v1 regsiter define.
> * features/rx.c: New.
> * features/rxv2.xml: New. v2 regsiter define.
Typo "regsiter".
> * features/rxv2.c: New.
> * rx-tdep.c: include register define.
Uppercase "Include".
> (RX_ACC_NUM): Delete.
> (RX_V1_NUM_REGS): New. num of v1 regster.
> (RX_V2_NUM_REGS): New. num of v2 regster.
Uppercase "Num". Typo "regster".
> (RX_NUM_REGS): v2 register support.
> (rx_reg_names): New.
> (rx_v2_reg_names): New.
> (rx_register_name): Use target description.
> (rxv2_register_name): New.
> (rx_register_type): Use target description.
> (rxv2_register_type): New.
> (rx_analyze_prologue): Use RX_V2_NUM_REGS.
> (rx_gdbarch_init): Use target description.
> (initalize_rx_tdep): Add target description initialize.
>
> ---
> gdb/features/rx.c | 78 +++++++++++++++++++++
> gdb/features/rx.xml | 70 +++++++++++++++++++
> gdb/features/rxv2.c | 80 ++++++++++++++++++++++
> gdb/features/rxv2.xml | 72 +++++++++++++++++++
> gdb/rx-tdep.c | 186 ++++++++++++++++++++++++++------------------------
> 5 files changed, 397 insertions(+), 89 deletions(-)
> create mode 100644 gdb/features/rx.c
> create mode 100644 gdb/features/rx.xml
> create mode 100644 gdb/features/rxv2.c
> create mode 100644 gdb/features/rxv2.xml
>
> diff --git a/gdb/features/rx.c b/gdb/features/rx.c
> new file mode 100644
> index 0000000..937e840
> --- /dev/null
> +++ b/gdb/features/rx.c
> @@ -0,0 +1,78 @@
> +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro:
> + Original: rx.xml */
There's been changes in the generator code meanwhile. I think
you'll need to regenerate these. Hopefully that won't be much
trouble.
> +++ b/gdb/features/rx.xml
> @@ -0,0 +1,70 @@
> +<?xml version="1.0"?>
> +<!-- Copyright (C) 2015 Free Software Foundation, Inc.
Needs to be 2015-2016 now.
> +
>
> +#define RX_NUM_REGS(arch) ((gdbarch_tdep(arch)->elf_flags & E_FLAG_RX_V2)? \
> + RX_V2_NUM_REGS:RX_V1_NUM_REGS)
Spaces around ? and :.
> +
> +static const char *const rx_reg_names[] = {
> + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
> + "r8", "r9", "r10","r11","r12","r13","r14","r15",
> + "usp","isp","psw","pc", "intb","bpsw","bpc","fintv",
> + "fpsw","acc"
> + };
> +
> +static const char *const rxv2_reg_names[] = {
> + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
> + "r8", "r9", "r10","r11","r12","r13","r14","r15",
> + "usp","isp","psw","pc", "intb","bpsw","bpc","fintv",
> + "fpsw","acc0","extb","acc1"
> + };
> +
> /* Implement the "register_name" gdbarch method. */
> static const char *
> -rx_register_name (struct gdbarch *gdbarch, int regnr)
> +rx_register_name (struct gdbarch *gdbarch, int reg_nr)
> {
> - static const char *const reg_names[] = {
> - "r0",
> - "r1",
> - "r2",
> - "r3",
> - "r4",
> - "r5",
> - "r6",
> - "r7",
> - "r8",
> - "r9",
> - "r10",
> - "r11",
> - "r12",
> - "r13",
> - "r14",
> - "r15",
> - "usp",
> - "isp",
> - "psw",
> - "pc",
> - "intb",
> - "bpsw",
> - "bpc",
> - "fintv",
> - "fpsw",
> - "acc"
> - };
> + if (reg_nr < RX_V1_NUM_REGS)
> + return rx_reg_names[reg_nr];
> + else
> + return tdesc_register_name (gdbarch, reg_nr);
I think you should prefer the tdesc's register names if
the tdesc as registers. See tic6x_register_name for
example. Not sure you can get here without a tdesc, even,
given the fallback tdescs in place.
> +}
>
> - return reg_names[regnr];
> +static const char *
> +rxv2_register_name (struct gdbarch *gdbarch, int reg_nr)
> +{
> + if (reg_nr < RX_V2_NUM_REGS)
> + return rxv2_reg_names[reg_nr];
> + else
> + return tdesc_register_name (gdbarch, reg_nr);
> }
>
Likewise.
> /* Implement the "register_type" gdbarch method. */
> static struct type *
> rx_register_type (struct gdbarch *gdbarch, int reg_nr)
> {
> - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> -
> - if (reg_nr == RX_PC_REGNUM)
> - return builtin_type (gdbarch)->builtin_func_ptr;
> - else if (reg_nr == RX_PSW_REGNUM || reg_nr == RX_BPSW_REGNUM)
> - return tdep->rx_psw_type;
> - else if (reg_nr == RX_FPSW_REGNUM)
> - return tdep->rx_fpsw_type;
> - else if (reg_nr == RX_ACC_REGNUM)
> - return builtin_type (gdbarch)->builtin_unsigned_long_long;
> - else
> - return builtin_type (gdbarch)->builtin_unsigned_long;
> + return tdesc_register_type (gdbarch, reg_nr);
> }
>
> +static struct type *
> +rxv2_register_type (struct gdbarch *gdbarch, int reg_nr)
> +{
> + return tdesc_register_type (gdbarch, reg_nr);
> +}
Here it seems like you're assuming a tdesc is available, which
gives more weight to my comment above.
>
> /* Function for finding saved registers in a 'struct pv_area'; this
> function is passed to pv_area_scan.
> @@ -225,7 +222,7 @@ rx_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
> {
> CORE_ADDR pc, next_pc;
> int rn;
> - pv_t reg[RX_NUM_REGS];
> + pv_t reg[RX_V2_NUM_REGS];
> struct pv_area *stack;
> struct cleanup *back_to;
> CORE_ADDR after_last_frame_setup_insn = start_pc;
> @@ -234,7 +231,7 @@ rx_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
>
> result->frame_type = frame_type;
>
> - for (rn = 0; rn < RX_NUM_REGS; rn++)
> + for (rn = 0; rn < RX_V2_NUM_REGS; rn++)
> {
> reg[rn] = pv_register (rn, 0);
> result->reg_offset[rn] = 1;
Will these loops still do the right thing for v1?
> @@ -1021,6 +1018,10 @@ rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
> struct gdbarch *gdbarch;
> struct gdbarch_tdep *tdep;
> int elf_flags;
> + int register_bytes, i;
> + int numregs;
> + struct tdesc_arch_data *tdesc_data = NULL;
> + const struct target_desc *tdesc = info.target_desc;
>
> /* Extract the elf_flags if available. */
> if (info.abfd != NULL
> @@ -1028,7 +1029,40 @@ rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
> elf_flags = elf_elfheader (info.abfd)->e_flags;
> else
> elf_flags = 0;
> + if (!tdesc_has_registers (tdesc))
> + /* Pick a default target description. */
> + tdesc = (info.bfd_arch_info->mach == bfd_mach_rx)?tdesc_rx:tdesc_rxv2;
Spaces around ? and :. Won't info.bfd_arch_info be NULL if you have
no program loaded in gdb at all?
>
> + numregs = (info.bfd_arch_info->mach == bfd_mach_rx)?RX_V1_NUM_REGS:RX_V2_NUM_REGS;
Spaces.
> +
> + /* Check any target description for validity. */
> + if (tdesc_has_registers (tdesc))
> + {
> + const struct tdesc_feature *feature;
> + int valid_p;
> + const char * const *reg;
> +
> + if (info.bfd_arch_info->mach == bfd_mach_rx)
> + feature = tdesc_find_feature (tdesc, "org.gnu.gdb.rx");
> + else
> + feature = tdesc_find_feature (tdesc, "org.gnu.gdb.rx.v2");
> + if (feature == NULL)
> + return NULL;
> +
> + tdesc_data = tdesc_data_alloc ();
> +
> + valid_p = 1;
> +
> + reg = (info.bfd_arch_info->mach == bfd_mach_rx)?rx_reg_names:rxv2_reg_names;
Spaces.
> + for (i = 0; i < numregs; i++)
> + valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
> + reg[i]);
> + if (!valid_p)
> + {
> + tdesc_data_cleanup (tdesc_data);
> + return NULL;
> + }
> + }
>
> /* Try to find the architecture in the list of already defined
> architectures. */
We're missing a change to the manual to document the new standard
target description features:
https://sourceware.org/gdb/onlinedocs/gdb/Standard-Target-Features.html#Standard-Target-Features
along with a NEWS entry.
Other that that, this looks pretty close to being ready. Thanks for the
v2, and again, sorry for the long delay. Going through a target description
makes it possible for the remote stub to describe random non-standard registers
(like e.g., i/o control registers) and gdb display them, all without further
changes to gdb, so I think it's well worth it to extra initial effort.
Please repost a fixed patch with a (concise, self-contained) rationale for
the change, as per [1], and I'll try to review it promptly. The idea is that
the commit log is an integral part of the patch that ends up pushed to git.
[1] - https://sourceware.org/gdb/wiki/ContributionChecklist
Thanks,
Pedro Alves
new file mode 100644
@@ -0,0 +1,78 @@
+/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro:
+ Original: rx.xml */
+
+#include "defs.h"
+#include "osabi.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_rx;
+static void
+initialize_tdesc_rx (void)
+{
+ struct target_desc *result = allocate_target_description ();
+ struct tdesc_feature *feature;
+ struct tdesc_type *field_type;
+
+ set_tdesc_architecture (result, bfd_scan_arch ("rx"));
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.rx");
+ field_type = tdesc_create_flags (feature, "rx_psw_type", 4);
+ tdesc_add_flag (field_type, 0, "C");
+ tdesc_add_flag (field_type, 1, "Z");
+ tdesc_add_flag (field_type, 2, "S");
+ tdesc_add_flag (field_type, 3, "O");
+ tdesc_add_flag (field_type, 16, "I");
+ tdesc_add_flag (field_type, 17, "U");
+ tdesc_add_flag (field_type, 20, "PM");
+ tdesc_add_flag (field_type, 24, "IPL");
+
+ field_type = tdesc_create_flags (feature, "rx_fpsw_type", 4);
+ tdesc_add_flag (field_type, 0, "RM");
+ tdesc_add_flag (field_type, 2, "CV");
+ tdesc_add_flag (field_type, 3, "CO");
+ tdesc_add_flag (field_type, 4, "CZ");
+ tdesc_add_flag (field_type, 5, "CU");
+ tdesc_add_flag (field_type, 6, "CX");
+ tdesc_add_flag (field_type, 7, "CE");
+ tdesc_add_flag (field_type, 8, "DN");
+ tdesc_add_flag (field_type, 10, "EV");
+ tdesc_add_flag (field_type, 11, "EO");
+ tdesc_add_flag (field_type, 12, "EZ");
+ tdesc_add_flag (field_type, 13, "EU");
+ tdesc_add_flag (field_type, 14, "EX");
+ tdesc_add_flag (field_type, 26, "FV");
+ tdesc_add_flag (field_type, 27, "FO");
+ tdesc_add_flag (field_type, 28, "FZ");
+ tdesc_add_flag (field_type, 29, "FU");
+ tdesc_add_flag (field_type, 30, "FX");
+ tdesc_add_flag (field_type, 31, "FS");
+
+ tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "data_ptr");
+ tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r5", 5, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r6", 6, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r7", 7, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r8", 8, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r9", 9, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r10", 10, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r11", 11, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r12", 12, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r13", 13, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r14", 14, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r15", 15, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "usp", 16, 1, NULL, 32, "data_ptr");
+ tdesc_create_reg (feature, "isp", 17, 1, NULL, 32, "data_ptr");
+ tdesc_create_reg (feature, "psw", 18, 1, NULL, 32, "rx_psw_type");
+ tdesc_create_reg (feature, "pc", 19, 1, NULL, 32, "code_ptr");
+ tdesc_create_reg (feature, "intb", 20, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "bpsw", 21, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "bpc", 22, 1, NULL, 32, "code_ptr");
+ tdesc_create_reg (feature, "fintv", 23, 1, NULL, 32, "code_ptr");
+ tdesc_create_reg (feature, "fpsw", 24, 1, NULL, 32, "rx_fpsw_type");
+ tdesc_create_reg (feature, "acc", 25, 1, NULL, 64, "int");
+
+ tdesc_rx = result;
+}
new file mode 100644
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2015 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>rx</architecture>
+ <feature name="org.gnu.gdb.rx">
+ <flags id="rx_psw_type" size="4">
+ <field name="C" start="0" end="0"/>
+ <field name="Z" start="1" end="1"/>
+ <field name="S" start="2" end="2"/>
+ <field name="O" start="3" end="3"/>
+ <field name="I" start="16" end="16"/>
+ <field name="U" start="17" end="17"/>
+ <field name="PM" start="20" end="20"/>
+ <field name="IPL" start="24" end="27"/>
+ </flags>
+ <flags id="rx_fpsw_type" size="4">
+ <field name="RM" start="0" end="1"/>
+ <field name="CV" start="2" end="2"/>
+ <field name="CO" start="3" end="3"/>
+ <field name="CZ" start="4" end="4"/>
+ <field name="CU" start="5" end="5"/>
+ <field name="CX" start="6" end="6"/>
+ <field name="CE" start="7" end="7"/>
+ <field name="DN" start="8" end="8"/>
+ <field name="EV" start="10" end="10"/>
+ <field name="EO" start="11" end="11"/>
+ <field name="EZ" start="12" end="12"/>
+ <field name="EU" start="13" end="13"/>
+ <field name="EX" start="14" end="14"/>
+ <field name="FV" start="26" end="26"/>
+ <field name="FO" start="27" end="27"/>
+ <field name="FZ" start="28" end="28"/>
+ <field name="FU" start="29" end="29"/>
+ <field name="FX" start="30" end="30"/>
+ <field name="FS" start="31" end="31"/>
+ </flags>
+ <reg name="r0" bitsize="32" type="data_ptr"/>
+ <reg name="r1" bitsize="32"/>
+ <reg name="r2" bitsize="32"/>
+ <reg name="r3" bitsize="32"/>
+ <reg name="r4" bitsize="32"/>
+ <reg name="r5" bitsize="32"/>
+ <reg name="r6" bitsize="32"/>
+ <reg name="r7" bitsize="32"/>
+ <reg name="r8" bitsize="32"/>
+ <reg name="r9" bitsize="32"/>
+ <reg name="r10" bitsize="32"/>
+ <reg name="r11" bitsize="32"/>
+ <reg name="r12" bitsize="32"/>
+ <reg name="r13" bitsize="32"/>
+ <reg name="r14" bitsize="32"/>
+ <reg name="r15" bitsize="32"/>
+ <reg name="usp" bitsize="32" type="data_ptr"/>
+ <reg name="isp" bitsize="32" type="data_ptr"/>
+ <reg name="psw" bitsize="32" type="rx_psw_type"/>
+ <reg name="pc" bitsize="32" type="code_ptr"/>
+ <reg name="intb" bitsize="32"/>
+ <reg name="bpsw" bitsize="32"/>
+ <reg name="bpc" bitsize="32" type="code_ptr"/>
+ <reg name="fintv" bitsize="32" type="code_ptr"/>
+ <reg name="fpsw" bitsize="32" type="rx_fpsw_type"/>
+ <reg name="acc" bitsize="64"/>
+ </feature>
+</target>
new file mode 100644
@@ -0,0 +1,80 @@
+/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro:
+ Original: rxv2.xml */
+
+#include "defs.h"
+#include "osabi.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_rxv2;
+static void
+initialize_tdesc_rxv2 (void)
+{
+ struct target_desc *result = allocate_target_description ();
+ struct tdesc_feature *feature;
+ struct tdesc_type *field_type;
+
+ set_tdesc_architecture (result, bfd_scan_arch ("rx:v2"));
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.rx.v2");
+ field_type = tdesc_create_flags (feature, "rx_psw_type", 4);
+ tdesc_add_flag (field_type, 0, "C");
+ tdesc_add_flag (field_type, 1, "Z");
+ tdesc_add_flag (field_type, 2, "S");
+ tdesc_add_flag (field_type, 3, "O");
+ tdesc_add_flag (field_type, 16, "I");
+ tdesc_add_flag (field_type, 17, "U");
+ tdesc_add_flag (field_type, 20, "PM");
+ tdesc_add_flag (field_type, 24, "IPL");
+
+ field_type = tdesc_create_flags (feature, "rx_fpsw_type", 4);
+ tdesc_add_flag (field_type, 0, "RM");
+ tdesc_add_flag (field_type, 2, "CV");
+ tdesc_add_flag (field_type, 3, "CO");
+ tdesc_add_flag (field_type, 4, "CZ");
+ tdesc_add_flag (field_type, 5, "CU");
+ tdesc_add_flag (field_type, 6, "CX");
+ tdesc_add_flag (field_type, 7, "CE");
+ tdesc_add_flag (field_type, 8, "DN");
+ tdesc_add_flag (field_type, 10, "EV");
+ tdesc_add_flag (field_type, 11, "EO");
+ tdesc_add_flag (field_type, 12, "EZ");
+ tdesc_add_flag (field_type, 13, "EU");
+ tdesc_add_flag (field_type, 14, "EX");
+ tdesc_add_flag (field_type, 26, "FV");
+ tdesc_add_flag (field_type, 27, "FO");
+ tdesc_add_flag (field_type, 28, "FZ");
+ tdesc_add_flag (field_type, 29, "FU");
+ tdesc_add_flag (field_type, 30, "FX");
+ tdesc_add_flag (field_type, 31, "FS");
+
+ tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "data_ptr");
+ tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r5", 5, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r6", 6, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r7", 7, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r8", 8, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r9", 9, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r10", 10, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r11", 11, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r12", 12, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r13", 13, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r14", 14, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "r15", 15, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "usp", 16, 1, NULL, 32, "data_ptr");
+ tdesc_create_reg (feature, "isp", 17, 1, NULL, 32, "data_ptr");
+ tdesc_create_reg (feature, "psw", 18, 1, NULL, 32, "rx_psw_type");
+ tdesc_create_reg (feature, "pc", 19, 1, NULL, 32, "code_ptr");
+ tdesc_create_reg (feature, "intb", 20, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "bpsw", 21, 1, NULL, 32, "rx_psw_type");
+ tdesc_create_reg (feature, "bpc", 22, 1, NULL, 32, "code_ptr");
+ tdesc_create_reg (feature, "fintv", 23, 1, NULL, 32, "code_ptr");
+ tdesc_create_reg (feature, "fpsw", 24, 1, NULL, 32, "rx_fpsw_type");
+ tdesc_create_reg (feature, "acc0", 25, 1, NULL, 64, "int64");
+ tdesc_create_reg (feature, "extb", 26, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "acc1", 27, 1, NULL, 64, "int64");
+
+ tdesc_rxv2 = result;
+}
new file mode 100644
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2015 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>rx:v2</architecture>
+ <feature name="org.gnu.gdb.rx.v2">
+ <flags id="rx_psw_type" size="4">
+ <field name="C" start="0" end="0"/>
+ <field name="Z" start="1" end="1"/>
+ <field name="S" start="2" end="2"/>
+ <field name="O" start="3" end="3"/>
+ <field name="I" start="16" end="16"/>
+ <field name="U" start="17" end="17"/>
+ <field name="PM" start="20" end="20"/>
+ <field name="IPL" start="24" end="27"/>
+ </flags>
+ <flags id="rx_fpsw_type" size="4">
+ <field name="RM" start="0" end="1"/>
+ <field name="CV" start="2" end="2"/>
+ <field name="CO" start="3" end="3"/>
+ <field name="CZ" start="4" end="4"/>
+ <field name="CU" start="5" end="5"/>
+ <field name="CX" start="6" end="6"/>
+ <field name="CE" start="7" end="7"/>
+ <field name="DN" start="8" end="8"/>
+ <field name="EV" start="10" end="10"/>
+ <field name="EO" start="11" end="11"/>
+ <field name="EZ" start="12" end="12"/>
+ <field name="EU" start="13" end="13"/>
+ <field name="EX" start="14" end="14"/>
+ <field name="FV" start="26" end="26"/>
+ <field name="FO" start="27" end="27"/>
+ <field name="FZ" start="28" end="28"/>
+ <field name="FU" start="29" end="29"/>
+ <field name="FX" start="30" end="30"/>
+ <field name="FS" start="31" end="31"/>
+ </flags>
+ <reg name="r0" bitsize="32" type="data_ptr"/>
+ <reg name="r1" bitsize="32"/>
+ <reg name="r2" bitsize="32"/>
+ <reg name="r3" bitsize="32"/>
+ <reg name="r4" bitsize="32"/>
+ <reg name="r5" bitsize="32"/>
+ <reg name="r6" bitsize="32"/>
+ <reg name="r7" bitsize="32"/>
+ <reg name="r8" bitsize="32"/>
+ <reg name="r9" bitsize="32"/>
+ <reg name="r10" bitsize="32"/>
+ <reg name="r11" bitsize="32"/>
+ <reg name="r12" bitsize="32"/>
+ <reg name="r13" bitsize="32"/>
+ <reg name="r14" bitsize="32"/>
+ <reg name="r15" bitsize="32"/>
+ <reg name="usp" bitsize="32" type="data_ptr"/>
+ <reg name="isp" bitsize="32" type="data_ptr"/>
+ <reg name="psw" bitsize="32" type="rx_psw_type"/>
+ <reg name="pc" bitsize="32" type="code_ptr"/>
+ <reg name="intb" bitsize="32"/>
+ <reg name="bpsw" bitsize="32" type="rx_psw_type"/>
+ <reg name="bpc" bitsize="32" type="code_ptr"/>
+ <reg name="fintv" bitsize="32" type="code_ptr"/>
+ <reg name="fpsw" bitsize="32" type="rx_fpsw_type"/>
+ <reg name="acc0" bitsize="64" type="int64"/>
+ <reg name="extb" bitsize="32"/>
+ <reg name="acc1" bitsize="64" type="int64"/>
+ </feature>
+</target>
@@ -37,6 +37,9 @@
#include "elf/rx.h"
#include "elf-bfd.h"
+#include "features/rx.c"
+#include "features/rxv2.c"
+
/* Certain important register numbers. */
enum
{
@@ -51,8 +54,8 @@ enum
RX_BPSW_REGNUM = 21,
RX_BPC_REGNUM = 22,
RX_FPSW_REGNUM = 24,
- RX_ACC_REGNUM = 25,
- RX_NUM_REGS = 26
+ RX_V1_NUM_REGS = 26,
+ RX_V2_NUM_REGS = 28,
};
/* RX frame types. */
@@ -110,63 +113,57 @@ struct rx_prologue
/* 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[RX_NUM_REGS];
+ int reg_offset[RX_V2_NUM_REGS];
};
+#define RX_NUM_REGS(arch) ((gdbarch_tdep(arch)->elf_flags & E_FLAG_RX_V2)? \
+ RX_V2_NUM_REGS:RX_V1_NUM_REGS)
+
+static const char *const rx_reg_names[] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10","r11","r12","r13","r14","r15",
+ "usp","isp","psw","pc", "intb","bpsw","bpc","fintv",
+ "fpsw","acc"
+ };
+
+static const char *const rxv2_reg_names[] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10","r11","r12","r13","r14","r15",
+ "usp","isp","psw","pc", "intb","bpsw","bpc","fintv",
+ "fpsw","acc0","extb","acc1"
+ };
+
/* Implement the "register_name" gdbarch method. */
static const char *
-rx_register_name (struct gdbarch *gdbarch, int regnr)
+rx_register_name (struct gdbarch *gdbarch, int reg_nr)
{
- static const char *const reg_names[] = {
- "r0",
- "r1",
- "r2",
- "r3",
- "r4",
- "r5",
- "r6",
- "r7",
- "r8",
- "r9",
- "r10",
- "r11",
- "r12",
- "r13",
- "r14",
- "r15",
- "usp",
- "isp",
- "psw",
- "pc",
- "intb",
- "bpsw",
- "bpc",
- "fintv",
- "fpsw",
- "acc"
- };
+ if (reg_nr < RX_V1_NUM_REGS)
+ return rx_reg_names[reg_nr];
+ else
+ return tdesc_register_name (gdbarch, reg_nr);
+}
- return reg_names[regnr];
+static const char *
+rxv2_register_name (struct gdbarch *gdbarch, int reg_nr)
+{
+ if (reg_nr < RX_V2_NUM_REGS)
+ return rxv2_reg_names[reg_nr];
+ else
+ return tdesc_register_name (gdbarch, reg_nr);
}
/* Implement the "register_type" gdbarch method. */
static struct type *
rx_register_type (struct gdbarch *gdbarch, int reg_nr)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- if (reg_nr == RX_PC_REGNUM)
- return builtin_type (gdbarch)->builtin_func_ptr;
- else if (reg_nr == RX_PSW_REGNUM || reg_nr == RX_BPSW_REGNUM)
- return tdep->rx_psw_type;
- else if (reg_nr == RX_FPSW_REGNUM)
- return tdep->rx_fpsw_type;
- else if (reg_nr == RX_ACC_REGNUM)
- return builtin_type (gdbarch)->builtin_unsigned_long_long;
- else
- return builtin_type (gdbarch)->builtin_unsigned_long;
+ return tdesc_register_type (gdbarch, reg_nr);
}
+static struct type *
+rxv2_register_type (struct gdbarch *gdbarch, int reg_nr)
+{
+ return tdesc_register_type (gdbarch, reg_nr);
+}
/* Function for finding saved registers in a 'struct pv_area'; this
function is passed to pv_area_scan.
@@ -225,7 +222,7 @@ rx_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
{
CORE_ADDR pc, next_pc;
int rn;
- pv_t reg[RX_NUM_REGS];
+ pv_t reg[RX_V2_NUM_REGS];
struct pv_area *stack;
struct cleanup *back_to;
CORE_ADDR after_last_frame_setup_insn = start_pc;
@@ -234,7 +231,7 @@ rx_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
result->frame_type = frame_type;
- for (rn = 0; rn < RX_NUM_REGS; rn++)
+ for (rn = 0; rn < RX_V2_NUM_REGS; rn++)
{
reg[rn] = pv_register (rn, 0);
result->reg_offset[rn] = 1;
@@ -1021,6 +1018,10 @@ rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
struct gdbarch *gdbarch;
struct gdbarch_tdep *tdep;
int elf_flags;
+ int register_bytes, i;
+ int numregs;
+ struct tdesc_arch_data *tdesc_data = NULL;
+ const struct target_desc *tdesc = info.target_desc;
/* Extract the elf_flags if available. */
if (info.abfd != NULL
@@ -1028,7 +1029,40 @@ rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
elf_flags = elf_elfheader (info.abfd)->e_flags;
else
elf_flags = 0;
+ if (!tdesc_has_registers (tdesc))
+ /* Pick a default target description. */
+ tdesc = (info.bfd_arch_info->mach == bfd_mach_rx)?tdesc_rx:tdesc_rxv2;
+ numregs = (info.bfd_arch_info->mach == bfd_mach_rx)?RX_V1_NUM_REGS:RX_V2_NUM_REGS;
+
+ /* Check any target description for validity. */
+ if (tdesc_has_registers (tdesc))
+ {
+ const struct tdesc_feature *feature;
+ int valid_p;
+ const char * const *reg;
+
+ if (info.bfd_arch_info->mach == bfd_mach_rx)
+ feature = tdesc_find_feature (tdesc, "org.gnu.gdb.rx");
+ else
+ feature = tdesc_find_feature (tdesc, "org.gnu.gdb.rx.v2");
+ if (feature == NULL)
+ return NULL;
+
+ tdesc_data = tdesc_data_alloc ();
+
+ valid_p = 1;
+
+ reg = (info.bfd_arch_info->mach == bfd_mach_rx)?rx_reg_names:rxv2_reg_names;
+ for (i = 0; i < numregs; i++)
+ valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
+ reg[i]);
+ if (!valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+ }
/* Try to find the architecture in the list of already defined
architectures. */
@@ -1048,49 +1082,18 @@ rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
gdbarch = gdbarch_alloc (&info, tdep);
tdep->elf_flags = elf_flags;
- /* Initialize the flags type for PSW and BPSW. */
-
- tdep->rx_psw_type = arch_flags_type (gdbarch, "rx_psw_type", 4);
- append_flags_type_flag (tdep->rx_psw_type, 0, "C");
- append_flags_type_flag (tdep->rx_psw_type, 1, "Z");
- append_flags_type_flag (tdep->rx_psw_type, 2, "S");
- append_flags_type_flag (tdep->rx_psw_type, 3, "O");
- append_flags_type_flag (tdep->rx_psw_type, 16, "I");
- append_flags_type_flag (tdep->rx_psw_type, 17, "U");
- append_flags_type_flag (tdep->rx_psw_type, 20, "PM");
- append_flags_type_flag (tdep->rx_psw_type, 24, "IPL0");
- append_flags_type_flag (tdep->rx_psw_type, 25, "IPL1");
- append_flags_type_flag (tdep->rx_psw_type, 26, "IPL2");
- append_flags_type_flag (tdep->rx_psw_type, 27, "IPL3");
-
- /* Initialize flags type for FPSW. */
-
- tdep->rx_fpsw_type = arch_flags_type (gdbarch, "rx_fpsw_type", 4);
- append_flags_type_flag (tdep->rx_fpsw_type, 0, "RM0");
- append_flags_type_flag (tdep->rx_fpsw_type, 1, "RM1");
- append_flags_type_flag (tdep->rx_fpsw_type, 2, "CV");
- append_flags_type_flag (tdep->rx_fpsw_type, 3, "CO");
- append_flags_type_flag (tdep->rx_fpsw_type, 4, "CZ");
- append_flags_type_flag (tdep->rx_fpsw_type, 5, "CU");
- append_flags_type_flag (tdep->rx_fpsw_type, 6, "CX");
- append_flags_type_flag (tdep->rx_fpsw_type, 7, "CE");
- append_flags_type_flag (tdep->rx_fpsw_type, 8, "DN");
- append_flags_type_flag (tdep->rx_fpsw_type, 10, "EV");
- append_flags_type_flag (tdep->rx_fpsw_type, 11, "EO");
- append_flags_type_flag (tdep->rx_fpsw_type, 12, "EZ");
- append_flags_type_flag (tdep->rx_fpsw_type, 13, "EU");
- append_flags_type_flag (tdep->rx_fpsw_type, 14, "EX");
- append_flags_type_flag (tdep->rx_fpsw_type, 26, "FV");
- append_flags_type_flag (tdep->rx_fpsw_type, 27, "FO");
- append_flags_type_flag (tdep->rx_fpsw_type, 28, "FZ");
- append_flags_type_flag (tdep->rx_fpsw_type, 29, "FU");
- append_flags_type_flag (tdep->rx_fpsw_type, 30, "FX");
- append_flags_type_flag (tdep->rx_fpsw_type, 31, "FS");
-
- set_gdbarch_num_regs (gdbarch, RX_NUM_REGS);
+ set_gdbarch_num_regs (gdbarch, numregs);
set_gdbarch_num_pseudo_regs (gdbarch, 0);
- set_gdbarch_register_name (gdbarch, rx_register_name);
- set_gdbarch_register_type (gdbarch, rx_register_type);
+ if (info.bfd_arch_info->mach == bfd_mach_rx)
+ {
+ set_gdbarch_register_name (gdbarch, rx_register_name);
+ set_gdbarch_register_type (gdbarch, rx_register_type);
+ }
+ else
+ {
+ set_gdbarch_register_name (gdbarch, rxv2_register_name);
+ set_gdbarch_register_type (gdbarch, rxv2_register_type);
+ }
set_gdbarch_pc_regnum (gdbarch, RX_PC_REGNUM);
set_gdbarch_sp_regnum (gdbarch, RX_SP_REGNUM);
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
@@ -1145,6 +1148,9 @@ rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* Virtual tables. */
set_gdbarch_vbit_in_delta (gdbarch, 1);
+ if (tdesc_data)
+ tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+
return gdbarch;
}
@@ -1157,4 +1163,6 @@ void
_initialize_rx_tdep (void)
{
register_gdbarch_init (bfd_arch_rx, rx_gdbarch_init);
+ initialize_tdesc_rx ();
+ initialize_tdesc_rxv2 ();
}