This is the mail archive of the binutils@sources.redhat.com 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-64 corrections


2004-06-03 Jan Beulich <jbeulich@novell.com>

	* gas/config/tc-i386.c: Adjust immediates to only those
permissible for
	the selected instruction suffix. Don't treat 32-bit addressing
in
	64-bit mode specially except for the width of the used base
and/or
	index registers. Force zero displacement on rip-relative
addressing
	when there is no other displacement.
	* opcodes/i386-dis.c: Show rip-relative addressing in 64-bit
mode
	regardless of address size prefix in effect.
	* gas/testsuite/gas/i386/x86-64-addr32.[ds]: New test for
x86-64
	32-bit addressing in 64-bit mode.
	* gas/testsuite/gas/i386/x86-64-rip.[ds]: New test for x86-64
	rip-relative addressing.
	* gas/testsuite/gas/i386/i386.exp: Run the two new tests.

---
/home/jbeulich/src/binutils/mainline/2004-06-03.09.12/gas/config/tc-i386.c	2004-04-20
14:17:14.000000000 +0200
+++ 2004-06-03.09.12/gas/config/tc-i386.c	2004-06-03
10:22:33.663347560 +0200
@@ -1914,15 +1930,13 @@
 		i.types[op] = Imm64 | Imm32S;
 		break;
 	      case LONG_MNEM_SUFFIX:
-		i.types[op] = Imm32 | Imm64;
+		i.types[op] = Imm32;
 		break;
 	      case WORD_MNEM_SUFFIX:
-		i.types[op] = Imm16 | Imm32 | Imm64;
-		break;
+		i.types[op] = Imm16;
 		break;
 	      case BYTE_MNEM_SUFFIX:
-		i.types[op] = Imm8 | Imm8S | Imm16 | Imm32S | Imm32;
-		break;
+		i.types[op] = Imm8 | Imm8S;
 		break;
 	      }
 	    break;
@@ -2496,7 +2516,7 @@
   unsigned int overlap0, overlap1, overlap2;
 
   overlap0 = i.types[0] & i.tm.operand_types[0];
-  if ((overlap0 & (Imm8 | Imm8S | Imm16 | Imm32 | Imm32S))
+  if ((overlap0 & (Imm8 | Imm8S | Imm16 | Imm32 | Imm32S | Imm64))
       && overlap0 != Imm8 && overlap0 != Imm8S
       && overlap0 != Imm16 && overlap0 != Imm32S
       && overlap0 != Imm32 && overlap0 != Imm64)
@@ -2529,7 +2549,7 @@
   i.types[0] = overlap0;
 
   overlap1 = i.types[1] & i.tm.operand_types[1];
-  if ((overlap1 & (Imm8 | Imm8S | Imm16 | Imm32S | Imm32))
+  if ((overlap1 & (Imm8 | Imm8S | Imm16 | Imm32S | Imm32 | Imm64))
       && overlap1 != Imm8 && overlap1 != Imm8S
       && overlap1 != Imm16 && overlap1 != Imm32S
       && overlap1 != Imm32 && overlap1 != Imm64)
@@ -2725,21 +2745,7 @@
 	      if (i.index_reg == 0)
 		{
 		  /* Operand is just <disp>  */
-		  if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX]
!= 0)
-		      && (flag_code != CODE_64BIT))
-		    {
-		      i.rm.regmem = NO_BASE_REGISTER_16;
-		      i.types[op] &= ~Disp;
-		      i.types[op] |= Disp16;
-		    }
-		  else if (flag_code != CODE_64BIT
-			   || (i.prefix[ADDR_PREFIX] != 0))
-		    {
-		      i.rm.regmem = NO_BASE_REGISTER;
-		      i.types[op] &= ~Disp;
-		      i.types[op] |= Disp32;
-		    }
-		  else
+		  if (flag_code == CODE_64BIT)
 		    {
 		      /* 64bit mode overwrites the 32bit absolute
 			 addressing by RIP relative addressing and
@@ -2748,8 +2754,17 @@
 		      i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
 		      i.sib.base = NO_BASE_REGISTER;
 		      i.sib.index = NO_INDEX_REGISTER;
-		      i.types[op] &= ~Disp;
-		      i.types[op] |= Disp32S;
+		      i.types[op] = ((i.prefix[ADDR_PREFIX] == 0) ?
Disp32S : Disp32);
+		    }
+		  else if ((flag_code == CODE_16BIT) ^
(i.prefix[ADDR_PREFIX] != 0))
+		    {
+		      i.rm.regmem = NO_BASE_REGISTER_16;
+		      i.types[op] = Disp16;
+		    }
+		  else
+		    {
+		      i.rm.regmem = NO_BASE_REGISTER;
+		      i.types[op] = Disp32;
 		    }
 		}
 	      else /* !i.base_reg && i.index_reg  */
@@ -2774,6 +2789,8 @@
 	      i.types[op] &= ~Disp;
 	      i.types[op] |= Disp32S;
 	      i.flags[op] = Operand_PCrel;
+	      if (! i.disp_operands)
+		   fake_zero_displacement = 1;
 	    }
 	  else if (i.base_reg->reg_type & Reg16)
 	    {
@@ -2810,10 +2827,7 @@
 	      if (flag_code == CODE_64BIT
 		  && (i.types[op] & Disp))
 		{
-		  if (i.types[op] & Disp8)
-		    i.types[op] = Disp8 | Disp32S;
-		  else
-		    i.types[op] = Disp32S;
+		  i.types[op] = (i.types[op] & Disp8) |
(i.prefix[ADDR_PREFIX] == 0 ? Disp32S : Disp32);
 		}
 	      i.rm.regmem = i.base_reg->reg_num;
 	      if ((i.base_reg->reg_flags & RegRex) != 0)
@@ -3993,28 +4007,16 @@
   ok = 1;
   if (flag_code == CODE_64BIT)
     {
-      if (i.prefix[ADDR_PREFIX] == 0)
-	{
-	  /* 64bit checks.  */
-	  if ((i.base_reg
-	       && ((i.base_reg->reg_type & Reg64) == 0)
-		   && (i.base_reg->reg_type != BaseIndex
-		       || i.index_reg))
-	      || (i.index_reg
-		  && ((i.index_reg->reg_type & (Reg64 | BaseIndex))
-		      != (Reg64 | BaseIndex))))
-	    ok = 0;
-	}
-      else
-	{
-	  /* 32bit checks.  */
-	  if ((i.base_reg
-	       && (i.base_reg->reg_type & (Reg32 | RegRex)) != Reg32)
-	      || (i.index_reg
-		  && ((i.index_reg->reg_type & (Reg32 | BaseIndex |
RegRex))
-		      != (Reg32 | BaseIndex))))
-	    ok = 0;
-	}
+      unsigned RegXX = (i.prefix[ADDR_PREFIX] == 0 ? Reg64 : Reg32);
+
+      if ((i.base_reg
+	   && ((i.base_reg->reg_type & RegXX) == 0)
+		&& (i.base_reg->reg_type != BaseIndex
+		    || i.index_reg))
+	  || (i.index_reg
+	      && ((i.index_reg->reg_type & (RegXX | BaseIndex))
+		  != (RegXX | BaseIndex))))
+	ok = 0;
     }
   else
     {
@@ -4047,8 +4049,7 @@
   if (!ok)
     {
 #if INFER_ADDR_PREFIX
-      if (flag_code != CODE_64BIT
-	  && i.prefix[ADDR_PREFIX] == 0 && stackop_size != '\0')
+      if (i.prefix[ADDR_PREFIX] == 0)
 	{
 	  i.prefix[ADDR_PREFIX] = ADDR_PREFIX_OPCODE;
 	  i.prefixes += 1;
@@ -4057,7 +4058,7 @@
 	     FIXME.  There doesn't seem to be any real need for
separate
 	     Disp16 and Disp32 flags.  The same goes for Imm16 and
Imm32.
 	     Removing them would probably clean up the code quite a lot.
 */
-	  if (i.types[this_operand] & (Disp16 | Disp32))
+	  if (flag_code != CODE_64BIT && (i.types[this_operand] &
(Disp16 | Disp32)))
 	     i.types[this_operand] ^= (Disp16 | Disp32);
 	  fudged = 1;
 	  goto tryprefix;
@@ -4070,9 +4071,8 @@
 	as_bad (_("`%s' is not a valid %s bit base/index expression"),
 		operand_string,
 		flag_code_names[flag_code]);
-      return 0;
     }
-  return 1;
+  return ok;
 }
 
 /* Parse OPERAND_STRING into the i386_insn structure I.  Returns
non-zero
---
/home/jbeulich/src/binutils/mainline/2004-06-03.09.12/gas/testsuite/gas/i386/i386.exp	2004-05-12
05:06:10.000000000 +0200
+++ 2004-06-03.09.12/gas/testsuite/gas/i386/i386.exp	2004-06-03
10:19:33.595722000 +0200
@@ -105,7 +105,9 @@
     set ASFLAGS "$ASFLAGS --64"
 
     run_dump_test "x86_64"
+    run_dump_test "x86-64-addr32"
     run_dump_test "x86-64-opcode"
+    run_dump_test "x86-64-rip"
     run_list_test "x86-64-inval" "-al"
 
     set ASFLAGS "$old_ASFLAGS"
---
/home/jbeulich/src/binutils/mainline/2004-06-03.09.12/gas/testsuite/gas/i386/x86-64-addr32.d	1970-01-01
01:00:00.000000000 +0100
+++
2004-06-03.09.12/gas/testsuite/gas/i386/x86-64-addr32.d	2004-06-02
14:45:09.000000000 +0200
@@ -0,0 +1,13 @@
+#as: -J
+#objdump: -drw
+#name: x86-64 32-bit addressing
+
+.*: +file format elf64-x86-64
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[	 ]*0:[	 ]+67 48 8d 80 00 00 00 00[	 ]+addr32[	 ]+lea[	
]+0x0\(%[re]ax\),%rax.*
+[	 ]*8:[	 ]+67 49 8d 80 00 00 00 00[	 ]+addr32[	 ]+lea[	
]+0x0\(%r8d?\),%rax.*
+[	 ]*10:[	 ]+67 48 8d 05 00 00 00 00[	 ]+addr32[	 ]+lea[	
]+0\(%[re]ip\),%rax.*
+[	 ]*18:[	 ]+67 48 8d 04 25 00 00 00 00[	 ]+addr32[	 ]+lea[	
]+0x0,%rax.*
---
/home/jbeulich/src/binutils/mainline/2004-06-03.09.12/gas/testsuite/gas/i386/x86-64-addr32.s	1970-01-01
01:00:00.000000000 +0100
+++
2004-06-03.09.12/gas/testsuite/gas/i386/x86-64-addr32.s	2004-06-02
14:05:47.000000000 +0200
@@ -0,0 +1,5 @@
+.text
+	lea		symbol(%eax), %rax
+	lea		symbol(%r8d), %rax
+	addr32 lea	symbol(%rip), %rax
+	addr32 lea	symbol, %rax
---
/home/jbeulich/src/binutils/mainline/2004-06-03.09.12/gas/testsuite/gas/i386/x86-64-rip.d	1970-01-01
01:00:00.000000000 +0100
+++
2004-06-03.09.12/gas/testsuite/gas/i386/x86-64-rip.d	2004-06-02
14:13:16.000000000 +0200
@@ -0,0 +1,13 @@
+#as: -J
+#objdump: -drw
+#name: x86-64 rip addressing
+
+.*: +file format elf64-x86-64
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[	 ]*0:[	 ]+8d 05 00 00 00 00[	 ]+lea[	 ]+0\(%rip\),%eax[	
]*(#.*)?
+[	 ]*6:[	 ]+8d 05 11 11 11 11[	 ]+lea[	
]+286331153\(%rip\),%eax[	 ]*(#.*)?
+[	 ]*c:[	 ]+8d 05 01 00 00 00[	 ]+lea[	 ]+1\(%rip\),%eax[	
]*(#.*)?
+[	 ]*12:[	 ]+8d 05 00 00 00 00[	 ]+lea[	 ]+0\(%rip\),%eax[	
]*(#.*)?
---
/home/jbeulich/src/binutils/mainline/2004-06-03.09.12/gas/testsuite/gas/i386/x86-64-rip.s	1970-01-01
01:00:00.000000000 +0100
+++
2004-06-03.09.12/gas/testsuite/gas/i386/x86-64-rip.s	2004-06-02
12:00:40.000000000 +0200
@@ -0,0 +1,5 @@
+.text
+	leal	symbol(%rip), %eax
+	leal	0x11111111(%rip), %eax
+	leal	1(%rip), %eax
+	leal	(%rip), %eax
---
/home/jbeulich/src/binutils/mainline/2004-06-03.09.12/opcodes/i386-dis.c	2004-03-12
14:38:16.000000000 +0100
+++ 2004-06-03.09.12/opcodes/i386-dis.c	2004-06-03
10:20:39.466708088 +0200
@@ -3094,7 +3096,7 @@
 	  if ((base & 7) == 5)
 	    {
 	      havebase = 0;
-	      if (mode_64bit && !havesib && (sizeflag & AFLAG))
+	      if (mode_64bit && !havesib)
 		riprel = 1;
 	      disp = get32s ();
 	    }


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