summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-09-29 03:33:25 +0000
committerChris Lattner <sabre@nondot.org>2010-09-29 03:33:25 +0000
commita4e1c749472b02bf94620f0c5aca7a0e3cc2bf78 (patch)
treeaf6d8470d557f88622111d93e1faff96506fa929
parent86a622246933859a5c76225ea5e8243a19101548 (diff)
downloadbcm5719-llvm-a4e1c749472b02bf94620f0c5aca7a0e3cc2bf78.tar.gz
bcm5719-llvm-a4e1c749472b02bf94620f0c5aca7a0e3cc2bf78.zip
implement support for 32-bit address operands in 64-bit mode, which
are defined to emit the 0x67 prefix byte. rdar://8482675 llvm-svn: 115021
-rw-r--r--llvm/lib/Target/X86/X86MCCodeEmitter.cpp23
-rw-r--r--llvm/test/MC/AsmParser/X86/x86_instructions.s15
2 files changed, 32 insertions, 6 deletions
diff --git a/llvm/lib/Target/X86/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/X86MCCodeEmitter.cpp
index ed39abd119a..c0154514712 100644
--- a/llvm/lib/Target/X86/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/X86MCCodeEmitter.cpp
@@ -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;
diff --git a/llvm/test/MC/AsmParser/X86/x86_instructions.s b/llvm/test/MC/AsmParser/X86/x86_instructions.s
index 1e164e71ea7..248cec19382 100644
--- a/llvm/test/MC/AsmParser/X86/x86_instructions.s
+++ b/llvm/test/MC/AsmParser/X86/x86_instructions.s
@@ -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]
+
OpenPOWER on IntegriCloud