mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
Lowers block address. Currently asserts when relocation model is not PIC. Patch by Akira Hatanaka
llvm-svn: 127027
This commit is contained in:
parent
49043825b4
commit
99619e5bef
@ -308,6 +308,12 @@ void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
|
|||||||
O << *Mang->getSymbol(MO.getGlobal());
|
O << *Mang->getSymbol(MO.getGlobal());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MachineOperand::MO_BlockAddress: {
|
||||||
|
MCSymbol* BA = GetBlockAddressSymbol(MO.getBlockAddress());
|
||||||
|
O << BA->getName();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MachineOperand::MO_ExternalSymbol:
|
case MachineOperand::MO_ExternalSymbol:
|
||||||
O << *GetExternalSymbolSymbol(MO.getSymbolName());
|
O << *GetExternalSymbolSymbol(MO.getSymbolName());
|
||||||
break;
|
break;
|
||||||
|
@ -121,7 +121,8 @@ SelectAddr(SDValue Addr, SDValue &Offset, SDValue &Base) {
|
|||||||
if (TM.getRelocationModel() == Reloc::PIC_) {
|
if (TM.getRelocationModel() == Reloc::PIC_) {
|
||||||
if ((Addr.getOpcode() == ISD::TargetGlobalAddress) ||
|
if ((Addr.getOpcode() == ISD::TargetGlobalAddress) ||
|
||||||
(Addr.getOpcode() == ISD::TargetConstantPool) ||
|
(Addr.getOpcode() == ISD::TargetConstantPool) ||
|
||||||
(Addr.getOpcode() == ISD::TargetJumpTable)){
|
(Addr.getOpcode() == ISD::TargetJumpTable) ||
|
||||||
|
(Addr.getOpcode() == ISD::TargetBlockAddress)) {
|
||||||
Base = CurDAG->getRegister(Mips::GP, MVT::i32);
|
Base = CurDAG->getRegister(Mips::GP, MVT::i32);
|
||||||
Offset = Addr;
|
Offset = Addr;
|
||||||
return true;
|
return true;
|
||||||
@ -170,6 +171,11 @@ SelectAddr(SDValue Addr, SDValue &Offset, SDValue &Base) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isa<BlockAddressSDNode>(Addr.getOperand(1))) {
|
||||||
|
Base = Addr.getOperand(0);
|
||||||
|
Offset = Addr.getOperand(1);
|
||||||
|
}
|
||||||
|
|
||||||
Base = Addr;
|
Base = Addr;
|
||||||
Offset = CurDAG->getTargetConstant(0, MVT::i32);
|
Offset = CurDAG->getTargetConstant(0, MVT::i32);
|
||||||
return true;
|
return true;
|
||||||
|
@ -89,6 +89,7 @@ MipsTargetLowering(MipsTargetMachine &TM)
|
|||||||
|
|
||||||
// Mips Custom Operations
|
// Mips Custom Operations
|
||||||
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
|
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
|
||||||
|
setOperationAction(ISD::BlockAddress, MVT::i32, Custom);
|
||||||
setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
|
setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
|
||||||
setOperationAction(ISD::JumpTable, MVT::i32, Custom);
|
setOperationAction(ISD::JumpTable, MVT::i32, Custom);
|
||||||
setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
|
setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
|
||||||
@ -375,6 +376,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const
|
|||||||
case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
|
case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
|
||||||
case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG);
|
case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG);
|
||||||
case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
|
case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
|
||||||
|
case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
|
||||||
case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
|
case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
|
||||||
case ISD::JumpTable: return LowerJumpTable(Op, DAG);
|
case ISD::JumpTable: return LowerJumpTable(Op, DAG);
|
||||||
case ISD::OR: return LowerANDOR(Op, DAG);
|
case ISD::OR: return LowerANDOR(Op, DAG);
|
||||||
@ -719,6 +721,28 @@ SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op,
|
|||||||
return SDValue(0,0);
|
return SDValue(0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDValue MipsTargetLowering::LowerBlockAddress(SDValue Op,
|
||||||
|
SelectionDAG &DAG) const {
|
||||||
|
if (getTargetMachine().getRelocationModel() != Reloc::PIC_) {
|
||||||
|
assert(false && "implement LowerBlockAddress for -static");
|
||||||
|
return SDValue(0, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// FIXME there isn't actually debug info here
|
||||||
|
DebugLoc dl = Op.getDebugLoc();
|
||||||
|
const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
|
||||||
|
SDValue BAGOTOffset = DAG.getBlockAddress(BA, MVT::i32, true,
|
||||||
|
MipsII::MO_GOT);
|
||||||
|
SDValue BALOOffset = DAG.getBlockAddress(BA, MVT::i32, true,
|
||||||
|
MipsII::MO_ABS_HILO);
|
||||||
|
SDValue Load = DAG.getLoad(MVT::i32, dl,
|
||||||
|
DAG.getEntryNode(), BAGOTOffset,
|
||||||
|
MachinePointerInfo(), false, false, 0);
|
||||||
|
SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, BALOOffset);
|
||||||
|
return DAG.getNode(ISD::ADD, dl, MVT::i32, Load, Lo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SDValue MipsTargetLowering::
|
SDValue MipsTargetLowering::
|
||||||
LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const
|
LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const
|
||||||
{
|
{
|
||||||
|
@ -107,6 +107,7 @@ namespace llvm {
|
|||||||
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||||
|
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const;
|
||||||
|
@ -548,6 +548,8 @@ def : Pat<(MipsJmpLink (i32 texternalsym:$dst)),
|
|||||||
def : Pat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
|
def : Pat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
|
||||||
def : Pat<(add CPURegs:$hi, (MipsLo tglobaladdr:$lo)),
|
def : Pat<(add CPURegs:$hi, (MipsLo tglobaladdr:$lo)),
|
||||||
(ADDiu CPURegs:$hi, tglobaladdr:$lo)>;
|
(ADDiu CPURegs:$hi, tglobaladdr:$lo)>;
|
||||||
|
def : Pat<(add CPURegs:$hi, (MipsLo tblockaddress:$lo)),
|
||||||
|
(ADDiu CPURegs:$hi, tblockaddress:$lo)>;
|
||||||
|
|
||||||
def : Pat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
|
def : Pat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
|
||||||
def : Pat<(add CPURegs:$hi, (MipsLo tjumptable:$lo)),
|
def : Pat<(add CPURegs:$hi, (MipsLo tjumptable:$lo)),
|
||||||
|
26
test/CodeGen/Mips/blockaddr.ll
Normal file
26
test/CodeGen/Mips/blockaddr.ll
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
; RUN: llc -march=mipsel < %s | FileCheck %s
|
||||||
|
|
||||||
|
@reg = common global i8* null, align 4
|
||||||
|
|
||||||
|
define i8* @dummy(i8* %x) nounwind readnone noinline {
|
||||||
|
entry:
|
||||||
|
ret i8* %x
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK: lw $2, %got($tmp1)($gp)
|
||||||
|
; CHECK: addiu $4, $2, %lo($tmp1)
|
||||||
|
; CHECK: lw $2, %got($tmp2)($gp)
|
||||||
|
; CHECK: addiu $2, $2, %lo($tmp2)
|
||||||
|
define void @f() nounwind {
|
||||||
|
entry:
|
||||||
|
%call = tail call i8* @dummy(i8* blockaddress(@f, %baz))
|
||||||
|
indirectbr i8* %call, [label %baz, label %foo]
|
||||||
|
|
||||||
|
foo: ; preds = %foo, %entry
|
||||||
|
store i8* blockaddress(@f, %foo), i8** @reg, align 4
|
||||||
|
br label %foo
|
||||||
|
|
||||||
|
baz: ; preds = %entry
|
||||||
|
store i8* null, i8** @reg, align 4
|
||||||
|
ret void
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user