1//===- MipsISelLowering.h - Mips DAG Lowering Interface ---------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the interfaces that Mips uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_TARGET_MIPS_MIPSISELLOWERING_H
15#define LLVM_LIB_TARGET_MIPS_MIPSISELLOWERING_H
16
17#include "MCTargetDesc/MipsABIInfo.h"
18#include "MCTargetDesc/MipsBaseInfo.h"
19#include "MCTargetDesc/MipsMCTargetDesc.h"
20#include "Mips.h"
21#include "llvm/CodeGen/CallingConvLower.h"
22#include "llvm/CodeGen/ISDOpcodes.h"
23#include "llvm/CodeGen/MachineMemOperand.h"
24#include "llvm/CodeGen/SelectionDAG.h"
25#include "llvm/CodeGen/SelectionDAGNodes.h"
26#include "llvm/CodeGen/TargetLowering.h"
27#include "llvm/CodeGen/ValueTypes.h"
28#include "llvm/CodeGenTypes/MachineValueType.h"
29#include "llvm/IR/CallingConv.h"
30#include "llvm/IR/InlineAsm.h"
31#include "llvm/IR/Type.h"
32#include "llvm/Target/TargetMachine.h"
33#include <algorithm>
34#include <deque>
35#include <utility>
36#include <vector>
37
38namespace llvm {
39
40class Argument;
41class FastISel;
42class FunctionLoweringInfo;
43class MachineBasicBlock;
44class MachineFrameInfo;
45class MachineInstr;
46class MipsCCState;
47class MipsFunctionInfo;
48class MipsSubtarget;
49class MipsTargetMachine;
50class TargetLibraryInfo;
51class TargetRegisterClass;
52
53 namespace MipsISD {
54
55 enum NodeType : unsigned {
56 // Start the numbering from where ISD NodeType finishes.
57 FIRST_NUMBER = ISD::BUILTIN_OP_END,
58
59 // Jump and link (call)
60 JmpLink,
61
62 // Tail call
63 TailCall,
64
65 // Get the Highest (63-48) 16 bits from a 64-bit immediate
66 Highest,
67
68 // Get the Higher (47-32) 16 bits from a 64-bit immediate
69 Higher,
70
71 // Get the High 16 bits from a 32/64-bit immediate
72 // No relation with Mips Hi register
73 Hi,
74
75 // Get the Lower 16 bits from a 32/64-bit immediate
76 // No relation with Mips Lo register
77 Lo,
78
79 // Get the High 16 bits from a 32 bit immediate for accessing the GOT.
80 GotHi,
81
82 // Get the High 16 bits from a 32-bit immediate for accessing TLS.
83 TlsHi,
84
85 // Handle gp_rel (small data/bss sections) relocation.
86 GPRel,
87
88 // Thread Pointer
89 ThreadPointer,
90
91 // Vector Floating Point Multiply and Subtract
92 FMS,
93
94 // Floating Point Branch Conditional
95 FPBrcond,
96
97 // Floating Point Compare
98 FPCmp,
99
100 // Floating point Abs
101 FAbs,
102
103 // Floating point select
104 FSELECT,
105
106 // Node used to generate an MTC1 i32 to f64 instruction
107 MTC1_D64,
108
109 // Floating Point Conditional Moves
110 CMovFP_T,
111 CMovFP_F,
112
113 // FP-to-int truncation node.
114 TruncIntFP,
115
116 // Return
117 Ret,
118
119 // Interrupt, exception, error trap Return
120 ERet,
121
122 // Software Exception Return.
123 EH_RETURN,
124
125 // Node used to extract integer from accumulator.
126 MFHI,
127 MFLO,
128
129 // Node used to insert integers to accumulator.
130 MTLOHI,
131
132 // Mult nodes.
133 Mult,
134 Multu,
135
136 // MAdd/Sub nodes
137 MAdd,
138 MAddu,
139 MSub,
140 MSubu,
141
142 // DivRem(u)
143 DivRem,
144 DivRemU,
145 DivRem16,
146 DivRemU16,
147
148 BuildPairF64,
149 ExtractElementF64,
150
151 Wrapper,
152
153 DynAlloc,
154
155 Sync,
156
157 Ext,
158 Ins,
159 CIns,
160
161 // EXTR.W intrinsic nodes.
162 EXTP,
163 EXTPDP,
164 EXTR_S_H,
165 EXTR_W,
166 EXTR_R_W,
167 EXTR_RS_W,
168 SHILO,
169 MTHLIP,
170
171 // DPA.W intrinsic nodes.
172 MULSAQ_S_W_PH,
173 MAQ_S_W_PHL,
174 MAQ_S_W_PHR,
175 MAQ_SA_W_PHL,
176 MAQ_SA_W_PHR,
177 DPAU_H_QBL,
178 DPAU_H_QBR,
179 DPSU_H_QBL,
180 DPSU_H_QBR,
181 DPAQ_S_W_PH,
182 DPSQ_S_W_PH,
183 DPAQ_SA_L_W,
184 DPSQ_SA_L_W,
185 DPA_W_PH,
186 DPS_W_PH,
187 DPAQX_S_W_PH,
188 DPAQX_SA_W_PH,
189 DPAX_W_PH,
190 DPSX_W_PH,
191 DPSQX_S_W_PH,
192 DPSQX_SA_W_PH,
193 MULSA_W_PH,
194
195 MULT,
196 MULTU,
197 MADD_DSP,
198 MADDU_DSP,
199 MSUB_DSP,
200 MSUBU_DSP,
201
202 // DSP shift nodes.
203 SHLL_DSP,
204 SHRA_DSP,
205 SHRL_DSP,
206
207 // DSP setcc and select_cc nodes.
208 SETCC_DSP,
209 SELECT_CC_DSP,
210
211 // Vector comparisons.
212 // These take a vector and return a boolean.
213 VALL_ZERO,
214 VANY_ZERO,
215 VALL_NONZERO,
216 VANY_NONZERO,
217
218 // These take a vector and return a vector bitmask.
219 VCEQ,
220 VCLE_S,
221 VCLE_U,
222 VCLT_S,
223 VCLT_U,
224
225 // Vector Shuffle with mask as an operand
226 VSHF, // Generic shuffle
227 SHF, // 4-element set shuffle.
228 ILVEV, // Interleave even elements
229 ILVOD, // Interleave odd elements
230 ILVL, // Interleave left elements
231 ILVR, // Interleave right elements
232 PCKEV, // Pack even elements
233 PCKOD, // Pack odd elements
234
235 // Vector Lane Copy
236 INSVE, // Copy element from one vector to another
237
238 // Combined (XOR (OR $a, $b), -1)
239 VNOR,
240
241 // Extended vector element extraction
242 VEXTRACT_SEXT_ELT,
243 VEXTRACT_ZEXT_ELT,
244
245 // Double select nodes for machines without conditional-move.
246 DOUBLE_SELECT_I,
247 DOUBLE_SELECT_I64,
248
249 // Load/Store Left/Right nodes.
250 FIRST_MEMORY_OPCODE,
251 LWL = FIRST_MEMORY_OPCODE,
252 LWR,
253 SWL,
254 SWR,
255 LDL,
256 LDR,
257 SDL,
258 SDR,
259 LAST_MEMORY_OPCODE = SDR,
260 };
261
262 } // ene namespace MipsISD
263
264 //===--------------------------------------------------------------------===//
265 // TargetLowering Implementation
266 //===--------------------------------------------------------------------===//
267
268 class MipsTargetLowering : public TargetLowering {
269 bool isMicroMips;
270
271 public:
272 explicit MipsTargetLowering(const MipsTargetMachine &TM,
273 const MipsSubtarget &STI);
274
275 static const MipsTargetLowering *create(const MipsTargetMachine &TM,
276 const MipsSubtarget &STI);
277
278 /// createFastISel - This method returns a target specific FastISel object,
279 /// or null if the target does not support "fast" ISel.
280 FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
281 const TargetLibraryInfo *libInfo) const override;
282
283 MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override {
284 return MVT::i32;
285 }
286
287 EVT getTypeForExtReturn(LLVMContext &Context, EVT VT,
288 ISD::NodeType) const override;
289
290 bool isCheapToSpeculateCttz(Type *Ty) const override;
291 bool isCheapToSpeculateCtlz(Type *Ty) const override;
292 bool hasBitTest(SDValue X, SDValue Y) const override;
293 bool shouldFoldConstantShiftPairToMask(const SDNode *N,
294 CombineLevel Level) const override;
295
296 /// Return the register type for a given MVT, ensuring vectors are treated
297 /// as a series of gpr sized integers.
298 MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC,
299 EVT VT) const override;
300
301 /// Return the number of registers for a given MVT, ensuring vectors are
302 /// treated as a series of gpr sized integers.
303 unsigned getNumRegistersForCallingConv(LLVMContext &Context,
304 CallingConv::ID CC,
305 EVT VT) const override;
306
307 /// Break down vectors to the correct number of gpr sized integers.
308 unsigned getVectorTypeBreakdownForCallingConv(
309 LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT,
310 unsigned &NumIntermediates, MVT &RegisterVT) const override;
311
312 /// Return the correct alignment for the current calling convention.
313 Align getABIAlignmentForCallingConv(Type *ArgTy,
314 const DataLayout &DL) const override {
315 const Align ABIAlign = DL.getABITypeAlign(Ty: ArgTy);
316 if (ArgTy->isVectorTy())
317 return std::min(a: ABIAlign, b: Align(8));
318 return ABIAlign;
319 }
320
321 ISD::NodeType getExtendForAtomicOps() const override {
322 return ISD::SIGN_EXTEND;
323 }
324
325 /// LowerOperation - Provide custom lowering hooks for some operations.
326 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
327
328 /// ReplaceNodeResults - Replace the results of node with an illegal result
329 /// type with new values built out of custom code.
330 ///
331 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,
332 SelectionDAG &DAG) const override;
333
334 /// getTargetNodeName - This method returns the name of a target specific
335 // DAG node.
336 const char *getTargetNodeName(unsigned Opcode) const override;
337
338 /// getSetCCResultType - get the ISD::SETCC result ValueType
339 EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
340 EVT VT) const override;
341
342 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
343
344 MachineBasicBlock *
345 EmitInstrWithCustomInserter(MachineInstr &MI,
346 MachineBasicBlock *MBB) const override;
347
348 void AdjustInstrPostInstrSelection(MachineInstr &MI,
349 SDNode *Node) const override;
350
351 void HandleByVal(CCState *, unsigned &, Align) const override;
352
353 Register getRegisterByName(const char* RegName, LLT VT,
354 const MachineFunction &MF) const override;
355
356 /// If a physical register, this returns the register that receives the
357 /// exception address on entry to an EH pad.
358 Register
359 getExceptionPointerRegister(const Constant *PersonalityFn) const override {
360 return ABI.IsN64() ? Mips::A0_64 : Mips::A0;
361 }
362
363 /// If a physical register, this returns the register that receives the
364 /// exception typeid on entry to a landing pad.
365 Register
366 getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
367 return ABI.IsN64() ? Mips::A1_64 : Mips::A1;
368 }
369
370 bool softPromoteHalfType() const override { return true; }
371
372 bool isJumpTableRelative() const override {
373 return getTargetMachine().isPositionIndependent();
374 }
375
376 CCAssignFn *CCAssignFnForCall() const;
377
378 CCAssignFn *CCAssignFnForReturn() const;
379
380 protected:
381 SDValue getGlobalReg(SelectionDAG &DAG, EVT Ty) const;
382
383 // This method creates the following nodes, which are necessary for
384 // computing a local symbol's address:
385 //
386 // (add (load (wrapper $gp, %got(sym)), %lo(sym))
387 template <class NodeTy>
388 SDValue getAddrLocal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG,
389 bool IsN32OrN64) const {
390 unsigned GOTFlag = IsN32OrN64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT;
391 SDValue GOT = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty),
392 getTargetNode(N, Ty, DAG, GOTFlag));
393 SDValue Load =
394 DAG.getLoad(VT: Ty, dl: DL, Chain: DAG.getEntryNode(), Ptr: GOT,
395 PtrInfo: MachinePointerInfo::getGOT(MF&: DAG.getMachineFunction()));
396 unsigned LoFlag = IsN32OrN64 ? MipsII::MO_GOT_OFST : MipsII::MO_ABS_LO;
397 SDValue Lo = DAG.getNode(MipsISD::Lo, DL, Ty,
398 getTargetNode(N, Ty, DAG, LoFlag));
399 return DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty, N1: Load, N2: Lo);
400 }
401
402 // This method creates the following nodes, which are necessary for
403 // computing a global symbol's address:
404 //
405 // (load (wrapper $gp, %got(sym)))
406 template <class NodeTy>
407 SDValue getAddrGlobal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG,
408 unsigned Flag, SDValue Chain,
409 const MachinePointerInfo &PtrInfo) const {
410 SDValue Tgt = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty),
411 getTargetNode(N, Ty, DAG, Flag));
412 return DAG.getLoad(VT: Ty, dl: DL, Chain, Ptr: Tgt, PtrInfo);
413 }
414
415 // This method creates the following nodes, which are necessary for
416 // computing a global symbol's address in large-GOT mode:
417 //
418 // (load (wrapper (add %hi(sym), $gp), %lo(sym)))
419 template <class NodeTy>
420 SDValue getAddrGlobalLargeGOT(NodeTy *N, const SDLoc &DL, EVT Ty,
421 SelectionDAG &DAG, unsigned HiFlag,
422 unsigned LoFlag, SDValue Chain,
423 const MachinePointerInfo &PtrInfo) const {
424 SDValue Hi = DAG.getNode(MipsISD::GotHi, DL, Ty,
425 getTargetNode(N, Ty, DAG, HiFlag));
426 Hi = DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty, N1: Hi, N2: getGlobalReg(DAG, Ty));
427 SDValue Wrapper = DAG.getNode(MipsISD::Wrapper, DL, Ty, Hi,
428 getTargetNode(N, Ty, DAG, LoFlag));
429 return DAG.getLoad(VT: Ty, dl: DL, Chain, Ptr: Wrapper, PtrInfo);
430 }
431
432 // This method creates the following nodes, which are necessary for
433 // computing a symbol's address in non-PIC mode:
434 //
435 // (add %hi(sym), %lo(sym))
436 //
437 // This method covers O32, N32 and N64 in sym32 mode.
438 template <class NodeTy>
439 SDValue getAddrNonPIC(NodeTy *N, const SDLoc &DL, EVT Ty,
440 SelectionDAG &DAG) const {
441 SDValue Hi = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI);
442 SDValue Lo = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO);
443 return DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty,
444 N1: DAG.getNode(Opcode: MipsISD::Hi, DL, VT: Ty, Operand: Hi),
445 N2: DAG.getNode(Opcode: MipsISD::Lo, DL, VT: Ty, Operand: Lo));
446 }
447
448 // This method creates the following nodes, which are necessary for
449 // computing a symbol's address in non-PIC mode for N64.
450 //
451 // (add (shl (add (shl (add %highest(sym), %higher(sim)), 16), %high(sym)),
452 // 16), %lo(%sym))
453 //
454 // FIXME: This method is not efficent for (micro)MIPS64R6.
455 template <class NodeTy>
456 SDValue getAddrNonPICSym64(NodeTy *N, const SDLoc &DL, EVT Ty,
457 SelectionDAG &DAG) const {
458 SDValue Hi = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI);
459 SDValue Lo = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO);
460
461 SDValue Highest =
462 DAG.getNode(MipsISD::Highest, DL, Ty,
463 getTargetNode(N, Ty, DAG, MipsII::MO_HIGHEST));
464 SDValue Higher = getTargetNode(N, Ty, DAG, MipsII::MO_HIGHER);
465 SDValue HigherPart =
466 DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty, N1: Highest,
467 N2: DAG.getNode(Opcode: MipsISD::Higher, DL, VT: Ty, Operand: Higher));
468 SDValue Cst = DAG.getConstant(Val: 16, DL, VT: MVT::i32);
469 SDValue Shift = DAG.getNode(Opcode: ISD::SHL, DL, VT: Ty, N1: HigherPart, N2: Cst);
470 SDValue Add = DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty, N1: Shift,
471 N2: DAG.getNode(Opcode: MipsISD::Hi, DL, VT: Ty, Operand: Hi));
472 SDValue Shift2 = DAG.getNode(Opcode: ISD::SHL, DL, VT: Ty, N1: Add, N2: Cst);
473
474 return DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty, N1: Shift2,
475 N2: DAG.getNode(Opcode: MipsISD::Lo, DL, VT: Ty, Operand: Lo));
476 }
477
478 // This method creates the following nodes, which are necessary for
479 // computing a symbol's address using gp-relative addressing:
480 //
481 // (add $gp, %gp_rel(sym))
482 template <class NodeTy>
483 SDValue getAddrGPRel(NodeTy *N, const SDLoc &DL, EVT Ty,
484 SelectionDAG &DAG, bool IsN64) const {
485 SDValue GPRel = getTargetNode(N, Ty, DAG, MipsII::MO_GPREL);
486 return DAG.getNode(
487 Opcode: ISD::ADD, DL, VT: Ty,
488 N1: DAG.getRegister(Reg: IsN64 ? Mips::GP_64 : Mips::GP, VT: Ty),
489 N2: DAG.getNode(Opcode: MipsISD::GPRel, DL, VTList: DAG.getVTList(VT: Ty), N: GPRel));
490 }
491
492 // This method creates the following nodes, which are necessary for
493 // loading a dllimported symbol:
494 //
495 // (lw (add (shl(%high(sym), 16), %low(sym)))
496 template <class NodeTy>
497 SDValue getDllimportSymbol(NodeTy *N, const SDLoc &DL, EVT Ty,
498 SelectionDAG &DAG) const {
499 SDValue Hi =
500 getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI | MipsII::MO_DLLIMPORT);
501 SDValue Lo =
502 getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO | MipsII::MO_DLLIMPORT);
503 return DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty, N1: DAG.getNode(Opcode: MipsISD::Lo, DL, VT: Ty, Operand: Lo),
504 N2: DAG.getNode(Opcode: MipsISD::Hi, DL, VT: Ty, Operand: Hi));
505 }
506
507 // This method creates the following nodes, which are necessary for
508 // loading a dllimported global variable:
509 //
510 // (lw (lw (add (shl(%high(sym), 16), %low(sym))))
511 template <class NodeTy>
512 SDValue getDllimportVariable(NodeTy *N, const SDLoc &DL, EVT Ty,
513 SelectionDAG &DAG, SDValue Chain,
514 const MachinePointerInfo &PtrInfo) const {
515 return DAG.getLoad(Ty, DL, Chain, getDllimportSymbol(N, DL, Ty, DAG),
516 PtrInfo);
517 }
518
519 /// This function fills Ops, which is the list of operands that will later
520 /// be used when a function call node is created. It also generates
521 /// copyToReg nodes to set up argument registers.
522 virtual void
523 getOpndList(SmallVectorImpl<SDValue> &Ops,
524 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
525 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
526 bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
527 SDValue Chain) const;
528
529 protected:
530 SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const;
531 SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const;
532
533 // Subtarget Info
534 const MipsSubtarget &Subtarget;
535 // Cache the ABI from the TargetMachine, we use it everywhere.
536 const MipsABIInfo &ABI;
537
538 private:
539 // Create a TargetGlobalAddress node.
540 SDValue getTargetNode(GlobalAddressSDNode *N, EVT Ty, SelectionDAG &DAG,
541 unsigned Flag) const;
542
543 // Create a TargetExternalSymbol node.
544 SDValue getTargetNode(ExternalSymbolSDNode *N, EVT Ty, SelectionDAG &DAG,
545 unsigned Flag) const;
546
547 // Create a TargetBlockAddress node.
548 SDValue getTargetNode(BlockAddressSDNode *N, EVT Ty, SelectionDAG &DAG,
549 unsigned Flag) const;
550
551 // Create a TargetJumpTable node.
552 SDValue getTargetNode(JumpTableSDNode *N, EVT Ty, SelectionDAG &DAG,
553 unsigned Flag) const;
554
555 // Create a TargetConstantPool node.
556 SDValue getTargetNode(ConstantPoolSDNode *N, EVT Ty, SelectionDAG &DAG,
557 unsigned Flag) const;
558
559 // Lower Operand helpers
560 SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
561 CallingConv::ID CallConv, bool isVarArg,
562 const SmallVectorImpl<ISD::InputArg> &Ins,
563 const SDLoc &dl, SelectionDAG &DAG,
564 SmallVectorImpl<SDValue> &InVals,
565 TargetLowering::CallLoweringInfo &CLI) const;
566
567 // Lower Operand specifics
568 SDValue lowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
569 SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
570 SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
571 SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
572 SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
573 SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
574 SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const;
575 SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const;
576 SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
577 SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const;
578 SDValue lowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const;
579 SDValue lowerFABS(SDValue Op, SelectionDAG &DAG) const;
580 SDValue lowerFABS32(SDValue Op, SelectionDAG &DAG,
581 bool HasExtractInsert) const;
582 SDValue lowerFABS64(SDValue Op, SelectionDAG &DAG,
583 bool HasExtractInsert) const;
584 SDValue lowerFCANONICALIZE(SDValue Op, SelectionDAG &DAG) const;
585 SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
586 SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
587 SDValue lowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
588 SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
589 SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG& DAG) const;
590 SDValue lowerShiftRightParts(SDValue Op, SelectionDAG& DAG,
591 bool IsSRA) const;
592 SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const;
593 SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const;
594 SDValue lowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const;
595 SDValue lowerConstantFP(SDValue Op, SelectionDAG &DAG) const;
596
597 /// isEligibleForTailCallOptimization - Check whether the call is eligible
598 /// for tail call optimization.
599 virtual bool
600 isEligibleForTailCallOptimization(const CCState &CCInfo,
601 unsigned NextStackOffset,
602 const MipsFunctionInfo &FI) const = 0;
603
604 /// copyByValArg - Copy argument registers which were used to pass a byval
605 /// argument to the stack. Create a stack frame object for the byval
606 /// argument.
607 void copyByValRegs(SDValue Chain, const SDLoc &DL,
608 std::vector<SDValue> &OutChains, SelectionDAG &DAG,
609 const ISD::ArgFlagsTy &Flags,
610 SmallVectorImpl<SDValue> &InVals,
611 const Argument *FuncArg, unsigned FirstReg,
612 unsigned LastReg, const CCValAssign &VA,
613 MipsCCState &State) const;
614
615 /// passByValArg - Pass a byval argument in registers or on stack.
616 void passByValArg(SDValue Chain, const SDLoc &DL,
617 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
618 SmallVectorImpl<SDValue> &MemOpChains, SDValue StackPtr,
619 MachineFrameInfo &MFI, SelectionDAG &DAG, SDValue Arg,
620 unsigned FirstReg, unsigned LastReg,
621 const ISD::ArgFlagsTy &Flags, bool isLittle,
622 const CCValAssign &VA) const;
623
624 /// writeVarArgRegs - Write variable function arguments passed in registers
625 /// to the stack. Also create a stack frame object for the first variable
626 /// argument.
627 void writeVarArgRegs(std::vector<SDValue> &OutChains, SDValue Chain,
628 const SDLoc &DL, SelectionDAG &DAG,
629 CCState &State) const;
630
631 SDValue
632 LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
633 const SmallVectorImpl<ISD::InputArg> &Ins,
634 const SDLoc &dl, SelectionDAG &DAG,
635 SmallVectorImpl<SDValue> &InVals) const override;
636
637 SDValue passArgOnStack(SDValue StackPtr, unsigned Offset, SDValue Chain,
638 SDValue Arg, const SDLoc &DL, bool IsTailCall,
639 SelectionDAG &DAG) const;
640
641 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
642 SmallVectorImpl<SDValue> &InVals) const override;
643
644 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
645 bool isVarArg,
646 const SmallVectorImpl<ISD::OutputArg> &Outs,
647 LLVMContext &Context, const Type *RetTy) const override;
648
649 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
650 const SmallVectorImpl<ISD::OutputArg> &Outs,
651 const SmallVectorImpl<SDValue> &OutVals,
652 const SDLoc &dl, SelectionDAG &DAG) const override;
653
654 SDValue LowerInterruptReturn(SmallVectorImpl<SDValue> &RetOps,
655 const SDLoc &DL, SelectionDAG &DAG) const;
656
657 bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const override;
658
659 // Inline asm support
660 ConstraintType getConstraintType(StringRef Constraint) const override;
661
662 /// Examine constraint string and operand type and determine a weight value.
663 /// The operand object must already have been set up with the operand type.
664 ConstraintWeight getSingleConstraintMatchWeight(
665 AsmOperandInfo &info, const char *constraint) const override;
666
667 /// This function parses registers that appear in inline-asm constraints.
668 /// It returns pair (0, 0) on failure.
669 std::pair<unsigned, const TargetRegisterClass *>
670 parseRegForInlineAsmConstraint(StringRef C, MVT VT) const;
671
672 std::pair<unsigned, const TargetRegisterClass *>
673 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
674 StringRef Constraint, MVT VT) const override;
675
676 /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
677 /// vector. If it is invalid, don't add anything to Ops. If hasMemory is
678 /// true it means one of the asm constraint of the inline asm instruction
679 /// being processed is 'm'.
680 void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint,
681 std::vector<SDValue> &Ops,
682 SelectionDAG &DAG) const override;
683
684 InlineAsm::ConstraintCode
685 getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
686 if (ConstraintCode == "o")
687 return InlineAsm::ConstraintCode::o;
688 if (ConstraintCode == "R")
689 return InlineAsm::ConstraintCode::R;
690 if (ConstraintCode == "ZC")
691 return InlineAsm::ConstraintCode::ZC;
692 return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
693 }
694
695 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
696 Type *Ty, unsigned AS,
697 Instruction *I = nullptr) const override;
698
699 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
700
701 EVT getOptimalMemOpType(const MemOp &Op,
702 const AttributeList &FuncAttributes) const override;
703
704 /// isFPImmLegal - Returns true if the target can instruction select the
705 /// specified FP immediate natively. If false, the legalizer will
706 /// materialize the FP immediate as a load from a constant pool.
707 bool isFPImmLegal(const APFloat &Imm, EVT VT,
708 bool ForCodeSize) const override;
709
710 bool isLegalICmpImmediate(int64_t Imm) const override;
711 bool isLegalAddImmediate(int64_t Imm) const override;
712
713 unsigned getJumpTableEncoding() const override;
714 SDValue getPICJumpTableRelocBase(SDValue Table,
715 SelectionDAG &DAG) const override;
716 bool useSoftFloat() const override;
717
718 bool shouldInsertFencesForAtomic(const Instruction *I) const override {
719 return true;
720 }
721
722 /// Emit a sign-extension using sll/sra, seb, or seh appropriately.
723 MachineBasicBlock *emitSignExtendToI32InReg(MachineInstr &MI,
724 MachineBasicBlock *BB,
725 unsigned Size, unsigned DstReg,
726 unsigned SrcRec) const;
727
728 MachineBasicBlock *emitAtomicBinary(MachineInstr &MI,
729 MachineBasicBlock *BB) const;
730 MachineBasicBlock *emitAtomicBinaryPartword(MachineInstr &MI,
731 MachineBasicBlock *BB,
732 unsigned Size) const;
733 MachineBasicBlock *emitAtomicCmpSwap(MachineInstr &MI,
734 MachineBasicBlock *BB) const;
735 MachineBasicBlock *emitAtomicCmpSwapPartword(MachineInstr &MI,
736 MachineBasicBlock *BB,
737 unsigned Size) const;
738 MachineBasicBlock *emitSEL_D(MachineInstr &MI, MachineBasicBlock *BB) const;
739 MachineBasicBlock *emitPseudoSELECT(MachineInstr &MI, MachineBasicBlock *BB,
740 bool isFPCmp, unsigned Opc) const;
741 MachineBasicBlock *emitPseudoD_SELECT(MachineInstr &MI,
742 MachineBasicBlock *BB) const;
743 MachineBasicBlock *emitLDR_W(MachineInstr &MI, MachineBasicBlock *BB) const;
744 MachineBasicBlock *emitLDR_D(MachineInstr &MI, MachineBasicBlock *BB) const;
745 MachineBasicBlock *emitSTR_W(MachineInstr &MI, MachineBasicBlock *BB) const;
746 MachineBasicBlock *emitSTR_D(MachineInstr &MI, MachineBasicBlock *BB) const;
747 };
748
749 /// Create MipsTargetLowering objects.
750 const MipsTargetLowering *
751 createMips16TargetLowering(const MipsTargetMachine &TM,
752 const MipsSubtarget &STI);
753 const MipsTargetLowering *
754 createMipsSETargetLowering(const MipsTargetMachine &TM,
755 const MipsSubtarget &STI);
756
757namespace Mips {
758
759FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
760 const TargetLibraryInfo *libInfo);
761
762} // end namespace Mips
763
764} // end namespace llvm
765
766#endif // LLVM_LIB_TARGET_MIPS_MIPSISELLOWERING_H
767