This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] x86: allow equates to registers


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  <jbeulich@novell.com>

	* 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  <jbeulich@novell.com>

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

Attachment: binutils-mainline-x86-reg-equate.patch
Description: Binary data


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]