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/ADT/DenseMap.h"
19 #include "llvm/IR/Intrinsics.h"
20 #include "llvm/CodeGen/SelectionDAGISel.h"
21 #include "llvm/Support/CommandLine.h"
22 #include "llvm/Support/Compiler.h"
23 #include "llvm/Support/Debug.h"
28 MaxNumOfUsesForConstExtenders("ga-max-num-uses-for-constant-extenders",
29 cl::Hidden, cl::init(2),
30 cl::desc("Maximum number of uses of a global address such that we still us a"
31 "constant extended instruction"));
33 //===----------------------------------------------------------------------===//
34 // Instruction Selector Implementation
35 //===----------------------------------------------------------------------===//
38 void initializeHexagonDAGToDAGISelPass(PassRegistry&);
41 //===--------------------------------------------------------------------===//
42 /// HexagonDAGToDAGISel - Hexagon specific code to select Hexagon machine
43 /// instructions for SelectionDAG operations.
46 class HexagonDAGToDAGISel : public SelectionDAGISel {
47 /// Subtarget - Keep a pointer to the Hexagon Subtarget around so that we can
48 /// make the right decision when generating code for different targets.
49 const HexagonSubtarget &Subtarget;
51 // Keep a reference to HexagonTargetMachine.
52 HexagonTargetMachine& TM;
53 const HexagonInstrInfo *TII;
54 DenseMap<const GlobalValue *, unsigned> GlobalAddressUseCountMap;
56 explicit HexagonDAGToDAGISel(HexagonTargetMachine &targetmachine,
57 CodeGenOpt::Level OptLevel)
58 : SelectionDAGISel(targetmachine, OptLevel),
59 Subtarget(targetmachine.getSubtarget<HexagonSubtarget>()),
61 TII(static_cast<const HexagonInstrInfo*>(TM.getInstrInfo())) {
62 initializeHexagonDAGToDAGISelPass(*PassRegistry::getPassRegistry());
64 bool hasNumUsesBelowThresGA(SDNode *N) const;
66 SDNode *Select(SDNode *N);
68 // Complex Pattern Selectors.
69 inline bool foldGlobalAddress(SDValue &N, SDValue &R);
70 inline bool foldGlobalAddressGP(SDValue &N, SDValue &R);
71 bool foldGlobalAddressImpl(SDValue &N, SDValue &R, bool ShouldLookForGP);
72 bool SelectADDRri(SDValue& N, SDValue &R1, SDValue &R2);
73 bool SelectADDRriS11_0(SDValue& N, SDValue &R1, SDValue &R2);
74 bool SelectADDRriS11_1(SDValue& N, SDValue &R1, SDValue &R2);
75 bool SelectADDRriS11_2(SDValue& N, SDValue &R1, SDValue &R2);
76 bool SelectMEMriS11_2(SDValue& Addr, SDValue &Base, SDValue &Offset);
77 bool SelectADDRriS11_3(SDValue& N, SDValue &R1, SDValue &R2);
78 bool SelectADDRrr(SDValue &Addr, SDValue &Base, SDValue &Offset);
79 bool SelectADDRriU6_0(SDValue& N, SDValue &R1, SDValue &R2);
80 bool SelectADDRriU6_1(SDValue& N, SDValue &R1, SDValue &R2);
81 bool SelectADDRriU6_2(SDValue& N, SDValue &R1, SDValue &R2);
83 virtual const char *getPassName() const {
84 return "Hexagon DAG->DAG Pattern Instruction Selection";
87 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
88 /// inline asm expressions.
89 virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
91 std::vector<SDValue> &OutOps);
92 bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset);
94 SDNode *SelectLoad(SDNode *N);
95 SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl);
96 SDNode *SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl);
97 SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode,
99 SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode,
101 SDNode *SelectBaseOffsetStore(StoreSDNode *ST, DebugLoc dl);
102 SDNode *SelectIndexedStore(StoreSDNode *ST, DebugLoc dl);
103 SDNode *SelectStore(SDNode *N);
104 SDNode *SelectSHL(SDNode *N);
105 SDNode *SelectSelect(SDNode *N);
106 SDNode *SelectTruncate(SDNode *N);
107 SDNode *SelectMul(SDNode *N);
108 SDNode *SelectZeroExtend(SDNode *N);
109 SDNode *SelectIntrinsicWOChain(SDNode *N);
110 SDNode *SelectIntrinsicWChain(SDNode *N);
111 SDNode *SelectConstant(SDNode *N);
112 SDNode *SelectConstantFP(SDNode *N);
113 SDNode *SelectAdd(SDNode *N);
114 bool isConstExtProfitable(SDNode *N) const;
116 // XformU7ToU7M1Imm - Return a target constant decremented by 1, in range
117 // [1..128], used in cmpb.gtu instructions.
118 inline SDValue XformU7ToU7M1Imm(signed Imm) {
119 assert((Imm >= 1 && Imm <= 128) && "Constant out of range for cmpb op");
120 return CurDAG->getTargetConstant(Imm - 1, MVT::i8);
123 // Include the pieces autogenerated from the target description.
124 #include "HexagonGenDAGISel.inc"
126 } // end anonymous namespace
129 /// createHexagonISelDag - This pass converts a legalized DAG into a
130 /// Hexagon-specific DAG, ready for instruction scheduling.
132 FunctionPass *llvm::createHexagonISelDag(HexagonTargetMachine &TM,
133 CodeGenOpt::Level OptLevel) {
134 return new HexagonDAGToDAGISel(TM, OptLevel);
137 static void initializePassOnce(PassRegistry &Registry) {
138 const char *Name = "Hexagon DAG->DAG Pattern Instruction Selection";
139 PassInfo *PI = new PassInfo(Name, "hexagon-isel",
140 &SelectionDAGISel::ID, 0, false, false);
141 Registry.registerPass(*PI, true);
144 void llvm::initializeHexagonDAGToDAGISelPass(PassRegistry &Registry) {
145 CALL_ONCE_INITIALIZATION(initializePassOnce)
149 static bool IsS11_0_Offset(SDNode * S) {
150 ConstantSDNode *N = cast<ConstantSDNode>(S);
152 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
154 int64_t v = (int64_t)N->getSExtValue();
159 static bool IsS11_1_Offset(SDNode * S) {
160 ConstantSDNode *N = cast<ConstantSDNode>(S);
162 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
164 int64_t v = (int64_t)N->getSExtValue();
165 return isShiftedInt<11,1>(v);
169 static bool IsS11_2_Offset(SDNode * S) {
170 ConstantSDNode *N = cast<ConstantSDNode>(S);
172 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
174 int64_t v = (int64_t)N->getSExtValue();
175 return isShiftedInt<11,2>(v);
179 static bool IsS11_3_Offset(SDNode * S) {
180 ConstantSDNode *N = cast<ConstantSDNode>(S);
182 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
184 int64_t v = (int64_t)N->getSExtValue();
185 return isShiftedInt<11,3>(v);
189 static bool IsU6_0_Offset(SDNode * S) {
190 ConstantSDNode *N = cast<ConstantSDNode>(S);
192 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
194 int64_t v = (int64_t)N->getSExtValue();
199 static bool IsU6_1_Offset(SDNode * S) {
200 ConstantSDNode *N = cast<ConstantSDNode>(S);
202 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
204 int64_t v = (int64_t)N->getSExtValue();
205 return isShiftedUInt<6,1>(v);
209 static bool IsU6_2_Offset(SDNode * S) {
210 ConstantSDNode *N = cast<ConstantSDNode>(S);
212 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
214 int64_t v = (int64_t)N->getSExtValue();
215 return isShiftedUInt<6,2>(v);
219 // Intrinsics that return a a predicate.
220 static unsigned doesIntrinsicReturnPredicate(unsigned ID)
225 case Intrinsic::hexagon_C2_cmpeq:
226 case Intrinsic::hexagon_C2_cmpgt:
227 case Intrinsic::hexagon_C2_cmpgtu:
228 case Intrinsic::hexagon_C2_cmpgtup:
229 case Intrinsic::hexagon_C2_cmpgtp:
230 case Intrinsic::hexagon_C2_cmpeqp:
231 case Intrinsic::hexagon_C2_bitsset:
232 case Intrinsic::hexagon_C2_bitsclr:
233 case Intrinsic::hexagon_C2_cmpeqi:
234 case Intrinsic::hexagon_C2_cmpgti:
235 case Intrinsic::hexagon_C2_cmpgtui:
236 case Intrinsic::hexagon_C2_cmpgei:
237 case Intrinsic::hexagon_C2_cmpgeui:
238 case Intrinsic::hexagon_C2_cmplt:
239 case Intrinsic::hexagon_C2_cmpltu:
240 case Intrinsic::hexagon_C2_bitsclri:
241 case Intrinsic::hexagon_C2_and:
242 case Intrinsic::hexagon_C2_or:
243 case Intrinsic::hexagon_C2_xor:
244 case Intrinsic::hexagon_C2_andn:
245 case Intrinsic::hexagon_C2_not:
246 case Intrinsic::hexagon_C2_orn:
247 case Intrinsic::hexagon_C2_pxfer_map:
248 case Intrinsic::hexagon_C2_any8:
249 case Intrinsic::hexagon_C2_all8:
250 case Intrinsic::hexagon_A2_vcmpbeq:
251 case Intrinsic::hexagon_A2_vcmpbgtu:
252 case Intrinsic::hexagon_A2_vcmpheq:
253 case Intrinsic::hexagon_A2_vcmphgt:
254 case Intrinsic::hexagon_A2_vcmphgtu:
255 case Intrinsic::hexagon_A2_vcmpweq:
256 case Intrinsic::hexagon_A2_vcmpwgt:
257 case Intrinsic::hexagon_A2_vcmpwgtu:
258 case Intrinsic::hexagon_C2_tfrrp:
259 case Intrinsic::hexagon_S2_tstbit_i:
260 case Intrinsic::hexagon_S2_tstbit_r:
266 // Intrinsics that have predicate operands.
267 static unsigned doesIntrinsicContainPredicate(unsigned ID)
272 case Intrinsic::hexagon_C2_tfrpr:
273 return Hexagon::TFR_RsPd;
274 case Intrinsic::hexagon_C2_and:
275 return Hexagon::AND_pp;
276 case Intrinsic::hexagon_C2_xor:
277 return Hexagon::XOR_pp;
278 case Intrinsic::hexagon_C2_or:
279 return Hexagon::OR_pp;
280 case Intrinsic::hexagon_C2_not:
281 return Hexagon::NOT_p;
282 case Intrinsic::hexagon_C2_any8:
283 return Hexagon::ANY_pp;
284 case Intrinsic::hexagon_C2_all8:
285 return Hexagon::ALL_pp;
286 case Intrinsic::hexagon_C2_vitpack:
287 return Hexagon::VITPACK_pp;
288 case Intrinsic::hexagon_C2_mask:
289 return Hexagon::MASK_p;
290 case Intrinsic::hexagon_C2_mux:
291 return Hexagon::MUX_rr;
293 // Mapping hexagon_C2_muxir to MUX_pri. This is pretty weird - but
294 // that's how it's mapped in q6protos.h.
295 case Intrinsic::hexagon_C2_muxir:
296 return Hexagon::MUX_ri;
298 // Mapping hexagon_C2_muxri to MUX_pir. This is pretty weird - but
299 // that's how it's mapped in q6protos.h.
300 case Intrinsic::hexagon_C2_muxri:
301 return Hexagon::MUX_ir;
303 case Intrinsic::hexagon_C2_muxii:
304 return Hexagon::MUX_ii;
305 case Intrinsic::hexagon_C2_vmux:
306 return Hexagon::VMUX_prr64;
307 case Intrinsic::hexagon_S2_valignrb:
308 return Hexagon::VALIGN_rrp;
309 case Intrinsic::hexagon_S2_vsplicerb:
310 return Hexagon::VSPLICE_rrp;
315 static bool OffsetFitsS11(EVT MemType, int64_t Offset) {
316 if (MemType == MVT::i64 && isShiftedInt<11,3>(Offset)) {
319 if (MemType == MVT::i32 && isShiftedInt<11,2>(Offset)) {
322 if (MemType == MVT::i16 && isShiftedInt<11,1>(Offset)) {
325 if (MemType == MVT::i8 && isInt<11>(Offset)) {
333 // Try to lower loads of GlobalAdresses into base+offset loads. Custom
334 // lowering for GlobalAddress nodes has already turned it into a
337 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl) {
338 SDValue Chain = LD->getChain();
339 SDNode* Const32 = LD->getBasePtr().getNode();
342 if (Const32->getOpcode() == HexagonISD::CONST32 &&
343 ISD::isNormalLoad(LD)) {
344 SDValue Base = Const32->getOperand(0);
345 EVT LoadedVT = LD->getMemoryVT();
346 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
347 if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) {
348 MVT PointerTy = TLI.getPointerTy();
349 const GlobalValue* GV =
350 cast<GlobalAddressSDNode>(Base)->getGlobal();
352 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
353 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
356 // Figure out base + offset opcode
357 if (LoadedVT == MVT::i64) Opcode = Hexagon::LDrid_indexed;
358 else if (LoadedVT == MVT::i32) Opcode = Hexagon::LDriw_indexed;
359 else if (LoadedVT == MVT::i16) Opcode = Hexagon::LDrih_indexed;
360 else if (LoadedVT == MVT::i8) Opcode = Hexagon::LDrib_indexed;
361 else llvm_unreachable("unknown memory type");
363 // Build indexed load.
364 SDValue TargetConstOff = CurDAG->getTargetConstant(Offset, PointerTy);
365 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
371 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
372 MemOp[0] = LD->getMemOperand();
373 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
374 ReplaceUses(LD, Result);
379 return SelectCode(LD);
383 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
387 SDValue Chain = LD->getChain();
388 EVT LoadedVT = LD->getMemoryVT();
389 SDValue Base = LD->getBasePtr();
390 SDValue Offset = LD->getOffset();
391 SDNode *OffsetNode = Offset.getNode();
392 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
393 SDValue N1 = LD->getOperand(1);
396 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
397 N1.getNode()->getValueType(0) == MVT::i32) {
398 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
399 SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
400 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
401 MVT::Other, Base, TargetConst,
403 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, MVT::i64,
404 SDValue(Result_1, 0));
405 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
406 MemOp[0] = LD->getMemOperand();
407 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
408 const SDValue Froms[] = { SDValue(LD, 0),
412 const SDValue Tos[] = { SDValue(Result_2, 0),
413 SDValue(Result_1, 1),
416 ReplaceUses(Froms, Tos, 3);
419 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
420 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
421 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
422 MVT::Other, Base, TargetConst0,
424 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl,
425 MVT::i64, SDValue(Result_1, 0));
426 SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl,
427 MVT::i32, Base, TargetConstVal,
428 SDValue(Result_1, 1));
429 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
430 MemOp[0] = LD->getMemOperand();
431 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
432 const SDValue Froms[] = { SDValue(LD, 0),
436 const SDValue Tos[] = { SDValue(Result_2, 0),
437 SDValue(Result_3, 0),
440 ReplaceUses(Froms, Tos, 3);
443 return SelectCode(LD);
447 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
451 SDValue Chain = LD->getChain();
452 EVT LoadedVT = LD->getMemoryVT();
453 SDValue Base = LD->getBasePtr();
454 SDValue Offset = LD->getOffset();
455 SDNode *OffsetNode = Offset.getNode();
456 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
457 SDValue N1 = LD->getOperand(1);
460 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
461 N1.getNode()->getValueType(0) == MVT::i32) {
462 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
463 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
464 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
465 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
466 MVT::i32, MVT::Other, Base,
467 TargetConstVal, Chain);
468 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
470 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
471 MVT::i64, MVT::Other,
473 SDValue(Result_1,0));
474 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
475 MemOp[0] = LD->getMemOperand();
476 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
477 const SDValue Froms[] = { SDValue(LD, 0),
481 const SDValue Tos[] = { SDValue(Result_3, 0),
482 SDValue(Result_1, 1),
485 ReplaceUses(Froms, Tos, 3);
489 // Generate an indirect load.
490 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
491 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
492 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
494 Base, TargetConst0, Chain);
495 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
497 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
498 MVT::i64, MVT::Other,
500 SDValue(Result_1,0));
501 // Add offset to base.
502 SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
503 Base, TargetConstVal,
504 SDValue(Result_1, 1));
505 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
506 MemOp[0] = LD->getMemOperand();
507 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
508 const SDValue Froms[] = { SDValue(LD, 0),
512 const SDValue Tos[] = { SDValue(Result_3, 0), // Load value.
513 SDValue(Result_4, 0), // New address.
516 ReplaceUses(Froms, Tos, 3);
520 return SelectCode(LD);
524 SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl) {
525 SDValue Chain = LD->getChain();
526 SDValue Base = LD->getBasePtr();
527 SDValue Offset = LD->getOffset();
528 SDNode *OffsetNode = Offset.getNode();
529 // Get the constant value.
530 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
531 EVT LoadedVT = LD->getMemoryVT();
534 // Check for zero ext loads.
535 bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD);
537 // Figure out the opcode.
538 if (LoadedVT == MVT::i64) {
539 if (TII->isValidAutoIncImm(LoadedVT, Val))
540 Opcode = Hexagon::POST_LDrid;
542 Opcode = Hexagon::LDrid;
543 } else if (LoadedVT == MVT::i32) {
544 if (TII->isValidAutoIncImm(LoadedVT, Val))
545 Opcode = Hexagon::POST_LDriw;
547 Opcode = Hexagon::LDriw;
548 } else if (LoadedVT == MVT::i16) {
549 if (TII->isValidAutoIncImm(LoadedVT, Val))
550 Opcode = zextval ? Hexagon::POST_LDriuh : Hexagon::POST_LDrih;
552 Opcode = zextval ? Hexagon::LDriuh : Hexagon::LDrih;
553 } else if (LoadedVT == MVT::i8) {
554 if (TII->isValidAutoIncImm(LoadedVT, Val))
555 Opcode = zextval ? Hexagon::POST_LDriub : Hexagon::POST_LDrib;
557 Opcode = zextval ? Hexagon::LDriub : Hexagon::LDrib;
559 llvm_unreachable("unknown memory type");
561 // For zero ext i64 loads, we need to add combine instructions.
562 if (LD->getValueType(0) == MVT::i64 &&
563 LD->getExtensionType() == ISD::ZEXTLOAD) {
564 return SelectIndexedLoadZeroExtend64(LD, Opcode, dl);
566 if (LD->getValueType(0) == MVT::i64 &&
567 LD->getExtensionType() == ISD::SEXTLOAD) {
568 // Handle sign ext i64 loads.
569 return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
571 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
572 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
573 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
575 MVT::i32, MVT::Other, Base,
576 TargetConstVal, Chain);
577 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
578 MemOp[0] = LD->getMemOperand();
579 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
580 const SDValue Froms[] = { SDValue(LD, 0),
584 const SDValue Tos[] = { SDValue(Result, 0),
588 ReplaceUses(Froms, Tos, 3);
591 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
592 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
593 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl,
595 MVT::Other, Base, TargetConst0,
597 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
598 Base, TargetConstVal,
599 SDValue(Result_1, 1));
600 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
601 MemOp[0] = LD->getMemOperand();
602 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
603 const SDValue Froms[] = { SDValue(LD, 0),
607 const SDValue Tos[] = { SDValue(Result_1, 0),
608 SDValue(Result_2, 0),
611 ReplaceUses(Froms, Tos, 3);
617 SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
619 DebugLoc dl = N->getDebugLoc();
620 LoadSDNode *LD = cast<LoadSDNode>(N);
621 ISD::MemIndexedMode AM = LD->getAddressingMode();
623 // Handle indexed loads.
624 if (AM != ISD::UNINDEXED) {
625 result = SelectIndexedLoad(LD, dl);
627 result = SelectBaseOffsetLoad(LD, dl);
634 SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) {
635 SDValue Chain = ST->getChain();
636 SDValue Base = ST->getBasePtr();
637 SDValue Offset = ST->getOffset();
638 SDValue Value = ST->getValue();
639 SDNode *OffsetNode = Offset.getNode();
640 // Get the constant value.
641 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
642 EVT StoredVT = ST->getMemoryVT();
644 // Offset value must be within representable range
645 // and must have correct alignment properties.
646 if (TII->isValidAutoIncImm(StoredVT, Val)) {
647 SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value,
651 // Figure out the post inc version of opcode.
652 if (StoredVT == MVT::i64) Opcode = Hexagon::POST_STdri;
653 else if (StoredVT == MVT::i32) Opcode = Hexagon::POST_STwri;
654 else if (StoredVT == MVT::i16) Opcode = Hexagon::POST_SThri;
655 else if (StoredVT == MVT::i8) Opcode = Hexagon::POST_STbri;
656 else llvm_unreachable("unknown memory type");
658 // Build post increment store.
659 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
661 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
662 MemOp[0] = ST->getMemOperand();
663 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
665 ReplaceUses(ST, Result);
666 ReplaceUses(SDValue(ST,1), SDValue(Result,1));
670 // Note: Order of operands matches the def of instruction:
671 // def STrid : STInst<(outs), (ins MEMri:$addr, DoubleRegs:$src1), ...
672 // and it differs for POST_ST* for instance.
673 SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value,
677 // Figure out the opcode.
678 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid;
679 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
680 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih;
681 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib;
682 else llvm_unreachable("unknown memory type");
684 // Build regular store.
685 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
686 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops,
688 // Build splitted incriment instruction.
689 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
692 SDValue(Result_1, 0));
693 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
694 MemOp[0] = ST->getMemOperand();
695 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
697 ReplaceUses(SDValue(ST,0), SDValue(Result_2,0));
698 ReplaceUses(SDValue(ST,1), SDValue(Result_1,0));
703 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
705 SDValue Chain = ST->getChain();
706 SDNode* Const32 = ST->getBasePtr().getNode();
707 SDValue Value = ST->getValue();
710 // Try to lower stores of GlobalAdresses into indexed stores. Custom
711 // lowering for GlobalAddress nodes has already turned it into a
712 // CONST32. Avoid truncating stores for the moment. Post-inc stores
713 // do the same. Don't think there's a reason for it, so will file a
715 if ((Const32->getOpcode() == HexagonISD::CONST32) &&
716 !(Value.getValueType() == MVT::i64 && ST->isTruncatingStore())) {
717 SDValue Base = Const32->getOperand(0);
718 if (Base.getOpcode() == ISD::TargetGlobalAddress) {
719 EVT StoredVT = ST->getMemoryVT();
720 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
721 if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) {
722 MVT PointerTy = TLI.getPointerTy();
723 const GlobalValue* GV =
724 cast<GlobalAddressSDNode>(Base)->getGlobal();
726 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
727 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
731 // Figure out base + offset opcode
732 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid_indexed;
733 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
734 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih_indexed;
735 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib_indexed;
736 else llvm_unreachable("unknown memory type");
738 SDValue Ops[] = {SDValue(NewBase,0),
739 CurDAG->getTargetConstant(Offset,PointerTy),
741 // build indexed store
742 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
744 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
745 MemOp[0] = ST->getMemOperand();
746 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
747 ReplaceUses(ST, Result);
753 return SelectCode(ST);
757 SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
758 DebugLoc dl = N->getDebugLoc();
759 StoreSDNode *ST = cast<StoreSDNode>(N);
760 ISD::MemIndexedMode AM = ST->getAddressingMode();
762 // Handle indexed stores.
763 if (AM != ISD::UNINDEXED) {
764 return SelectIndexedStore(ST, dl);
767 return SelectBaseOffsetStore(ST, dl);
770 SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
771 DebugLoc dl = N->getDebugLoc();
774 // %conv.i = sext i32 %tmp1 to i64
775 // %conv2.i = sext i32 %add to i64
776 // %mul.i = mul nsw i64 %conv2.i, %conv.i
778 // --- match with the following ---
780 // %mul.i = mpy (%tmp1, %add)
783 if (N->getValueType(0) == MVT::i64) {
784 // Shifting a i64 signed multiply.
785 SDValue MulOp0 = N->getOperand(0);
786 SDValue MulOp1 = N->getOperand(1);
791 // Handle sign_extend and sextload.
792 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
793 SDValue Sext0 = MulOp0.getOperand(0);
794 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
795 return SelectCode(N);
799 } else if (MulOp0.getOpcode() == ISD::LOAD) {
800 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
801 if (LD->getMemoryVT() != MVT::i32 ||
802 LD->getExtensionType() != ISD::SEXTLOAD ||
803 LD->getAddressingMode() != ISD::UNINDEXED) {
804 return SelectCode(N);
807 SDValue Chain = LD->getChain();
808 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
809 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
811 LD->getBasePtr(), TargetConst0,
814 return SelectCode(N);
817 // Same goes for the second operand.
818 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
819 SDValue Sext1 = MulOp1.getOperand(0);
820 if (Sext1.getNode()->getValueType(0) != MVT::i32) {
821 return SelectCode(N);
825 } else if (MulOp1.getOpcode() == ISD::LOAD) {
826 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
827 if (LD->getMemoryVT() != MVT::i32 ||
828 LD->getExtensionType() != ISD::SEXTLOAD ||
829 LD->getAddressingMode() != ISD::UNINDEXED) {
830 return SelectCode(N);
833 SDValue Chain = LD->getChain();
834 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
835 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
837 LD->getBasePtr(), TargetConst0,
840 return SelectCode(N);
843 // Generate a mpy instruction.
844 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY64, dl, MVT::i64,
846 ReplaceUses(N, Result);
850 return SelectCode(N);
854 SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) {
855 DebugLoc dl = N->getDebugLoc();
856 SDValue N0 = N->getOperand(0);
857 if (N0.getOpcode() == ISD::SETCC) {
858 SDValue N00 = N0.getOperand(0);
859 if (N00.getOpcode() == ISD::SIGN_EXTEND_INREG) {
860 SDValue N000 = N00.getOperand(0);
861 SDValue N001 = N00.getOperand(1);
862 if (cast<VTSDNode>(N001)->getVT() == MVT::i16) {
863 SDValue N01 = N0.getOperand(1);
864 SDValue N02 = N0.getOperand(2);
866 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
867 // i16:Other),IntRegs:i32:$src1, SETLT:Other),IntRegs:i32:$src1,
868 // IntRegs:i32:$src2)
869 // Emits: (MAXh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
870 // Pattern complexity = 9 cost = 1 size = 0.
871 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETLT) {
872 SDValue N1 = N->getOperand(1);
874 SDValue N2 = N->getOperand(2);
876 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
877 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
878 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
880 SDNode *Result = CurDAG->getMachineNode(Hexagon::MAXw_rr, dl,
882 SDValue(SextNode, 0),
884 ReplaceUses(N, Result);
890 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
891 // i16:Other), IntRegs:i32:$src1, SETGT:Other), IntRegs:i32:$src1,
892 // IntRegs:i32:$src2)
893 // Emits: (MINh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
894 // Pattern complexity = 9 cost = 1 size = 0.
895 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETGT) {
896 SDValue N1 = N->getOperand(1);
898 SDValue N2 = N->getOperand(2);
900 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
901 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
902 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
904 SDNode *Result = CurDAG->getMachineNode(Hexagon::MINw_rr, dl,
906 SDValue(SextNode, 0),
908 ReplaceUses(N, Result);
917 return SelectCode(N);
921 SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
922 DebugLoc dl = N->getDebugLoc();
923 SDValue Shift = N->getOperand(0);
926 // %conv.i = sext i32 %tmp1 to i64
927 // %conv2.i = sext i32 %add to i64
928 // %mul.i = mul nsw i64 %conv2.i, %conv.i
929 // %shr5.i = lshr i64 %mul.i, 32
930 // %conv3.i = trunc i64 %shr5.i to i32
932 // --- match with the following ---
934 // %conv3.i = mpy (%tmp1, %add)
937 if (N->getValueType(0) == MVT::i32) {
939 if (Shift.getNode()->getValueType(0) == MVT::i64) {
940 // Trunc child is logical shift right.
941 if (Shift.getOpcode() != ISD::SRL) {
942 return SelectCode(N);
945 SDValue ShiftOp0 = Shift.getOperand(0);
946 SDValue ShiftOp1 = Shift.getOperand(1);
949 if (ShiftOp1.getOpcode() != ISD::Constant) {
950 return SelectCode(N);
954 cast<ConstantSDNode>(ShiftOp1.getNode())->getSExtValue();
955 if (ShiftConst != 32) {
956 return SelectCode(N);
959 // Shifting a i64 signed multiply
960 SDValue Mul = ShiftOp0;
961 if (Mul.getOpcode() != ISD::MUL) {
962 return SelectCode(N);
965 SDValue MulOp0 = Mul.getOperand(0);
966 SDValue MulOp1 = Mul.getOperand(1);
971 // Handle sign_extend and sextload
972 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
973 SDValue Sext0 = MulOp0.getOperand(0);
974 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
975 return SelectCode(N);
979 } else if (MulOp0.getOpcode() == ISD::LOAD) {
980 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
981 if (LD->getMemoryVT() != MVT::i32 ||
982 LD->getExtensionType() != ISD::SEXTLOAD ||
983 LD->getAddressingMode() != ISD::UNINDEXED) {
984 return SelectCode(N);
987 SDValue Chain = LD->getChain();
988 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
989 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
992 TargetConst0, Chain), 0);
994 return SelectCode(N);
997 // Same goes for the second operand.
998 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
999 SDValue Sext1 = MulOp1.getOperand(0);
1000 if (Sext1.getNode()->getValueType(0) != MVT::i32)
1001 return SelectCode(N);
1004 } else if (MulOp1.getOpcode() == ISD::LOAD) {
1005 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
1006 if (LD->getMemoryVT() != MVT::i32 ||
1007 LD->getExtensionType() != ISD::SEXTLOAD ||
1008 LD->getAddressingMode() != ISD::UNINDEXED) {
1009 return SelectCode(N);
1012 SDValue Chain = LD->getChain();
1013 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1014 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
1017 TargetConst0, Chain), 0);
1019 return SelectCode(N);
1022 // Generate a mpy instruction.
1023 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY, dl, MVT::i32,
1025 ReplaceUses(N, Result);
1030 return SelectCode(N);
1034 SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
1035 DebugLoc dl = N->getDebugLoc();
1036 if (N->getValueType(0) == MVT::i32) {
1037 SDValue Shl_0 = N->getOperand(0);
1038 SDValue Shl_1 = N->getOperand(1);
1040 if (Shl_1.getOpcode() == ISD::Constant) {
1041 if (Shl_0.getOpcode() == ISD::MUL) {
1042 SDValue Mul_0 = Shl_0.getOperand(0); // Val
1043 SDValue Mul_1 = Shl_0.getOperand(1); // Const
1044 // RHS of mul is const.
1045 if (Mul_1.getOpcode() == ISD::Constant) {
1047 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1049 cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue();
1050 int32_t ValConst = MulConst << ShlConst;
1051 SDValue Val = CurDAG->getTargetConstant(ValConst,
1053 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode()))
1054 if (isInt<9>(CN->getSExtValue())) {
1056 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl,
1057 MVT::i32, Mul_0, Val);
1058 ReplaceUses(N, Result);
1063 } else if (Shl_0.getOpcode() == ISD::SUB) {
1064 SDValue Sub_0 = Shl_0.getOperand(0); // Const 0
1065 SDValue Sub_1 = Shl_0.getOperand(1); // Val
1066 if (Sub_0.getOpcode() == ISD::Constant) {
1068 cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue();
1069 if (SubConst == 0) {
1070 if (Sub_1.getOpcode() == ISD::SHL) {
1071 SDValue Shl2_0 = Sub_1.getOperand(0); // Val
1072 SDValue Shl2_1 = Sub_1.getOperand(1); // Const
1073 if (Shl2_1.getOpcode() == ISD::Constant) {
1075 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1077 cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue();
1078 int32_t ValConst = 1 << (ShlConst+Shl2Const);
1079 SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32);
1080 if (ConstantSDNode *CN =
1081 dyn_cast<ConstantSDNode>(Val.getNode()))
1082 if (isInt<9>(CN->getSExtValue())) {
1084 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl, MVT::i32,
1086 ReplaceUses(N, Result);
1096 return SelectCode(N);
1101 // If there is an zero_extend followed an intrinsic in DAG (this means - the
1102 // result of the intrinsic is predicate); convert the zero_extend to
1103 // transfer instruction.
1105 // Zero extend -> transfer is lowered here. Otherwise, zero_extend will be
1106 // converted into a MUX as predicate registers defined as 1 bit in the
1107 // compiler. Architecture defines them as 8-bit registers.
1108 // We want to preserve all the lower 8-bits and, not just 1 LSB bit.
1110 SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
1111 DebugLoc dl = N->getDebugLoc();
1112 SDNode *IsIntrinsic = N->getOperand(0).getNode();
1113 if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
1115 cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue();
1116 if (doesIntrinsicReturnPredicate(ID)) {
1117 // Now we need to differentiate target data types.
1118 if (N->getValueType(0) == MVT::i64) {
1119 // Convert the zero_extend to Rs = Pd followed by COMBINE_rr(0,Rs).
1120 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1121 SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
1123 SDValue(IsIntrinsic, 0));
1124 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl,
1127 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
1128 MVT::i64, MVT::Other,
1129 SDValue(Result_2, 0),
1130 SDValue(Result_1, 0));
1131 ReplaceUses(N, Result_3);
1134 if (N->getValueType(0) == MVT::i32) {
1135 // Convert the zero_extend to Rs = Pd
1136 SDNode* RsPd = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
1138 SDValue(IsIntrinsic, 0));
1139 ReplaceUses(N, RsPd);
1142 llvm_unreachable("Unexpected value type");
1145 return SelectCode(N);
1150 // Checking for intrinsics which have predicate registers as operand(s)
1151 // and lowering to the actual intrinsic.
1153 SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
1154 DebugLoc dl = N->getDebugLoc();
1155 unsigned ID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
1156 unsigned IntrinsicWithPred = doesIntrinsicContainPredicate(ID);
1158 // We are concerned with only those intrinsics that have predicate registers
1159 // as at least one of the operands.
1160 if (IntrinsicWithPred) {
1161 SmallVector<SDValue, 8> Ops;
1162 const MCInstrDesc &MCID = TII->get(IntrinsicWithPred);
1163 const TargetRegisterInfo *TRI = TM.getRegisterInfo();
1165 // Iterate over all the operands of the intrinsics.
1166 // For PredRegs, do the transfer.
1167 // For Double/Int Regs, just preserve the value
1168 // For immediates, lower it.
1169 for (unsigned i = 1; i < N->getNumOperands(); ++i) {
1170 SDNode *Arg = N->getOperand(i).getNode();
1171 const TargetRegisterClass *RC = TII->getRegClass(MCID, i, TRI, *MF);
1173 if (RC == &Hexagon::IntRegsRegClass ||
1174 RC == &Hexagon::DoubleRegsRegClass) {
1175 Ops.push_back(SDValue(Arg, 0));
1176 } else if (RC == &Hexagon::PredRegsRegClass) {
1178 SDNode *PdRs = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
1180 Ops.push_back(SDValue(PdRs,0));
1181 } else if (RC == NULL && (dyn_cast<ConstantSDNode>(Arg) != NULL)) {
1182 // This is immediate operand. Lower it here making sure that we DO have
1183 // const SDNode for immediate value.
1184 int32_t Val = cast<ConstantSDNode>(Arg)->getSExtValue();
1185 SDValue SDVal = CurDAG->getTargetConstant(Val, MVT::i32);
1186 Ops.push_back(SDVal);
1188 llvm_unreachable("Unimplemented");
1191 EVT ReturnValueVT = N->getValueType(0);
1192 SDNode *Result = CurDAG->getMachineNode(IntrinsicWithPred, dl,
1194 Ops.data(), Ops.size());
1195 ReplaceUses(N, Result);
1198 return SelectCode(N);
1202 // Map floating point constant values.
1204 SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
1205 DebugLoc dl = N->getDebugLoc();
1206 ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
1207 APFloat APF = CN->getValueAPF();
1208 if (N->getValueType(0) == MVT::f32) {
1209 return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32,
1210 CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32));
1212 else if (N->getValueType(0) == MVT::f64) {
1213 return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64,
1214 CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64));
1217 return SelectCode(N);
1222 // Map predicate true (encoded as -1 in LLVM) to a XOR.
1224 SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
1225 DebugLoc dl = N->getDebugLoc();
1226 if (N->getValueType(0) == MVT::i1) {
1228 int32_t Val = cast<ConstantSDNode>(N)->getSExtValue();
1230 // Create the IntReg = 1 node.
1232 CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
1233 CurDAG->getTargetConstant(0, MVT::i32));
1236 SDNode* Pd = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
1237 SDValue(IntRegTFR, 0));
1240 SDNode* NotPd = CurDAG->getMachineNode(Hexagon::NOT_p, dl, MVT::i1,
1244 Result = CurDAG->getMachineNode(Hexagon::XOR_pp, dl, MVT::i1,
1245 SDValue(Pd, 0), SDValue(NotPd, 0));
1247 // We have just built:
1249 // Pd = xor(not(Pd), Pd)
1251 ReplaceUses(N, Result);
1256 return SelectCode(N);
1261 // Map add followed by a asr -> asr +=.
1263 SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
1264 DebugLoc dl = N->getDebugLoc();
1265 if (N->getValueType(0) != MVT::i32) {
1266 return SelectCode(N);
1268 // Identify nodes of the form: add(asr(...)).
1269 SDNode* Src1 = N->getOperand(0).getNode();
1270 if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse()
1271 || Src1->getValueType(0) != MVT::i32) {
1272 return SelectCode(N);
1275 // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that
1276 // Rd and Rd' are assigned to the same register
1277 SDNode* Result = CurDAG->getMachineNode(Hexagon::ASR_ADD_rr, dl, MVT::i32,
1279 Src1->getOperand(0),
1280 Src1->getOperand(1));
1281 ReplaceUses(N, Result);
1287 SDNode *HexagonDAGToDAGISel::Select(SDNode *N) {
1288 if (N->isMachineOpcode())
1289 return NULL; // Already selected.
1292 switch (N->getOpcode()) {
1294 return SelectConstant(N);
1296 case ISD::ConstantFP:
1297 return SelectConstantFP(N);
1300 return SelectAdd(N);
1303 return SelectSHL(N);
1306 return SelectLoad(N);
1309 return SelectStore(N);
1312 return SelectSelect(N);
1315 return SelectTruncate(N);
1318 return SelectMul(N);
1320 case ISD::ZERO_EXTEND:
1321 return SelectZeroExtend(N);
1323 case ISD::INTRINSIC_WO_CHAIN:
1324 return SelectIntrinsicWOChain(N);
1327 return SelectCode(N);
1332 // Hexagon_TODO: Five functions for ADDRri?! Surely there must be a better way
1333 // to define these instructions.
1335 bool HexagonDAGToDAGISel::SelectADDRri(SDValue& Addr, SDValue &Base,
1337 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1338 Addr.getOpcode() == ISD::TargetGlobalAddress)
1339 return false; // Direct calls.
1341 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1342 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1343 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1347 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1352 bool HexagonDAGToDAGISel::SelectADDRriS11_0(SDValue& Addr, SDValue &Base,
1354 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1355 Addr.getOpcode() == ISD::TargetGlobalAddress)
1356 return false; // Direct calls.
1358 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1359 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1360 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1361 return (IsS11_0_Offset(Offset.getNode()));
1364 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1365 return (IsS11_0_Offset(Offset.getNode()));
1369 bool HexagonDAGToDAGISel::SelectADDRriS11_1(SDValue& Addr, SDValue &Base,
1371 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1372 Addr.getOpcode() == ISD::TargetGlobalAddress)
1373 return false; // Direct calls.
1375 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1376 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1377 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1378 return (IsS11_1_Offset(Offset.getNode()));
1381 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1382 return (IsS11_1_Offset(Offset.getNode()));
1386 bool HexagonDAGToDAGISel::SelectADDRriS11_2(SDValue& Addr, SDValue &Base,
1388 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1389 Addr.getOpcode() == ISD::TargetGlobalAddress)
1390 return false; // Direct calls.
1392 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1393 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1394 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1395 return (IsS11_2_Offset(Offset.getNode()));
1398 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1399 return (IsS11_2_Offset(Offset.getNode()));
1403 bool HexagonDAGToDAGISel::SelectADDRriU6_0(SDValue& Addr, SDValue &Base,
1405 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1406 Addr.getOpcode() == ISD::TargetGlobalAddress)
1407 return false; // Direct calls.
1409 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1410 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1411 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1412 return (IsU6_0_Offset(Offset.getNode()));
1415 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1416 return (IsU6_0_Offset(Offset.getNode()));
1420 bool HexagonDAGToDAGISel::SelectADDRriU6_1(SDValue& Addr, SDValue &Base,
1422 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1423 Addr.getOpcode() == ISD::TargetGlobalAddress)
1424 return false; // Direct calls.
1426 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1427 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1428 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1429 return (IsU6_1_Offset(Offset.getNode()));
1432 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1433 return (IsU6_1_Offset(Offset.getNode()));
1437 bool HexagonDAGToDAGISel::SelectADDRriU6_2(SDValue& Addr, SDValue &Base,
1439 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1440 Addr.getOpcode() == ISD::TargetGlobalAddress)
1441 return false; // Direct calls.
1443 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1444 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1445 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1446 return (IsU6_2_Offset(Offset.getNode()));
1449 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1450 return (IsU6_2_Offset(Offset.getNode()));
1454 bool HexagonDAGToDAGISel::SelectMEMriS11_2(SDValue& Addr, SDValue &Base,
1457 if (Addr.getOpcode() != ISD::ADD) {
1458 return(SelectADDRriS11_2(Addr, Base, Offset));
1461 return SelectADDRriS11_2(Addr, Base, Offset);
1465 bool HexagonDAGToDAGISel::SelectADDRriS11_3(SDValue& Addr, SDValue &Base,
1467 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1468 Addr.getOpcode() == ISD::TargetGlobalAddress)
1469 return false; // Direct calls.
1471 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1472 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1473 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1474 return (IsS11_3_Offset(Offset.getNode()));
1477 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1478 return (IsS11_3_Offset(Offset.getNode()));
1481 bool HexagonDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1,
1483 if (Addr.getOpcode() == ISD::FrameIndex) return false;
1484 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1485 Addr.getOpcode() == ISD::TargetGlobalAddress)
1486 return false; // Direct calls.
1488 if (Addr.getOpcode() == ISD::ADD) {
1489 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
1490 if (isInt<13>(CN->getSExtValue()))
1491 return false; // Let the reg+imm pattern catch this!
1492 R1 = Addr.getOperand(0);
1493 R2 = Addr.getOperand(1);
1503 // Handle generic address case. It is accessed from inlined asm =m constraints,
1504 // which could have any kind of pointer.
1505 bool HexagonDAGToDAGISel::SelectAddr(SDNode *Op, SDValue Addr,
1506 SDValue &Base, SDValue &Offset) {
1507 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1508 Addr.getOpcode() == ISD::TargetGlobalAddress)
1509 return false; // Direct calls.
1511 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1512 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1513 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1517 if (Addr.getOpcode() == ISD::ADD) {
1518 Base = Addr.getOperand(0);
1519 Offset = Addr.getOperand(1);
1524 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1529 bool HexagonDAGToDAGISel::
1530 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
1531 std::vector<SDValue> &OutOps) {
1534 switch (ConstraintCode) {
1535 case 'o': // Offsetable.
1536 case 'v': // Not offsetable.
1537 default: return true;
1538 case 'm': // Memory.
1539 if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
1544 OutOps.push_back(Op0);
1545 OutOps.push_back(Op1);
1549 bool HexagonDAGToDAGISel::isConstExtProfitable(SDNode *N) const {
1550 unsigned UseCount = 0;
1551 for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
1555 return (UseCount <= 1);
1559 //===--------------------------------------------------------------------===//
1560 // Return 'true' if use count of the global address is below threshold.
1561 //===--------------------------------------------------------------------===//
1562 bool HexagonDAGToDAGISel::hasNumUsesBelowThresGA(SDNode *N) const {
1563 assert(N->getOpcode() == ISD::TargetGlobalAddress &&
1564 "Expecting a target global address");
1566 // Always try to fold the address.
1567 if (TM.getOptLevel() == CodeGenOpt::Aggressive)
1570 GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N);
1571 DenseMap<const GlobalValue *, unsigned>::const_iterator GI =
1572 GlobalAddressUseCountMap.find(GA->getGlobal());
1574 if (GI == GlobalAddressUseCountMap.end())
1577 return GI->second <= MaxNumOfUsesForConstExtenders;
1580 //===--------------------------------------------------------------------===//
1581 // Return true if the non GP-relative global address can be folded.
1582 //===--------------------------------------------------------------------===//
1583 inline bool HexagonDAGToDAGISel::foldGlobalAddress(SDValue &N, SDValue &R) {
1584 return foldGlobalAddressImpl(N, R, false);
1587 //===--------------------------------------------------------------------===//
1588 // Return true if the GP-relative global address can be folded.
1589 //===--------------------------------------------------------------------===//
1590 inline bool HexagonDAGToDAGISel::foldGlobalAddressGP(SDValue &N, SDValue &R) {
1591 return foldGlobalAddressImpl(N, R, true);
1594 //===--------------------------------------------------------------------===//
1595 // Fold offset of the global address if number of uses are below threshold.
1596 //===--------------------------------------------------------------------===//
1597 bool HexagonDAGToDAGISel::foldGlobalAddressImpl(SDValue &N, SDValue &R,
1598 bool ShouldLookForGP) {
1599 if (N.getOpcode() == ISD::ADD) {
1600 SDValue N0 = N.getOperand(0);
1601 SDValue N1 = N.getOperand(1);
1602 if ((ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32_GP)) ||
1603 (!ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32))) {
1604 ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1);
1605 GlobalAddressSDNode *GA =
1606 dyn_cast<GlobalAddressSDNode>(N0.getOperand(0));
1609 (GA->getOpcode() == ISD::TargetGlobalAddress)) {
1610 if ((N0.getOpcode() == HexagonISD::CONST32) &&
1611 !hasNumUsesBelowThresGA(GA))
1613 R = CurDAG->getTargetGlobalAddress(GA->getGlobal(),
1614 Const->getDebugLoc(),
1617 (uint64_t)Const->getSExtValue());