mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-03 13:31:05 +00:00
Define a wrapper node for target constant nodes (tglobaladdr, etc.).
Need this to prevent emitting illegal conditional move instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132240 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d6a8136e66
commit
342837d0dc
@ -119,13 +119,9 @@ SelectAddr(SDValue Addr, SDValue &Offset, SDValue &Base) {
|
||||
|
||||
// on PIC code Load GA
|
||||
if (TM.getRelocationModel() == Reloc::PIC_) {
|
||||
if ((Addr.getOpcode() == ISD::TargetGlobalAddress) ||
|
||||
(Addr.getOpcode() == ISD::TargetConstantPool) ||
|
||||
(Addr.getOpcode() == ISD::TargetJumpTable) ||
|
||||
(Addr.getOpcode() == ISD::TargetBlockAddress) ||
|
||||
(Addr.getOpcode() == ISD::TargetExternalSymbol)) {
|
||||
if (Addr.getOpcode() == MipsISD::WrapperPIC) {
|
||||
Base = CurDAG->getRegister(Mips::GP, MVT::i32);
|
||||
Offset = Addr;
|
||||
Offset = Addr.getOperand(0);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
|
@ -55,6 +55,7 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
case MipsISD::DivRemU: return "MipsISD::DivRemU";
|
||||
case MipsISD::BuildPairF64: return "MipsISD::BuildPairF64";
|
||||
case MipsISD::ExtractElementF64: return "MipsISD::ExtractElementF64";
|
||||
case MipsISD::WrapperPIC: return "MipsISD::WrapperPIC";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
@ -770,6 +771,7 @@ SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op,
|
||||
} else {
|
||||
SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0,
|
||||
MipsII::MO_GOT);
|
||||
GA = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, GA);
|
||||
SDValue ResNode = DAG.getLoad(MVT::i32, dl,
|
||||
DAG.getEntryNode(), GA, MachinePointerInfo(),
|
||||
false, false, 0);
|
||||
@ -807,6 +809,7 @@ SDValue MipsTargetLowering::LowerBlockAddress(SDValue Op,
|
||||
|
||||
SDValue BAGOTOffset = DAG.getBlockAddress(BA, MVT::i32, true,
|
||||
MipsII::MO_GOT);
|
||||
BAGOTOffset = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, BAGOTOffset);
|
||||
SDValue BALOOffset = DAG.getBlockAddress(BA, MVT::i32, true,
|
||||
MipsII::MO_ABS_LO);
|
||||
SDValue Load = DAG.getLoad(MVT::i32, dl,
|
||||
@ -841,10 +844,12 @@ LowerJumpTable(SDValue Op, SelectionDAG &DAG) const
|
||||
if (!IsPIC) {
|
||||
SDValue Ops[] = { JTI };
|
||||
HiPart = DAG.getNode(MipsISD::Hi, dl, DAG.getVTList(MVT::i32), Ops, 1);
|
||||
} else // Emit Load from Global Pointer
|
||||
} else {// Emit Load from Global Pointer
|
||||
JTI = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, JTI);
|
||||
HiPart = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), JTI,
|
||||
MachinePointerInfo(),
|
||||
false, false, 0);
|
||||
}
|
||||
|
||||
SDValue JTILo = DAG.getTargetJumpTable(JT->getIndex(), PtrVT,
|
||||
MipsII::MO_ABS_LO);
|
||||
@ -884,6 +889,7 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG) const
|
||||
} else {
|
||||
SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(),
|
||||
N->getOffset(), MipsII::MO_GOT);
|
||||
CP = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, CP);
|
||||
SDValue Load = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(),
|
||||
CP, MachinePointerInfo::getConstantPool(),
|
||||
false, false, 0);
|
||||
@ -1288,6 +1294,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
|
||||
if (IsPIC) {
|
||||
if (LoadSymAddr) {
|
||||
// Load callee address
|
||||
Callee = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, Callee);
|
||||
SDValue LoadValue = DAG.getLoad(MVT::i32, dl, Chain, Callee,
|
||||
MachinePointerInfo::getGOT(),
|
||||
false, false, 0);
|
||||
|
@ -67,7 +67,9 @@ namespace llvm {
|
||||
DivRemU,
|
||||
|
||||
BuildPairF64,
|
||||
ExtractElementF64
|
||||
ExtractElementF64,
|
||||
|
||||
WrapperPIC
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -75,6 +75,9 @@ def MipsDivRem : SDNode<"MipsISD::DivRem", SDT_MipsDivRem,
|
||||
def MipsDivRemU : SDNode<"MipsISD::DivRemU", SDT_MipsDivRem,
|
||||
[SDNPOutGlue]>;
|
||||
|
||||
// wrapper node
|
||||
def MipsWrapperPIC : SDNode<"MipsISD::WrapperPIC", SDTIntUnaryOp>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Mips Instruction Predicate Definitions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -589,6 +592,17 @@ def : Pat<(add CPURegs:$gp, (MipsGPRel tglobaladdr:$in)),
|
||||
def : Pat<(add CPURegs:$gp, (MipsGPRel tconstpool:$in)),
|
||||
(ADDiu CPURegs:$gp, tconstpool:$in)>;
|
||||
|
||||
// wrapper_pic
|
||||
class WrapperPICPat<SDNode node>:
|
||||
Pat<(MipsWrapperPIC node:$in),
|
||||
(ADDiu GP, node:$in)>;
|
||||
|
||||
def : WrapperPICPat<tglobaladdr>;
|
||||
def : WrapperPICPat<tconstpool>;
|
||||
def : WrapperPICPat<texternalsym>;
|
||||
def : WrapperPICPat<tblockaddress>;
|
||||
def : WrapperPICPat<tjumptable>;
|
||||
|
||||
// Mips does not have "not", so we expand our way
|
||||
def : Pat<(not CPURegs:$in),
|
||||
(NOR CPURegs:$in, ZERO)>;
|
||||
@ -656,13 +670,6 @@ multiclass MovnPats<RegisterClass RC, Instruction MOVNInst> {
|
||||
defm : MovzPats<CPURegs, MOVZ_I>;
|
||||
defm : MovnPats<CPURegs, MOVN_I>;
|
||||
|
||||
// select patterns with got access
|
||||
let AddedComplexity = 10 in
|
||||
def : Pat<(select (setne CPURegs:$lhs, CPURegs:$rhs),
|
||||
(i32 tglobaladdr:$T), CPURegs:$F),
|
||||
(MOVN_I CPURegs:$F, (ADDiu GP, tglobaladdr:$T),
|
||||
(XOR CPURegs:$lhs, CPURegs:$rhs))>;
|
||||
|
||||
// setcc patterns
|
||||
def : Pat<(seteq CPURegs:$lhs, CPURegs:$rhs),
|
||||
(SLTu (XOR CPURegs:$lhs, CPURegs:$rhs), 1)>;
|
||||
|
@ -4,8 +4,8 @@
|
||||
@i1 = global [3 x i32] [i32 1, i32 2, i32 3], align 4
|
||||
@i3 = common global i32* null, align 4
|
||||
|
||||
; CHECK: lw ${{[0-9]+}}, %got(i3)($gp)
|
||||
; CHECK: addiu ${{[0-9]+}}, $gp, %got(i1)
|
||||
; CHECK: lw ${{[0-9]+}}, %got(i3)($gp)
|
||||
define i32* @cmov1(i32 %s) nounwind readonly {
|
||||
entry:
|
||||
%tobool = icmp ne i32 %s, 0
|
||||
@ -14,3 +14,19 @@ entry:
|
||||
ret i32* %cond
|
||||
}
|
||||
|
||||
@c = global i32 1, align 4
|
||||
@d = global i32 0, align 4
|
||||
|
||||
; CHECK: cmov2:
|
||||
; CHECK: addiu $[[R0:[0-9]+]], $gp, %got(c)
|
||||
; CHECK: addiu $[[R1:[0-9]+]], $gp, %got(d)
|
||||
; CHECK: movn $[[R1]], $[[R0]], ${{[0-9]+}}
|
||||
define i32 @cmov2(i32 %s) nounwind readonly {
|
||||
entry:
|
||||
%tobool = icmp ne i32 %s, 0
|
||||
%tmp1 = load i32* @c, align 4
|
||||
%tmp2 = load i32* @d, align 4
|
||||
%cond = select i1 %tobool, i32 %tmp1, i32 %tmp2
|
||||
ret i32 %cond
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user