Move address override handling in X86MCCodeEmitter to a place where it works for...
authorCraig Topper <craig.topper@gmail.com>
Fri, 31 Jan 2014 05:33:45 +0000 (05:33 +0000)
committerCraig Topper <craig.topper@gmail.com>
Fri, 31 Jan 2014 05:33:45 +0000 (05:33 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200516 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
test/MC/X86/x86_64-avx-encoding.s
test/MC/X86/x86_64-tbm-encoding.s

index 52d6d14a8f81b1a1e18e459d6cde79c4e3ca4c74..7d81bbe9857fd555bdc6ca2e42a677922634f507 100644 (file)
@@ -966,10 +966,6 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
     break;
   }
 
-  // Emit segment override opcode prefix as needed.
-  if (MemOperand >= 0)
-    EmitSegmentOverridePrefix(CurByte, MemOperand+X86::AddrSegmentReg, MI, OS);
-
   if (!HasEVEX) {
     // VEX opcode prefix can have 2 or 3 bytes
     //
@@ -1152,48 +1148,6 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
                                         const MCSubtargetInfo &STI,
                                         raw_ostream &OS) const {
 
-  // Emit the lock opcode prefix as needed.
-  if (TSFlags & X86II::LOCK)
-    EmitByte(0xF0, CurByte, OS);
-
-  // Emit segment override opcode prefix as needed.
-  if (MemOperand >= 0)
-    EmitSegmentOverridePrefix(CurByte, MemOperand+X86::AddrSegmentReg, MI, OS);
-
-  // Emit the repeat opcode prefix as needed.
-  if ((TSFlags & X86II::Op0Mask) == X86II::REP)
-    EmitByte(0xF3, CurByte, OS);
-
-  // Emit the address size opcode prefix as needed.
-  bool need_address_override;
-  // The AdSize prefix is only for 32-bit and 64-bit modes. Hm, perhaps we
-  // should introduce an AdSize16 bit instead of having seven special cases?
-  if ((!is16BitMode(STI) && TSFlags & X86II::AdSize) ||
-      (is16BitMode(STI) && (MI.getOpcode() == X86::JECXZ_32 ||
-                         MI.getOpcode() == X86::MOV8o8a ||
-                         MI.getOpcode() == X86::MOV16o16a ||
-                         MI.getOpcode() == X86::MOV32o32a ||
-                         MI.getOpcode() == X86::MOV8ao8 ||
-                         MI.getOpcode() == X86::MOV16ao16 ||
-                         MI.getOpcode() == X86::MOV32ao32))) {
-    need_address_override = true;
-  } else if (MemOperand == -1) {
-    need_address_override = false;
-  } else if (is64BitMode(STI)) {
-    assert(!Is16BitMemOperand(MI, MemOperand, STI));
-    need_address_override = Is32BitMemOperand(MI, MemOperand);
-  } else if (is32BitMode(STI)) {
-    assert(!Is64BitMemOperand(MI, MemOperand));
-    need_address_override = Is16BitMemOperand(MI, MemOperand, STI);
-  } else {
-    assert(is16BitMode(STI));
-    assert(!Is64BitMemOperand(MI, MemOperand));
-    need_address_override = !Is16BitMemOperand(MI, MemOperand, STI);
-  }
-
-  if (need_address_override)
-    EmitByte(0x67, CurByte, OS);
-
   // Emit the operand size opcode prefix as needed.
   if (TSFlags & (is16BitMode(STI) ? X86II::OpSize16 : X86II::OpSize))
     EmitByte(0x66, CurByte, OS);
@@ -1309,6 +1263,49 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
   int MemoryOperand = X86II::getMemoryOperandNo(TSFlags, Opcode);
   if (MemoryOperand != -1) MemoryOperand += CurOp;
 
+  // Emit the lock opcode prefix as needed.
+  if (TSFlags & X86II::LOCK)
+    EmitByte(0xF0, CurByte, OS);
+
+  // Emit segment override opcode prefix as needed.
+  if (MemoryOperand >= 0)
+    EmitSegmentOverridePrefix(CurByte, MemoryOperand+X86::AddrSegmentReg,
+                              MI, OS);
+
+  // Emit the repeat opcode prefix as needed.
+  if ((TSFlags & X86II::Op0Mask) == X86II::REP)
+    EmitByte(0xF3, CurByte, OS);
+
+  // Emit the address size opcode prefix as needed.
+  bool need_address_override;
+  // The AdSize prefix is only for 32-bit and 64-bit modes. Hm, perhaps we
+  // should introduce an AdSize16 bit instead of having seven special cases?
+  if ((!is16BitMode(STI) && TSFlags & X86II::AdSize) ||
+      (is16BitMode(STI) && (MI.getOpcode() == X86::JECXZ_32 ||
+                         MI.getOpcode() == X86::MOV8o8a ||
+                         MI.getOpcode() == X86::MOV16o16a ||
+                         MI.getOpcode() == X86::MOV32o32a ||
+                         MI.getOpcode() == X86::MOV8ao8 ||
+                         MI.getOpcode() == X86::MOV16ao16 ||
+                         MI.getOpcode() == X86::MOV32ao32))) {
+    need_address_override = true;
+  } else if (MemoryOperand < 0) {
+    need_address_override = false;
+  } else if (is64BitMode(STI)) {
+    assert(!Is16BitMemOperand(MI, MemoryOperand, STI));
+    need_address_override = Is32BitMemOperand(MI, MemoryOperand);
+  } else if (is32BitMode(STI)) {
+    assert(!Is64BitMemOperand(MI, MemoryOperand));
+    need_address_override = Is16BitMemOperand(MI, MemoryOperand, STI);
+  } else {
+    assert(is16BitMode(STI));
+    assert(!Is64BitMemOperand(MI, MemoryOperand));
+    need_address_override = !Is16BitMemOperand(MI, MemoryOperand, STI);
+  }
+
+  if (need_address_override)
+    EmitByte(0x67, CurByte, OS);
+
   if (!HasVEXPrefix)
     EmitOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, STI, OS);
   else
index 5ba8064ff48acc90c426e34c68f82a16c161ce07..1704b94a72985f8baeb31bc3b34e8ae461217744 100644 (file)
@@ -1557,7 +1557,7 @@ vdivpd  -4(%rcx,%rbx,8), %xmm10, %xmm11
           vcvtdq2ps  %xmm13, %xmm10
 
 // CHECK: vcvtdq2ps  (%ecx), %xmm13
-// CHECK: encoding: [0xc5,0x78,0x5b,0x29]
+// CHECK: encoding: [0x67,0xc5,0x78,0x5b,0x29]
           vcvtdq2ps  (%ecx), %xmm13
 
 // CHECK: vcvttps2dq  %xmm12, %xmm11
index 180578bfc01cd30622250fab0393a19e34a767e3..a9b8f34caa4252afe7a3d802787544a464ad2b61 100644 (file)
 // CHECK: tzmsk   (%rdi), %rax
 // CHECK: encoding: [0x8f,0xe9,0xf8,0x01,0x27]
           tzmsk   (%rdi), %rax
+
+// CHECK: encoding: [0x67,0xc4,0xe2,0x60,0xf7,0x07]
+          bextr   %ebx, (%edi), %eax
+
+// CHECK: encoding: [0x67,0x8f,0xea,0x78,0x10,0x07,A,A,A,A]
+          bextr   $foo, (%edi), %eax