SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { SDLoc DL(Op); switch (Op.getOpcode()) { default: llvm_unreachable("unimplemented operation lowering"); return SDValue(); case ISD::FrameIndex: return LowerFrameIndex(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG); case ISD::JumpTable: return LowerJumpTable(Op, DAG); case ISD::BR_JT: return LowerBR_JT(Op, DAG); case ISD::VASTART: return LowerVASTART(Op, DAG); case ISD::BlockAddress: case ISD::BRIND: fail(DL, DAG, "WebAssembly hasn't implemented computed gotos"); return SDValue(); case ISD::RETURNADDR: // Probably nothing meaningful can be returned here. fail(DL, DAG, "WebAssembly hasn't implemented __builtin_return_address"); return SDValue(); case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); case ISD::CopyToReg: return LowerCopyToReg(Op, DAG); } }
/// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to /// be zero. Op is expected to be a target specific node. Used by DAG /// combiner. void SparcTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op, const APInt &Mask, APInt &KnownZero, APInt &KnownOne, const SelectionDAG &DAG, unsigned Depth) const { APInt KnownZero2, KnownOne2; KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0); // Don't know anything. switch (Op.getOpcode()) { default: break; case SPISD::SELECT_ICC: case SPISD::SELECT_FCC: DAG.ComputeMaskedBits(Op.getOperand(1), Mask, KnownZero, KnownOne, Depth+1); DAG.ComputeMaskedBits(Op.getOperand(0), Mask, KnownZero2, KnownOne2, Depth+1); assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?"); // Only known if known in both the LHS and RHS. KnownOne &= KnownOne2; KnownZero &= KnownZero2; break; } }
// Expansion of ADDE / SUBE. This is a bit involved since blackfin doesn't have // add-with-carry instructions. SDValue BlackfinTargetLowering::LowerADDE(SDValue Op, SelectionDAG &DAG) const { // Operands: lhs, rhs, carry-in (AC0 flag) // Results: sum, carry-out (AC0 flag) DebugLoc dl = Op.getDebugLoc(); unsigned Opcode = Op.getOpcode()==ISD::ADDE ? BF::ADD : BF::SUB; // zext incoming carry flag in AC0 to 32 bits SDNode* CarryIn = DAG.getMachineNode(BF::MOVE_cc_ac0, dl, MVT::i32, /* flag= */ Op.getOperand(2)); CarryIn = DAG.getMachineNode(BF::MOVECC_zext, dl, MVT::i32, SDValue(CarryIn, 0)); // Add operands, produce sum and carry flag SDNode *Sum = DAG.getMachineNode(Opcode, dl, MVT::i32, MVT::Glue, Op.getOperand(0), Op.getOperand(1)); // Store intermediate carry from Sum SDNode* Carry1 = DAG.getMachineNode(BF::MOVE_cc_ac0, dl, MVT::i32, /* flag= */ SDValue(Sum, 1)); // Add incoming carry, again producing an output flag Sum = DAG.getMachineNode(Opcode, dl, MVT::i32, MVT::Glue, SDValue(Sum, 0), SDValue(CarryIn, 0)); // Update AC0 with the intermediate carry, producing a flag. SDNode *CarryOut = DAG.getMachineNode(BF::OR_ac0_cc, dl, MVT::Glue, SDValue(Carry1, 0)); // Compose (i32, flag) pair SDValue ops[2] = { SDValue(Sum, 0), SDValue(CarryOut, 0) }; return DAG.getMergeValues(ops, 2, dl); }
SDValue MSP430TargetLowering::LowerShifts(SDValue Op, SelectionDAG &DAG) { unsigned Opc = Op.getOpcode(); SDNode* N = Op.getNode(); MVT VT = Op.getValueType(); DebugLoc dl = N->getDebugLoc(); // We currently only lower shifts of constant argument. if (!isa<ConstantSDNode>(N->getOperand(1))) return SDValue(); uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); // Expand the stuff into sequence of shifts. // FIXME: for some shift amounts this might be done better! // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N SDValue Victim = N->getOperand(0); if (Opc == ISD::SRL && ShiftAmount) { // Emit a special goodness here: // srl A, 1 => clrc; rrc A Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim); ShiftAmount -= 1; } while (ShiftAmount--) Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA), dl, VT, Victim); return Victim; }
bool AMDGPUDAGToDAGISel::SelectADDR(SDValue Addr, SDValue& R1, SDValue& R2) { if (Addr.getOpcode() == ISD::TargetExternalSymbol || Addr.getOpcode() == ISD::TargetGlobalAddress) { return false; } return SelectADDRParam(Addr, R1, R2); }
bool AMDGPUDAGToDAGISel::SelectADDRVTX_READ(SDValue Addr, SDValue &Base, SDValue &Offset) { ConstantSDNode * IMMOffset; if (Addr.getOpcode() == ISD::ADD && (IMMOffset = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) && isInt<16>(IMMOffset->getZExtValue())) { Base = Addr.getOperand(0); Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), MVT::i32); return true; // If the pointer address is constant, we can move it to the offset field. } else if ((IMMOffset = dyn_cast<ConstantSDNode>(Addr)) && isInt<16>(IMMOffset->getZExtValue())) { Base = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), CurDAG->getEntryNode().getDebugLoc(), AMDGPU::ZERO, MVT::i32); Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), MVT::i32); return true; } // Default case, no offset Base = Addr; Offset = CurDAG->getTargetConstant(0, MVT::i32); return true; }
SDValue MSP430TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); case ISD::SHL: // FALLTHROUGH case ISD::SRL: case ISD::SRA: return LowerShifts(Op, DAG); case ISD::RET: return LowerRET(Op, DAG); case ISD::CALL: return LowerCALL(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG); case ISD::BR_CC: return LowerBR_CC(Op, DAG); case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG); default: assert(0 && "unimplemented operand"); return SDValue(); } }
// ComplexPattern used on BPF Load/Store instructions bool BPFDAGToDAGISel::SelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset) { // if Address is FI, get the TargetFrameIndex. SDLoc DL(Addr); if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64); Offset = CurDAG->getTargetConstant(0, DL, MVT::i64); return true; } if (Addr.getOpcode() == ISD::TargetExternalSymbol || Addr.getOpcode() == ISD::TargetGlobalAddress) return false; // Addresses of the form Addr+const or Addr|const if (CurDAG->isBaseWithConstantOffset(Addr)) { ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)); if (isInt<16>(CN->getSExtValue())) { // If the first operand is a FI, get the TargetFI Node if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64); else Base = Addr.getOperand(0); Offset = CurDAG->getTargetConstant(CN->getSExtValue(), DL, MVT::i64); return true; } } Base = Addr; Offset = CurDAG->getTargetConstant(0, DL, MVT::i64); return true; }
SDValue LanaiTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { switch (Op.getOpcode()) { case ISD::MUL: return LowerMUL(Op, DAG); case ISD::BR_CC: return LowerBR_CC(Op, DAG); case ISD::ConstantPool: return LowerConstantPool(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); case ISD::JumpTable: return LowerJumpTable(Op, DAG); case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); case ISD::SETCC: return LowerSETCC(Op, DAG); case ISD::SETCCE: return LowerSETCCE(Op, DAG); case ISD::SRL_PARTS: return LowerSRL_PARTS(Op, DAG); case ISD::VASTART: return LowerVASTART(Op, DAG); case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG); case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); default: llvm_unreachable("unimplemented operand"); } }
// Match memory operand of the form [reg], [imm+reg], and [reg+imm] bool PTXDAGToDAGISel::SelectADDRri(SDValue &Addr, SDValue &Base, SDValue &Offset) { if (Addr.getOpcode() != ISD::ADD) { // let SelectADDRii handle the [imm] case if (isImm(Addr)) return false; // it is [reg] Base = Addr; Offset = CurDAG->getTargetConstant(0, MVT::i32); return true; } if (Addr.getNumOperands() < 2) return false; // let SelectADDRii handle the [imm+imm] case if (isImm(Addr.getOperand(0)) && isImm(Addr.getOperand(1))) return false; // try [reg+imm] and [imm+reg] for (int i = 0; i < 2; i ++) if (SelectImm(Addr.getOperand(1-i), Offset)) { Base = Addr.getOperand(i); return true; } // neither [reg+imm] nor [imm+reg] return false; }
/// ComplexPattern used on MipsInstrInfo /// Used on Mips Load/Store instructions bool MipsSEDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset) const { // if Address is FI, get the TargetFrameIndex. if (selectAddrFrameIndex(Addr, Base, Offset)) return true; // on PIC code Load GA if (Addr.getOpcode() == MipsISD::Wrapper) { Base = Addr.getOperand(0); Offset = Addr.getOperand(1); return true; } if (!TM.isPositionIndependent()) { if ((Addr.getOpcode() == ISD::TargetExternalSymbol || Addr.getOpcode() == ISD::TargetGlobalAddress)) return false; } // Addresses of the form FI+const or FI|const if (selectAddrFrameIndexOffset(Addr, Base, Offset, 16)) return true; // Operand is a result from an ADD. if (Addr.getOpcode() == ISD::ADD) { // When loading from constant pools, load the lower address part in // the instruction itself. Example, instead of: // lui $2, %hi($CPI1_0) // addiu $2, $2, %lo($CPI1_0) // lwc1 $f0, 0($2) // Generate: // lui $2, %hi($CPI1_0) // lwc1 $f0, %lo($CPI1_0)($2) if (Addr.getOperand(1).getOpcode() == MipsISD::Lo || Addr.getOperand(1).getOpcode() == MipsISD::GPRel) { SDValue Opnd0 = Addr.getOperand(1).getOperand(0); if (isa<ConstantPoolSDNode>(Opnd0) || isa<GlobalAddressSDNode>(Opnd0) || isa<JumpTableSDNode>(Opnd0)) { Base = Addr.getOperand(0); Offset = Opnd0; return true; } } } return false; }
/// ComplexPattern used on MBlazeInstrInfo /// Used on MBlaze Load/Store instructions bool MBlazeDAGToDAGISel:: SelectAddr(SDNode *Op, SDValue Addr, SDValue &Offset, SDValue &Base) { // if Address is FI, get the TargetFrameIndex. if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); Offset = CurDAG->getTargetConstant(0, MVT::i32); return true; } // on PIC code Load GA if (TM.getRelocationModel() == Reloc::PIC_) { if ((Addr.getOpcode() == ISD::TargetGlobalAddress) || (Addr.getOpcode() == ISD::TargetConstantPool) || (Addr.getOpcode() == ISD::TargetJumpTable)){ Base = CurDAG->getRegister(MBlaze::R15, MVT::i32); Offset = Addr; return true; } } else { if ((Addr.getOpcode() == ISD::TargetExternalSymbol || Addr.getOpcode() == ISD::TargetGlobalAddress)) return false; } // Operand is a result from an ADD. if (Addr.getOpcode() == ISD::ADD) { if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) { if (Predicate_immSExt16(CN)) { // If the first operand is a FI, get the TargetFI Node if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode> (Addr.getOperand(0))) { Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); } else { Base = Addr.getOperand(0); } Offset = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32); return true; } } } Base = Addr; Offset = CurDAG->getTargetConstant(0, MVT::i32); return true; }
SDValue Cpu0TargetLowering:: LowerOperation(SDValue Op, SelectionDAG &DAG) const { switch (Op.getOpcode()) { case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); } return SDValue(); }
// Match memory operand of the form [reg+reg] bool PTXDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1, SDValue &R2) { if (Addr.getOpcode() != ISD::ADD || Addr.getNumOperands() < 2 || isImm(Addr.getOperand(0)) || isImm(Addr.getOperand(1))) return false; R1 = Addr; R2 = CurDAG->getTargetConstant(0, MVT::i32); return true; }
bool AMDGPUDAGToDAGISel::SelectADDRIndirect(SDValue Addr, SDValue &Base, SDValue &Offset) { ConstantSDNode *C; if ((C = dyn_cast<ConstantSDNode>(Addr))) { Base = CurDAG->getRegister(AMDGPU::INDIRECT_BASE_ADDR, MVT::i32); Offset = CurDAG->getTargetConstant(C->getZExtValue(), MVT::i32); } else if ((Addr.getOpcode() == ISD::ADD || Addr.getOpcode() == ISD::OR) && (C = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))) { Base = Addr.getOperand(0); Offset = CurDAG->getTargetConstant(C->getZExtValue(), MVT::i32); } else { Base = Addr; Offset = CurDAG->getTargetConstant(0, MVT::i32); } return true; }
bool XCoreDAGToDAGISel::tryBRIND(SDNode *N) { SDLoc dl(N); // (brind (int_xcore_checkevent (addr))) SDValue Chain = N->getOperand(0); SDValue Addr = N->getOperand(1); if (Addr->getOpcode() != ISD::INTRINSIC_W_CHAIN) return false; unsigned IntNo = cast<ConstantSDNode>(Addr->getOperand(1))->getZExtValue(); if (IntNo != Intrinsic::xcore_checkevent) return false; SDValue nextAddr = Addr->getOperand(2); SDValue CheckEventChainOut(Addr.getNode(), 1); if (!CheckEventChainOut.use_empty()) { // If the chain out of the checkevent intrinsic is an operand of the // indirect branch or used in a TokenFactor which is the operand of the // indirect branch then build a new chain which uses the chain coming into // the checkevent intrinsic instead. SDValue CheckEventChainIn = Addr->getOperand(0); SDValue NewChain = replaceInChain(CurDAG, Chain, CheckEventChainOut, CheckEventChainIn); if (!NewChain.getNode()) return false; Chain = NewChain; } // Enable events on the thread using setsr 1 and then disable them immediately // after with clrsr 1. If any resources owned by the thread are ready an event // will be taken. If no resource is ready we branch to the address which was // the operand to the checkevent intrinsic. SDValue constOne = getI32Imm(1, dl); SDValue Glue = SDValue(CurDAG->getMachineNode(XCore::SETSR_branch_u6, dl, MVT::Glue, constOne, Chain), 0); Glue = SDValue(CurDAG->getMachineNode(XCore::CLRSR_branch_u6, dl, MVT::Glue, constOne, Glue), 0); if (nextAddr->getOpcode() == XCoreISD::PCRelativeWrapper && nextAddr->getOperand(0)->getOpcode() == ISD::TargetBlockAddress) { CurDAG->SelectNodeTo(N, XCore::BRFU_lu6, MVT::Other, nextAddr->getOperand(0), Glue); return true; } CurDAG->SelectNodeTo(N, XCore::BAU_1r, MVT::Other, nextAddr, Glue); return true; }
bool SparcDAGToDAGISel::SelectADDRri(SDValue Addr, SDValue &Base, SDValue &Offset) { if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { Base = CurDAG->getTargetFrameIndex( FIN->getIndex(), TLI->getPointerTy(CurDAG->getDataLayout())); Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); return true; } if (Addr.getOpcode() == ISD::TargetExternalSymbol || Addr.getOpcode() == ISD::TargetGlobalAddress || Addr.getOpcode() == ISD::TargetGlobalTLSAddress) return false; // direct calls. if (Addr.getOpcode() == ISD::ADD) { if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) { if (isInt<13>(CN->getSExtValue())) { if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) { // Constant offset from frame ref. Base = CurDAG->getTargetFrameIndex( FIN->getIndex(), TLI->getPointerTy(CurDAG->getDataLayout())); } else { Base = Addr.getOperand(0); } Offset = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32); return true; } } if (Addr.getOperand(0).getOpcode() == SPISD::Lo) { Base = Addr.getOperand(1); Offset = Addr.getOperand(0).getOperand(0); return true; } if (Addr.getOperand(1).getOpcode() == SPISD::Lo) { Base = Addr.getOperand(0); Offset = Addr.getOperand(1).getOperand(0); return true; } } Base = Addr; Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); return true; }
SDValue PTXTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { switch (Op.getOpcode()) { default: llvm_unreachable("Unimplemented operand"); case ISD::SETCC: return LowerSETCC(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); } }
// SelectDirectAddr - Match a direct address for DAG. // A direct address could be a globaladdress or externalsymbol. bool NVPTXDAGToDAGISel::SelectDirectAddr(SDValue N, SDValue &Address) { // Return true if TGA or ES. if (N.getOpcode() == ISD::TargetGlobalAddress || N.getOpcode() == ISD::TargetExternalSymbol) { Address = N; return true; } if (N.getOpcode() == NVPTXISD::Wrapper) { Address = N.getOperand(0); return true; } if (N.getOpcode() == ISD::INTRINSIC_WO_CHAIN) { unsigned IID = cast<ConstantSDNode>(N.getOperand(0))->getZExtValue(); if (IID == Intrinsic::nvvm_ptr_gen_to_param) if (N.getOperand(1).getOpcode() == NVPTXISD::MoveParam) return (SelectDirectAddr(N.getOperand(1).getOperand(0), Address)); } return false; }
// Look at LHS/RHS/CC and see if they are a lowered setcc instruction. If so // set LHS/RHS and SPCC to the LHS/RHS of the setcc and SPCC to the condition. static void LookThroughSetCC(SDValue &LHS, SDValue &RHS, ISD::CondCode CC, unsigned &SPCC) { if (isa<ConstantSDNode>(RHS) && cast<ConstantSDNode>(RHS)->isNullValue() && CC == ISD::SETNE && ((LHS.getOpcode() == SPISD::SELECT_ICC && LHS.getOperand(3).getOpcode() == SPISD::CMPICC) || (LHS.getOpcode() == SPISD::SELECT_FCC && LHS.getOperand(3).getOpcode() == SPISD::CMPFCC)) && isa<ConstantSDNode>(LHS.getOperand(0)) && isa<ConstantSDNode>(LHS.getOperand(1)) && cast<ConstantSDNode>(LHS.getOperand(0))->isOne() && cast<ConstantSDNode>(LHS.getOperand(1))->isNullValue()) { SDValue CMPCC = LHS.getOperand(3); SPCC = cast<ConstantSDNode>(LHS.getOperand(2))->getZExtValue(); LHS = CMPCC.getOperand(0); RHS = CMPCC.getOperand(1); } }
SDNode *PTXDAGToDAGISel::SelectREAD_PARAM(SDNode *Node) { SDValue index = Node->getOperand(1); DebugLoc dl = Node->getDebugLoc(); if (index.getOpcode() != ISD::TargetConstant) llvm_unreachable("READ_PARAM: index is not ISD::TargetConstant"); return PTXInstrInfo:: GetPTXMachineNode(CurDAG, PTX::LDpi, dl, MVT::i32, index); }
SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { switch (Op.getOpcode()) { default: llvm_unreachable("unimplemented operation lowering"); return SDValue(); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); } }
SDValue R600TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { switch (Op.getOpcode()) { default: return AMDGPUTargetLowering::LowerOperation(Op, DAG); case ISD::BR_CC: return LowerBR_CC(Op, DAG); case ISD::ROTL: return LowerROTL(Op, DAG); case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); case ISD::SETCC: return LowerSETCC(Op, DAG); } }
/// ComplexPattern used on Cpu0InstrInfo /// Used on Cpu0 Load/Store instructions bool Cpu0DAGToDAGISel:: SelectAddr(SDNode *Parent, SDValue Addr, SDValue &Base, SDValue &Offset) { EVT ValTy = Addr.getValueType(); // If Parent is an unaligned f32 load or store, select a (base + index) // floating point load/store instruction (luxc1 or suxc1). const LSBaseSDNode* LS = 0; if (Parent && (LS = dyn_cast<LSBaseSDNode>(Parent))) { EVT VT = LS->getMemoryVT(); if (VT.getSizeInBits() / 8 > LS->getAlignment()) { assert(TLI.allowsUnalignedMemoryAccesses(VT) && "Unaligned loads/stores not supported for this type."); if (VT == MVT::f32) return false; } } // if Address is FI, get the TargetFrameIndex. if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); Offset = CurDAG->getTargetConstant(0, ValTy); return true; } // on PIC code Load GA if (Addr.getOpcode() == Cpu0ISD::Wrapper) { Base = Addr.getOperand(0); Offset = Addr.getOperand(1); return true; } if (TM.getRelocationModel() != Reloc::PIC_) { if ((Addr.getOpcode() == ISD::TargetExternalSymbol || Addr.getOpcode() == ISD::TargetGlobalAddress)) return false; } Base = Addr; Offset = CurDAG->getTargetConstant(0, ValTy); return true; }
/// ComplexPattern used on MipsInstrInfo /// Used on Mips Load/Store instructions bool MipsSEDAGToDAGISel::selectAddrRegReg(SDValue Addr, SDValue &Base, SDValue &Offset) const { // Operand is a result from an ADD. if (Addr.getOpcode() == ISD::ADD) { Base = Addr.getOperand(0); Offset = Addr.getOperand(1); return true; } return false; }
bool XCoreDAGToDAGISel::SelectADDRcpii(SDValue Op, SDValue Addr, SDValue &Base, SDValue &Offset) { if (Addr.getOpcode() == XCoreISD::CPRelativeWrapper) { Base = Addr.getOperand(0); Offset = CurDAG->getTargetConstant(0, MVT::i32); return true; } if (Addr.getOpcode() == ISD::ADD) { ConstantSDNode *CN = 0; if ((Addr.getOperand(0).getOpcode() == XCoreISD::CPRelativeWrapper) && (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) && (CN->getSExtValue() % 4 == 0)) { // Constant word offset from a object in the data region Base = Addr.getOperand(0).getOperand(0); Offset = CurDAG->getTargetConstant(CN->getSExtValue(), MVT::i32); return true; } } return false; }
SDValue MipsTargetLowering:: LowerANDOR(SDValue Op, SelectionDAG &DAG) { SDValue LHS = Op.getOperand(0); SDValue RHS = Op.getOperand(1); DebugLoc dl = Op.getDebugLoc(); if (LHS.getOpcode() != MipsISD::FPCmp || RHS.getOpcode() != MipsISD::FPCmp) return Op; SDValue True = DAG.getConstant(1, MVT::i32); SDValue False = DAG.getConstant(0, MVT::i32); SDValue LSEL = DAG.getNode(MipsISD::FPSelectCC, dl, True.getValueType(), LHS, True, False, LHS.getOperand(2)); SDValue RSEL = DAG.getNode(MipsISD::FPSelectCC, dl, True.getValueType(), RHS, True, False, RHS.getOperand(2)); return DAG.getNode(Op.getOpcode(), dl, MVT::i32, LSEL, RSEL); }
/*! \param Op The ISD instruction operand \param N The address to be tested \param Base The base address \param Index The base address index */ bool SPUDAGToDAGISel::SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index) { // These match the addr256k operand type: EVT OffsVT = MVT::i16; SDValue Zero = CurDAG->getTargetConstant(0, OffsVT); int64_t val; switch (N.getOpcode()) { case ISD::Constant: val = dyn_cast<ConstantSDNode>(N.getNode())->getSExtValue(); Base = CurDAG->getTargetConstant( val , MVT::i32); Index = Zero; return true; case ISD::ConstantPool: case ISD::GlobalAddress: report_fatal_error("SPU SelectAFormAddr: Pool/Global not lowered."); /*NOTREACHED*/ case ISD::TargetConstant: case ISD::TargetGlobalAddress: case ISD::TargetJumpTable: report_fatal_error("SPUSelectAFormAddr: Target Constant/Pool/Global " "not wrapped as A-form address."); /*NOTREACHED*/ case SPUISD::AFormAddr: // Just load from memory if there's only a single use of the location, // otherwise, this will get handled below with D-form offset addresses if (N.hasOneUse()) { SDValue Op0 = N.getOperand(0); switch (Op0.getOpcode()) { case ISD::TargetConstantPool: case ISD::TargetJumpTable: Base = Op0; Index = Zero; return true; case ISD::TargetGlobalAddress: { GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0); const GlobalValue *GV = GSDN->getGlobal(); if (GV->getAlignment() == 16) { Base = Op0; Index = Zero; return true; } break; } } } break; } return false; }
bool AMDGPUDAGToDAGISel::SelectADDRParam( SDValue Addr, SDValue& R1, SDValue& R2) { if (Addr.getOpcode() == ISD::FrameIndex) { if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { R1 = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); R2 = CurDAG->getTargetConstant(0, MVT::i32); } else { R1 = Addr; R2 = CurDAG->getTargetConstant(0, MVT::i32); } } else if (Addr.getOpcode() == ISD::ADD) { R1 = Addr.getOperand(0); R2 = Addr.getOperand(1); } else { R1 = Addr; R2 = CurDAG->getTargetConstant(0, MVT::i32); } return true; }
SDValue SystemZTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { case ISD::BR_CC: return LowerBR_CC(Op, DAG); case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::JumpTable: return LowerJumpTable(Op, DAG); case ISD::ConstantPool: return LowerConstantPool(Op, DAG); default: llvm_unreachable("Should not custom lower this!"); return SDValue(); } }