[PATCH] x86: allow equates to registers

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] x86: allow equates to registers

Jan Beulich
This patch allows, on x86/x86-64, registers to be on the right side of
.equ and similar operations, and (obviously) also allows the resulting
symbols to be used.

The new test being added requires the previously submitted equate
handling
adjustment patch
(http://sourceware.org/ml/binutils/2005-10/msg00297.html).

Built and tested on i686-pc-linux-gnu and x86_64-unknown-linux-gnu and
for several i?86-*-* cross targets.

Jan

gas/
2005-10-21  Jan Beulich  <[hidden email]>

        * config/tc-i386.c (i386_operand): Don't check register prefix
here.
        (parse_real_register): Rename from parse_register.
        (parse_register): New.
        (i386_parse_name): New.
        (md_operand): New.
        (intel_e11): Don't tolerate registers in offset expressions
anymore.
        (intel_get_token): Don't check register prefix here. Copy the
actual
        register token, not the canonical register name.
        * config/tc-i386.h (md_operand): Delete.
        (i386_parse_name): Declare.
        (md_parse_name): Define.

gas/testsuite/
2005-10-21  Jan Beulich  <[hidden email]>

        * gas/i386/intel.s: Replace register used in offset expression.
        * gas/i386/intel.e: Adjust.
        * gas/i386/intelbad.l: Adjust.
        * gas/i386/equ.[sed]: New.
        * gas/i386/i386.exp: Run new test.

---
/home/jbeulich/src/binutils/mainline/2005-10-20/gas/config/tc-i386.c 2005-09-28
17:31:17.000000000 +0200
+++ 2005-10-20/gas/config/tc-i386.c 2005-10-21 16:50:03.764128544
+0200
@@ -4419,8 +4419,7 @@ i386_operand (operand_string)
     }
 
   /* Check if operand is a register.  */
-  if ((*op_string == REGISTER_PREFIX || allow_naked_reg)
-      && (r = parse_register (op_string, &end_op)) != NULL)
+  if ((r = parse_register (op_string, &end_op)) != NULL)
     {
       /* Check for a segment override by searching for ':' after a
  segment register.  */
@@ -4558,8 +4557,7 @@ i386_operand (operand_string)
     ++base_string;
 
   if (*base_string == ','
-      || ((*base_string == REGISTER_PREFIX || allow_naked_reg)
-  && (i.base_reg = parse_register (base_string,
&end_op)) != NULL))
+      || ((i.base_reg = parse_register (base_string, &end_op))
!= NULL))
     {
       displacement_string_end = temp_string;
 
@@ -4579,8 +4577,7 @@ i386_operand (operand_string)
   if (is_space_char (*base_string))
     ++base_string;
 
-  if ((*base_string == REGISTER_PREFIX ||
allow_naked_reg)
-      && (i.index_reg = parse_register (base_string,
&end_op)) != NULL)
+  if ((i.index_reg = parse_register (base_string,
&end_op)) != NULL)
     {
       base_string = end_op;
       if (is_space_char (*base_string))
@@ -5157,9 +5154,7 @@ output_invalid (c)
 /* REG_STRING starts *before* REGISTER_PREFIX.  */
 
 static const reg_entry *
-parse_register (reg_string, end_op)
-     char *reg_string;
-     char **end_op;
+parse_real_register (char *reg_string, char **end_op)
 {
   char *s = reg_string;
   char *p;
@@ -5226,6 +5221,80 @@ parse_register (reg_string, end_op)
 
   return r;
 }
+
+/* REG_STRING starts *before* REGISTER_PREFIX.  */
+
+static const reg_entry *
+parse_register (char *reg_string, char **end_op)
+{
+  const reg_entry *r;
+
+  if (*reg_string == REGISTER_PREFIX || allow_naked_reg)
+    r = parse_real_register (reg_string, end_op);
+  else
+    r = NULL;
+  if (!r)
+    {
+      char *save = input_line_pointer;
+      char c;
+      symbolS *symbolP;
+
+      input_line_pointer = reg_string;
+      c = get_symbol_end ();
+      symbolP = symbol_find (reg_string);
+      if (symbolP && S_GET_SEGMENT (symbolP) == reg_section)
+ {
+  const expressionS *e = symbol_get_value_expression (symbolP);
+
+  know (e->X_op == O_register);
+  know (e->X_add_number >= 0 && (valueT) e->X_add_number <
ARRAY_SIZE (i386_regtab));
+  r = i386_regtab + e->X_add_number;
+  *end_op = input_line_pointer;
+ }
+      *input_line_pointer = c;
+      input_line_pointer = save;
+    }
+  return r;
+}
+
+int
+i386_parse_name (char *name, expressionS *e, char *nextcharP)
+{
+  const reg_entry *r;
+  char *end = input_line_pointer;
+
+  *end = *nextcharP;
+  r = parse_register (name, &input_line_pointer);
+  if (r && end <= input_line_pointer)
+    {
+      *nextcharP = *input_line_pointer;
+      *input_line_pointer = 0;
+      e->X_op = O_register;
+      e->X_add_number = r - i386_regtab;
+      return 1;
+    }
+  input_line_pointer = end;
+  *end = 0;
+  return 0;
+}
+
+void
+md_operand (expressionS *e)
+{
+  if (*input_line_pointer == REGISTER_PREFIX)
+    {
+      char *end;
+      const reg_entry *r = parse_real_register (input_line_pointer,
&end);
+
+      if (r)
+ {
+  e->X_op = O_register;
+  e->X_add_number = r - i386_regtab;
+  input_line_pointer = end;
+ }
+    }
+}
+
 
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
 const char *md_shortopts = "kVQ:sqn";
@@ -6566,16 +6635,8 @@ intel_e11 ()
     i.types[this_operand] |= BaseIndex;
   }
 
- /* Offset modifier. Add the register to the displacement string
to be
-   parsed as an immediate expression after we're done.  */
- else if (intel_parser.in_offset)
-  {
-    as_warn (_("Using register names in OFFSET expressions is
deprecated"));
-    strcat (intel_parser.disp, reg->reg_name);
-  }
-
- /* It's neither base nor index nor offset.  */
- else if (!intel_parser.is_mem)
+ /* It's neither base nor index.  */
+ else if (!intel_parser.in_offset && !intel_parser.is_mem)
   {
     i.types[this_operand] |= reg->reg_type & ~BaseIndex;
     i.op[this_operand].regs = reg;
@@ -6804,19 +6865,15 @@ intel_get_token ()
  new_token.code = T_ID;
     }
 
-  else if ((*intel_parser.op_string == REGISTER_PREFIX ||
allow_naked_reg)
-   && ((reg = parse_register (intel_parser.op_string, &end_op))
!= NULL))
+  else if ((reg = parse_register (intel_parser.op_string, &end_op)) !=
NULL)
     {
+      size_t len = end_op - intel_parser.op_string;
+
       new_token.code = T_REG;
       new_token.reg = reg;
 
-      if (*intel_parser.op_string == REGISTER_PREFIX)
- {
-  new_token.str[0] = REGISTER_PREFIX;
-  new_token.str[1] = '\0';
- }
-
-      strcat (new_token.str, reg->reg_name);
+      memcpy (new_token.str, intel_parser.op_string, len);
+      new_token.str[len] = '\0';
     }
 
   else if (is_identifier_char (*intel_parser.op_string))
---
/home/jbeulich/src/binutils/mainline/2005-10-20/gas/config/tc-i386.h 2005-09-13
13:58:50.000000000 +0200
+++ 2005-10-20/gas/config/tc-i386.h 2005-10-21 16:50:03.767128088
+0200
@@ -434,7 +434,8 @@ extern int tc_i386_fix_adjustable PARAMS
    || (FIX)->fx_r_type == BFD_RELOC_386_GOTPC \
    || TC_FORCE_RELOCATION (FIX))
 
-#define md_operand(x)
+extern int i386_parse_name (char *, expressionS *, char *);
+#define md_parse_name(s, e, m, c) i386_parse_name (s, e, c)
 
 extern const struct relax_type md_relax_table[];
 #define TC_GENERIC_RELAX_TABLE md_relax_table
---
/home/jbeulich/src/binutils/mainline/2005-10-20/gas/testsuite/gas/i386/equ.d 1970-01-01
01:00:00.000000000 +0100
+++ 2005-10-20/gas/testsuite/gas/i386/equ.d 2005-10-21
16:11:15.000000000 +0200
@@ -0,0 +1,26 @@
+#objdump: -drw
+#name: i386 equates
+#stderr: equ.e
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <_start>:
+[ 0-9a-f]+:[ 0-9a-f]+mov[ ]+\$0xffffffff,%eax
+[ 0-9a-f]+:[ 0-9a-f]+mov[ ]+0xffffffff,%eax
+[ 0-9a-f]+:[ 0-9a-f]+mov[ ]+\$0x0,%eax[ 0-9a-f]+:[
        a-zA-Z0-9_]+xtrn
+[ 0-9a-f]+:[ 0-9a-f]+mov[ ]+0x0,%eax[ 0-9a-f]+:[
        a-zA-Z0-9_]+xtrn
+[ 0-9a-f]+:[ 0-9a-f]+test[ ]+%ecx,%ecx
+[ 0-9a-f]+:[ 0-9a-f]+mov[ ]+%fs:\(%ecx,%ecx,4\),%ecx
+[ 0-9a-f]+:[ 0-9a-f]+fadd[ ]+%st\(1\),%st
+[ 0-9a-f]+:[ 0-9a-f]+mov[ ]+\$0xfffffffe,%eax
+[ 0-9a-f]+:[ 0-9a-f]+mov[ ]+0xfffffffe,%eax
+[ 0-9a-f]+:[ 0-9a-f]+mov[ ]+\$0x0,%eax[ 0-9a-f]+:[
        a-zA-Z0-9_]+xtrn
+[ 0-9a-f]+:[ 0-9a-f]+mov[ ]+0x0,%eax[ 0-9a-f]+:[
        a-zA-Z0-9_]+xtrn
+[ 0-9a-f]+:[ 0-9a-f]+test[ ]+%edx,%edx
+[ 0-9a-f]+:[ 0-9a-f]+mov[ ]+%gs:\(%edx,%edx,8\),%edx
+[ 0-9a-f]+:[ 0-9a-f]+mov[ ]+%gs:\(%edx,%edx,8\),%edx
+[ 0-9a-f]+:[ 0-9a-f]+fadd[ ]+%st\(1\),%st
+[ 0-9a-f]+:[ 0-9a-f]+fadd[ ]+%st\(7\),%st
+pass
---
/home/jbeulich/src/binutils/mainline/2005-10-20/gas/testsuite/gas/i386/equ.e 1970-01-01
01:00:00.000000000 +0100
+++ 2005-10-20/gas/testsuite/gas/i386/equ.e 2005-10-21
15:43:51.000000000 +0200
@@ -0,0 +1,2 @@
+.*: Assembler messages:
+.*:23: Warning: Treating .* as memory reference
---
/home/jbeulich/src/binutils/mainline/2005-10-20/gas/testsuite/gas/i386/equ.s 1970-01-01
01:00:00.000000000 +0100
+++ 2005-10-20/gas/testsuite/gas/i386/equ.s 2005-10-21
15:36:49.000000000 +0200
@@ -0,0 +1,37 @@
+ .text
+_start:
+
+ .att_syntax prefix
+ .equ r, -1
+ .equ s, -1
+ movl $r, %eax
+ movl (r), %eax
+ .equ r, xtrn; .global r # temporary (hopefully)
+ movl $r, %eax
+ movl r, %eax
+ .equ r, %ecx
+ .equ s, %fs
+ testl r, r
+ movl s:(r,r,4), r
+ .equ x, %st(1)
+ fadd x
+
+ .intel_syntax noprefix
+ .equ r, -2
+ .equ s, -2
+ mov eax, r
+ mov eax, [r]
+ .equ r, xtrn
+ mov eax, offset r
+ mov eax, [r]
+ .equ r, edx
+ .equ s, gs
+ test r, r
+ mov r, s:[r+r*8]
+ mov r, s:[8*r+r]
+ fadd x
+ .equ x, st(7)
+ fadd x
+
+ .equ r, -3
+ .equ s, -3
---
/home/jbeulich/src/binutils/mainline/2005-10-20/gas/testsuite/gas/i386/i386.exp 2005-08-24
12:47:18.000000000 +0200
+++ 2005-10-20/gas/testsuite/gas/i386/i386.exp 2005-10-21
16:50:03.789124744 +0200
@@ -63,6 +63,7 @@ if [expr ([istarget "i*86-*-*"] ||  [ist
     run_dump_test "vmx"
     run_dump_test "suffix"
     run_dump_test "immed32"
+    run_dump_test "equ"
 
     if {![istarget "*-*-aix*"]
  && (![is_elf_format] || [istarget "*-*-linux*"]
---
/home/jbeulich/src/binutils/mainline/2005-10-20/gas/testsuite/gas/i386/intel.e 2005-03-14
09:49:39.000000000 +0100
+++ 2005-10-20/gas/testsuite/gas/i386/intel.e 2005-10-21
16:51:03.138102328 +0200
@@ -5,4 +5,3 @@
 .*:157: Warning: Treating .\[0x90909090\]. as memory reference
 .*:492: Warning: Treating .\[0x90909090\]. as memory reference
 .*:493: Warning: Treating .\[0x90909090\]. as memory reference
-.*:580: Warning: Using register names in OFFSET expressions is
deprecated
---
/home/jbeulich/src/binutils/mainline/2005-10-20/gas/testsuite/gas/i386/intel.s 2005-08-24
08:57:12.000000000 +0200
+++ 2005-10-20/gas/testsuite/gas/i386/intel.s 2005-10-21
16:51:03.158099288 +0200
@@ -577,7 +577,7 @@ bar:
  call gs_foo
  call short_foo
  fstp   QWORD PTR [eax+edx*8]
- mov ecx, OFFSET FLAT:ss
+ mov ecx, OFFSET FLAT:xyz
  mov BYTE PTR [esi+edx], al
  mov BYTE PTR [edx+esi], al
  mov BYTE PTR [edx*2+esi], al
---
/home/jbeulich/src/binutils/mainline/2005-10-20/gas/testsuite/gas/i386/intelbad.l 2005-03-14
13:55:01.000000000 +0100
+++ 2005-10-20/gas/testsuite/gas/i386/intelbad.l 2005-10-21
16:51:03.161098832 +0200
@@ -101,9 +101,9 @@
 .*:131: Error: .*
 .*:132: Error: .*
 .*:133: Error: .*
-.*:135: Warning: .*
-.*:136: Warning: .*
-.*:137: Warning: .*
+.*:135: Error: .*
+.*:136: Error: .*
+.*:137: Error: .*
 .*:138: Warning: .*
 .*:139: Warning: .*
 .*:141: Error: .*


binutils-mainline-x86-reg-equate.patch (14K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] x86: allow equates to registers

Nick Clifton
Hi Jan,

> This patch allows, on x86/x86-64, registers to be on the right side of
> .equ and similar operations, and (obviously) also allows the resulting
> symbols to be used.

I have not seen any adverse comments to this patch, so:

> gas/
> 2005-10-21  Jan Beulich  <[hidden email]>
>
> * config/tc-i386.c (i386_operand): Don't check register prefix
> here.
> (parse_real_register): Rename from parse_register.
> (parse_register): New.
> (i386_parse_name): New.
> (md_operand): New.
> (intel_e11): Don't tolerate registers in offset expressions
> anymore.
> (intel_get_token): Don't check register prefix here. Copy the
> actual
> register token, not the canonical register name.
> * config/tc-i386.h (md_operand): Delete.
> (i386_parse_name): Declare.
> (md_parse_name): Define.
>
> gas/testsuite/
> 2005-10-21  Jan Beulich  <[hidden email]>
>
> * gas/i386/intel.s: Replace register used in offset expression.
> * gas/i386/intel.e: Adjust.
> * gas/i386/intelbad.l: Adjust.
> * gas/i386/equ.[sed]: New.
> * gas/i386/i386.exp: Run new test.

Approved - please apply.

Cheers
   Nick
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] x86: allow equates to registers

Jan Beulich
Nick,

I already applied it when I remembered the dependency noted in the
submission email. How about that patch
(http://sourceware.org/ml/binutils/2005-10/msg00297.html), without
which the newly added test is expected to fail.

Jan

>>> Nick Clifton <[hidden email]> 26.10.05 12:12:50 >>>
Hi Jan,

> This patch allows, on x86/x86-64, registers to be on the right side
of
> .equ and similar operations, and (obviously) also allows the
resulting
> symbols to be used.

I have not seen any adverse comments to this patch, so:

> gas/
> 2005-10-21  Jan Beulich  <[hidden email]>
>
> * config/tc-i386.c (i386_operand): Don't check register prefix
> here.
> (parse_real_register): Rename from parse_register.
> (parse_register): New.
> (i386_parse_name): New.
> (md_operand): New.
> (intel_e11): Don't tolerate registers in offset expressions
> anymore.
> (intel_get_token): Don't check register prefix here. Copy the
> actual
> register token, not the canonical register name.
> * config/tc-i386.h (md_operand): Delete.
> (i386_parse_name): Declare.
> (md_parse_name): Define.
>
> gas/testsuite/
> 2005-10-21  Jan Beulich  <[hidden email]>
>
> * gas/i386/intel.s: Replace register used in offset expression.
> * gas/i386/intel.e: Adjust.
> * gas/i386/intelbad.l: Adjust.
> * gas/i386/equ.[sed]: New.
> * gas/i386/i386.exp: Run new test.

Approved - please apply.

Cheers
   Nick
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] further equate handling adjustment

Nick Clifton
Hi Jan,

 > gas/
 > 2005-10-21  Jan Beulich  <[hidden email]>
 >
 > * read.c (assign_symbol): Also consider equates already
 > defined.
 > * symbols.c (symbol_clone): Also cone the underlying BFD
 > symbol.
 > * config/obj-coff.h (obj_symbol_clone_hook): New.
 > (coff_obj_symbol_clone_hook): Declare.
 > * config/obj-coff.c (coff_obj_symbol_clone_hook): New.
 >
 > gas/testsuite/
 > 2005-10-21  Jan Beulich  <[hidden email]>
 >
 > * gas/all/gas.exp: Don't xfail equiv1 test anymore.

Approved - please apply.

Cheers
   Nick
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] x86: allow equates to registers

Nick Clifton
In reply to this post by Jan Beulich
Hi Jan,

> I already applied it when I remembered the dependency noted in the
> submission email. How about that patch
> (http://sourceware.org/ml/binutils/2005-10/msg00297.html), without
> which the newly added test is expected to fail.

Ah - good point - I have posted an approval for that patch as well.

Cheers
   Nick