Lowers block address. Currently asserts when relocation model is not PIC. Patch by...
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Fri, 4 Mar 2011 20:01:52 +0000 (20:01 +0000)
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Fri, 4 Mar 2011 20:01:52 +0000 (20:01 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127027 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MipsAsmPrinter.cpp
lib/Target/Mips/MipsISelDAGToDAG.cpp
lib/Target/Mips/MipsISelLowering.cpp
lib/Target/Mips/MipsISelLowering.h
lib/Target/Mips/MipsInstrInfo.td
test/CodeGen/Mips/blockaddr.ll [new file with mode: 0644]

index 1a5605d2e52da04e626b676f9d27a905d56e0d9e..24f2e89aa5962fb3f2e909dc2a09b552588e94e2 100644 (file)
@@ -308,6 +308,12 @@ void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
       O << *Mang->getSymbol(MO.getGlobal());
       break;
 
+    case MachineOperand::MO_BlockAddress: {
+      MCSymbol* BA = GetBlockAddressSymbol(MO.getBlockAddress());
+      O << BA->getName();
+      break;
+    }
+
     case MachineOperand::MO_ExternalSymbol:
       O << *GetExternalSymbolSymbol(MO.getSymbolName());
       break;
index dc135c2d9abe529b1cef156992a92bd940d03e44..c0b09229d126e9e228841de5ea3a6f026bfb0c0a 100644 (file)
@@ -121,7 +121,8 @@ SelectAddr(SDValue Addr, SDValue &Offset, SDValue &Base) {
   if (TM.getRelocationModel() == Reloc::PIC_) {
     if ((Addr.getOpcode() == ISD::TargetGlobalAddress) ||
         (Addr.getOpcode() == ISD::TargetConstantPool) ||
-        (Addr.getOpcode() == ISD::TargetJumpTable)){
+        (Addr.getOpcode() == ISD::TargetJumpTable) ||
+        (Addr.getOpcode() == ISD::TargetBlockAddress)) {
       Base   = CurDAG->getRegister(Mips::GP, MVT::i32);
       Offset = Addr;
       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;
   Offset = CurDAG->getTargetConstant(0, MVT::i32);
   return true;
index a563d3cbd2c985302b96404d978794f9eb815885..d9775973a0629c57275501c9aa36674c7ac1341f 100644 (file)
@@ -89,6 +89,7 @@ MipsTargetLowering(MipsTargetMachine &TM)
 
   // Mips Custom Operations
   setOperationAction(ISD::GlobalAddress,      MVT::i32,   Custom);
+  setOperationAction(ISD::BlockAddress,       MVT::i32,   Custom);
   setOperationAction(ISD::GlobalTLSAddress,   MVT::i32,   Custom);
   setOperationAction(ISD::JumpTable,          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::FP_TO_SINT:         return LowerFP_TO_SINT(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::JumpTable:          return LowerJumpTable(Op, DAG);
     case ISD::OR:                 return LowerANDOR(Op, DAG);
@@ -719,6 +721,28 @@ SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op,
   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::
 LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const
 {
index aafea6b056158724e7130555a6c6c688766bcd10..720b6f4d7d04d11e667a526ecc173bdec0c3b4c1 100644 (file)
@@ -107,6 +107,7 @@ namespace llvm {
     SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerFP_TO_SINT(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 LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const;
index 65ef6558b2d80286c6ca6e8ae24b1685f4bfd265..d9905148a3590b2542cf993f0c1abe6e0fda8bce 100644 (file)
@@ -548,6 +548,8 @@ def : Pat<(MipsJmpLink (i32 texternalsym:$dst)),
 def : Pat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
 def : Pat<(add CPURegs:$hi, (MipsLo 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<(add CPURegs:$hi, (MipsLo tjumptable:$lo)),
diff --git a/test/CodeGen/Mips/blockaddr.ll b/test/CodeGen/Mips/blockaddr.ll
new file mode 100644 (file)
index 0000000..2b06314
--- /dev/null
@@ -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
+}