#include "XCore.h"
#include "XCoreTargetMachine.h"
-#include "llvm/CallingConv.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.h"
-#include "llvm/Intrinsics.h"
-#include "llvm/LLVMContext.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
///
namespace {
class XCoreDAGToDAGISel : public SelectionDAGISel {
- const XCoreTargetLowering &Lowering;
- const XCoreSubtarget &Subtarget;
public:
XCoreDAGToDAGISel(XCoreTargetMachine &TM, CodeGenOpt::Level OptLevel)
- : SelectionDAGISel(TM, OptLevel),
- Lowering(*TM.getTargetLowering()),
- Subtarget(*TM.getSubtargetImpl()) { }
+ : SelectionDAGISel(TM, OptLevel) {}
- SDNode *Select(SDNode *N);
+ SDNode *Select(SDNode *N) override;
SDNode *SelectBRIND(SDNode *N);
/// getI32Imm - Return a target constant with the specified value, of type
/// i32.
- inline SDValue getI32Imm(unsigned Imm) {
- return CurDAG->getTargetConstant(Imm, MVT::i32);
+ inline SDValue getI32Imm(unsigned Imm, SDLoc dl) {
+ return CurDAG->getTargetConstant(Imm, dl, MVT::i32);
}
inline bool immMskBitp(SDNode *inN) const {
if (!isMask_32(value)) {
return false;
}
- int msksize = 32 - CountLeadingZeros_32(value);
+ int msksize = 32 - countLeadingZeros(value);
return (msksize >= 1 && msksize <= 8) ||
msksize == 16 || msksize == 24 || msksize == 32;
}
// Complex Pattern Selectors.
bool SelectADDRspii(SDValue Addr, SDValue &Base, SDValue &Offset);
- bool SelectADDRdpii(SDValue Addr, SDValue &Base, SDValue &Offset);
- bool SelectADDRcpii(SDValue Addr, SDValue &Base, SDValue &Offset);
-
- virtual const char *getPassName() const {
+
+ bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
+ std::vector<SDValue> &OutOps) override;
+
+ const char *getPassName() const override {
return "XCore DAG->DAG Pattern Instruction Selection";
}
bool XCoreDAGToDAGISel::SelectADDRspii(SDValue Addr, SDValue &Base,
SDValue &Offset) {
- FrameIndexSDNode *FIN = 0;
+ FrameIndexSDNode *FIN = nullptr;
if ((FIN = dyn_cast<FrameIndexSDNode>(Addr))) {
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
- Offset = CurDAG->getTargetConstant(0, MVT::i32);
+ Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
return true;
}
if (Addr.getOpcode() == ISD::ADD) {
- ConstantSDNode *CN = 0;
+ ConstantSDNode *CN = nullptr;
if ((FIN = dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
&& (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
&& (CN->getSExtValue() % 4 == 0 && CN->getSExtValue() >= 0)) {
// Constant positive word offset from frame index
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
- Offset = CurDAG->getTargetConstant(CN->getSExtValue(), MVT::i32);
- return true;
- }
- }
- return false;
-}
-
-bool XCoreDAGToDAGISel::SelectADDRdpii(SDValue Addr, SDValue &Base,
- SDValue &Offset) {
- if (Addr.getOpcode() == XCoreISD::DPRelativeWrapper) {
- 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::DPRelativeWrapper)
- && (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
- && (CN->getSExtValue() % 4 == 0 && CN->getSExtValue() >= 0)) {
- // Constant word offset from a object in the data region
- Base = Addr.getOperand(0).getOperand(0);
- Offset = CurDAG->getTargetConstant(CN->getSExtValue(), MVT::i32);
+ Offset = CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(Addr),
+ MVT::i32);
return true;
}
}
return false;
}
-bool XCoreDAGToDAGISel::SelectADDRcpii(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 && CN->getSExtValue() >= 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;
+bool XCoreDAGToDAGISel::
+SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
+ std::vector<SDValue> &OutOps) {
+ SDValue Reg;
+ switch (ConstraintID) {
+ default: return true;
+ case InlineAsm::Constraint_m: // Memory.
+ switch (Op.getOpcode()) {
+ default: return true;
+ case XCoreISD::CPRelativeWrapper:
+ Reg = CurDAG->getRegister(XCore::CP, MVT::i32);
+ break;
+ case XCoreISD::DPRelativeWrapper:
+ Reg = CurDAG->getRegister(XCore::DP, MVT::i32);
+ break;
}
}
+ OutOps.push_back(Reg);
+ OutOps.push_back(Op.getOperand(0));
return false;
}
SDNode *XCoreDAGToDAGISel::Select(SDNode *N) {
- DebugLoc dl = N->getDebugLoc();
+ SDLoc dl(N);
switch (N->getOpcode()) {
default: break;
case ISD::Constant: {
if (immMskBitp(N)) {
// Transformation function: get the size of a mask
// Look for the first non-zero bit
- SDValue MskSize = getI32Imm(32 - CountLeadingZeros_32(Val));
+ SDValue MskSize = getI32Imm(32 - countLeadingZeros((uint32_t)Val), dl);
return CurDAG->getMachineNode(XCore::MKMSK_rus, dl,
MVT::i32, MskSize);
}
else if (!isUInt<16>(Val)) {
- SDValue CPIdx =
- CurDAG->getTargetConstantPool(ConstantInt::get(
- Type::getInt32Ty(*CurDAG->getContext()), Val),
- TLI.getPointerTy());
+ SDValue CPIdx = CurDAG->getTargetConstantPool(
+ ConstantInt::get(Type::getInt32Ty(*CurDAG->getContext()), Val),
+ getTargetLowering()->getPointerTy(CurDAG->getDataLayout()));
SDNode *node = CurDAG->getMachineNode(XCore::LDWCP_lru6, dl, MVT::i32,
MVT::Other, CPIdx,
CurDAG->getEntryNode());
MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
- MemOp[0] = MF->getMachineMemOperand(
- MachinePointerInfo::getConstantPool(), MachineMemOperand::MOLoad, 4, 4);
+ MemOp[0] =
+ MF->getMachineMemOperand(MachinePointerInfo::getConstantPool(*MF),
+ MachineMemOperand::MOLoad, 4, 4);
cast<MachineSDNode>(node)->setMemRefs(MemOp, MemOp + 1);
return node;
}
SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
N->getOperand(2) };
return CurDAG->getMachineNode(XCore::LADD_l5r, dl, MVT::i32, MVT::i32,
- Ops, 3);
+ Ops);
}
case XCoreISD::LSUB: {
SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
N->getOperand(2) };
return CurDAG->getMachineNode(XCore::LSUB_l5r, dl, MVT::i32, MVT::i32,
- Ops, 3);
+ Ops);
}
case XCoreISD::MACCU: {
SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
N->getOperand(2), N->getOperand(3) };
return CurDAG->getMachineNode(XCore::MACCU_l4r, dl, MVT::i32, MVT::i32,
- Ops, 4);
+ Ops);
}
case XCoreISD::MACCS: {
SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
N->getOperand(2), N->getOperand(3) };
return CurDAG->getMachineNode(XCore::MACCS_l4r, dl, MVT::i32, MVT::i32,
- Ops, 4);
+ Ops);
}
case XCoreISD::LMUL: {
SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
N->getOperand(2), N->getOperand(3) };
return CurDAG->getMachineNode(XCore::LMUL_l6r, dl, MVT::i32, MVT::i32,
- Ops, 4);
+ Ops);
}
- case ISD::INTRINSIC_WO_CHAIN: {
- unsigned IntNo = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
- switch (IntNo) {
- case Intrinsic::xcore_crc8:
- SDValue Ops[] = { N->getOperand(1), N->getOperand(2), N->getOperand(3) };
- return CurDAG->getMachineNode(XCore::CRC8_l4r, dl, MVT::i32, MVT::i32,
- Ops, 3);
- }
- break;
+ case XCoreISD::CRC8: {
+ SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2) };
+ return CurDAG->getMachineNode(XCore::CRC8_l4r, dl, MVT::i32, MVT::i32,
+ Ops);
}
case ISD::BRIND:
if (SDNode *ResNode = SelectBRIND(N))
}
if (!found)
return SDValue();
- return CurDAG->getNode(ISD::TokenFactor, Chain->getDebugLoc(), MVT::Other,
- &Ops[0], Ops.size());
+ return CurDAG->getNode(ISD::TokenFactor, SDLoc(Chain), MVT::Other, Ops);
}
SDNode *XCoreDAGToDAGISel::SelectBRIND(SDNode *N) {
- DebugLoc dl = N->getDebugLoc();
+ 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 0;
+ return nullptr;
unsigned IntNo = cast<ConstantSDNode>(Addr->getOperand(1))->getZExtValue();
if (IntNo != Intrinsic::xcore_checkevent)
- return 0;
+ return nullptr;
SDValue nextAddr = Addr->getOperand(2);
SDValue CheckEventChainOut(Addr.getNode(), 1);
if (!CheckEventChainOut.use_empty()) {
SDValue NewChain = replaceInChain(CurDAG, Chain, CheckEventChainOut,
CheckEventChainIn);
if (!NewChain.getNode())
- return 0;
+ return nullptr;
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);
+ SDValue constOne = getI32Imm(1, dl);
SDValue Glue =
SDValue(CurDAG->getMachineNode(XCore::SETSR_branch_u6, dl, MVT::Glue,
constOne, Chain), 0);