implement support for 32-bit address operands in 64-bit mode, which
authorChris Lattner <sabre@nondot.org>
Wed, 29 Sep 2010 03:33:25 +0000 (03:33 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 29 Sep 2010 03:33:25 +0000 (03:33 +0000)
are defined to emit the 0x67 prefix byte.  rdar://8482675

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115021 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86MCCodeEmitter.cpp
test/MC/AsmParser/X86/x86_instructions.s

index ed39abd119a75d7668324d9bbb52345e42fa71f2..c0154514712c58a9851c417bd3b4733a4c9a01aa 100644 (file)
@@ -179,6 +179,18 @@ static MCFixupKind getImmFixupKind(uint64_t TSFlags) {
   }
 }
 
+/// Is32BitMemOperand - Return true if the specified instruction with a memory
+/// operand should emit the 0x67 prefix byte in 64-bit mode due to a 32-bit
+/// memory operand.  Op specifies the operand # of the memoperand.
+static bool Is32BitMemOperand(const MCInst &MI, unsigned Op) {
+  const MCOperand &BaseReg  = MI.getOperand(Op+X86::AddrBaseReg);
+  const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg);
+  
+  if (BaseReg.getReg() != 0 && X86::GR32RegClass.contains(BaseReg.getReg()) ||
+      IndexReg.getReg() != 0 && X86::GR32RegClass.contains(IndexReg.getReg()))
+    return true;
+  return false;
+}
 
 void X86MCCodeEmitter::
 EmitImmediate(const MCOperand &DispOp, unsigned Size, MCFixupKind FixupKind,
@@ -221,10 +233,10 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
                                         uint64_t TSFlags, unsigned &CurByte,
                                         raw_ostream &OS,
                                         SmallVectorImpl<MCFixup> &Fixups) const{
-  const MCOperand &Disp     = MI.getOperand(Op+3);
-  const MCOperand &Base     = MI.getOperand(Op);
-  const MCOperand &Scale    = MI.getOperand(Op+1);
-  const MCOperand &IndexReg = MI.getOperand(Op+2);
+  const MCOperand &Disp     = MI.getOperand(Op+X86::AddrDisp);
+  const MCOperand &Base     = MI.getOperand(Op+X86::AddrBaseReg);
+  const MCOperand &Scale    = MI.getOperand(Op+X86::AddrScaleAmt);
+  const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg);
   unsigned BaseReg = Base.getReg();
 
   // Handle %rip relative addressing.
@@ -713,7 +725,8 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
     EmitByte(0x66, CurByte, OS);
 
   // Emit the address size opcode prefix as needed.
-  if (TSFlags & X86II::AdSize)
+  if ((TSFlags & X86II::AdSize) ||
+      (MemOperand != -1 && Is64BitMode && Is32BitMemOperand(MI, MemOperand)))
     EmitByte(0x67, CurByte, OS);
 
   bool Need0FPrefix = false;
index 1e164e71ea7d28827fd10db4edcf5d39b62714c7..248cec193827222cbdb97e13a820fd80243782b6 100644 (file)
@@ -320,7 +320,7 @@ enter $0x7ace,$0x7f
 
 // rdar://8456389
 // CHECK: fstps        (%eax)
-// CHECK: encoding: [0xd9,0x18]
+// CHECK: encoding: [0x67,0xd9,0x18]
 fstp   (%eax)
 
 // rdar://8456364
@@ -436,3 +436,16 @@ roundss $0xE, %xmm0, %xmm0 // CHECK: encoding: [0x66,0x0f,0x3a,0x0a,0xc0,0x0e]
 roundps $0xE, %xmm0, %xmm0 // CHECK: encoding: [0x66,0x0f,0x3a,0x08,0xc0,0x0e]
 roundsd $0xE, %xmm0, %xmm0 // CHECK: encoding: [0x66,0x0f,0x3a,0x0b,0xc0,0x0e]
 roundpd $0xE, %xmm0, %xmm0 // CHECK: encoding: [0x66,0x0f,0x3a,0x09,0xc0,0x0e]
+
+
+// rdar://8482675 - 32-bit mem operand support in 64-bit mode (0x67 prefix)
+leal   8(%eax), %esi
+// CHECK: leal 8(%eax), %esi
+// CHECK: encoding: [0x67,0x8d,0x70,0x08]
+leaq   8(%eax), %rsi
+// CHECK: leaq 8(%eax), %rsi
+// CHECK: encoding: [0x67,0x48,0x8d,0x70,0x08]
+leaq   8(%rax), %rsi
+// CHECK: leaq 8(%rax), %rsi
+// CHECK: encoding: [0x48,0x8d,0x70,0x08]
+