From 6a7cd42213f0834afaa71849eccf6d252ddc0b7d Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 2 Mar 2016 07:32:43 +0000 Subject: [PATCH] [X86] Make X86MCCodeEmitter::DetermineREXPrefix locate operands more like how VEX prefix handling does. llvm-svn: 262467 --- .../Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp | 104 ++++++++++----------- llvm/test/MC/X86/x86-64.s | 4 + 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index f9d8e0c..30306e9 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -981,9 +981,9 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, /// DetermineREXPrefix - Determine if the MCInst has to be encoded with a X86-64 /// REX prefix which specifies 1) 64-bit instructions, 2) non-default operand /// size, and 3) use of X86-64 extended registers. -static unsigned DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags, - const MCInstrDesc &Desc) { - unsigned REX = 0; +static uint8_t DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags, + int MemOperand, const MCInstrDesc &Desc) { + uint8_t REX = 0; bool UsesHighByteReg = false; if (TSFlags & X86II::REX_W) @@ -992,13 +992,10 @@ static unsigned DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags, if (MI.getNumOperands() == 0) return REX; unsigned NumOps = MI.getNumOperands(); - // FIXME: MCInst should explicitize the two-addrness. - bool isTwoAddr = NumOps > 1 && - Desc.getOperandConstraint(1, MCOI::TIED_TO) != -1; + unsigned CurOp = X86II::getOperandBias(Desc); // If it accesses SPL, BPL, SIL, or DIL, then it requires a 0x40 REX prefix. - unsigned i = isTwoAddr ? 1 : 0; - for (; i != NumOps; ++i) { + for (unsigned i = CurOp; i != NumOps; ++i) { const MCOperand &MO = MI.getOperand(i); if (!MO.isReg()) continue; unsigned Reg = MO.getReg(); @@ -1012,65 +1009,64 @@ static unsigned DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags, } switch (TSFlags & X86II::FormMask) { + case X86II::AddRegFrm: + if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp++).getReg())) + REX |= 1 << 0; // set REX.B + break; case X86II::MRMSrcReg: - if (MI.getOperand(0).isReg() && - X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg())) + if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp++).getReg())) REX |= 1 << 2; // set REX.R - i = isTwoAddr ? 2 : 1; - for (; i != NumOps; ++i) { - const MCOperand &MO = MI.getOperand(i); - if (MO.isReg() && X86II::isX86_64ExtendedReg(MO.getReg())) - REX |= 1 << 0; // set REX.B - } + if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp++).getReg())) + REX |= 1 << 0; // set REX.B break; case X86II::MRMSrcMem: { - if (MI.getOperand(0).isReg() && - X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg())) + if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp++).getReg())) REX |= 1 << 2; // set REX.R - unsigned Bit = 0; - i = isTwoAddr ? 2 : 1; - for (; i != NumOps; ++i) { - const MCOperand &MO = MI.getOperand(i); - if (MO.isReg()) { - if (X86II::isX86_64ExtendedReg(MO.getReg())) - REX |= 1 << Bit; // set REX.B (Bit=0) and REX.X (Bit=1) - Bit++; - } - } + if (X86II::isX86_64ExtendedReg( + MI.getOperand(MemOperand+X86::AddrBaseReg).getReg())) + REX |= 1 << 0; // set REX.B + if (X86II::isX86_64ExtendedReg( + MI.getOperand(MemOperand+X86::AddrIndexReg).getReg())) + REX |= 1 << 1; // set REX.X + CurOp += X86::AddrNumOperands; break; } + case X86II::MRMDestReg: + if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp++).getReg())) + REX |= 1 << 0; // set REX.B + if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp++).getReg())) + REX |= 1 << 2; // set REX.R + break; + case X86II::MRMDestMem: + if (X86II::isX86_64ExtendedReg( + MI.getOperand(MemOperand+X86::AddrBaseReg).getReg())) + REX |= 1 << 0; // set REX.B + if (X86II::isX86_64ExtendedReg( + MI.getOperand(MemOperand+X86::AddrIndexReg).getReg())) + REX |= 1 << 1; // set REX.X + CurOp += X86::AddrNumOperands; + if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp++).getReg())) + REX |= 1 << 2; // set REX.R + break; case X86II::MRMXm: case X86II::MRM0m: case X86II::MRM1m: case X86II::MRM2m: case X86II::MRM3m: case X86II::MRM4m: case X86II::MRM5m: case X86II::MRM6m: case X86II::MRM7m: - case X86II::MRMDestMem: { - unsigned e = (isTwoAddr ? X86::AddrNumOperands+1 : X86::AddrNumOperands); - i = isTwoAddr ? 1 : 0; - if (NumOps > e && MI.getOperand(e).isReg() && - X86II::isX86_64ExtendedReg(MI.getOperand(e).getReg())) - REX |= 1 << 2; // set REX.R - unsigned Bit = 0; - for (; i != e; ++i) { - const MCOperand &MO = MI.getOperand(i); - if (MO.isReg()) { - if (X86II::isX86_64ExtendedReg(MO.getReg())) - REX |= 1 << Bit; // REX.B (Bit=0) and REX.X (Bit=1) - Bit++; - } - } + if (X86II::isX86_64ExtendedReg( + MI.getOperand(MemOperand+X86::AddrBaseReg).getReg())) + REX |= 1 << 0; // set REX.B + if (X86II::isX86_64ExtendedReg( + MI.getOperand(MemOperand+X86::AddrIndexReg).getReg())) + REX |= 1 << 1; // set REX.X break; - } - default: - if (MI.getOperand(0).isReg() && - X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg())) + case X86II::MRMXr: + case X86II::MRM0r: case X86II::MRM1r: + case X86II::MRM2r: case X86II::MRM3r: + case X86II::MRM4r: case X86II::MRM5r: + case X86II::MRM6r: case X86II::MRM7r: + if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp++).getReg())) REX |= 1 << 0; // set REX.B - i = isTwoAddr ? 2 : 1; - for (unsigned e = NumOps; i != e; ++i) { - const MCOperand &MO = MI.getOperand(i); - if (MO.isReg() && X86II::isX86_64ExtendedReg(MO.getReg())) - REX |= 1 << 2; // set REX.R - } break; } if (REX && UsesHighByteReg) @@ -1131,7 +1127,7 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, // Handle REX prefix. // FIXME: Can this come before F2 etc to simplify emission? if (is64BitMode(STI)) { - if (unsigned REX = DetermineREXPrefix(MI, TSFlags, Desc)) + if (uint8_t REX = DetermineREXPrefix(MI, TSFlags, MemOperand, Desc)) EmitByte(0x40 | REX, CurByte, OS); } diff --git a/llvm/test/MC/X86/x86-64.s b/llvm/test/MC/X86/x86-64.s index 7bcbe0b..8a5410b 100644 --- a/llvm/test/MC/X86/x86-64.s +++ b/llvm/test/MC/X86/x86-64.s @@ -1474,3 +1474,7 @@ vmovq %xmm0, %rax // CHECK: mwaitx // CHECK: encoding: [0x0f,0x01,0xfb] mwaitx %rax, %rcx, %rbx + +// CHECK: movl %r15d, (%r15,%r15) +// CHECK: encoding: [0x47,0x89,0x3c,0x3f] +movl %r15d, (%r15,%r15) -- 2.7.4