From 8a5072903e2037da1cfdaffa5a26be00f3d76a22 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 29 Sep 2010 03:33:25 +0000 Subject: [PATCH] implement support for 32-bit address operands in 64-bit mode, which 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 | 23 ++++++++++++++++++----- test/MC/AsmParser/X86/x86_instructions.s | 15 ++++++++++++++- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/lib/Target/X86/X86MCCodeEmitter.cpp b/lib/Target/X86/X86MCCodeEmitter.cpp index ed39abd119a..c0154514712 100644 --- a/lib/Target/X86/X86MCCodeEmitter.cpp +++ b/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 &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/test/MC/AsmParser/X86/x86_instructions.s b/test/MC/AsmParser/X86/x86_instructions.s index 1e164e71ea7..248cec19382 100644 --- a/test/MC/AsmParser/X86/x86_instructions.s +++ b/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] + -- 2.34.1