mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-20 12:31:40 +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
|
// on PIC code Load GA
|
||||||
if (TM.getRelocationModel() == Reloc::PIC_) {
|
if (TM.getRelocationModel() == Reloc::PIC_) {
|
||||||
if ((Addr.getOpcode() == ISD::TargetGlobalAddress) ||
|
if (Addr.getOpcode() == MipsISD::WrapperPIC) {
|
||||||
(Addr.getOpcode() == ISD::TargetConstantPool) ||
|
|
||||||
(Addr.getOpcode() == ISD::TargetJumpTable) ||
|
|
||||||
(Addr.getOpcode() == ISD::TargetBlockAddress) ||
|
|
||||||
(Addr.getOpcode() == ISD::TargetExternalSymbol)) {
|
|
||||||
Base = CurDAG->getRegister(Mips::GP, MVT::i32);
|
Base = CurDAG->getRegister(Mips::GP, MVT::i32);
|
||||||
Offset = Addr;
|
Offset = Addr.getOperand(0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -55,6 +55,7 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
|||||||
case MipsISD::DivRemU: return "MipsISD::DivRemU";
|
case MipsISD::DivRemU: return "MipsISD::DivRemU";
|
||||||
case MipsISD::BuildPairF64: return "MipsISD::BuildPairF64";
|
case MipsISD::BuildPairF64: return "MipsISD::BuildPairF64";
|
||||||
case MipsISD::ExtractElementF64: return "MipsISD::ExtractElementF64";
|
case MipsISD::ExtractElementF64: return "MipsISD::ExtractElementF64";
|
||||||
|
case MipsISD::WrapperPIC: return "MipsISD::WrapperPIC";
|
||||||
default: return NULL;
|
default: return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -770,6 +771,7 @@ SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op,
|
|||||||
} else {
|
} else {
|
||||||
SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0,
|
SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0,
|
||||||
MipsII::MO_GOT);
|
MipsII::MO_GOT);
|
||||||
|
GA = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, GA);
|
||||||
SDValue ResNode = DAG.getLoad(MVT::i32, dl,
|
SDValue ResNode = DAG.getLoad(MVT::i32, dl,
|
||||||
DAG.getEntryNode(), GA, MachinePointerInfo(),
|
DAG.getEntryNode(), GA, MachinePointerInfo(),
|
||||||
false, false, 0);
|
false, false, 0);
|
||||||
@ -807,6 +809,7 @@ SDValue MipsTargetLowering::LowerBlockAddress(SDValue Op,
|
|||||||
|
|
||||||
SDValue BAGOTOffset = DAG.getBlockAddress(BA, MVT::i32, true,
|
SDValue BAGOTOffset = DAG.getBlockAddress(BA, MVT::i32, true,
|
||||||
MipsII::MO_GOT);
|
MipsII::MO_GOT);
|
||||||
|
BAGOTOffset = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, BAGOTOffset);
|
||||||
SDValue BALOOffset = DAG.getBlockAddress(BA, MVT::i32, true,
|
SDValue BALOOffset = DAG.getBlockAddress(BA, MVT::i32, true,
|
||||||
MipsII::MO_ABS_LO);
|
MipsII::MO_ABS_LO);
|
||||||
SDValue Load = DAG.getLoad(MVT::i32, dl,
|
SDValue Load = DAG.getLoad(MVT::i32, dl,
|
||||||
@ -841,10 +844,12 @@ LowerJumpTable(SDValue Op, SelectionDAG &DAG) const
|
|||||||
if (!IsPIC) {
|
if (!IsPIC) {
|
||||||
SDValue Ops[] = { JTI };
|
SDValue Ops[] = { JTI };
|
||||||
HiPart = DAG.getNode(MipsISD::Hi, dl, DAG.getVTList(MVT::i32), Ops, 1);
|
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,
|
HiPart = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), JTI,
|
||||||
MachinePointerInfo(),
|
MachinePointerInfo(),
|
||||||
false, false, 0);
|
false, false, 0);
|
||||||
|
}
|
||||||
|
|
||||||
SDValue JTILo = DAG.getTargetJumpTable(JT->getIndex(), PtrVT,
|
SDValue JTILo = DAG.getTargetJumpTable(JT->getIndex(), PtrVT,
|
||||||
MipsII::MO_ABS_LO);
|
MipsII::MO_ABS_LO);
|
||||||
@ -884,6 +889,7 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG) const
|
|||||||
} else {
|
} else {
|
||||||
SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(),
|
SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(),
|
||||||
N->getOffset(), MipsII::MO_GOT);
|
N->getOffset(), MipsII::MO_GOT);
|
||||||
|
CP = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, CP);
|
||||||
SDValue Load = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(),
|
SDValue Load = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(),
|
||||||
CP, MachinePointerInfo::getConstantPool(),
|
CP, MachinePointerInfo::getConstantPool(),
|
||||||
false, false, 0);
|
false, false, 0);
|
||||||
@ -1288,6 +1294,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
|
|||||||
if (IsPIC) {
|
if (IsPIC) {
|
||||||
if (LoadSymAddr) {
|
if (LoadSymAddr) {
|
||||||
// Load callee address
|
// Load callee address
|
||||||
|
Callee = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, Callee);
|
||||||
SDValue LoadValue = DAG.getLoad(MVT::i32, dl, Chain, Callee,
|
SDValue LoadValue = DAG.getLoad(MVT::i32, dl, Chain, Callee,
|
||||||
MachinePointerInfo::getGOT(),
|
MachinePointerInfo::getGOT(),
|
||||||
false, false, 0);
|
false, false, 0);
|
||||||
|
@ -67,7 +67,9 @@ namespace llvm {
|
|||||||
DivRemU,
|
DivRemU,
|
||||||
|
|
||||||
BuildPairF64,
|
BuildPairF64,
|
||||||
ExtractElementF64
|
ExtractElementF64,
|
||||||
|
|
||||||
|
WrapperPIC
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +75,9 @@ def MipsDivRem : SDNode<"MipsISD::DivRem", SDT_MipsDivRem,
|
|||||||
def MipsDivRemU : SDNode<"MipsISD::DivRemU", SDT_MipsDivRem,
|
def MipsDivRemU : SDNode<"MipsISD::DivRemU", SDT_MipsDivRem,
|
||||||
[SDNPOutGlue]>;
|
[SDNPOutGlue]>;
|
||||||
|
|
||||||
|
// wrapper node
|
||||||
|
def MipsWrapperPIC : SDNode<"MipsISD::WrapperPIC", SDTIntUnaryOp>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Mips Instruction Predicate Definitions.
|
// Mips Instruction Predicate Definitions.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -589,6 +592,17 @@ def : Pat<(add CPURegs:$gp, (MipsGPRel tglobaladdr:$in)),
|
|||||||
def : Pat<(add CPURegs:$gp, (MipsGPRel tconstpool:$in)),
|
def : Pat<(add CPURegs:$gp, (MipsGPRel tconstpool:$in)),
|
||||||
(ADDiu CPURegs:$gp, 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
|
// Mips does not have "not", so we expand our way
|
||||||
def : Pat<(not CPURegs:$in),
|
def : Pat<(not CPURegs:$in),
|
||||||
(NOR CPURegs:$in, ZERO)>;
|
(NOR CPURegs:$in, ZERO)>;
|
||||||
@ -656,13 +670,6 @@ multiclass MovnPats<RegisterClass RC, Instruction MOVNInst> {
|
|||||||
defm : MovzPats<CPURegs, MOVZ_I>;
|
defm : MovzPats<CPURegs, MOVZ_I>;
|
||||||
defm : MovnPats<CPURegs, MOVN_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
|
// setcc patterns
|
||||||
def : Pat<(seteq CPURegs:$lhs, CPURegs:$rhs),
|
def : Pat<(seteq CPURegs:$lhs, CPURegs:$rhs),
|
||||||
(SLTu (XOR CPURegs:$lhs, CPURegs:$rhs), 1)>;
|
(SLTu (XOR CPURegs:$lhs, CPURegs:$rhs), 1)>;
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
@i1 = global [3 x i32] [i32 1, i32 2, i32 3], align 4
|
@i1 = global [3 x i32] [i32 1, i32 2, i32 3], align 4
|
||||||
@i3 = common global i32* null, align 4
|
@i3 = common global i32* null, align 4
|
||||||
|
|
||||||
; CHECK: lw ${{[0-9]+}}, %got(i3)($gp)
|
|
||||||
; CHECK: addiu ${{[0-9]+}}, $gp, %got(i1)
|
; CHECK: addiu ${{[0-9]+}}, $gp, %got(i1)
|
||||||
|
; CHECK: lw ${{[0-9]+}}, %got(i3)($gp)
|
||||||
define i32* @cmov1(i32 %s) nounwind readonly {
|
define i32* @cmov1(i32 %s) nounwind readonly {
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp ne i32 %s, 0
|
%tobool = icmp ne i32 %s, 0
|
||||||
@ -14,3 +14,19 @@ entry:
|
|||||||
ret i32* %cond
|
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…
x
Reference in New Issue
Block a user