summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2014-01-31 05:33:45 +0000
committerCraig Topper <craig.topper@gmail.com>2014-01-31 05:33:45 +0000
commit2bb06b00028e7230ed063af6ce7b3e506522c734 (patch)
tree5efe4875fa273a83fd8ea241692f749dfa68294e /lib
parent8498c08404f00eed029018139478ae462a424036 (diff)
downloadllvm-2bb06b00028e7230ed063af6ce7b3e506522c734.tar.gz
llvm-2bb06b00028e7230ed063af6ce7b3e506522c734.tar.bz2
llvm-2bb06b00028e7230ed063af6ce7b3e506522c734.tar.xz
Move address override handling in X86MCCodeEmitter to a place where it works for VEX encoded instructions too. This allows 32-bit addressing to work in 64-bit mode.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200516 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp89
1 files changed, 43 insertions, 46 deletions
diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index 52d6d14a8f..7d81bbe985 100644
--- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -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