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 "MipsSelectionDAGInfo.h"
22#include "llvm/CodeGen/CallingConvLower.h"
23#include "llvm/CodeGen/ISDOpcodes.h"
24#include "llvm/CodeGen/MachineMemOperand.h"
25#include "llvm/CodeGen/SelectionDAG.h"
26#include "llvm/CodeGen/SelectionDAGNodes.h"
27#include "llvm/CodeGen/TargetLowering.h"
28#include "llvm/CodeGen/ValueTypes.h"
29#include "llvm/CodeGenTypes/MachineValueType.h"
30#include "llvm/IR/CallingConv.h"
31#include "llvm/IR/InlineAsm.h"
32#include "llvm/IR/Type.h"
33#include "llvm/Target/TargetMachine.h"
34#include <algorithm>
35#include <deque>
36#include <utility>
37#include <vector>
38
39namespace llvm {
40
41class Argument;
42class FastISel;
43class FunctionLoweringInfo;
44class MachineBasicBlock;
45class MachineFrameInfo;
46class MachineInstr;
47class MipsCCState;
48class MipsFunctionInfo;
49class MipsSubtarget;
50class MipsTargetMachine;
51class TargetLibraryInfo;
52class MCRegisterClass;
53using TargetRegisterClass = MCRegisterClass;
54
55 //===--------------------------------------------------------------------===//
56 // TargetLowering Implementation
57 //===--------------------------------------------------------------------===//
58
59 class MipsTargetLowering : public TargetLowering {
60 bool isMicroMips;
61
62 public:
63 explicit MipsTargetLowering(const MipsTargetMachine &TM,
64 const MipsSubtarget &STI);
65
66 static const MipsTargetLowering *create(const MipsTargetMachine &TM,
67 const MipsSubtarget &STI);
68
69 /// createFastISel - This method returns a target specific FastISel object,
70 /// or null if the target does not support "fast" ISel.
71 FastISel *
72 createFastISel(FunctionLoweringInfo &funcInfo,
73 const TargetLibraryInfo *libInfo,
74 const LibcallLoweringInfo *libcallLowering) const override;
75
76 MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override {
77 return MVT::i32;
78 }
79
80 EVT getTypeForExtReturn(LLVMContext &Context, EVT VT,
81 ISD::NodeType) const override;
82
83 bool isCheapToSpeculateCttz(Type *Ty) const override;
84 bool isCheapToSpeculateCtlz(Type *Ty) const override;
85 bool hasBitTest(SDValue X, SDValue Y) const override;
86 bool shouldFoldConstantShiftPairToMask(const SDNode *N) const override;
87
88 /// Return the register type for a given MVT, ensuring vectors are treated
89 /// as a series of gpr sized integers.
90 MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC,
91 EVT VT) const override;
92
93 /// Return the number of registers for a given MVT, ensuring vectors are
94 /// treated as a series of gpr sized integers.
95 unsigned getNumRegistersForCallingConv(LLVMContext &Context,
96 CallingConv::ID CC,
97 EVT VT) const override;
98
99 /// Break down vectors to the correct number of gpr sized integers.
100 unsigned getVectorTypeBreakdownForCallingConv(
101 LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT,
102 unsigned &NumIntermediates, MVT &RegisterVT) const override;
103
104 /// Return the correct alignment for the current calling convention.
105 Align getABIAlignmentForCallingConv(Type *ArgTy,
106 const DataLayout &DL) const override {
107 const Align ABIAlign = DL.getABITypeAlign(Ty: ArgTy);
108 if (ArgTy->isVectorTy())
109 return std::min(a: ABIAlign, b: Align(8));
110 return ABIAlign;
111 }
112
113 ISD::NodeType getExtendForAtomicOps() const override {
114 return ISD::SIGN_EXTEND;
115 }
116
117 /// LowerOperation - Provide custom lowering hooks for some operations.
118 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
119
120 /// ReplaceNodeResults - Replace the results of node with an illegal result
121 /// type with new values built out of custom code.
122 ///
123 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,
124 SelectionDAG &DAG) const override;
125
126 /// getSetCCResultType - get the ISD::SETCC result ValueType
127 EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
128 EVT VT) const override;
129
130 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
131
132 MachineBasicBlock *
133 EmitInstrWithCustomInserter(MachineInstr &MI,
134 MachineBasicBlock *MBB) const override;
135
136 void AdjustInstrPostInstrSelection(MachineInstr &MI,
137 SDNode *Node) const override;
138
139 void HandleByVal(CCState *, unsigned &, Align) const override;
140
141 Register getRegisterByName(const char* RegName, LLT VT,
142 const MachineFunction &MF) const override;
143
144 /// If a physical register, this returns the register that receives the
145 /// exception address on entry to an EH pad.
146 Register
147 getExceptionPointerRegister(ExceptionHandling EH,
148 const Constant *PersonalityFn) const override {
149 return ABI.IsN64() ? Mips::A0_64 : Mips::A0;
150 }
151
152 /// If a physical register, this returns the register that receives the
153 /// exception typeid on entry to a landing pad.
154 Register
155 getExceptionSelectorRegister(ExceptionHandling EH,
156 const Constant *PersonalityFn) const override {
157 return ABI.IsN64() ? Mips::A1_64 : Mips::A1;
158 }
159
160 bool isJumpTableRelative() const override {
161 return getTargetMachine().isPositionIndependent();
162 }
163
164 CCAssignFn *CCAssignFnForCall() const;
165
166 CCAssignFn *CCAssignFnForReturn() const;
167
168 protected:
169 SDValue getGlobalReg(SelectionDAG &DAG, EVT Ty) const;
170
171 // This method creates the following nodes, which are necessary for
172 // computing a local symbol's address:
173 //
174 // (add (load (wrapper $gp, %got(sym)), %lo(sym))
175 template <class NodeTy>
176 SDValue getAddrLocal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG,
177 bool IsN32OrN64) const {
178 unsigned GOTFlag = IsN32OrN64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT;
179 SDValue GOT = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty),
180 getTargetNode(N, Ty, DAG, GOTFlag));
181 SDValue Load =
182 DAG.getLoad(VT: Ty, dl: DL, Chain: DAG.getEntryNode(), Ptr: GOT,
183 PtrInfo: MachinePointerInfo::getGOT(MF&: DAG.getMachineFunction()));
184 unsigned LoFlag = IsN32OrN64 ? MipsII::MO_GOT_OFST : MipsII::MO_ABS_LO;
185 SDValue Lo = DAG.getNode(MipsISD::Lo, DL, Ty,
186 getTargetNode(N, Ty, DAG, LoFlag));
187 return DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty, N1: Load, N2: Lo);
188 }
189
190 // This method creates the following nodes, which are necessary for
191 // computing a global symbol's address:
192 //
193 // (load (wrapper $gp, %got(sym)))
194 template <class NodeTy>
195 SDValue getAddrGlobal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG,
196 unsigned Flag, SDValue Chain,
197 const MachinePointerInfo &PtrInfo) const {
198 SDValue Tgt = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty),
199 getTargetNode(N, Ty, DAG, Flag));
200 return DAG.getLoad(VT: Ty, dl: DL, Chain, Ptr: Tgt, PtrInfo);
201 }
202
203 // This method creates the following nodes, which are necessary for
204 // computing a global symbol's address in large-GOT mode:
205 //
206 // (load (wrapper (add %hi(sym), $gp), %lo(sym)))
207 template <class NodeTy>
208 SDValue getAddrGlobalLargeGOT(NodeTy *N, const SDLoc &DL, EVT Ty,
209 SelectionDAG &DAG, unsigned HiFlag,
210 unsigned LoFlag, SDValue Chain,
211 const MachinePointerInfo &PtrInfo) const {
212 SDValue Hi = DAG.getNode(MipsISD::GotHi, DL, Ty,
213 getTargetNode(N, Ty, DAG, HiFlag));
214 Hi = DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty, N1: Hi, N2: getGlobalReg(DAG, Ty));
215 SDValue Wrapper = DAG.getNode(MipsISD::Wrapper, DL, Ty, Hi,
216 getTargetNode(N, Ty, DAG, LoFlag));
217 return DAG.getLoad(VT: Ty, dl: DL, Chain, Ptr: Wrapper, PtrInfo);
218 }
219
220 // This method creates the following nodes, which are necessary for
221 // computing a symbol's address in non-PIC mode:
222 //
223 // (add %hi(sym), %lo(sym))
224 //
225 // This method covers O32, N32 and N64 in sym32 mode.
226 template <class NodeTy>
227 SDValue getAddrNonPIC(NodeTy *N, const SDLoc &DL, EVT Ty,
228 SelectionDAG &DAG) const {
229 SDValue Hi = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI);
230 SDValue Lo = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO);
231 return DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty,
232 N1: DAG.getNode(Opcode: MipsISD::Hi, DL, VT: Ty, Operand: Hi),
233 N2: DAG.getNode(Opcode: MipsISD::Lo, DL, VT: Ty, Operand: Lo));
234 }
235
236 // This method creates the following nodes, which are necessary for
237 // computing a symbol's address in non-PIC mode for N64.
238 //
239 // (add (shl (add (shl (add %highest(sym), %higher(sim)), 16), %high(sym)),
240 // 16), %lo(%sym))
241 //
242 // FIXME: This method is not efficent for (micro)MIPS64R6.
243 template <class NodeTy>
244 SDValue getAddrNonPICSym64(NodeTy *N, const SDLoc &DL, EVT Ty,
245 SelectionDAG &DAG) const {
246 SDValue Hi = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI);
247 SDValue Lo = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO);
248
249 SDValue Highest =
250 DAG.getNode(MipsISD::Highest, DL, Ty,
251 getTargetNode(N, Ty, DAG, MipsII::MO_HIGHEST));
252 SDValue Higher = getTargetNode(N, Ty, DAG, MipsII::MO_HIGHER);
253 SDValue HigherPart =
254 DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty, N1: Highest,
255 N2: DAG.getNode(Opcode: MipsISD::Higher, DL, VT: Ty, Operand: Higher));
256 SDValue Cst = DAG.getConstant(Val: 16, DL, VT: MVT::i32);
257 SDValue Shift = DAG.getNode(Opcode: ISD::SHL, DL, VT: Ty, N1: HigherPart, N2: Cst);
258 SDValue Add = DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty, N1: Shift,
259 N2: DAG.getNode(Opcode: MipsISD::Hi, DL, VT: Ty, Operand: Hi));
260 SDValue Shift2 = DAG.getNode(Opcode: ISD::SHL, DL, VT: Ty, N1: Add, N2: Cst);
261
262 return DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty, N1: Shift2,
263 N2: DAG.getNode(Opcode: MipsISD::Lo, DL, VT: Ty, Operand: Lo));
264 }
265
266 // This method creates the following nodes, which are necessary for
267 // computing a symbol's address using gp-relative addressing:
268 //
269 // (add $gp, %gp_rel(sym))
270 template <class NodeTy>
271 SDValue getAddrGPRel(NodeTy *N, const SDLoc &DL, EVT Ty,
272 SelectionDAG &DAG, bool IsN64) const {
273 SDValue GPRel = getTargetNode(N, Ty, DAG, MipsII::MO_GPREL);
274 return DAG.getNode(
275 Opcode: ISD::ADD, DL, VT: Ty,
276 N1: DAG.getRegister(Reg: IsN64 ? Mips::GP_64 : Mips::GP, VT: Ty),
277 N2: DAG.getNode(Opcode: MipsISD::GPRel, DL, VTList: DAG.getVTList(VT: Ty), N: GPRel));
278 }
279
280 // This method creates the following nodes, which are necessary for
281 // loading a dllimported symbol:
282 //
283 // (lw (add (shl(%high(sym), 16), %low(sym)))
284 template <class NodeTy>
285 SDValue getDllimportSymbol(NodeTy *N, const SDLoc &DL, EVT Ty,
286 SelectionDAG &DAG) const {
287 SDValue Hi =
288 getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI | MipsII::MO_DLLIMPORT);
289 SDValue Lo =
290 getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO | MipsII::MO_DLLIMPORT);
291 return DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty, N1: DAG.getNode(Opcode: MipsISD::Lo, DL, VT: Ty, Operand: Lo),
292 N2: DAG.getNode(Opcode: MipsISD::Hi, DL, VT: Ty, Operand: Hi));
293 }
294
295 // This method creates the following nodes, which are necessary for
296 // loading a dllimported global variable:
297 //
298 // (lw (lw (add (shl(%high(sym), 16), %low(sym))))
299 template <class NodeTy>
300 SDValue getDllimportVariable(NodeTy *N, const SDLoc &DL, EVT Ty,
301 SelectionDAG &DAG, SDValue Chain,
302 const MachinePointerInfo &PtrInfo) const {
303 return DAG.getLoad(Ty, DL, Chain, getDllimportSymbol(N, DL, Ty, DAG),
304 PtrInfo);
305 }
306
307 /// This function fills Ops, which is the list of operands that will later
308 /// be used when a function call node is created. It also generates
309 /// copyToReg nodes to set up argument registers.
310 virtual void
311 getOpndList(SmallVectorImpl<SDValue> &Ops,
312 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
313 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
314 bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
315 SDValue Chain) const;
316
317 protected:
318 SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const;
319 SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const;
320
321 // Subtarget Info
322 const MipsSubtarget &Subtarget;
323 // Cache the ABI from the TargetMachine, we use it everywhere.
324 const MipsABIInfo &ABI;
325
326 private:
327 // Create a TargetGlobalAddress node.
328 SDValue getTargetNode(GlobalAddressSDNode *N, EVT Ty, SelectionDAG &DAG,
329 unsigned Flag) const;
330
331 // Create a TargetExternalSymbol node.
332 SDValue getTargetNode(ExternalSymbolSDNode *N, EVT Ty, SelectionDAG &DAG,
333 unsigned Flag) const;
334
335 // Create a TargetBlockAddress node.
336 SDValue getTargetNode(BlockAddressSDNode *N, EVT Ty, SelectionDAG &DAG,
337 unsigned Flag) const;
338
339 // Create a TargetJumpTable node.
340 SDValue getTargetNode(JumpTableSDNode *N, EVT Ty, SelectionDAG &DAG,
341 unsigned Flag) const;
342
343 // Create a TargetConstantPool node.
344 SDValue getTargetNode(ConstantPoolSDNode *N, EVT Ty, SelectionDAG &DAG,
345 unsigned Flag) const;
346
347 // Lower Operand helpers
348 SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
349 CallingConv::ID CallConv, bool isVarArg,
350 const SmallVectorImpl<ISD::InputArg> &Ins,
351 const SDLoc &dl, SelectionDAG &DAG,
352 SmallVectorImpl<SDValue> &InVals,
353 TargetLowering::CallLoweringInfo &CLI) const;
354
355 // Lower Operand specifics
356 SDValue lowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
357 SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
358 SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
359 SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
360 SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
361 SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
362 SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const;
363 SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const;
364 SDValue lowerFSETCC(SDValue Op, SelectionDAG &DAG) const;
365 SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
366 SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const;
367 SDValue lowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const;
368 SDValue lowerFABS(SDValue Op, SelectionDAG &DAG) const;
369 SDValue lowerFABS32(SDValue Op, SelectionDAG &DAG,
370 bool HasExtractInsert) const;
371 SDValue lowerFABS64(SDValue Op, SelectionDAG &DAG,
372 bool HasExtractInsert) const;
373 SDValue lowerFCANONICALIZE(SDValue Op, SelectionDAG &DAG) const;
374 SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
375 SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
376 SDValue lowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
377 SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
378 SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG& DAG) const;
379 SDValue lowerShiftRightParts(SDValue Op, SelectionDAG& DAG,
380 bool IsSRA) const;
381 SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const;
382 SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const;
383 SDValue lowerSTRICT_FP_TO_INT(SDValue Op, SelectionDAG &DAG) const;
384 SDValue lowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const;
385
386 /// isEligibleForTailCallOptimization - Check whether the call is eligible
387 /// for tail call optimization.
388 virtual bool
389 isEligibleForTailCallOptimization(const CCState &CCInfo,
390 unsigned NextStackOffset,
391 const MipsFunctionInfo &FI) const = 0;
392
393 /// copyByValArg - Copy argument registers which were used to pass a byval
394 /// argument to the stack. Create a stack frame object for the byval
395 /// argument.
396 void copyByValRegs(SDValue Chain, const SDLoc &DL,
397 std::vector<SDValue> &OutChains, SelectionDAG &DAG,
398 const ISD::ArgFlagsTy &Flags,
399 SmallVectorImpl<SDValue> &InVals,
400 const Argument *FuncArg, unsigned FirstReg,
401 unsigned LastReg, const CCValAssign &VA,
402 MipsCCState &State) const;
403
404 /// passByValArg - Pass a byval argument in registers or on stack.
405 void passByValArg(SDValue Chain, const SDLoc &DL,
406 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
407 SmallVectorImpl<SDValue> &MemOpChains, SDValue StackPtr,
408 MachineFrameInfo &MFI, SelectionDAG &DAG, SDValue Arg,
409 unsigned FirstReg, unsigned LastReg,
410 const ISD::ArgFlagsTy &Flags, bool isLittle,
411 const CCValAssign &VA) const;
412
413 /// writeVarArgRegs - Write variable function arguments passed in registers
414 /// to the stack. Also create a stack frame object for the first variable
415 /// argument.
416 void writeVarArgRegs(std::vector<SDValue> &OutChains, SDValue Chain,
417 const SDLoc &DL, SelectionDAG &DAG,
418 CCState &State) const;
419
420 SDValue
421 LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
422 const SmallVectorImpl<ISD::InputArg> &Ins,
423 const SDLoc &dl, SelectionDAG &DAG,
424 SmallVectorImpl<SDValue> &InVals) const override;
425
426 SDValue passArgOnStack(SDValue StackPtr, unsigned Offset, SDValue Chain,
427 SDValue Arg, const SDLoc &DL, bool IsTailCall,
428 SelectionDAG &DAG) const;
429
430 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
431 SmallVectorImpl<SDValue> &InVals) const override;
432
433 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
434 bool isVarArg,
435 const SmallVectorImpl<ISD::OutputArg> &Outs,
436 LLVMContext &Context, const Type *RetTy) const override;
437
438 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
439 const SmallVectorImpl<ISD::OutputArg> &Outs,
440 const SmallVectorImpl<SDValue> &OutVals,
441 const SDLoc &dl, SelectionDAG &DAG) const override;
442
443 SDValue LowerInterruptReturn(SmallVectorImpl<SDValue> &RetOps,
444 const SDLoc &DL, SelectionDAG &DAG) const;
445
446 bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const override;
447
448 // Inline asm support
449 ConstraintType getConstraintType(StringRef Constraint) const override;
450
451 /// Examine constraint string and operand type and determine a weight value.
452 /// The operand object must already have been set up with the operand type.
453 ConstraintWeight getSingleConstraintMatchWeight(
454 AsmOperandInfo &info, const char *constraint) const override;
455
456 /// This function parses registers that appear in inline-asm constraints.
457 /// It returns pair (0, 0) on failure.
458 std::pair<unsigned, const TargetRegisterClass *>
459 parseRegForInlineAsmConstraint(StringRef C, MVT VT) const;
460
461 std::pair<unsigned, const TargetRegisterClass *>
462 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
463 StringRef Constraint, MVT VT) const override;
464
465 /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
466 /// vector. If it is invalid, don't add anything to Ops. If hasMemory is
467 /// true it means one of the asm constraint of the inline asm instruction
468 /// being processed is 'm'.
469 void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint,
470 std::vector<SDValue> &Ops,
471 SelectionDAG &DAG) const override;
472
473 InlineAsm::ConstraintCode
474 getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
475 if (ConstraintCode == "o")
476 return InlineAsm::ConstraintCode::o;
477 if (ConstraintCode == "R")
478 return InlineAsm::ConstraintCode::R;
479 if (ConstraintCode == "ZC")
480 return InlineAsm::ConstraintCode::ZC;
481 return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
482 }
483
484 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
485 Type *Ty, unsigned AS,
486 Instruction *I = nullptr) const override;
487
488 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
489
490 EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
491 const AttributeList &FuncAttributes) const override;
492
493 /// isFPImmLegal - Returns true if the target can instruction select the
494 /// specified FP immediate natively. If false, the legalizer will
495 /// materialize the FP immediate as a load from a constant pool.
496 bool isFPImmLegal(const APFloat &Imm, EVT VT,
497 bool ForCodeSize) const override;
498
499 bool isLegalICmpImmediate(int64_t Imm) const override;
500 bool isLegalAddImmediate(int64_t Imm) const override;
501
502 unsigned getJumpTableEncoding() const override;
503 SDValue getPICJumpTableRelocBase(SDValue Table,
504 SelectionDAG &DAG) const override;
505 bool useSoftFloat() const override;
506
507 bool shouldInsertFencesForAtomic(const Instruction *I) const override {
508 return true;
509 }
510
511 int getCPURegisterIndex(StringRef Name) const;
512
513 ArrayRef<MCPhysReg> getRoundingControlRegisters() const override;
514
515 /// Emit a sign-extension using sll/sra, seb, or seh appropriately.
516 MachineBasicBlock *emitSignExtendToI32InReg(MachineInstr &MI,
517 MachineBasicBlock *BB,
518 unsigned Size, unsigned DstReg,
519 unsigned SrcRec) const;
520
521 MachineBasicBlock *emitAtomicBinary(MachineInstr &MI,
522 MachineBasicBlock *BB) const;
523 MachineBasicBlock *emitAtomicBinaryPartword(MachineInstr &MI,
524 MachineBasicBlock *BB,
525 unsigned Size) const;
526 MachineBasicBlock *emitAtomicCmpSwap(MachineInstr &MI,
527 MachineBasicBlock *BB) const;
528 MachineBasicBlock *emitAtomicCmpSwapPartword(MachineInstr &MI,
529 MachineBasicBlock *BB,
530 unsigned Size) const;
531 MachineBasicBlock *emitSEL_D(MachineInstr &MI, MachineBasicBlock *BB) const;
532 MachineBasicBlock *emitPseudoSELECT(MachineInstr &MI, MachineBasicBlock *BB,
533 bool isFPCmp, unsigned Opc) const;
534 MachineBasicBlock *emitPseudoD_SELECT(MachineInstr &MI,
535 MachineBasicBlock *BB) const;
536 MachineBasicBlock *emitLDR_W(MachineInstr &MI, MachineBasicBlock *BB) const;
537 MachineBasicBlock *emitLDR_D(MachineInstr &MI, MachineBasicBlock *BB) const;
538 MachineBasicBlock *emitSTR_W(MachineInstr &MI, MachineBasicBlock *BB) const;
539 MachineBasicBlock *emitSTR_D(MachineInstr &MI, MachineBasicBlock *BB) const;
540 };
541
542 /// Create MipsTargetLowering objects.
543 const MipsTargetLowering *
544 createMips16TargetLowering(const MipsTargetMachine &TM,
545 const MipsSubtarget &STI);
546 const MipsTargetLowering *
547 createMipsSETargetLowering(const MipsTargetMachine &TM,
548 const MipsSubtarget &STI);
549
550namespace Mips {
551
552FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
553 const TargetLibraryInfo *libInfo,
554 const LibcallLoweringInfo *libcallLowering);
555
556} // end namespace Mips
557
558} // end namespace llvm
559
560#endif // LLVM_LIB_TARGET_MIPS_MIPSISELLOWERING_H
561