1
0
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:
Bruno Cardoso Lopes 2011-03-04 20:01:52 +00:00
parent 49043825b4
commit 99619e5bef
6 changed files with 66 additions and 1 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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
{ {

View File

@ -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;

View File

@ -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)),

View 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
}