aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2021-03-30 14:08:11 +0200
committerJan Beulich <jbeulich@suse.com>2021-03-30 14:08:11 +0200
commit6288d05f11827f993308e6a2693516e2c123c0fb (patch)
treec83372fd531e4f4c3fd551da638244be6b13b138 /gas
parentca5312a2416f065517c354cb6a9cc2616174761b (diff)
downloadgdb-6288d05f11827f993308e6a2693516e2c123c0fb.zip
gdb-6288d05f11827f993308e6a2693516e2c123c0fb.tar.gz
gdb-6288d05f11827f993308e6a2693516e2c123c0fb.tar.bz2
x86: adjust st(<N>) parsing
st(1) ... st(7) will never be looked up in the hash table, so there's no point inserting the entries. It's also not really necessary to do a 2nd hash lookup after parsing the register number, nor is there a real reason for having both st and st(0) entries. Plus we can easily do away with the need for st to be first in the table.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog7
-rw-r--r--gas/config/tc-i386.c28
2 files changed, 29 insertions, 6 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 8bdc392..468be74 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,12 @@
2021-03-30 Jan Beulich <jbeulich@suse.com>
+ * config/tc-i386.c (reg_st0): New.
+ (md_begin): Convert to switch(). Initialize reg_st0. Don't
+ insert other st(N).
+ (parse_real_register): Adjust st(N) processing.
+
+2021-03-30 Jan Beulich <jbeulich@suse.com>
+
* config/tc-i386.c (rc_op): Delete.
(struct Rounding_Operation): Move ...
(struct _i386_insn): ... here. Change field "rounding".
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index ba13013..3a7d504 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -214,6 +214,7 @@ static const char *default_arch = DEFAULT_ARCH;
static const reg_entry bad_reg = { "<bad>", OPERAND_TYPE_NONE, 0, 0,
{ Dw2Inval, Dw2Inval } };
+static const reg_entry *reg_st0;
static const reg_entry *reg_k0;
/* VEX prefix. */
@@ -3087,11 +3088,27 @@ md_begin (void)
for (regtab = i386_regtab; regtab_size--; regtab++)
{
+ switch (regtab->reg_type.bitfield.class)
+ {
+ case Reg:
+ if (regtab->reg_type.bitfield.tbyte)
+ {
+ /* There's no point inserting st(<N>) in the hash table, as
+ parentheses aren't included in register_chars[] anyway. */
+ if (regtab->reg_type.bitfield.instance != Accum)
+ continue;
+ reg_st0 = regtab;
+ }
+ break;
+
+ case RegMask:
+ if (!regtab->reg_num)
+ reg_k0 = regtab;
+ break;
+ }
+
if (str_hash_insert (reg_hash, regtab->reg_name, regtab, 0) != NULL)
as_fatal (_("duplicate %s"), regtab->reg_name);
-
- if (regtab->reg_type.bitfield.class == RegMask && !regtab->reg_num)
- reg_k0 = regtab;
}
}
@@ -12712,7 +12729,7 @@ parse_real_register (char *reg_string, char **end_op)
r = (const reg_entry *) str_hash_find (reg_hash, reg_name_given);
/* Handle floating point regs, allowing spaces in the (i) part. */
- if (r == i386_regtab /* %st is first entry of table */)
+ if (r == reg_st0)
{
if (!cpu_arch_flags.bitfield.cpu8087
&& !cpu_arch_flags.bitfield.cpu287
@@ -12736,8 +12753,7 @@ parse_real_register (char *reg_string, char **end_op)
if (*s == ')')
{
*end_op = s + 1;
- r = (const reg_entry *) str_hash_find (reg_hash, "st(0)");
- know (r);
+ know (r[fpr].reg_num == fpr);
return r + fpr;
}
}