[PATCH 5/7] x86: adjust st(<N>) parsing

Jan Beulich jbeulich@suse.com
Fri Mar 26 13:49:06 GMT 2021


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/
2021-03-XX  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.

opcodes/
2021-03-XX  Jan Beulich  <jbeulich@suse.com>

	* 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.

--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -214,6 +214,7 @@ static const char *default_arch = DEFAUL
 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, c
   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, c
 	      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;
 		}
 	    }
--- 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;
--- 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



More information about the Binutils mailing list