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-64: fix Intel mode disassembly of cbw/cwd extensions


cbw/cwd and derivates were not correctly disassembled in Intel mode.

Built and tested on i686-pc-linux-gnu, x86_64-unknown-linux-gnu, and a few
cross x86 targets.

opcodes/
2006-11-30  Jan Beulich  <jbeulich@novell.com>

	* i386-dis.c (dis386): Use 'R' and 'O' for cbw/cwd unconditionally.
	(putop): For 'O' suffix, print 'q' in Intel mode, and mark data prefix
	used. For 'R' and 'W' suffix, simplify and fix Intel mode.

gas/testsuite/
2006-11-30  Jan Beulich  <jbeulich@novell.com>

	* gas/i386/intel.s: Use Intel syntax in Intel syntax test.
	* gas/i386/x86-64-cbw.[sd]: New.
	* gas/i386/x86-64-cbw-intel.d: New.
	* gas/i386/i386.exp: Run new tests.

--- 2006-11-30/gas/testsuite/gas/i386/i386.exp	2006-11-13 15:22:00.000000000 +0100
+++ 2006-11-30/gas/testsuite/gas/i386/i386.exp	2006-11-20 17:59:55.000000000 +0100
@@ -155,6 +155,8 @@ if [expr ([istarget "i*86-*-*"] || [ista
     run_dump_test "x86-64-merom"
     run_dump_test "x86-64-rep"
     run_dump_test "x86-64-rep-suffix"
+    run_dump_test "x86-64-cbw"
+    run_dump_test "x86-64-cbw-intel"
     run_dump_test "x86-64-gidt"
     run_dump_test "x86-64-nops"
     if ![istarget "*-*-mingw64*"] then {
--- 2006-11-30/gas/testsuite/gas/i386/intel.s	2005-10-21 16:51:03.000000000 +0200
+++ 2006-11-30/gas/testsuite/gas/i386/intel.s	2006-11-20 14:50:07.000000000 +0100
@@ -484,8 +484,8 @@ foo:
  xchg   bp, ax
  xchg   si, ax
  xchg   di, ax
- cbtw
- cwtd
+ cbw
+ cwd
  callw  0x9090,0x9090
  pushfw
  popfw
--- 2006-11-30/gas/testsuite/gas/i386/x86-64-cbw-intel.d	1970-01-01 01:00:00.000000000 +0100
+++ 2006-11-30/gas/testsuite/gas/i386/x86-64-cbw-intel.d	2006-11-20 16:19:57.000000000 +0100
@@ -0,0 +1,26 @@
+#source: x86-64-cbw.s
+#objdump: -dwMintel
+#name: x86-64 CBW/CWD & Co (Intel disassembly)
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <_cbw>:
+   0:	66 98                	cbw    
+   2:	98                   	cwde   
+   3:	48 98                	cdqe   
+   5:	66 40 98             	rex cbw    
+   8:	40 98                	rex cwde   
+   a:	66                   	data16
+   b:	48 98                	cdqe   
+
+0+00d <_cwd>:
+   d:	66 99                	cwd    
+   f:	99                   	cdq    
+  10:	48 99                	cqo    
+  12:	66 40 99             	rex cwd    
+  15:	40 99                	rex cdq    
+  17:	66                   	data16
+  18:	48 99                	cqo    
+#pass
--- 2006-11-30/gas/testsuite/gas/i386/x86-64-cbw.d	1970-01-01 01:00:00.000000000 +0100
+++ 2006-11-30/gas/testsuite/gas/i386/x86-64-cbw.d	2006-11-20 16:17:36.000000000 +0100
@@ -0,0 +1,25 @@
+#objdump: -dw
+#name: x86-64 CBW/CWD & Co
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <_cbw>:
+   0:	66 98                	cbtw   
+   2:	98                   	cwtl   
+   3:	48 98                	cltq   
+   5:	66 40 98             	rex cbtw   
+   8:	40 98                	rex cwtl   
+   a:	66                   	data16
+   b:	48 98                	cltq   
+
+0+00d <_cwd>:
+   d:	66 99                	cwtd   
+   f:	99                   	cltd   
+  10:	48 99                	cqto   
+  12:	66 40 99             	rex cwtd   
+  15:	40 99                	rex cltd   
+  17:	66                   	data16
+  18:	48 99                	cqto   
+#pass
--- 2006-11-30/gas/testsuite/gas/i386/x86-64-cbw.s	1970-01-01 01:00:00.000000000 +0100
+++ 2006-11-30/gas/testsuite/gas/i386/x86-64-cbw.s	2006-11-20 16:22:46.000000000 +0100
@@ -0,0 +1,18 @@
+ .intel_syntax noprefix
+ .text
+_cbw:
+	cbw
+	cwde
+	cdqe
+	rex cbw
+	rex cwde
+	rex64 cbw
+_cwd:
+	cwd
+	cdq
+	cqo
+	rex cwd
+	rex cdq
+	rex64 cwd
+
+	.p2align	4,0
--- 2006-11-30/opcodes/i386-dis.c	2006-11-13 15:22:14.000000000 +0100
+++ 2006-11-30/opcodes/i386-dis.c	2006-11-21 09:43:56.000000000 +0100
@@ -506,17 +506,17 @@ struct dis386 {
    'J' => print 'l'
    'L' => print 'l' if suffix_always is true
    'N' => print 'n' if instruction has no wait "prefix"
-   'O' => print 'd', or 'o'
+   'O' => print 'd' or 'o' (or 'q' in Intel mode)
    'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
    .      or suffix_always is true.  print 'q' if rex prefix is present.
    'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
    .      is true
-   'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
+   'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
    'S' => print 'w', 'l' or 'q' if suffix_always is true
    'T' => print 'q' in 64bit mode and behave as 'P' otherwise
    'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
    'V' => print 'q' in 64bit mode and behave as 'S' otherwise
-   'W' => print 'b' or 'w' ("w" or "de" in intel mode)
+   'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
    'X' => print 's', 'd' depending on data16 prefix (for XMM)
    'Y' => 'q' if instruction has an REX 64bit overwrite prefix
    'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
@@ -703,8 +703,8 @@ static const struct dis386 dis386[] = {
   { "xchgS",		RMeSI, eAX, XX, XX },
   { "xchgS",		RMeDI, eAX, XX, XX },
   /* 98 */
-  { "cW{tR||tR|}",	XX, XX, XX, XX },
-  { "cR{tO||tO|}",	XX, XX, XX, XX },
+  { "cW{t||t|}R",	XX, XX, XX, XX },
+  { "cR{t||t|}O",	XX, XX, XX, XX },
   { "Jcall{T|}",	Ap, XX, XX, XX },
   { "(bad)",		XX, XX, XX, XX },	/* fwait */
   { "pushfT",		XX, XX, XX, XX },
@@ -3812,8 +3812,12 @@ putop (const char *template, int sizefla
 	  USED_REX (REX_MODE64);
 	  if (rex & REX_MODE64)
 	    *obufp++ = 'o';
+	  else if (intel_syntax && (sizeflag & DFLAG))
+	    *obufp++ = 'q';
 	  else
 	    *obufp++ = 'd';
+	  if (!(rex & REX_MODE64))
+	    used_prefixes |= (prefixes & PREFIX_DATA);
 	  break;
 	case 'T':
 	  if (intel_syntax)
@@ -3874,33 +3878,20 @@ putop (const char *template, int sizefla
 	  break;
 	case 'R':
 	  USED_REX (REX_MODE64);
-	  if (intel_syntax)
+	  if (rex & REX_MODE64)
+	    *obufp++ = 'q';
+	  else if (sizeflag & DFLAG)
 	    {
-	      if (rex & REX_MODE64)
-		{
-		  *obufp++ = 'q';
-		  *obufp++ = 't';
-		}
-	      else if (sizeflag & DFLAG)
-		{
+	      if (intel_syntax)
 		  *obufp++ = 'd';
-		  *obufp++ = 'q';
-		}
 	      else
-		{
-		  *obufp++ = 'w';
-		  *obufp++ = 'd';
-		}
+		  *obufp++ = 'l';
 	    }
 	  else
-	    {
-	      if (rex & REX_MODE64)
-		*obufp++ = 'q';
-	      else if (sizeflag & DFLAG)
-		*obufp++ = 'l';
-	      else
-		*obufp++ = 'w';
-	    }
+	    *obufp++ = 'w';
+	  if (intel_syntax && !p[1]
+	      && ((rex & REX_MODE64) || (sizeflag & DFLAG)))
+	    *obufp++ = 'e';
 	  if (!(rex & REX_MODE64))
 	    used_prefixes |= (prefixes & PREFIX_DATA);
 	  break;
@@ -3950,31 +3941,19 @@ putop (const char *template, int sizefla
 	  /* implicit operand size 'l' for i386 or 'q' for x86-64 */
 	case 'W':
 	  /* operand size flag for cwtl, cbtw */
-	  USED_REX (0);
-	  if (rex)
-	    *obufp++ = 'l';
+	  USED_REX (REX_MODE64);
+	  if (rex & REX_MODE64)
+	    {
+	      if (intel_syntax)
+		*obufp++ = 'd';
+	      else
+		*obufp++ = 'l';
+	    }
 	  else if (sizeflag & DFLAG)
 	    *obufp++ = 'w';
 	  else
 	    *obufp++ = 'b';
-	  if (intel_syntax)
-	    {
-	      if (rex)
-		{
-		  *obufp++ = 'q';
-		  *obufp++ = 'e';
-		}
-	      if (sizeflag & DFLAG)
-		{
-		  *obufp++ = 'd';
-		  *obufp++ = 'e';
-		}
-	      else
-		{
-		  *obufp++ = 'w';
-		}
-	    }
-	  if (!rex)
+	  if (!(rex & REX_MODE64))
 	    used_prefixes |= (prefixes & PREFIX_DATA);
 	  break;
 	}



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