From 6288d05f11827f993308e6a2693516e2c123c0fb Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 30 Mar 2021 14:08:11 +0200 Subject: [PATCH] x86: adjust st() 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. --- gas/ChangeLog | 7 +++++++ gas/config/tc-i386.c | 28 ++++++++++++++++++++++------ opcodes/ChangeLog | 7 +++++++ opcodes/i386-opc.h | 6 +++--- opcodes/i386-reg.tbl | 6 ++---- opcodes/i386-tbl.h | 6 +----- 6 files changed, 42 insertions(+), 18 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 8bdc3920489..468be74256c 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2021-03-30 Jan Beulich + + * 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 * config/tc-i386.c (rc_op): Delete. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index ba130138531..3a7d50484ff 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 = { "", 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() 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; } } diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 81c0fa2e7f3..5acb021fa48 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,10 @@ +2021-03-30 Jan Beulich + + * i386-opc.h (REGNAM_AL, REGNAM_AX, REGNAM_EAX): Adjust values. + * i386-reg.tbl (st): Move down. + (st(0)): Delete. Extend comment. + * i386-tbl.h: Re-generate. + 2021-03-29 Jan Beulich * i386-opc.tbl (movq, movabs): Move next to mov counterparts. diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h index 115895c65ed..a2a657eeda0 100644 --- a/opcodes/i386-opc.h +++ b/opcodes/i386-opc.h @@ -991,9 +991,9 @@ typedef struct reg_entry; /* Entries in i386_regtab. */ -#define REGNAM_AL 1 -#define REGNAM_AX 25 -#define REGNAM_EAX 41 +#define REGNAM_AL 0 +#define REGNAM_AX 24 +#define REGNAM_EAX 40 extern const reg_entry i386_regtab[]; extern const unsigned int i386_regtab_size; diff --git a/opcodes/i386-reg.tbl b/opcodes/i386-reg.tbl index 7ea974de665..be2c1ccc9f2 100644 --- a/opcodes/i386-reg.tbl +++ b/opcodes/i386-reg.tbl @@ -18,8 +18,6 @@ // Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA // 02110-1301, USA. -// Make %st first as we test for it. -st, Class=Reg|Instance=Accum|Tbyte, 0, 0, 11, 33 // 8 bit regs al, Class=Reg|Instance=Accum|Byte, 0, 0, Dw2Inval, Dw2Inval cl, Class=Reg|Instance=RegC|Byte, 0, 1, Dw2Inval, Dw2Inval @@ -300,8 +298,8 @@ eip, Dword, RegRex64, RegIP, 8, Dw2Inval // for addressing. riz, Qword|BaseIndex, RegRex64, RegIZ, Dw2Inval, Dw2Inval eiz, Dword|BaseIndex, 0, RegIZ, Dw2Inval, Dw2Inval -// fp regs. -st(0), Class=Reg|Instance=Accum|Tbyte, 0, 0, 11, 33 +// fp regs. No need for an explicit st(0) here. +st, Class=Reg|Instance=Accum|Tbyte, 0, 0, 11, 33 st(1), Class=Reg|Tbyte, 0, 1, 12, 34 st(2), Class=Reg|Tbyte, 0, 2, 13, 35 st(3), Class=Reg|Tbyte, 0, 3, 14, 36 diff --git a/opcodes/i386-tbl.h b/opcodes/i386-tbl.h index 0a326fd8786..d2ca247f028 100644 --- a/opcodes/i386-tbl.h +++ b/opcodes/i386-tbl.h @@ -64204,10 +64204,6 @@ const insn_template i386_optab[] = const reg_entry i386_regtab[] = { - { "st", - { { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0 } }, - 0, 0, { 11, 33 } }, { "al", { { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, @@ -65260,7 +65256,7 @@ const reg_entry i386_regtab[] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, 0, RegIZ, { Dw2Inval, Dw2Inval } }, - { "st(0)", + { "st", { { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 } }, 0, 0, { 11, 33 } }, -- 2.30.2