diff options
author | Scott Michel <scottm@aero.org> | 2008-01-11 21:01:19 +0000 |
---|---|---|
committer | Scott Michel <scottm@aero.org> | 2008-01-11 21:01:19 +0000 |
commit | 497e888daf9ba6489928e1153804ed12a7fe44c5 (patch) | |
tree | 689b7eba823de615856afce10540803e5a9b3a5e /lib/Target/CellSPU | |
parent | ef68e75618bb0c1369076283a876853608cc1436 (diff) | |
download | external_llvm-497e888daf9ba6489928e1153804ed12a7fe44c5.zip external_llvm-497e888daf9ba6489928e1153804ed12a7fe44c5.tar.gz external_llvm-497e888daf9ba6489928e1153804ed12a7fe44c5.tar.bz2 |
More CellSPU refinements:
- struct_2.ll: Completely unaligned load/store testing
- call_indirect.ll, struct_1.ll: Add test lines to exercise
X-form [$reg($reg)] addressing
At this point, loads and stores should be under control (he says
in an optimistic tone of voice.)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45882 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/CellSPU')
-rw-r--r-- | lib/Target/CellSPU/SPUISelDAGToDAG.cpp | 34 | ||||
-rw-r--r-- | lib/Target/CellSPU/SPUISelLowering.cpp | 17 |
2 files changed, 36 insertions, 15 deletions
diff --git a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp index bb3b100..167d3c3 100644 --- a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp +++ b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp @@ -456,8 +456,9 @@ SPUDAGToDAGISel::SelectDFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, const SDOperand Op0 = N.getOperand(0); // Frame index/base const SDOperand Op1 = N.getOperand(1); // Offset within base - if (Op1.getOpcode() == ISD::Constant - || Op1.getOpcode() == ISD::TargetConstant) { + if ((Op1.getOpcode() == ISD::Constant + || Op1.getOpcode() == ISD::TargetConstant) + && Op0.getOpcode() != SPUISD::XFormAddr) { ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1); assert(CN != 0 && "SelectDFormAddr: Expected a constant"); @@ -499,12 +500,19 @@ SPUDAGToDAGISel::SelectDFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, } else return false; } else if (Opc == SPUISD::DFormAddr) { - // D-Form address: This is pretty straightforward, naturally... - ConstantSDNode *CN = cast<ConstantSDNode>(N.getOperand(1)); - assert(CN != 0 && "SelectDFormAddr/SPUISD::DFormAddr expecting constant"); - Base = CurDAG->getTargetConstant(CN->getValue(), PtrTy); - Index = N.getOperand(0); - return true; + // D-Form address: This is pretty straightforward, + // naturally... but make sure that this isn't a D-form address + // with a X-form address embedded within: + const SDOperand Op0 = N.getOperand(0); // Frame index/base + const SDOperand Op1 = N.getOperand(1); // Offset within base + + if (Op0.getOpcode() != SPUISD::XFormAddr) { + ConstantSDNode *CN = cast<ConstantSDNode>(Op1); + assert(CN != 0 && "SelectDFormAddr/SPUISD::DFormAddr expecting constant"); + Base = CurDAG->getTargetConstant(CN->getValue(), PtrTy); + Index = Op0; + return true; + } } else if (Opc == ISD::FrameIndex) { // Stack frame index must be less than 512 (divided by 16): FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N); @@ -564,6 +572,12 @@ SPUDAGToDAGISel::SelectXFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, Base = N; Index = N.getOperand(1); return true; + } else if (Opc == SPUISD::DFormAddr) { + // Must be a D-form address with an X-form address embedded + // within: + Base = N.getOperand(0); + Index = N.getOperand(1); + return true; } else if (N.getNumOperands() == 2) { SDOperand N1 = N.getOperand(0); SDOperand N2 = N.getOperand(1); @@ -578,14 +592,14 @@ SPUDAGToDAGISel::SelectXFormAddr(SDOperand Op, SDOperand N, SDOperand &Base, /*UNREACHED*/ } else { cerr << "SelectXFormAddr: 2-operand unhandled operand:\n"; - N.Val->dump(); + N.Val->dump(CurDAG); cerr << "\n"; abort(); /*UNREACHED*/ } } else { cerr << "SelectXFormAddr: Unhandled operand type:\n"; - N.Val->dump(); + N.Val->dump(CurDAG); cerr << "\n"; abort(); /*UNREACHED*/ diff --git a/lib/Target/CellSPU/SPUISelLowering.cpp b/lib/Target/CellSPU/SPUISelLowering.cpp index 59e2068..706eea9 100644 --- a/lib/Target/CellSPU/SPUISelLowering.cpp +++ b/lib/Target/CellSPU/SPUISelLowering.cpp @@ -90,13 +90,11 @@ namespace { const unsigned Opc = Op.getOpcode(); return (Opc == ISD::GlobalAddress || Opc == ISD::GlobalTLSAddress - /* || Opc == ISD::FrameIndex */ || Opc == ISD::JumpTable || Opc == ISD::ConstantPool || Opc == ISD::ExternalSymbol || Opc == ISD::TargetGlobalAddress || Opc == ISD::TargetGlobalTLSAddress - /* || Opc == ISD::TargetFrameIndex */ || Opc == ISD::TargetJumpTable || Opc == ISD::TargetConstantPool || Opc == ISD::TargetExternalSymbol @@ -566,7 +564,7 @@ LowerLOAD(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) { // Rotate the chunk if necessary if (rotamt < 0) rotamt += 16; - if (rotamt != 0) { + if (rotamt != 0 || !was16aligned) { SDVTList vecvts = DAG.getVTList(MVT::v16i8, MVT::Other); if (was16aligned) { @@ -574,10 +572,12 @@ LowerLOAD(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) { Ops[1] = result; Ops[2] = DAG.getConstant(rotamt, MVT::i16); } else { + MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); LoadSDNode *LN1 = cast<LoadSDNode>(result); Ops[0] = the_chain; Ops[1] = result; - Ops[2] = LN1->getBasePtr(); + Ops[2] = DAG.getNode(ISD::ADD, PtrVT, LN1->getBasePtr(), + DAG.getConstant(rotamt, PtrVT)); } result = DAG.getNode(SPUISD::ROTBYTES_LEFT_CHAINED, vecvts, Ops, 3); @@ -690,7 +690,6 @@ LowerSTORE(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) { } chunk_offset &= 0xf; - chunk_offset /= (MVT::getSizeInBits(StVT == MVT::i1 ? (unsigned) MVT::i8 : StVT) / 8); SDOperand insertEltOffs = DAG.getConstant(chunk_offset, PtrVT); SDOperand insertEltPtr; @@ -700,10 +699,18 @@ LowerSTORE(SDOperand Op, SelectionDAG &DAG, const SPUSubtarget *ST) { // a new D-form address with a slot offset and the orignal base pointer. // Otherwise generate a D-form address with the slot offset relative // to the stack pointer, which is always aligned. + DEBUG(cerr << "CellSPU LowerSTORE: basePtr = "); + DEBUG(basePtr.Val->dump(&DAG)); + DEBUG(cerr << "\n"); + if (basePtr.getOpcode() == SPUISD::DFormAddr) { insertEltPtr = DAG.getNode(SPUISD::DFormAddr, PtrVT, basePtr.getOperand(0), insertEltOffs); + } else if (basePtr.getOpcode() == SPUISD::XFormAddr || + (basePtr.getOpcode() == ISD::ADD + && basePtr.getOperand(0).getOpcode() == SPUISD::XFormAddr)) { + insertEltPtr = basePtr; } else { insertEltPtr = DAG.getNode(SPUISD::DFormAddr, PtrVT, DAG.getRegister(SPU::R1, PtrVT), |