[llvm] r198586 - Add OpSize16 bit, for instructions which need 0x66 prefix in 16-bit mode

Craig Topper craig.topper at gmail.com
Sun Jan 5 22:02:58 PST 2014


Author: ctopper
Date: Mon Jan  6 00:02:58 2014
New Revision: 198586

URL: http://llvm.org/viewvc/llvm-project?rev=198586&view=rev
Log:
Add OpSize16 bit, for instructions which need 0x66 prefix in 16-bit mode

The 0x66 prefix toggles between 16-bit and 32-bit addressing mode.
So in 32-bit mode it is used to switch to 16-bit addressing mode for the
following instruction, while in 16-bit mode it's the other way round — it's
used to switch to 32-bit mode instead.

Thus, emit the 0x66 prefix byte for OpSize only in 32-bit (and 64-bit) mode,
and introduce a new OpSize16 bit which is used in 16-bit mode instead.

This is just the basic infrastructure for that change; a subsequent patch
will add the new OpSize16 bit to the 32-bit instructions that need it.

Patch from David Woodhouse.


Modified:
    llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
    llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
    llvm/trunk/lib/Target/X86/X86InstrFormats.td
    llvm/trunk/test/MC/X86/x86-16.s

Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h?rev=198586&r1=198585&r2=198586&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h Mon Jan  6 00:02:58 2014
@@ -295,13 +295,15 @@ namespace X86II {
 
     // OpSize - Set if this instruction requires an operand size prefix (0x66),
     // which most often indicates that the instruction operates on 16 bit data
-    // instead of 32 bit data.
+    // instead of 32 bit data. OpSize16 in 16 bit mode indicates that the
+    // instruction operates on 32 bit data instead of 16 bit data.
     OpSize      = 1 << 6,
+    OpSize16    = 1 << 7,
 
     // AsSize - Set if this instruction requires an operand size prefix (0x67),
     // which most often indicates that the instruction address 16 bit address
     // instead of 32 bit address (or 32 bit address in 64 bit mode).
-    AdSize      = 1 << 7,
+    AdSize      = 1 << 8,
 
     //===------------------------------------------------------------------===//
     // Op0Mask - There are several prefix bytes that are used to form two byte
@@ -309,7 +311,7 @@ namespace X86II {
     // used to obtain the setting of this field.  If no bits in this field is
     // set, there is no prefix byte for obtaining a multibyte opcode.
     //
-    Op0Shift    = 8,
+    Op0Shift    = 9,
     Op0Mask     = 0x1F << Op0Shift,
 
     // TB - TwoByte - Set if this instruction has a two byte opcode, which

Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp?rev=198586&r1=198585&r2=198586&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp Mon Jan  6 00:02:58 2014
@@ -1191,8 +1191,7 @@ void X86MCCodeEmitter::EmitOpcodePrefix(
     EmitByte(0x67, CurByte, OS);
 
   // Emit the operand size opcode prefix as needed.
-  // FIXME for is16BitMode().
-  if (TSFlags & X86II::OpSize)
+  if (TSFlags & (is16BitMode(Features) ? X86II::OpSize16 : X86II::OpSize))
     EmitByte(0x66, CurByte, OS);
 
   bool Need0FPrefix = false;

Modified: llvm/trunk/lib/Target/X86/X86InstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFormats.td?rev=198586&r1=198585&r2=198586&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrFormats.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrFormats.td Mon Jan  6 00:02:58 2014
@@ -112,6 +112,7 @@ def CD8VT8 : CD8VForm<7>;  // v := 8
 // Prefix byte classes which are used to indicate to the ad-hoc machine code
 // emitter that various prefix bytes are required.
 class OpSize { bit hasOpSizePrefix = 1; }
+class OpSize16 { bit hasOpSize16Prefix = 1; }
 class AdSize { bit hasAdSizePrefix = 1; }
 class REX_W  { bit hasREX_WPrefix = 1; }
 class LOCK   { bit hasLockPrefix = 1; }
@@ -191,6 +192,7 @@ class X86Inst<bits<8> opcod, Format f, I
                             // AsmString from the parser, but still disassemble.
 
   bit hasOpSizePrefix = 0;  // Does this inst have a 0x66 prefix?
+  bit hasOpSize16Prefix = 0;// Does this inst have a 0x66 prefix in 16-bit mode?
   bit hasAdSizePrefix = 0;  // Does this inst have a 0x67 prefix?
 
   bits<5> Prefix = 0;       // Which prefix byte does this inst have?
@@ -222,32 +224,33 @@ class X86Inst<bits<8> opcod, Format f, I
   // TSFlags layout should be kept in sync with X86InstrInfo.h.
   let TSFlags{5-0}   = FormBits;
   let TSFlags{6}     = hasOpSizePrefix;
-  let TSFlags{7}     = hasAdSizePrefix;
-  let TSFlags{12-8}  = Prefix;
-  let TSFlags{13}    = hasREX_WPrefix;
-  let TSFlags{16-14} = ImmT.Value;
-  let TSFlags{19-17} = FPForm.Value;
-  let TSFlags{20}    = hasLockPrefix;
-  let TSFlags{22-21} = SegOvrBits;
-  let TSFlags{24-23} = ExeDomain.Value;
-  let TSFlags{32-25} = Opcode;
-  let TSFlags{33}    = hasVEXPrefix;
-  let TSFlags{34}    = hasVEX_WPrefix;
-  let TSFlags{35}    = hasVEX_4VPrefix;
-  let TSFlags{36}    = hasVEX_4VOp3Prefix;
-  let TSFlags{37}    = hasVEX_i8ImmReg;
-  let TSFlags{38}    = hasVEX_L;
-  let TSFlags{39}    = ignoresVEX_L;
-  let TSFlags{40}    = hasEVEXPrefix;
-  let TSFlags{41}    = hasEVEX_K;
-  let TSFlags{42}    = hasEVEX_Z;
-  let TSFlags{43}    = hasEVEX_L2;
-  let TSFlags{44}    = hasEVEX_B;
-  let TSFlags{46-45} = EVEX_CD8E;
-  let TSFlags{49-47} = EVEX_CD8V;
-  let TSFlags{50}    = has3DNow0F0FOpcode;
-  let TSFlags{51}    = hasMemOp4Prefix;
-  let TSFlags{52}    = hasXOP_Prefix;
+  let TSFlags{7}     = hasOpSize16Prefix;
+  let TSFlags{8}     = hasAdSizePrefix;
+  let TSFlags{13-9}  = Prefix;
+  let TSFlags{14}    = hasREX_WPrefix;
+  let TSFlags{17-15} = ImmT.Value;
+  let TSFlags{20-18} = FPForm.Value;
+  let TSFlags{21}    = hasLockPrefix;
+  let TSFlags{23-22} = SegOvrBits;
+  let TSFlags{25-24} = ExeDomain.Value;
+  let TSFlags{33-26} = Opcode;
+  let TSFlags{34}    = hasVEXPrefix;
+  let TSFlags{35}    = hasVEX_WPrefix;
+  let TSFlags{36}    = hasVEX_4VPrefix;
+  let TSFlags{37}    = hasVEX_4VOp3Prefix;
+  let TSFlags{38}    = hasVEX_i8ImmReg;
+  let TSFlags{39}    = hasVEX_L;
+  let TSFlags{40}    = ignoresVEX_L;
+  let TSFlags{41}    = hasEVEXPrefix;
+  let TSFlags{42}    = hasEVEX_K;
+  let TSFlags{43}    = hasEVEX_Z;
+  let TSFlags{44}    = hasEVEX_L2;
+  let TSFlags{45}    = hasEVEX_B;
+  let TSFlags{47-46} = EVEX_CD8E;
+  let TSFlags{50-48} = EVEX_CD8V;
+  let TSFlags{51}    = has3DNow0F0FOpcode;
+  let TSFlags{52}    = hasMemOp4Prefix;
+  let TSFlags{53}    = hasXOP_Prefix;
 }
 
 class PseudoI<dag oops, dag iops, list<dag> pattern>

Modified: llvm/trunk/test/MC/X86/x86-16.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/x86-16.s?rev=198586&r1=198585&r2=198586&view=diff
==============================================================================
--- llvm/trunk/test/MC/X86/x86-16.s (original)
+++ llvm/trunk/test/MC/X86/x86-16.s Mon Jan  6 00:02:58 2014
@@ -27,6 +27,9 @@
 // CHECK: testb	%bl, %cl                # encoding: [0x84,0xcb]
         testb %bl, %cl
 
+// CHECK: addw	%ax, %ax                # encoding: [0x01,0xc0]
+        addw %ax, %ax
+
 into
 // CHECK: into
 // CHECK:  encoding: [0xce]
@@ -40,6 +43,10 @@ int $255
 // CHECK: int $255
 // CHECK:  encoding: [0xcd,0xff]
 
+// CHECK: cmovbw %bx, %bx
+cmovnae	%bx,%bx
+
+
 // CHECK: fmul	%st(0)
 // CHECK:  encoding: [0xd8,0xc8]
         fmul %st(0), %st
@@ -64,10 +71,119 @@ int $255
 // CHECK:  encoding: [0xd8,0xf0]
         fdiv %st(0), %st
 
+// CHECK: movw	%cs, %ax
+// CHECK:  encoding: [0x8c,0xc8]
+        movw %cs, %ax
+
+// CHECK: movw	%cs, (%eax)
+// CHECK:  encoding: [0x67,0x8c,0x08]
+        movw %cs, (%eax)
+
+// CHECK: movw	(%eax), %cs
+// CHECK:  encoding: [0x67,0x8e,0x08]
+        movw (%eax), %cs
+
+// CHECK: movl	%cr0, %eax
+// CHECK:  encoding: [0x0f,0x20,0xc0]
+        movl %cr0,%eax
+
+// CHECK: movl	%cr1, %eax
+// CHECK:  encoding: [0x0f,0x20,0xc8]
+        movl %cr1,%eax
+
+// CHECK: movl	%cr2, %eax
+// CHECK:  encoding: [0x0f,0x20,0xd0]
+        movl %cr2,%eax
+
+// CHECK: movl	%cr3, %eax
+// CHECK:  encoding: [0x0f,0x20,0xd8]
+        movl %cr3,%eax
+
+// CHECK: movl	%cr4, %eax
+// CHECK:  encoding: [0x0f,0x20,0xe0]
+        movl %cr4,%eax
+
+// CHECK: movl	%dr0, %eax
+// CHECK:  encoding: [0x0f,0x21,0xc0]
+        movl %dr0,%eax
+
+// CHECK: movl	%dr1, %eax
+// CHECK:  encoding: [0x0f,0x21,0xc8]
+        movl %dr1,%eax
+
+// CHECK: movl	%dr1, %eax
+// CHECK:  encoding: [0x0f,0x21,0xc8]
+        movl %dr1,%eax
+
+// CHECK: movl	%dr2, %eax
+// CHECK:  encoding: [0x0f,0x21,0xd0]
+        movl %dr2,%eax
+
+// CHECK: movl	%dr3, %eax
+// CHECK:  encoding: [0x0f,0x21,0xd8]
+        movl %dr3,%eax
+
+// CHECK: movl	%dr4, %eax
+// CHECK:  encoding: [0x0f,0x21,0xe0]
+        movl %dr4,%eax
+
+// CHECK: movl	%dr5, %eax
+// CHECK:  encoding: [0x0f,0x21,0xe8]
+        movl %dr5,%eax
+
+// CHECK: movl	%dr6, %eax
+// CHECK:  encoding: [0x0f,0x21,0xf0]
+        movl %dr6,%eax
+
+// CHECK: movl	%dr7, %eax
+// CHECK:  encoding: [0x0f,0x21,0xf8]
+        movl %dr7,%eax
+
 // CHECK: wait
 // CHECK:  encoding: [0x9b]
 	fwait
 
+sysret
+// CHECK: sysretl
+// CHECK: encoding: [0x0f,0x07]
+sysretl
+// CHECK: sysretl
+// CHECK: encoding: [0x0f,0x07]
+
+testl	%ecx, -24(%ebp)
+// CHECK: testl	-24(%ebp), %ecx
+testl	-24(%ebp), %ecx
+// CHECK: testl	-24(%ebp), %ecx
+
+
+pushw %cs
+// CHECK: pushw	%cs
+// CHECK: encoding: [0x0e]
+pushw %ds
+// CHECK: pushw	%ds
+// CHECK: encoding: [0x1e]
+pushw %ss
+// CHECK: pushw	%ss
+// CHECK: encoding: [0x16]
+pushw %es
+// CHECK: pushw	%es
+// CHECK: encoding: [0x06]
+pushw %fs
+// CHECK: pushw	%fs
+// CHECK: encoding: [0x0f,0xa0]
+pushw %gs
+// CHECK: pushw	%gs
+// CHECK: encoding: [0x0f,0xa8]
+
+pushfd
+// CHECK: pushfl
+popfd
+// CHECK: popfl
+pushfl
+// CHECK: pushfl
+popfl
+// CHECK: popfl
+
 
 	setc	%bl
 	setnae	%bl
@@ -103,9 +219,15 @@ ljmpl	$0x7ace,$0x7ace
 // CHECK:	incb	%al # encoding: [0xfe,0xc0]
 	incb %al
 
+// CHECK:	incw	%ax # encoding: [0x40]
+	incw %ax
+
 // CHECK:	decb	%al # encoding: [0xfe,0xc8]
 	decb %al
 
+// CHECK:	decw	%ax # encoding: [0x48]
+	decw %ax
+
 // CHECK: pshufw $14, %mm4, %mm0 # encoding: [0x0f,0x70,0xc4,0x0e]
 pshufw $14, %mm4, %mm0
 
@@ -152,6 +274,10 @@ pshufw $90, %mm4, %mm0
 // CHECK:  encoding: [0x2f]
         	das
 
+// CHECK: bound	2(%eax), %bx
+// CHECK:  encoding: [0x67,0x62,0x58,0x02]
+        	bound	2(%eax),%bx
+
 // CHECK: arpl	%bx, %bx
 // CHECK:  encoding: [0x63,0xdb]
         	arpl	%bx,%bx
@@ -219,11 +345,23 @@ pshufw $90, %mm4, %mm0
 	outsb	%ds:(%si), %dx
 	outsb	(%si), %dx
 
+// CHECK: outsw # encoding: [0x6f]
+// CHECK: outsw
+// CHECK: outsw
+	outsw
+	outsw	%ds:(%si), %dx
+	outsw	(%si), %dx
+
 // CHECK: insb # encoding: [0x6c]
 // CHECK: insb
 	insb
 	insb	%dx, %es:(%di)
 
+// CHECK: insw # encoding: [0x6d]
+// CHECK: insw
+	insw
+	insw	%dx, %es:(%di)
+
 // CHECK: movsb # encoding: [0xa4]
 // CHECK: movsb
 // CHECK: movsb
@@ -231,6 +369,13 @@ pshufw $90, %mm4, %mm0
 	movsb	%ds:(%si), %es:(%di)
 	movsb	(%si), %es:(%di)
 
+// CHECK: movsw # encoding: [0xa5]
+// CHECK: movsw
+// CHECK: movsw
+	movsw
+	movsw	%ds:(%si), %es:(%di)
+	movsw	(%si), %es:(%di)
+
 // CHECK: lodsb # encoding: [0xac]
 // CHECK: lodsb
 // CHECK: lodsb
@@ -242,6 +387,17 @@ pshufw $90, %mm4, %mm0
 	lods	%ds:(%si), %al
 	lods	(%si), %al
 
+// CHECK: lodsw # encoding: [0xad]
+// CHECK: lodsw
+// CHECK: lodsw
+// CHECK: lodsw
+// CHECK: lodsw
+	lodsw
+	lodsw	%ds:(%si), %ax
+	lodsw	(%si), %ax
+	lods	%ds:(%si), %ax
+	lods	(%si), %ax
+
 // CHECK: stosb # encoding: [0xaa]
 // CHECK: stosb
 // CHECK: stosb
@@ -249,6 +405,17 @@ pshufw $90, %mm4, %mm0
 	stosb	%al, %es:(%di)
 	stos	%al, %es:(%di)
 
+// CHECK: stosw # encoding: [0xab]
+// CHECK: stosw
+// CHECK: stosw
+	stosw
+	stosw	%ax, %es:(%di)
+	stos	%ax, %es:(%di)
+
+// CHECK: strw
+// CHECK: encoding: [0x0f,0x00,0xc8]
+	str %ax
+
 // CHECK: fsubp
 // CHECK: encoding: [0xde,0xe1]
 fsubp %st,%st(1)
@@ -257,3 +424,6 @@ fsubp %st,%st(1)
 // CHECK: encoding: [0xde,0xe2]
 fsubp   %st, %st(2)
 
+// CHECK: xchgw %ax, %ax
+// CHECK: encoding: [0x90]
+xchgw %ax, %ax





More information about the llvm-commits mailing list