[PATCH] x86: allow equates to registers
Jan Beulich
JBeulich@novell.com
Fri Oct 21 16:01:00 GMT 2005
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: .*
-------------- next part --------------
A non-text attachment was scrubbed...
Name: binutils-mainline-x86-reg-equate.patch
Type: application/octet-stream
Size: 10851 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20051021/745065f1/attachment.obj>
More information about the Binutils
mailing list