1 //===-- HexagonISelDAGToDAG.cpp - A dag to dag inst selector for Hexagon --===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines an instruction selector for the Hexagon target.
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "hexagon-isel"
16 #include "HexagonISelLowering.h"
17 #include "HexagonTargetMachine.h"
18 #include "llvm/CodeGen/SelectionDAGISel.h"
19 #include "llvm/IR/Intrinsics.h"
20 #include "llvm/Support/Compiler.h"
21 #include "llvm/Support/Debug.h"
26 //===----------------------------------------------------------------------===//
27 // Instruction Selector Implementation
28 //===----------------------------------------------------------------------===//
30 //===--------------------------------------------------------------------===//
31 /// HexagonDAGToDAGISel - Hexagon specific code to select Hexagon machine
32 /// instructions for SelectionDAG operations.
35 class HexagonDAGToDAGISel : public SelectionDAGISel {
36 /// Subtarget - Keep a pointer to the Hexagon Subtarget around so that we can
37 /// make the right decision when generating code for different targets.
38 const HexagonSubtarget &Subtarget;
40 // Keep a reference to HexagonTargetMachine.
41 HexagonTargetMachine& TM;
42 const HexagonInstrInfo *TII;
45 explicit HexagonDAGToDAGISel(HexagonTargetMachine &targetmachine)
46 : SelectionDAGISel(targetmachine),
47 Subtarget(targetmachine.getSubtarget<HexagonSubtarget>()),
49 TII(static_cast<const HexagonInstrInfo*>(TM.getInstrInfo())) {
53 SDNode *Select(SDNode *N);
55 // Complex Pattern Selectors.
56 bool SelectADDRri(SDValue& N, SDValue &R1, SDValue &R2);
57 bool SelectADDRriS11_0(SDValue& N, SDValue &R1, SDValue &R2);
58 bool SelectADDRriS11_1(SDValue& N, SDValue &R1, SDValue &R2);
59 bool SelectADDRriS11_2(SDValue& N, SDValue &R1, SDValue &R2);
60 bool SelectMEMriS11_2(SDValue& Addr, SDValue &Base, SDValue &Offset);
61 bool SelectADDRriS11_3(SDValue& N, SDValue &R1, SDValue &R2);
62 bool SelectADDRrr(SDValue &Addr, SDValue &Base, SDValue &Offset);
63 bool SelectADDRriU6_0(SDValue& N, SDValue &R1, SDValue &R2);
64 bool SelectADDRriU6_1(SDValue& N, SDValue &R1, SDValue &R2);
65 bool SelectADDRriU6_2(SDValue& N, SDValue &R1, SDValue &R2);
67 virtual const char *getPassName() const {
68 return "Hexagon DAG->DAG Pattern Instruction Selection";
71 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
72 /// inline asm expressions.
73 virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
75 std::vector<SDValue> &OutOps);
76 bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset);
78 SDNode *SelectLoad(SDNode *N);
79 SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl);
80 SDNode *SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl);
81 SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode,
83 SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode,
85 SDNode *SelectBaseOffsetStore(StoreSDNode *ST, DebugLoc dl);
86 SDNode *SelectIndexedStore(StoreSDNode *ST, DebugLoc dl);
87 SDNode *SelectStore(SDNode *N);
88 SDNode *SelectSHL(SDNode *N);
89 SDNode *SelectSelect(SDNode *N);
90 SDNode *SelectTruncate(SDNode *N);
91 SDNode *SelectMul(SDNode *N);
92 SDNode *SelectZeroExtend(SDNode *N);
93 SDNode *SelectIntrinsicWOChain(SDNode *N);
94 SDNode *SelectIntrinsicWChain(SDNode *N);
95 SDNode *SelectConstant(SDNode *N);
96 SDNode *SelectConstantFP(SDNode *N);
97 SDNode *SelectAdd(SDNode *N);
98 bool isConstExtProfitable(SDNode *N) const;
100 // Include the pieces autogenerated from the target description.
101 #include "HexagonGenDAGISel.inc"
103 } // end anonymous namespace
106 /// createHexagonISelDag - This pass converts a legalized DAG into a
107 /// Hexagon-specific DAG, ready for instruction scheduling.
109 FunctionPass *llvm::createHexagonISelDag(HexagonTargetMachine &TM) {
110 return new HexagonDAGToDAGISel(TM);
113 static bool IsS11_0_Offset(SDNode * S) {
114 ConstantSDNode *N = cast<ConstantSDNode>(S);
116 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
118 int64_t v = (int64_t)N->getSExtValue();
123 static bool IsS11_1_Offset(SDNode * S) {
124 ConstantSDNode *N = cast<ConstantSDNode>(S);
126 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
128 int64_t v = (int64_t)N->getSExtValue();
129 return isShiftedInt<11,1>(v);
133 static bool IsS11_2_Offset(SDNode * S) {
134 ConstantSDNode *N = cast<ConstantSDNode>(S);
136 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
138 int64_t v = (int64_t)N->getSExtValue();
139 return isShiftedInt<11,2>(v);
143 static bool IsS11_3_Offset(SDNode * S) {
144 ConstantSDNode *N = cast<ConstantSDNode>(S);
146 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
148 int64_t v = (int64_t)N->getSExtValue();
149 return isShiftedInt<11,3>(v);
153 static bool IsU6_0_Offset(SDNode * S) {
154 ConstantSDNode *N = cast<ConstantSDNode>(S);
156 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
158 int64_t v = (int64_t)N->getSExtValue();
163 static bool IsU6_1_Offset(SDNode * S) {
164 ConstantSDNode *N = cast<ConstantSDNode>(S);
166 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
168 int64_t v = (int64_t)N->getSExtValue();
169 return isShiftedUInt<6,1>(v);
173 static bool IsU6_2_Offset(SDNode * S) {
174 ConstantSDNode *N = cast<ConstantSDNode>(S);
176 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
178 int64_t v = (int64_t)N->getSExtValue();
179 return isShiftedUInt<6,2>(v);
183 // Intrinsics that return a a predicate.
184 static unsigned doesIntrinsicReturnPredicate(unsigned ID)
189 case Intrinsic::hexagon_C2_cmpeq:
190 case Intrinsic::hexagon_C2_cmpgt:
191 case Intrinsic::hexagon_C2_cmpgtu:
192 case Intrinsic::hexagon_C2_cmpgtup:
193 case Intrinsic::hexagon_C2_cmpgtp:
194 case Intrinsic::hexagon_C2_cmpeqp:
195 case Intrinsic::hexagon_C2_bitsset:
196 case Intrinsic::hexagon_C2_bitsclr:
197 case Intrinsic::hexagon_C2_cmpeqi:
198 case Intrinsic::hexagon_C2_cmpgti:
199 case Intrinsic::hexagon_C2_cmpgtui:
200 case Intrinsic::hexagon_C2_cmpgei:
201 case Intrinsic::hexagon_C2_cmpgeui:
202 case Intrinsic::hexagon_C2_cmplt:
203 case Intrinsic::hexagon_C2_cmpltu:
204 case Intrinsic::hexagon_C2_bitsclri:
205 case Intrinsic::hexagon_C2_and:
206 case Intrinsic::hexagon_C2_or:
207 case Intrinsic::hexagon_C2_xor:
208 case Intrinsic::hexagon_C2_andn:
209 case Intrinsic::hexagon_C2_not:
210 case Intrinsic::hexagon_C2_orn:
211 case Intrinsic::hexagon_C2_pxfer_map:
212 case Intrinsic::hexagon_C2_any8:
213 case Intrinsic::hexagon_C2_all8:
214 case Intrinsic::hexagon_A2_vcmpbeq:
215 case Intrinsic::hexagon_A2_vcmpbgtu:
216 case Intrinsic::hexagon_A2_vcmpheq:
217 case Intrinsic::hexagon_A2_vcmphgt:
218 case Intrinsic::hexagon_A2_vcmphgtu:
219 case Intrinsic::hexagon_A2_vcmpweq:
220 case Intrinsic::hexagon_A2_vcmpwgt:
221 case Intrinsic::hexagon_A2_vcmpwgtu:
222 case Intrinsic::hexagon_C2_tfrrp:
223 case Intrinsic::hexagon_S2_tstbit_i:
224 case Intrinsic::hexagon_S2_tstbit_r:
230 // Intrinsics that have predicate operands.
231 static unsigned doesIntrinsicContainPredicate(unsigned ID)
236 case Intrinsic::hexagon_C2_tfrpr:
237 return Hexagon::TFR_RsPd;
238 case Intrinsic::hexagon_C2_and:
239 return Hexagon::AND_pp;
240 case Intrinsic::hexagon_C2_xor:
241 return Hexagon::XOR_pp;
242 case Intrinsic::hexagon_C2_or:
243 return Hexagon::OR_pp;
244 case Intrinsic::hexagon_C2_not:
245 return Hexagon::NOT_p;
246 case Intrinsic::hexagon_C2_any8:
247 return Hexagon::ANY_pp;
248 case Intrinsic::hexagon_C2_all8:
249 return Hexagon::ALL_pp;
250 case Intrinsic::hexagon_C2_vitpack:
251 return Hexagon::VITPACK_pp;
252 case Intrinsic::hexagon_C2_mask:
253 return Hexagon::MASK_p;
254 case Intrinsic::hexagon_C2_mux:
255 return Hexagon::MUX_rr;
257 // Mapping hexagon_C2_muxir to MUX_pri. This is pretty weird - but
258 // that's how it's mapped in q6protos.h.
259 case Intrinsic::hexagon_C2_muxir:
260 return Hexagon::MUX_ri;
262 // Mapping hexagon_C2_muxri to MUX_pir. This is pretty weird - but
263 // that's how it's mapped in q6protos.h.
264 case Intrinsic::hexagon_C2_muxri:
265 return Hexagon::MUX_ir;
267 case Intrinsic::hexagon_C2_muxii:
268 return Hexagon::MUX_ii;
269 case Intrinsic::hexagon_C2_vmux:
270 return Hexagon::VMUX_prr64;
271 case Intrinsic::hexagon_S2_valignrb:
272 return Hexagon::VALIGN_rrp;
273 case Intrinsic::hexagon_S2_vsplicerb:
274 return Hexagon::VSPLICE_rrp;
279 static bool OffsetFitsS11(EVT MemType, int64_t Offset) {
280 if (MemType == MVT::i64 && isShiftedInt<11,3>(Offset)) {
283 if (MemType == MVT::i32 && isShiftedInt<11,2>(Offset)) {
286 if (MemType == MVT::i16 && isShiftedInt<11,1>(Offset)) {
289 if (MemType == MVT::i8 && isInt<11>(Offset)) {
297 // Try to lower loads of GlobalAdresses into base+offset loads. Custom
298 // lowering for GlobalAddress nodes has already turned it into a
301 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl) {
302 SDValue Chain = LD->getChain();
303 SDNode* Const32 = LD->getBasePtr().getNode();
306 if (Const32->getOpcode() == HexagonISD::CONST32 &&
307 ISD::isNormalLoad(LD)) {
308 SDValue Base = Const32->getOperand(0);
309 EVT LoadedVT = LD->getMemoryVT();
310 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
311 if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) {
312 MVT PointerTy = TLI.getPointerTy();
313 const GlobalValue* GV =
314 cast<GlobalAddressSDNode>(Base)->getGlobal();
316 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
317 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
320 // Figure out base + offset opcode
321 if (LoadedVT == MVT::i64) Opcode = Hexagon::LDrid_indexed;
322 else if (LoadedVT == MVT::i32) Opcode = Hexagon::LDriw_indexed;
323 else if (LoadedVT == MVT::i16) Opcode = Hexagon::LDrih_indexed;
324 else if (LoadedVT == MVT::i8) Opcode = Hexagon::LDrib_indexed;
325 else llvm_unreachable("unknown memory type");
327 // Build indexed load.
328 SDValue TargetConstOff = CurDAG->getTargetConstant(Offset, PointerTy);
329 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
335 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
336 MemOp[0] = LD->getMemOperand();
337 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
338 ReplaceUses(LD, Result);
343 return SelectCode(LD);
347 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
351 SDValue Chain = LD->getChain();
352 EVT LoadedVT = LD->getMemoryVT();
353 SDValue Base = LD->getBasePtr();
354 SDValue Offset = LD->getOffset();
355 SDNode *OffsetNode = Offset.getNode();
356 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
357 SDValue N1 = LD->getOperand(1);
360 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
361 N1.getNode()->getValueType(0) == MVT::i32) {
362 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
363 SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
364 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
365 MVT::Other, Base, TargetConst,
367 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, MVT::i64,
368 SDValue(Result_1, 0));
369 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
370 MemOp[0] = LD->getMemOperand();
371 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
372 const SDValue Froms[] = { SDValue(LD, 0),
376 const SDValue Tos[] = { SDValue(Result_2, 0),
377 SDValue(Result_1, 1),
380 ReplaceUses(Froms, Tos, 3);
383 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
384 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
385 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
386 MVT::Other, Base, TargetConst0,
388 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl,
389 MVT::i64, SDValue(Result_1, 0));
390 SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl,
391 MVT::i32, Base, TargetConstVal,
392 SDValue(Result_1, 1));
393 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
394 MemOp[0] = LD->getMemOperand();
395 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
396 const SDValue Froms[] = { SDValue(LD, 0),
400 const SDValue Tos[] = { SDValue(Result_2, 0),
401 SDValue(Result_3, 0),
404 ReplaceUses(Froms, Tos, 3);
407 return SelectCode(LD);
411 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
415 SDValue Chain = LD->getChain();
416 EVT LoadedVT = LD->getMemoryVT();
417 SDValue Base = LD->getBasePtr();
418 SDValue Offset = LD->getOffset();
419 SDNode *OffsetNode = Offset.getNode();
420 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
421 SDValue N1 = LD->getOperand(1);
424 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
425 N1.getNode()->getValueType(0) == MVT::i32) {
426 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
427 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
428 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
429 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
430 MVT::i32, MVT::Other, Base,
431 TargetConstVal, Chain);
432 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
434 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
435 MVT::i64, MVT::Other,
437 SDValue(Result_1,0));
438 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
439 MemOp[0] = LD->getMemOperand();
440 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
441 const SDValue Froms[] = { SDValue(LD, 0),
445 const SDValue Tos[] = { SDValue(Result_3, 0),
446 SDValue(Result_1, 1),
449 ReplaceUses(Froms, Tos, 3);
453 // Generate an indirect load.
454 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
455 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
456 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
458 Base, TargetConst0, Chain);
459 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
461 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
462 MVT::i64, MVT::Other,
464 SDValue(Result_1,0));
465 // Add offset to base.
466 SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
467 Base, TargetConstVal,
468 SDValue(Result_1, 1));
469 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
470 MemOp[0] = LD->getMemOperand();
471 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
472 const SDValue Froms[] = { SDValue(LD, 0),
476 const SDValue Tos[] = { SDValue(Result_3, 0), // Load value.
477 SDValue(Result_4, 0), // New address.
480 ReplaceUses(Froms, Tos, 3);
484 return SelectCode(LD);
488 SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl) {
489 SDValue Chain = LD->getChain();
490 SDValue Base = LD->getBasePtr();
491 SDValue Offset = LD->getOffset();
492 SDNode *OffsetNode = Offset.getNode();
493 // Get the constant value.
494 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
495 EVT LoadedVT = LD->getMemoryVT();
498 // Check for zero ext loads.
499 bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD);
501 // Figure out the opcode.
502 if (LoadedVT == MVT::i64) {
503 if (TII->isValidAutoIncImm(LoadedVT, Val))
504 Opcode = Hexagon::POST_LDrid;
506 Opcode = Hexagon::LDrid;
507 } else if (LoadedVT == MVT::i32) {
508 if (TII->isValidAutoIncImm(LoadedVT, Val))
509 Opcode = Hexagon::POST_LDriw;
511 Opcode = Hexagon::LDriw;
512 } else if (LoadedVT == MVT::i16) {
513 if (TII->isValidAutoIncImm(LoadedVT, Val))
514 Opcode = zextval ? Hexagon::POST_LDriuh : Hexagon::POST_LDrih;
516 Opcode = zextval ? Hexagon::LDriuh : Hexagon::LDrih;
517 } else if (LoadedVT == MVT::i8) {
518 if (TII->isValidAutoIncImm(LoadedVT, Val))
519 Opcode = zextval ? Hexagon::POST_LDriub : Hexagon::POST_LDrib;
521 Opcode = zextval ? Hexagon::LDriub : Hexagon::LDrib;
523 llvm_unreachable("unknown memory type");
525 // For zero ext i64 loads, we need to add combine instructions.
526 if (LD->getValueType(0) == MVT::i64 &&
527 LD->getExtensionType() == ISD::ZEXTLOAD) {
528 return SelectIndexedLoadZeroExtend64(LD, Opcode, dl);
530 if (LD->getValueType(0) == MVT::i64 &&
531 LD->getExtensionType() == ISD::SEXTLOAD) {
532 // Handle sign ext i64 loads.
533 return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
535 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
536 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
537 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
539 MVT::i32, MVT::Other, Base,
540 TargetConstVal, Chain);
541 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
542 MemOp[0] = LD->getMemOperand();
543 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
544 const SDValue Froms[] = { SDValue(LD, 0),
548 const SDValue Tos[] = { SDValue(Result, 0),
552 ReplaceUses(Froms, Tos, 3);
555 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
556 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
557 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl,
559 MVT::Other, Base, TargetConst0,
561 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
562 Base, TargetConstVal,
563 SDValue(Result_1, 1));
564 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
565 MemOp[0] = LD->getMemOperand();
566 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
567 const SDValue Froms[] = { SDValue(LD, 0),
571 const SDValue Tos[] = { SDValue(Result_1, 0),
572 SDValue(Result_2, 0),
575 ReplaceUses(Froms, Tos, 3);
581 SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
583 DebugLoc dl = N->getDebugLoc();
584 LoadSDNode *LD = cast<LoadSDNode>(N);
585 ISD::MemIndexedMode AM = LD->getAddressingMode();
587 // Handle indexed loads.
588 if (AM != ISD::UNINDEXED) {
589 result = SelectIndexedLoad(LD, dl);
591 result = SelectBaseOffsetLoad(LD, dl);
598 SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) {
599 SDValue Chain = ST->getChain();
600 SDValue Base = ST->getBasePtr();
601 SDValue Offset = ST->getOffset();
602 SDValue Value = ST->getValue();
603 SDNode *OffsetNode = Offset.getNode();
604 // Get the constant value.
605 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
606 EVT StoredVT = ST->getMemoryVT();
608 // Offset value must be within representable range
609 // and must have correct alignment properties.
610 if (TII->isValidAutoIncImm(StoredVT, Val)) {
611 SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value,
615 // Figure out the post inc version of opcode.
616 if (StoredVT == MVT::i64) Opcode = Hexagon::POST_STdri;
617 else if (StoredVT == MVT::i32) Opcode = Hexagon::POST_STwri;
618 else if (StoredVT == MVT::i16) Opcode = Hexagon::POST_SThri;
619 else if (StoredVT == MVT::i8) Opcode = Hexagon::POST_STbri;
620 else llvm_unreachable("unknown memory type");
622 // Build post increment store.
623 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
625 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
626 MemOp[0] = ST->getMemOperand();
627 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
629 ReplaceUses(ST, Result);
630 ReplaceUses(SDValue(ST,1), SDValue(Result,1));
634 // Note: Order of operands matches the def of instruction:
635 // def STrid : STInst<(outs), (ins MEMri:$addr, DoubleRegs:$src1), ...
636 // and it differs for POST_ST* for instance.
637 SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value,
641 // Figure out the opcode.
642 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid;
643 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
644 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih;
645 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib;
646 else llvm_unreachable("unknown memory type");
648 // Build regular store.
649 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
650 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops,
652 // Build splitted incriment instruction.
653 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
656 SDValue(Result_1, 0));
657 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
658 MemOp[0] = ST->getMemOperand();
659 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
661 ReplaceUses(SDValue(ST,0), SDValue(Result_2,0));
662 ReplaceUses(SDValue(ST,1), SDValue(Result_1,0));
667 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
669 SDValue Chain = ST->getChain();
670 SDNode* Const32 = ST->getBasePtr().getNode();
671 SDValue Value = ST->getValue();
674 // Try to lower stores of GlobalAdresses into indexed stores. Custom
675 // lowering for GlobalAddress nodes has already turned it into a
676 // CONST32. Avoid truncating stores for the moment. Post-inc stores
677 // do the same. Don't think there's a reason for it, so will file a
679 if ((Const32->getOpcode() == HexagonISD::CONST32) &&
680 !(Value.getValueType() == MVT::i64 && ST->isTruncatingStore())) {
681 SDValue Base = Const32->getOperand(0);
682 if (Base.getOpcode() == ISD::TargetGlobalAddress) {
683 EVT StoredVT = ST->getMemoryVT();
684 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
685 if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) {
686 MVT PointerTy = TLI.getPointerTy();
687 const GlobalValue* GV =
688 cast<GlobalAddressSDNode>(Base)->getGlobal();
690 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
691 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
695 // Figure out base + offset opcode
696 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid_indexed;
697 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
698 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih_indexed;
699 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib_indexed;
700 else llvm_unreachable("unknown memory type");
702 SDValue Ops[] = {SDValue(NewBase,0),
703 CurDAG->getTargetConstant(Offset,PointerTy),
705 // build indexed store
706 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
708 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
709 MemOp[0] = ST->getMemOperand();
710 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
711 ReplaceUses(ST, Result);
717 return SelectCode(ST);
721 SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
722 DebugLoc dl = N->getDebugLoc();
723 StoreSDNode *ST = cast<StoreSDNode>(N);
724 ISD::MemIndexedMode AM = ST->getAddressingMode();
726 // Handle indexed stores.
727 if (AM != ISD::UNINDEXED) {
728 return SelectIndexedStore(ST, dl);
731 return SelectBaseOffsetStore(ST, dl);
734 SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
735 DebugLoc dl = N->getDebugLoc();
738 // %conv.i = sext i32 %tmp1 to i64
739 // %conv2.i = sext i32 %add to i64
740 // %mul.i = mul nsw i64 %conv2.i, %conv.i
742 // --- match with the following ---
744 // %mul.i = mpy (%tmp1, %add)
747 if (N->getValueType(0) == MVT::i64) {
748 // Shifting a i64 signed multiply.
749 SDValue MulOp0 = N->getOperand(0);
750 SDValue MulOp1 = N->getOperand(1);
755 // Handle sign_extend and sextload.
756 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
757 SDValue Sext0 = MulOp0.getOperand(0);
758 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
759 return SelectCode(N);
763 } else if (MulOp0.getOpcode() == ISD::LOAD) {
764 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
765 if (LD->getMemoryVT() != MVT::i32 ||
766 LD->getExtensionType() != ISD::SEXTLOAD ||
767 LD->getAddressingMode() != ISD::UNINDEXED) {
768 return SelectCode(N);
771 SDValue Chain = LD->getChain();
772 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
773 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
775 LD->getBasePtr(), TargetConst0,
778 return SelectCode(N);
781 // Same goes for the second operand.
782 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
783 SDValue Sext1 = MulOp1.getOperand(0);
784 if (Sext1.getNode()->getValueType(0) != MVT::i32) {
785 return SelectCode(N);
789 } else if (MulOp1.getOpcode() == ISD::LOAD) {
790 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
791 if (LD->getMemoryVT() != MVT::i32 ||
792 LD->getExtensionType() != ISD::SEXTLOAD ||
793 LD->getAddressingMode() != ISD::UNINDEXED) {
794 return SelectCode(N);
797 SDValue Chain = LD->getChain();
798 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
799 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
801 LD->getBasePtr(), TargetConst0,
804 return SelectCode(N);
807 // Generate a mpy instruction.
808 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY64, dl, MVT::i64,
810 ReplaceUses(N, Result);
814 return SelectCode(N);
818 SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) {
819 DebugLoc dl = N->getDebugLoc();
820 SDValue N0 = N->getOperand(0);
821 if (N0.getOpcode() == ISD::SETCC) {
822 SDValue N00 = N0.getOperand(0);
823 if (N00.getOpcode() == ISD::SIGN_EXTEND_INREG) {
824 SDValue N000 = N00.getOperand(0);
825 SDValue N001 = N00.getOperand(1);
826 if (cast<VTSDNode>(N001)->getVT() == MVT::i16) {
827 SDValue N01 = N0.getOperand(1);
828 SDValue N02 = N0.getOperand(2);
830 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
831 // i16:Other),IntRegs:i32:$src1, SETLT:Other),IntRegs:i32:$src1,
832 // IntRegs:i32:$src2)
833 // Emits: (MAXh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
834 // Pattern complexity = 9 cost = 1 size = 0.
835 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETLT) {
836 SDValue N1 = N->getOperand(1);
838 SDValue N2 = N->getOperand(2);
840 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
841 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
842 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
844 SDNode *Result = CurDAG->getMachineNode(Hexagon::MAXw_rr, dl,
846 SDValue(SextNode, 0),
848 ReplaceUses(N, Result);
854 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
855 // i16:Other), IntRegs:i32:$src1, SETGT:Other), IntRegs:i32:$src1,
856 // IntRegs:i32:$src2)
857 // Emits: (MINh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
858 // Pattern complexity = 9 cost = 1 size = 0.
859 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETGT) {
860 SDValue N1 = N->getOperand(1);
862 SDValue N2 = N->getOperand(2);
864 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
865 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
866 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
868 SDNode *Result = CurDAG->getMachineNode(Hexagon::MINw_rr, dl,
870 SDValue(SextNode, 0),
872 ReplaceUses(N, Result);
881 return SelectCode(N);
885 SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
886 DebugLoc dl = N->getDebugLoc();
887 SDValue Shift = N->getOperand(0);
890 // %conv.i = sext i32 %tmp1 to i64
891 // %conv2.i = sext i32 %add to i64
892 // %mul.i = mul nsw i64 %conv2.i, %conv.i
893 // %shr5.i = lshr i64 %mul.i, 32
894 // %conv3.i = trunc i64 %shr5.i to i32
896 // --- match with the following ---
898 // %conv3.i = mpy (%tmp1, %add)
901 if (N->getValueType(0) == MVT::i32) {
903 if (Shift.getNode()->getValueType(0) == MVT::i64) {
904 // Trunc child is logical shift right.
905 if (Shift.getOpcode() != ISD::SRL) {
906 return SelectCode(N);
909 SDValue ShiftOp0 = Shift.getOperand(0);
910 SDValue ShiftOp1 = Shift.getOperand(1);
913 if (ShiftOp1.getOpcode() != ISD::Constant) {
914 return SelectCode(N);
918 cast<ConstantSDNode>(ShiftOp1.getNode())->getSExtValue();
919 if (ShiftConst != 32) {
920 return SelectCode(N);
923 // Shifting a i64 signed multiply
924 SDValue Mul = ShiftOp0;
925 if (Mul.getOpcode() != ISD::MUL) {
926 return SelectCode(N);
929 SDValue MulOp0 = Mul.getOperand(0);
930 SDValue MulOp1 = Mul.getOperand(1);
935 // Handle sign_extend and sextload
936 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
937 SDValue Sext0 = MulOp0.getOperand(0);
938 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
939 return SelectCode(N);
943 } else if (MulOp0.getOpcode() == ISD::LOAD) {
944 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
945 if (LD->getMemoryVT() != MVT::i32 ||
946 LD->getExtensionType() != ISD::SEXTLOAD ||
947 LD->getAddressingMode() != ISD::UNINDEXED) {
948 return SelectCode(N);
951 SDValue Chain = LD->getChain();
952 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
953 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
956 TargetConst0, Chain), 0);
958 return SelectCode(N);
961 // Same goes for the second operand.
962 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
963 SDValue Sext1 = MulOp1.getOperand(0);
964 if (Sext1.getNode()->getValueType(0) != MVT::i32)
965 return SelectCode(N);
968 } else if (MulOp1.getOpcode() == ISD::LOAD) {
969 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
970 if (LD->getMemoryVT() != MVT::i32 ||
971 LD->getExtensionType() != ISD::SEXTLOAD ||
972 LD->getAddressingMode() != ISD::UNINDEXED) {
973 return SelectCode(N);
976 SDValue Chain = LD->getChain();
977 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
978 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
981 TargetConst0, Chain), 0);
983 return SelectCode(N);
986 // Generate a mpy instruction.
987 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY, dl, MVT::i32,
989 ReplaceUses(N, Result);
994 return SelectCode(N);
998 SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
999 DebugLoc dl = N->getDebugLoc();
1000 if (N->getValueType(0) == MVT::i32) {
1001 SDValue Shl_0 = N->getOperand(0);
1002 SDValue Shl_1 = N->getOperand(1);
1004 if (Shl_1.getOpcode() == ISD::Constant) {
1005 if (Shl_0.getOpcode() == ISD::MUL) {
1006 SDValue Mul_0 = Shl_0.getOperand(0); // Val
1007 SDValue Mul_1 = Shl_0.getOperand(1); // Const
1008 // RHS of mul is const.
1009 if (Mul_1.getOpcode() == ISD::Constant) {
1011 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1013 cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue();
1014 int32_t ValConst = MulConst << ShlConst;
1015 SDValue Val = CurDAG->getTargetConstant(ValConst,
1017 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode()))
1018 if (isInt<9>(CN->getSExtValue())) {
1020 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl,
1021 MVT::i32, Mul_0, Val);
1022 ReplaceUses(N, Result);
1027 } else if (Shl_0.getOpcode() == ISD::SUB) {
1028 SDValue Sub_0 = Shl_0.getOperand(0); // Const 0
1029 SDValue Sub_1 = Shl_0.getOperand(1); // Val
1030 if (Sub_0.getOpcode() == ISD::Constant) {
1032 cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue();
1033 if (SubConst == 0) {
1034 if (Sub_1.getOpcode() == ISD::SHL) {
1035 SDValue Shl2_0 = Sub_1.getOperand(0); // Val
1036 SDValue Shl2_1 = Sub_1.getOperand(1); // Const
1037 if (Shl2_1.getOpcode() == ISD::Constant) {
1039 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1041 cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue();
1042 int32_t ValConst = 1 << (ShlConst+Shl2Const);
1043 SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32);
1044 if (ConstantSDNode *CN =
1045 dyn_cast<ConstantSDNode>(Val.getNode()))
1046 if (isInt<9>(CN->getSExtValue())) {
1048 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl, MVT::i32,
1050 ReplaceUses(N, Result);
1060 return SelectCode(N);
1065 // If there is an zero_extend followed an intrinsic in DAG (this means - the
1066 // result of the intrinsic is predicate); convert the zero_extend to
1067 // transfer instruction.
1069 // Zero extend -> transfer is lowered here. Otherwise, zero_extend will be
1070 // converted into a MUX as predicate registers defined as 1 bit in the
1071 // compiler. Architecture defines them as 8-bit registers.
1072 // We want to preserve all the lower 8-bits and, not just 1 LSB bit.
1074 SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
1075 DebugLoc dl = N->getDebugLoc();
1076 SDNode *IsIntrinsic = N->getOperand(0).getNode();
1077 if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
1079 cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue();
1080 if (doesIntrinsicReturnPredicate(ID)) {
1081 // Now we need to differentiate target data types.
1082 if (N->getValueType(0) == MVT::i64) {
1083 // Convert the zero_extend to Rs = Pd followed by COMBINE_rr(0,Rs).
1084 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1085 SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
1087 SDValue(IsIntrinsic, 0));
1088 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl,
1091 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
1092 MVT::i64, MVT::Other,
1093 SDValue(Result_2, 0),
1094 SDValue(Result_1, 0));
1095 ReplaceUses(N, Result_3);
1098 if (N->getValueType(0) == MVT::i32) {
1099 // Convert the zero_extend to Rs = Pd
1100 SDNode* RsPd = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
1102 SDValue(IsIntrinsic, 0));
1103 ReplaceUses(N, RsPd);
1106 llvm_unreachable("Unexpected value type");
1109 return SelectCode(N);
1114 // Checking for intrinsics which have predicate registers as operand(s)
1115 // and lowering to the actual intrinsic.
1117 SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
1118 DebugLoc dl = N->getDebugLoc();
1119 unsigned ID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
1120 unsigned IntrinsicWithPred = doesIntrinsicContainPredicate(ID);
1122 // We are concerned with only those intrinsics that have predicate registers
1123 // as at least one of the operands.
1124 if (IntrinsicWithPred) {
1125 SmallVector<SDValue, 8> Ops;
1126 const MCInstrDesc &MCID = TII->get(IntrinsicWithPred);
1127 const TargetRegisterInfo *TRI = TM.getRegisterInfo();
1129 // Iterate over all the operands of the intrinsics.
1130 // For PredRegs, do the transfer.
1131 // For Double/Int Regs, just preserve the value
1132 // For immediates, lower it.
1133 for (unsigned i = 1; i < N->getNumOperands(); ++i) {
1134 SDNode *Arg = N->getOperand(i).getNode();
1135 const TargetRegisterClass *RC = TII->getRegClass(MCID, i, TRI, *MF);
1137 if (RC == &Hexagon::IntRegsRegClass ||
1138 RC == &Hexagon::DoubleRegsRegClass) {
1139 Ops.push_back(SDValue(Arg, 0));
1140 } else if (RC == &Hexagon::PredRegsRegClass) {
1142 SDNode *PdRs = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
1144 Ops.push_back(SDValue(PdRs,0));
1145 } else if (RC == NULL && (dyn_cast<ConstantSDNode>(Arg) != NULL)) {
1146 // This is immediate operand. Lower it here making sure that we DO have
1147 // const SDNode for immediate value.
1148 int32_t Val = cast<ConstantSDNode>(Arg)->getSExtValue();
1149 SDValue SDVal = CurDAG->getTargetConstant(Val, MVT::i32);
1150 Ops.push_back(SDVal);
1152 llvm_unreachable("Unimplemented");
1155 EVT ReturnValueVT = N->getValueType(0);
1156 SDNode *Result = CurDAG->getMachineNode(IntrinsicWithPred, dl,
1158 Ops.data(), Ops.size());
1159 ReplaceUses(N, Result);
1162 return SelectCode(N);
1166 // Map floating point constant values.
1168 SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
1169 DebugLoc dl = N->getDebugLoc();
1170 ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
1171 APFloat APF = CN->getValueAPF();
1172 if (N->getValueType(0) == MVT::f32) {
1173 return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32,
1174 CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32));
1176 else if (N->getValueType(0) == MVT::f64) {
1177 return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64,
1178 CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64));
1181 return SelectCode(N);
1186 // Map predicate true (encoded as -1 in LLVM) to a XOR.
1188 SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
1189 DebugLoc dl = N->getDebugLoc();
1190 if (N->getValueType(0) == MVT::i1) {
1192 int32_t Val = cast<ConstantSDNode>(N)->getSExtValue();
1194 // Create the IntReg = 1 node.
1196 CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
1197 CurDAG->getTargetConstant(0, MVT::i32));
1200 SDNode* Pd = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
1201 SDValue(IntRegTFR, 0));
1204 SDNode* NotPd = CurDAG->getMachineNode(Hexagon::NOT_p, dl, MVT::i1,
1208 Result = CurDAG->getMachineNode(Hexagon::XOR_pp, dl, MVT::i1,
1209 SDValue(Pd, 0), SDValue(NotPd, 0));
1211 // We have just built:
1213 // Pd = xor(not(Pd), Pd)
1215 ReplaceUses(N, Result);
1220 return SelectCode(N);
1225 // Map add followed by a asr -> asr +=.
1227 SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
1228 DebugLoc dl = N->getDebugLoc();
1229 if (N->getValueType(0) != MVT::i32) {
1230 return SelectCode(N);
1232 // Identify nodes of the form: add(asr(...)).
1233 SDNode* Src1 = N->getOperand(0).getNode();
1234 if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse()
1235 || Src1->getValueType(0) != MVT::i32) {
1236 return SelectCode(N);
1239 // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that
1240 // Rd and Rd' are assigned to the same register
1241 SDNode* Result = CurDAG->getMachineNode(Hexagon::ASR_ADD_rr, dl, MVT::i32,
1243 Src1->getOperand(0),
1244 Src1->getOperand(1));
1245 ReplaceUses(N, Result);
1251 SDNode *HexagonDAGToDAGISel::Select(SDNode *N) {
1252 if (N->isMachineOpcode())
1253 return NULL; // Already selected.
1256 switch (N->getOpcode()) {
1258 return SelectConstant(N);
1260 case ISD::ConstantFP:
1261 return SelectConstantFP(N);
1264 return SelectAdd(N);
1267 return SelectSHL(N);
1270 return SelectLoad(N);
1273 return SelectStore(N);
1276 return SelectSelect(N);
1279 return SelectTruncate(N);
1282 return SelectMul(N);
1284 case ISD::ZERO_EXTEND:
1285 return SelectZeroExtend(N);
1287 case ISD::INTRINSIC_WO_CHAIN:
1288 return SelectIntrinsicWOChain(N);
1291 return SelectCode(N);
1296 // Hexagon_TODO: Five functions for ADDRri?! Surely there must be a better way
1297 // to define these instructions.
1299 bool HexagonDAGToDAGISel::SelectADDRri(SDValue& Addr, SDValue &Base,
1301 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1302 Addr.getOpcode() == ISD::TargetGlobalAddress)
1303 return false; // Direct calls.
1305 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1306 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1307 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1311 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1316 bool HexagonDAGToDAGISel::SelectADDRriS11_0(SDValue& Addr, SDValue &Base,
1318 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1319 Addr.getOpcode() == ISD::TargetGlobalAddress)
1320 return false; // Direct calls.
1322 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1323 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1324 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1325 return (IsS11_0_Offset(Offset.getNode()));
1328 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1329 return (IsS11_0_Offset(Offset.getNode()));
1333 bool HexagonDAGToDAGISel::SelectADDRriS11_1(SDValue& Addr, SDValue &Base,
1335 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1336 Addr.getOpcode() == ISD::TargetGlobalAddress)
1337 return false; // Direct calls.
1339 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1340 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1341 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1342 return (IsS11_1_Offset(Offset.getNode()));
1345 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1346 return (IsS11_1_Offset(Offset.getNode()));
1350 bool HexagonDAGToDAGISel::SelectADDRriS11_2(SDValue& Addr, SDValue &Base,
1352 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1353 Addr.getOpcode() == ISD::TargetGlobalAddress)
1354 return false; // Direct calls.
1356 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1357 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1358 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1359 return (IsS11_2_Offset(Offset.getNode()));
1362 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1363 return (IsS11_2_Offset(Offset.getNode()));
1367 bool HexagonDAGToDAGISel::SelectADDRriU6_0(SDValue& Addr, SDValue &Base,
1369 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1370 Addr.getOpcode() == ISD::TargetGlobalAddress)
1371 return false; // Direct calls.
1373 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1374 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1375 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1376 return (IsU6_0_Offset(Offset.getNode()));
1379 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1380 return (IsU6_0_Offset(Offset.getNode()));
1384 bool HexagonDAGToDAGISel::SelectADDRriU6_1(SDValue& Addr, SDValue &Base,
1386 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1387 Addr.getOpcode() == ISD::TargetGlobalAddress)
1388 return false; // Direct calls.
1390 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1391 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1392 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1393 return (IsU6_1_Offset(Offset.getNode()));
1396 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1397 return (IsU6_1_Offset(Offset.getNode()));
1401 bool HexagonDAGToDAGISel::SelectADDRriU6_2(SDValue& Addr, SDValue &Base,
1403 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1404 Addr.getOpcode() == ISD::TargetGlobalAddress)
1405 return false; // Direct calls.
1407 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1408 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1409 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1410 return (IsU6_2_Offset(Offset.getNode()));
1413 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1414 return (IsU6_2_Offset(Offset.getNode()));
1418 bool HexagonDAGToDAGISel::SelectMEMriS11_2(SDValue& Addr, SDValue &Base,
1421 if (Addr.getOpcode() != ISD::ADD) {
1422 return(SelectADDRriS11_2(Addr, Base, Offset));
1425 return SelectADDRriS11_2(Addr, Base, Offset);
1429 bool HexagonDAGToDAGISel::SelectADDRriS11_3(SDValue& Addr, SDValue &Base,
1431 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1432 Addr.getOpcode() == ISD::TargetGlobalAddress)
1433 return false; // Direct calls.
1435 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1436 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1437 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1438 return (IsS11_3_Offset(Offset.getNode()));
1441 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1442 return (IsS11_3_Offset(Offset.getNode()));
1445 bool HexagonDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1,
1447 if (Addr.getOpcode() == ISD::FrameIndex) return false;
1448 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1449 Addr.getOpcode() == ISD::TargetGlobalAddress)
1450 return false; // Direct calls.
1452 if (Addr.getOpcode() == ISD::ADD) {
1453 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
1454 if (isInt<13>(CN->getSExtValue()))
1455 return false; // Let the reg+imm pattern catch this!
1456 R1 = Addr.getOperand(0);
1457 R2 = Addr.getOperand(1);
1467 // Handle generic address case. It is accessed from inlined asm =m constraints,
1468 // which could have any kind of pointer.
1469 bool HexagonDAGToDAGISel::SelectAddr(SDNode *Op, SDValue Addr,
1470 SDValue &Base, SDValue &Offset) {
1471 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1472 Addr.getOpcode() == ISD::TargetGlobalAddress)
1473 return false; // Direct calls.
1475 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1476 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1477 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1481 if (Addr.getOpcode() == ISD::ADD) {
1482 Base = Addr.getOperand(0);
1483 Offset = Addr.getOperand(1);
1488 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1493 bool HexagonDAGToDAGISel::
1494 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
1495 std::vector<SDValue> &OutOps) {
1498 switch (ConstraintCode) {
1499 case 'o': // Offsetable.
1500 case 'v': // Not offsetable.
1501 default: return true;
1502 case 'm': // Memory.
1503 if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
1508 OutOps.push_back(Op0);
1509 OutOps.push_back(Op1);
1513 bool HexagonDAGToDAGISel::isConstExtProfitable(SDNode *N) const {
1514 unsigned UseCount = 0;
1515 for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
1519 return (UseCount <= 1);