34 #include "tce_config.h"
35 #include <llvm/IR/Intrinsics.h>
36 #include <llvm/Support/Debug.h>
37 #include <llvm/Support/Compiler.h>
38 #include <llvm/Support/raw_ostream.h>
48 #define DEFAULT_TYPE MVT::i64
49 #define MOVE_IMM TCE::MOVI64sa
51 #define DEFAULT_TYPE MVT::i32
52 #define MOVE_IMM TCE::MOVI32ri
62 bool SelectADDRrr(SDValue N, SDValue &R1, SDValue &R2);
63 bool SelectADDRri(SDValue N, SDValue &Base, SDValue &Offset);
65 void Select(llvm::SDNode* op)
override;
68 return "TCE DAG->DAG Pattern Instruction Selection";
73 static bool isBroadcast(SDNode *n);
74 static bool isConstantBuild(SDNode* n);
75 static bool isConstantFPBuild(SDNode* n);
76 void SelectOptimizedBuildVector(SDNode* n);
79 EVT getIntegerVectorVT(EVT vt);
81 MachineSDNode* createPackNode(SDNode*n,
const EVT& vt,
int laneCount, SDValue* vals);
87 #include "TCEGenDAGISel.inc"
96 subtarget_(*tm.getSubtargetImpl()), tm_(&tm) {
106 #define SELECT_NODE_AND_RETURN(args...) \
107 CurDAG->SelectNodeTo(args); \
109 #define RETURN_SELECTED_NODE(node) \
122 if (n->isMachineOpcode()) {
128 if (n->getOpcode() >= ISD::BUILTIN_OP_END &&
132 }
else if (n->getOpcode() == ISD::BR) {
133 SDValue chain = n->getOperand(0);
135 MachineBasicBlock* dest =
136 cast<BasicBlockSDNode>(n->getOperand(1))->getBasicBlock();
138 n, TCE::TCEBR, MVT::Other, CurDAG->getBasicBlock(dest), chain);
139 }
else if (n->getOpcode() == ISD::FrameIndex) {
140 int fi = cast<FrameIndexSDNode>(n)->getIndex();
142 if (n->hasOneUse()) {
147 auto fiN = CurDAG->getMachineNode(
153 }
else if (n->getOpcode() == ISD::VSELECT ||
154 (n->getOpcode() == ISD::SELECT &&
155 !n->getOperand(1).getValueType().isVector())) {
156 SDNode* node2 = dyn_cast<SDNode>(n->getOperand(0));
157 if (node2->getOpcode() == ISD::SETCC) {
158 SDValue val1 = n->getOperand(1);
159 SDValue val2 = n->getOperand(2);
161 SDValue n2val1 = node2->getOperand(0);
162 SDValue n2val2 = node2->getOperand(1);
164 if (val1 == n2val1 && val2 == n2val2 && node2->hasOneUse()) {
166 ISD::CondCode cc = cast<CondCodeSDNode>(
167 node2->getOperand(2))->get();
177 n,opc, n->getSimpleValueType(0), val1, val2);
187 n, opc, n->getSimpleValueType(0), val1, val2);
195 n, opc, n->getSimpleValueType(0), val1, val2);
203 n, opc, n->getSimpleValueType(0), val1, val2);
211 }
else if (n->getOpcode() == ISD::SHL ||
212 n->getOpcode() == ISD::SRA ||
213 n->getOpcode() == ISD::SRL) {
214 SDValue shifted = n->getOperand(0);
215 SDValue shifter = n->getOperand(1);
216 EVT shiftedVt = shifted.getValueType();
217 EVT shifterVt = shifter.getValueType();
219 }
else if (n->getOpcode() == ISD::AND ||
220 n->getOpcode() == ISD::OR ||
221 n->getOpcode() == ISD::XOR) {
222 SDValue lhs = n->getOperand(0);
223 SDValue rhs = n->getOperand(1);
224 EVT lhsVt = lhs.getValueType();
225 EVT rhsVt = rhs.getValueType();
230 #undef SELECT_NODE_AND_RETURN
231 #undef RETURN_SELECTED_NODE
238 SDValue addr, SDValue& base, SDValue& offset) {
240 if (FrameIndexSDNode* fin = dyn_cast<FrameIndexSDNode>(addr)) {
241 base = CurDAG->getTargetFrameIndex(fin->getIndex(),
DEFAULT_TYPE);
242 offset = CurDAG->getTargetConstant(0, SDLoc(),
DEFAULT_TYPE);
244 }
else if (addr.getOpcode() == ISD::TargetExternalSymbol ||
245 addr.getOpcode() == ISD::TargetGlobalAddress) {
250 offset = CurDAG->getTargetConstant(0, SDLoc(),
DEFAULT_TYPE);
259 SDValue addr, SDValue& r1, SDValue& r2) {
261 if (addr.getOpcode() == ISD::TargetGlobalAddress) {
266 }
else if (addr.getOpcode() == ISD::TargetExternalSymbol) {
268 }
else if (addr.getOpcode() == ISD::FrameIndex) {
274 r2 = CurDAG->getTargetConstant(0, SDLoc(),
DEFAULT_TYPE);
290 return TCETargetLowering::isBroadcast(n);
295 int operandCount = n->getNumOperands();
296 for (
unsigned i = 1; i <operandCount; i++) {
297 SDValue val2 = n->getOperand(i);
298 SDNode *n2 = val2.getNode();
299 if (n2->getOpcode() != ISD::Constant ) {
308 int operandCount = n->getNumOperands();
309 for (
unsigned i = 1; i <operandCount; i++) {
310 SDValue val2 = n->getOperand(i);
311 SDNode *n2 = val2.getNode();
312 if (n2->getOpcode() != ISD::ConstantFP) {