summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2006-10-30 08:00:44 +0000
committerEvan Cheng <evan.cheng@apple.com>2006-10-30 08:00:44 +0000
commit84a28d4e76553e124af965888b01d4874e8d821e (patch)
tree33f5287bd3d28c3d5746ade64ee304276fbc6d62 /llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
parentc3e695137dc98bb8238d9c06b9305cccfd735dff (diff)
downloadbcm5719-llvm-84a28d4e76553e124af965888b01d4874e8d821e.tar.gz
bcm5719-llvm-84a28d4e76553e124af965888b01d4874e8d821e.zip
Lower jumptable to BR_JT. The legalizer can lower it to a BRIND or let the target custom lower it.
llvm-svn: 31293
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp48
1 files changed, 48 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 125e46c0cad..bb4280b5c80 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -16,6 +16,7 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
@@ -1240,6 +1241,53 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
}
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
break;
+ case ISD::BR_JT:
+ Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
+ // Ensure that libcalls are emitted before a branch.
+ Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END);
+ Tmp1 = LegalizeOp(Tmp1);
+ LastCALLSEQ_END = DAG.getEntryNode();
+
+ Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the jumptable node.
+ Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2));
+
+ switch (TLI.getOperationAction(ISD::BR_JT, MVT::Other)) {
+ default: assert(0 && "This action is not supported yet!");
+ case TargetLowering::Legal: break;
+ case TargetLowering::Custom:
+ Tmp1 = TLI.LowerOperation(Result, DAG);
+ if (Tmp1.Val) Result = Tmp1;
+ break;
+ case TargetLowering::Expand: {
+ SDOperand Chain = Result.getOperand(0);
+ SDOperand Table = Result.getOperand(1);
+ SDOperand Index = Result.getOperand(2);
+
+ MVT::ValueType PTy = TLI.getPointerTy();
+ bool isPIC = TLI.getTargetMachine().getRelocationModel() == Reloc::PIC_;
+ // PIC jump table entries are 32-bit values.
+ unsigned EntrySize = isPIC ? 4 : MVT::getSizeInBits(PTy)/8;
+ Index= DAG.getNode(ISD::MUL, PTy, Index, DAG.getConstant(EntrySize, PTy));
+ SDOperand Addr = DAG.getNode(ISD::ADD, PTy, Index, Table);
+ SDOperand LD = DAG.getLoad(isPIC ? MVT::i32 : PTy, Chain, Addr, NULL, 0);
+ if (isPIC) {
+ // For PIC, the sequence is:
+ // BRIND(load(Jumptable + index) + RelocBase)
+ // RelocBase is the JumpTable on PPC and X86, GOT on Alpha
+ SDOperand Reloc;
+ if (TLI.usesGlobalOffsetTable())
+ Reloc = DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, PTy);
+ else
+ Reloc = Table;
+ Addr= (PTy != MVT::i32) ? DAG.getNode(ISD::SIGN_EXTEND, PTy, LD) : Addr;
+ Addr = DAG.getNode(ISD::ADD, PTy, Addr, Reloc);
+ Result = DAG.getNode(ISD::BRIND, MVT::Other, LD.getValue(1), Addr);
+ } else {
+ Result = DAG.getNode(ISD::BRIND, MVT::Other, LD.getValue(1), LD);
+ }
+ }
+ }
+ break;
case ISD::BRCOND:
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
// Ensure that libcalls are emitted before a return.
OpenPOWER on IntegriCloud