aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYao Qi <yao.qi@linaro.org>2017-07-26 14:39:54 +0100
committerYao Qi <yao.qi@linaro.org>2017-07-26 14:39:54 +0100
commitea03d0d3c32b22aeddfeb139a4a515f7e5961347 (patch)
tree93bd39d275e82ffe4e66a7ca209540aa031c29f9 /gdb/target-descriptions.c
parentGenerate c for feature instead of tdesc (diff)
downloadbinutils-gdb-ea03d0d3c32b22aeddfeb139a4a515f7e5961347.tar.gz
binutils-gdb-ea03d0d3c32b22aeddfeb139a4a515f7e5961347.tar.bz2
binutils-gdb-ea03d0d3c32b22aeddfeb139a4a515f7e5961347.zip
Lazily and dynamically create i386-linux target descriptions
Instead of using pre-generated target descriptions, this patch changes GDB to lazily and dynamically create target descriptions according to the target hardware capability (xcr0 in i386). This support any combination of target features. Some reg in target description has "regnum" attribute, so its register number is got from the attribute value instead from sequential allocation. <reg name="xmm0" bitsize="128" type="vec128" regnum="32"/> when target description is created, it should match the regnum, so this patch adds a new field m_next_regnum to track it, if attribute number is greater than the m_next_regnum, print the code to set register number explicitly. gdb: 2017-07-26 Yao Qi <yao.qi@linaro.org> * i386-linux-tdep.c: Don't include features/i386/i386-*linux.c. Include features/i386/32bit-*.c. (i386_linux_read_description): Generate target description if it doesn't exist. (_initialize_i386_linux_tdep): Don't call _initialize_tdesc_i386 functions. * features/i386/32bit-linux.c: Re-generated. * features/i386/32bit-sse.c: Likewise. * target-descriptions.c (print_c_feature::visit): Print code to set register number if needed. (print_c_feature) <m_next_regnum>: New field.
Diffstat (limited to 'gdb/target-descriptions.c')
-rw-r--r--gdb/target-descriptions.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c
index 5fd07ef0451..333cbd89ab7 100644
--- a/gdb/target-descriptions.c
+++ b/gdb/target-descriptions.c
@@ -2104,6 +2104,48 @@ public:
void visit (const tdesc_reg *reg) override
{
+ /* Most "reg" in XML target descriptions don't have "regnum"
+ attribute, so the register number is allocated sequentially.
+ In case that reg has "regnum" attribute, register number
+ should be set by that explicitly. */
+
+ if (reg->target_regnum < m_next_regnum)
+ {
+ /* The integrity check, it can catch some errors on register
+ number collision, like this,
+
+ <reg name="x0" bitsize="32"/>
+ <reg name="x1" bitsize="32"/>
+ <reg name="x2" bitsize="32"/>
+ <reg name="x3" bitsize="32"/>
+ <reg name="ps" bitsize="32" regnum="3"/>
+
+ but it also has false negatives. The target description
+ below is correct,
+
+ <reg name="x1" bitsize="32" regnum="1"/>
+ <reg name="x3" bitsize="32" regnum="3"/>
+ <reg name="x2" bitsize="32" regnum="2"/>
+ <reg name="x4" bitsize="32" regnum="4"/>
+
+ but it is not a good practice, so still error on this,
+ and also print the message so that it can be saved in the
+ generated c file. */
+
+ printf_unfiltered ("ERROR: \"regnum\" attribute %ld ",
+ reg->target_regnum);
+ printf_unfiltered ("is not the largest number (%d).\n",
+ m_next_regnum);
+ error (_("\"regnum\" attribute %ld is not the largest number (%d)."),
+ reg->target_regnum, m_next_regnum);
+ }
+
+ if (reg->target_regnum > m_next_regnum)
+ {
+ printf_unfiltered (" regnum = %ld;\n", reg->target_regnum);
+ m_next_regnum = reg->target_regnum;
+ }
+
printf_unfiltered (" tdesc_create_reg (feature, \"%s\", regnum++, %d, ",
reg->name, reg->save_restore);
if (reg->group)
@@ -2111,8 +2153,13 @@ public:
else
printf_unfiltered ("NULL, ");
printf_unfiltered ("%d, \"%s\");\n", reg->bitsize, reg->type);
+
+ m_next_regnum++;
}
+private:
+ /* The register number to use for the next register we see. */
+ int m_next_regnum = 0;
};
static void