mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 00:32:55 +00:00
- Use a different wrapper node for RIP-relative GV, etc.
- Proper support for both small static and PIC modes under X86-64 - Some (non-optimal) support for medium modes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32046 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2bbff6d173
commit
0085a28d13
@ -590,63 +590,19 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
|
||||
break;
|
||||
}
|
||||
|
||||
case ISD::TargetConstantPool:
|
||||
if (AM.BaseType == X86ISelAddressMode::RegBase &&
|
||||
AM.Base.Reg.Val == 0 &&
|
||||
AM.CP == 0) {
|
||||
ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(N);
|
||||
AM.CP = CP->getConstVal();
|
||||
AM.Align = CP->getAlignment();
|
||||
AM.Disp += CP->getOffset();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ISD::TargetGlobalAddress:
|
||||
if (AM.BaseType == X86ISelAddressMode::RegBase &&
|
||||
AM.Base.Reg.Val == 0 &&
|
||||
AM.GV == 0) {
|
||||
GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(N);
|
||||
AM.GV = G->getGlobal();
|
||||
AM.Disp += G->getOffset();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ISD::TargetExternalSymbol:
|
||||
if (isRoot &&
|
||||
AM.BaseType == X86ISelAddressMode::RegBase &&
|
||||
AM.Base.Reg.Val == 0) {
|
||||
ExternalSymbolSDNode *S = cast<ExternalSymbolSDNode>(N.getOperand(0));
|
||||
AM.ES = S->getSymbol();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ISD::TargetJumpTable:
|
||||
if (isRoot &&
|
||||
AM.BaseType == X86ISelAddressMode::RegBase &&
|
||||
AM.Base.Reg.Val == 0) {
|
||||
JumpTableSDNode *J = cast<JumpTableSDNode>(N.getOperand(0));
|
||||
AM.JT = J->getIndex();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case X86ISD::Wrapper:
|
||||
case X86ISD::WrapperRIP: {
|
||||
bool isRIP = N.getOpcode() == X86ISD::WrapperRIP;
|
||||
// Under X86-64 non-small code model, GV (and friends) are 64-bits.
|
||||
if (!isRIP && Subtarget->is64Bit() && TM.getCodeModel() != CodeModel::Small)
|
||||
break;
|
||||
|
||||
// If value is available in a register both base and index components have
|
||||
// been picked, we can't fit the result available in the register in the
|
||||
// addressing mode. Duplicate GlobalAddress or ConstantPool as displacement.
|
||||
|
||||
// Can't fit GV or CP in addressing mode for X86-64 medium or large code
|
||||
// model since the displacement field is 32-bit. Ok for small code model.
|
||||
|
||||
// For X86-64 PIC code, only allow GV / CP + displacement so we can use RIP
|
||||
// relative addressing mode.
|
||||
if (Subtarget->is64Bit() && TM.getCodeModel() != CodeModel::Small)
|
||||
break;
|
||||
if (!Available || (AM.Base.Reg.Val && AM.IndexReg.Val)) {
|
||||
bool isRIP = Subtarget->is64Bit();
|
||||
// For X86-64 PIC code, only allow GV / CP + displacement so we can use
|
||||
// RIP relative addressing mode.
|
||||
if (isRIP &&
|
||||
(AM.Base.Reg.Val || AM.Scale > 1 || AM.IndexReg.Val ||
|
||||
AM.BaseType == X86ISelAddressMode::FrameIndexBase))
|
||||
@ -683,6 +639,7 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ISD::FrameIndex:
|
||||
if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base.Reg.Val == 0) {
|
||||
@ -1040,7 +997,8 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
|
||||
SDOperand N0 = N.getOperand(0);
|
||||
SDOperand N1 = N.getOperand(1);
|
||||
if (N.Val->getValueType(0) == PtrVT &&
|
||||
N0.getOpcode() == X86ISD::Wrapper &&
|
||||
(N0.getOpcode() == X86ISD::Wrapper
|
||||
|| N0.getOpcode() == X86ISD::WrapperRIP) &&
|
||||
N1.getOpcode() == ISD::Constant) {
|
||||
unsigned Offset = (unsigned)cast<ConstantSDNode>(N1)->getValue();
|
||||
SDOperand C(0, 0);
|
||||
|
@ -3832,8 +3832,15 @@ X86TargetLowering::LowerConstantPool(SDOperand Op, SelectionDAG &DAG) {
|
||||
SDOperand Result = DAG.getTargetConstantPool(CP->getConstVal(),
|
||||
getPointerTy(),
|
||||
CP->getAlignment());
|
||||
// Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode.
|
||||
TargetMachine &tm = getTargetMachine();
|
||||
unsigned WrapperOpcode = (Subtarget->is64Bit() &&
|
||||
(tm.getCodeModel() == CodeModel::Small ||
|
||||
tm.getCodeModel() == CodeModel::Medium) &&
|
||||
tm.getRelocationModel() == Reloc::PIC_)
|
||||
? X86ISD::WrapperRIP : X86ISD::Wrapper;
|
||||
Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result);
|
||||
if (Subtarget->isTargetDarwin()) {
|
||||
Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
|
||||
// With PIC, the address is actually $g + Offset.
|
||||
if (!Subtarget->is64Bit() &&
|
||||
getTargetMachine().getRelocationModel() == Reloc::PIC_)
|
||||
@ -3848,8 +3855,15 @@ SDOperand
|
||||
X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
|
||||
GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
|
||||
SDOperand Result = DAG.getTargetGlobalAddress(GV, getPointerTy());
|
||||
// Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode.
|
||||
TargetMachine &tm = getTargetMachine();
|
||||
unsigned WrapperOpcode = (Subtarget->is64Bit() &&
|
||||
(tm.getCodeModel() == CodeModel::Small ||
|
||||
tm.getCodeModel() == CodeModel::Medium) &&
|
||||
tm.getRelocationModel() == Reloc::PIC_)
|
||||
? X86ISD::WrapperRIP : X86ISD::Wrapper;
|
||||
Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result);
|
||||
if (Subtarget->isTargetDarwin()) {
|
||||
Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
|
||||
// With PIC, the address is actually $g + Offset.
|
||||
if (!Subtarget->is64Bit() &&
|
||||
getTargetMachine().getRelocationModel() == Reloc::PIC_)
|
||||
@ -3865,7 +3879,6 @@ X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
|
||||
Subtarget->GVRequiresExtraLoad(GV, false))
|
||||
Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0);
|
||||
} else if (Subtarget->GVRequiresExtraLoad(GV, false)) {
|
||||
Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
|
||||
Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0);
|
||||
}
|
||||
|
||||
@ -3876,8 +3889,15 @@ SDOperand
|
||||
X86TargetLowering::LowerExternalSymbol(SDOperand Op, SelectionDAG &DAG) {
|
||||
const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
|
||||
SDOperand Result = DAG.getTargetExternalSymbol(Sym, getPointerTy());
|
||||
// Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode.
|
||||
TargetMachine &tm = getTargetMachine();
|
||||
unsigned WrapperOpcode = (Subtarget->is64Bit() &&
|
||||
(tm.getCodeModel() == CodeModel::Small ||
|
||||
tm.getCodeModel() == CodeModel::Medium) &&
|
||||
tm.getRelocationModel() == Reloc::PIC_)
|
||||
? X86ISD::WrapperRIP : X86ISD::Wrapper;
|
||||
Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result);
|
||||
if (Subtarget->isTargetDarwin()) {
|
||||
Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
|
||||
// With PIC, the address is actually $g + Offset.
|
||||
if (!Subtarget->is64Bit() &&
|
||||
getTargetMachine().getRelocationModel() == Reloc::PIC_)
|
||||
@ -4244,8 +4264,15 @@ SDOperand X86TargetLowering::LowerBRCOND(SDOperand Op, SelectionDAG &DAG) {
|
||||
SDOperand X86TargetLowering::LowerJumpTable(SDOperand Op, SelectionDAG &DAG) {
|
||||
JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
|
||||
SDOperand Result = DAG.getTargetJumpTable(JT->getIndex(), getPointerTy());
|
||||
// Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode.
|
||||
TargetMachine &tm = getTargetMachine();
|
||||
unsigned WrapperOpcode = (Subtarget->is64Bit() &&
|
||||
(tm.getCodeModel() == CodeModel::Small ||
|
||||
tm.getCodeModel() == CodeModel::Medium) &&
|
||||
tm.getRelocationModel() == Reloc::PIC_)
|
||||
? X86ISD::WrapperRIP : X86ISD::Wrapper;
|
||||
Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result);
|
||||
if (Subtarget->isTargetDarwin()) {
|
||||
Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
|
||||
// With PIC, the address is actually $g + Offset.
|
||||
if (!Subtarget->is64Bit() &&
|
||||
getTargetMachine().getRelocationModel() == Reloc::PIC_)
|
||||
@ -4978,6 +5005,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
case X86ISD::LOAD_UA: return "X86ISD::LOAD_UA";
|
||||
case X86ISD::GlobalBaseReg: return "X86ISD::GlobalBaseReg";
|
||||
case X86ISD::Wrapper: return "X86ISD::Wrapper";
|
||||
case X86ISD::WrapperRIP: return "X86ISD::WrapperRIP";
|
||||
case X86ISD::S2VEC: return "X86ISD::S2VEC";
|
||||
case X86ISD::PEXTRW: return "X86ISD::PEXTRW";
|
||||
case X86ISD::PINSRW: return "X86ISD::PINSRW";
|
||||
@ -5220,12 +5248,13 @@ static SDOperand getShuffleScalarElt(SDNode *N, unsigned i, SelectionDAG &DAG) {
|
||||
/// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the
|
||||
/// node is a GlobalAddress + an offset.
|
||||
static bool isGAPlusOffset(SDNode *N, GlobalValue* &GA, int64_t &Offset) {
|
||||
if (N->getOpcode() == X86ISD::Wrapper) {
|
||||
unsigned Opc = N->getOpcode();
|
||||
if (Opc == X86ISD::Wrapper || Opc == X86ISD::WrapperRIP) {
|
||||
if (dyn_cast<GlobalAddressSDNode>(N->getOperand(0))) {
|
||||
GA = cast<GlobalAddressSDNode>(N->getOperand(0))->getGlobal();
|
||||
return true;
|
||||
}
|
||||
} else if (N->getOpcode() == ISD::ADD) {
|
||||
} else if (Opc == ISD::ADD) {
|
||||
SDOperand N1 = N->getOperand(0);
|
||||
SDOperand N2 = N->getOperand(1);
|
||||
if (isGAPlusOffset(N1.Val, GA, Offset)) {
|
||||
|
@ -150,6 +150,10 @@ namespace llvm {
|
||||
/// TargetExternalSymbol, and TargetGlobalAddress.
|
||||
Wrapper,
|
||||
|
||||
/// WrapperRIP - Special wrapper used under X86-64 PIC mode for RIP
|
||||
/// relative displacements.
|
||||
WrapperRIP,
|
||||
|
||||
/// S2VEC - X86 version of SCALAR_TO_VECTOR. The destination base does not
|
||||
/// have to match the operand type.
|
||||
S2VEC,
|
||||
|
@ -84,7 +84,8 @@ def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr,
|
||||
def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc,
|
||||
[SDNPHasChain, SDNPOutFlag]>;
|
||||
|
||||
def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
|
||||
def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
|
||||
def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// X86 Operand Definitions.
|
||||
@ -169,6 +170,8 @@ def HasSSE3 : Predicate<"Subtarget->hasSSE3()">;
|
||||
def FPStack : Predicate<"!Subtarget->hasSSE2()">;
|
||||
def In32BitMode : Predicate<"!Subtarget->is64Bit()">;
|
||||
def In64BitMode : Predicate<"Subtarget->is64Bit()">;
|
||||
def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;
|
||||
def NotSmallCode :Predicate<"TM.getCodeModel() != CodeModel::Small">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// X86 specific pattern fragments.
|
||||
|
@ -36,7 +36,8 @@ def lea64_32mem : Operand<i32> {
|
||||
// Complex Pattern Definitions...
|
||||
//
|
||||
def lea64addr : ComplexPattern<i64, 4, "SelectLEAAddr",
|
||||
[add, mul, shl, or, frameindex, X86Wrapper], []>;
|
||||
[add, mul, shl, or, frameindex, X86WrapperRIP],
|
||||
[]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instruction templates...
|
||||
@ -1020,6 +1021,30 @@ def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (ops GR64:$dst, i64i32imm:$src),
|
||||
// Non-Instruction Patterns
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// ConstantPool GlobalAddress, ExternalSymbol, and JumpTable
|
||||
def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
|
||||
(MOV64ri32 tconstpool :$dst)>, Requires<[SmallCode]>;
|
||||
def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
|
||||
(MOV64ri32 tjumptable :$dst)>, Requires<[SmallCode]>;
|
||||
def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
|
||||
(MOV64ri32 tglobaladdr :$dst)>, Requires<[SmallCode]>;
|
||||
def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
|
||||
(MOV64ri32 texternalsym:$dst)>, Requires<[SmallCode]>;
|
||||
|
||||
def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
|
||||
(MOV64ri tconstpool :$dst)>, Requires<[NotSmallCode]>;
|
||||
def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
|
||||
(MOV64ri tjumptable :$dst)>, Requires<[NotSmallCode]>;
|
||||
def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
|
||||
(MOV64ri tglobaladdr :$dst)>, Requires<[NotSmallCode]>;
|
||||
def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
|
||||
(MOV64ri texternalsym:$dst)>, Requires<[NotSmallCode]>;
|
||||
|
||||
def : Pat<(store (i64 (X86Wrapper tglobaladdr:$src)), addr:$dst),
|
||||
(MOV64mi32 addr:$dst, tglobaladdr:$src)>, Requires<[SmallCode]>;
|
||||
def : Pat<(store (i64 (X86Wrapper texternalsym:$src)), addr:$dst),
|
||||
(MOV64mi32 addr:$dst, texternalsym:$src)>, Requires<[SmallCode]>;
|
||||
|
||||
// Calls
|
||||
// Direct PC relative function call for small code model. 32-bit displacement
|
||||
// sign extended to 64-bit.
|
||||
|
Loading…
x
Reference in New Issue
Block a user