Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ std::string X86_MC::ParseX86Triple(const Triple &TT) {
else
FS = "-64bit-mode,-32bit-mode,+16bit-mode";

if (TT.isX32())
FS += ",+x32";

return FS;
}

Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/X86/X86.td
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ def Is32Bit : SubtargetFeature<"32bit-mode", "Is32Bit", "true",
"32-bit mode (80386)">;
def Is16Bit : SubtargetFeature<"16bit-mode", "Is16Bit", "true",
"16-bit mode (i8086)">;
def IsX32 : SubtargetFeature<"x32", "IsX32", "true",
"64-bit with ILP32 programming model (e.g. x32 ABI)">;

//===----------------------------------------------------------------------===//
// X86 Subtarget ISA features
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/Target/X86/X86InstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ include "X86InstrFragments.td"
include "X86InstrFragmentsSIMD.td"

//===----------------------------------------------------------------------===//
// X86 Operand Definitions.
// X86 Predicate Definitions.
//
include "X86InstrOperands.td"
include "X86InstrPredicates.td"

//===----------------------------------------------------------------------===//
// X86 Predicate Definitions.
// X86 Operand Definitions.
//
include "X86InstrPredicates.td"
include "X86InstrOperands.td"

//===----------------------------------------------------------------------===//
// X86 Instruction Format Definitions.
Expand Down
30 changes: 22 additions & 8 deletions llvm/lib/Target/X86/X86InstrOperands.td
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@
//
//===----------------------------------------------------------------------===//

def x86_ptr_rc : RegClassByHwMode<
[X86_32, X86_64, X86_64_X32],
[GR32, GR64, LOW32_ADDR_ACCESS]>;

// A version of ptr_rc which excludes SP, ESP, and RSP. This is used for
// the index operand of an address, to conform to x86 encoding restrictions.
def ptr_rc_nosp : PointerLikeRegClass<1>;
def ptr_rc_nosp : RegClassByHwMode<
[X86_32, X86_64, X86_64_X32],
[GR32_NOSP, GR64_NOSP, GR32_NOSP]>;

// *mem - Operand definitions for the funky X86 addressing mode operands.
//
Expand Down Expand Up @@ -53,7 +59,7 @@ class X86MemOperand<string printMethod,
AsmOperandClass parserMatchClass = X86MemAsmOperand,
int size = 0> : Operand<iPTR> {
let PrintMethod = printMethod;
let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, SEGMENT_REG);
let MIOperandInfo = (ops x86_ptr_rc, i8imm, ptr_rc_nosp, i32imm, SEGMENT_REG);
let ParserMatchClass = parserMatchClass;
let OperandType = "OPERAND_MEMORY";
int Size = size;
Expand All @@ -63,7 +69,7 @@ class X86MemOperand<string printMethod,
class X86VMemOperand<RegisterClass RC, string printMethod,
AsmOperandClass parserMatchClass, int size = 0>
: X86MemOperand<printMethod, parserMatchClass, size> {
let MIOperandInfo = (ops ptr_rc, i8imm, RC, i32imm, SEGMENT_REG);
let MIOperandInfo = (ops x86_ptr_rc, i8imm, RC, i32imm, SEGMENT_REG);
}

def anymem : X86MemOperand<"printMemReference">;
Expand Down Expand Up @@ -113,8 +119,14 @@ def sdmem : X86MemOperand<"printqwordmem", X86Mem64AsmOperand>;

// A version of i8mem for use on x86-64 and x32 that uses a NOREX GPR instead
// of a plain GPR, so that it doesn't potentially require a REX prefix.
def ptr_rc_norex : PointerLikeRegClass<2>;
def ptr_rc_norex_nosp : PointerLikeRegClass<3>;
def ptr_rc_norex : RegClassByHwMode<
[X86_32, X86_64, X86_64_X32],
[GR32_NOREX, GR64_NOREX, GR32_NOREX]>;

def ptr_rc_norex_nosp : RegClassByHwMode<
[X86_32, X86_64, X86_64_X32],
[GR32_NOREX_NOSP, GR64_NOREX_NOSP, GR32_NOREX_NOSP]>;


def i8mem_NOREX : X86MemOperand<"printbytemem", X86Mem8AsmOperand, 8> {
let MIOperandInfo = (ops ptr_rc_norex, i8imm, ptr_rc_norex_nosp, i32imm,
Expand All @@ -123,7 +135,9 @@ def i8mem_NOREX : X86MemOperand<"printbytemem", X86Mem8AsmOperand, 8> {

// GPRs available for tailcall.
// It represents GR32_TC, GR64_TC or GR64_TCW64.
def ptr_rc_tailcall : PointerLikeRegClass<4>;
def ptr_rc_tailcall : RegClassByHwMode<
[X86_32, X86_64, X86_64_X32],
[GR32_TC, GR64_TC, GR64_TC]>;

// Special i32mem for addresses of load folding tail calls. These are not
// allowed to use callee-saved registers since they must be scheduled
Expand Down Expand Up @@ -270,12 +284,12 @@ let RenderMethod = "addMemOffsOperands" in {

class X86SrcIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
: X86MemOperand<printMethod, parserMatchClass> {
let MIOperandInfo = (ops ptr_rc, SEGMENT_REG);
let MIOperandInfo = (ops x86_ptr_rc, SEGMENT_REG);
}

class X86DstIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
: X86MemOperand<printMethod, parserMatchClass> {
let MIOperandInfo = (ops ptr_rc);
let MIOperandInfo = (ops x86_ptr_rc);
}

def srcidx8 : X86SrcIdxOperand<"printSrcIdx8", X86SrcIdx8Operand>;
Expand Down
14 changes: 14 additions & 0 deletions llvm/lib/Target/X86/X86InstrPredicates.td
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,12 @@ def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
AssemblerPredicate<(all_of (not Is64Bit)), "Not 64-bit mode">;
def In64BitMode : Predicate<"Subtarget->is64Bit()">,
AssemblerPredicate<(all_of Is64Bit), "64-bit mode">;

def IsX32Mode : Predicate<"Subtarget->getTargetTriple().isX32()">,
AssemblerPredicate<(all_of IsX32), "x32 ABI">;
def NotX32Mode : Predicate<"!Subtarget->getTargetTriple().isX32()">,
AssemblerPredicate<(all_of (not IsX32)), "not x32 ABI">;

def IsLP64 : Predicate<"Subtarget->isTarget64BitLP64()">;
def NotLP64 : Predicate<"!Subtarget->isTarget64BitLP64()">;
def In16BitMode : Predicate<"Subtarget->is16Bit()">,
Expand Down Expand Up @@ -250,3 +256,11 @@ def HasMFence : Predicate<"Subtarget->hasMFence()">;
def HasFastDPWSSD: Predicate<"Subtarget->hasFastDPWSSD()">;
def UseIndirectThunkCalls : Predicate<"Subtarget->useIndirectThunkCalls()">;
def NotUseIndirectThunkCalls : Predicate<"!Subtarget->useIndirectThunkCalls()">;

//===----------------------------------------------------------------------===//
// HwModes
//===----------------------------------------------------------------------===//

defvar X86_32 = DefaultMode;
def X86_64 : HwMode<[In64BitMode, NotX32Mode]>;
def X86_64_X32 : HwMode<[IsX32Mode]>;
35 changes: 8 additions & 27 deletions llvm/lib/Target/X86/X86RegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,33 +194,14 @@ X86RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,

const TargetRegisterClass *
X86RegisterInfo::getPointerRegClass(unsigned Kind) const {
switch (Kind) {
default: llvm_unreachable("Unexpected Kind in getPointerRegClass!");
case 0: // Normal GPRs.
if (IsTarget64BitLP64)
return &X86::GR64RegClass;
// If the target is 64bit but we have been told to use 32bit addresses,
// we can still use 64-bit register as long as we know the high bits
// are zeros.
// Reflect that in the returned register class.
return Is64Bit ? &X86::LOW32_ADDR_ACCESSRegClass : &X86::GR32RegClass;
case 1: // Normal GPRs except the stack pointer (for encoding reasons).
if (IsTarget64BitLP64)
return &X86::GR64_NOSPRegClass;
// NOSP does not contain RIP, so no special case here.
return &X86::GR32_NOSPRegClass;
case 2: // NOREX GPRs.
if (IsTarget64BitLP64)
return &X86::GR64_NOREXRegClass;
return &X86::GR32_NOREXRegClass;
case 3: // NOREX GPRs except the stack pointer (for encoding reasons).
if (IsTarget64BitLP64)
return &X86::GR64_NOREX_NOSPRegClass;
// NOSP does not contain RIP, so no special case here.
return &X86::GR32_NOREX_NOSPRegClass;
case 4: // Available for tailcall (not callee-saved GPRs).
return Is64Bit ? &X86::GR64_TCRegClass : &X86::GR32_TCRegClass;
}
assert(Kind == 0 && "this should only be used for default cases");
if (IsTarget64BitLP64)
return &X86::GR64RegClass;
// If the target is 64bit but we have been told to use 32bit addresses,
// we can still use 64-bit register as long as we know the high bits
// are zeros.
// Reflect that in the returned register class.
return Is64Bit ? &X86::LOW32_ADDR_ACCESSRegClass : &X86::GR32RegClass;
}

const TargetRegisterClass *
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/X86/X86Subtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,10 @@ class X86Subtarget final : public X86GenSubtargetInfo {
#include "X86GenSubtargetInfo.inc"

/// Is this x86_64 with the ILP32 programming model (x32 ABI)?
bool isTarget64BitILP32() const { return Is64Bit && (TargetTriple.isX32()); }
bool isTarget64BitILP32() const { return Is64Bit && IsX32; }

/// Is this x86_64 with the LP64 programming model (standard AMD64, no x32)?
bool isTarget64BitLP64() const { return Is64Bit && (!TargetTriple.isX32()); }
bool isTarget64BitLP64() const { return Is64Bit && !IsX32; }

PICStyles::Style getPICStyle() const { return PICStyle; }
void setPICStyle(PICStyles::Style Style) { PICStyle = Style; }
Expand Down
4 changes: 2 additions & 2 deletions llvm/utils/TableGen/X86FoldTablesEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,10 +553,10 @@ void X86FoldTablesEmitter::updateTables(const CodeGenInstruction *RegInst,
for (unsigned I = RegOutSize, E = RegInst->Operands.size(); I < E; I++) {
const Record *RegOpRec = RegInst->Operands[I].Rec;
const Record *MemOpRec = MemInst->Operands[I].Rec;
// PointerLikeRegClass: For instructions like TAILJMPr, TAILJMPr64,
// RegClassByHwMode: For instructions like TAILJMPr, TAILJMPr64,
// TAILJMPr64_REX
if ((isRegisterOperand(RegOpRec) ||
RegOpRec->isSubClassOf("PointerLikeRegClass")) &&
(RegOpRec->isSubClassOf("RegClassByHwMode"))) &&
isMemoryOperand(MemOpRec)) {
switch (I) {
case 0:
Expand Down