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.getArgRegPtr(I: 0);
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.getArgRegPtr(I: 1);
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 LocalLinkage,
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 SDValue lowerConstantFP(SDValue Op, SelectionDAG &DAG) const;
386
387 /// isEligibleForTailCallOptimization - Check whether the call is eligible
388 /// for tail call optimization.
389 virtual bool
390 isEligibleForTailCallOptimization(const CCState &CCInfo,
391 unsigned NextStackOffset,
392 const MipsFunctionInfo &FI) const = 0;
393
394 /// copyByValArg - Copy argument registers which were used to pass a byval
395 /// argument to the stack. Create a stack frame object for the byval
396 /// argument.
397 void copyByValRegs(SDValue Chain, const SDLoc &DL,
398 std::vector<SDValue> &OutChains, SelectionDAG &DAG,
399 const ISD::ArgFlagsTy &Flags,
400 SmallVectorImpl<SDValue> &InVals,
401 const Argument *FuncArg, unsigned FirstReg,
402 unsigned LastReg, const CCValAssign &VA,
403 MipsCCState &State) const;
404
405 /// passByValArg - Pass a byval argument in registers or on stack.
406 void passByValArg(SDValue Chain, const SDLoc &DL,
407 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
408 SmallVectorImpl<SDValue> &MemOpChains, SDValue StackPtr,
409 MachineFrameInfo &MFI, SelectionDAG &DAG, SDValue Arg,
410 unsigned FirstReg, unsigned LastReg,
411 const ISD::ArgFlagsTy &Flags, bool isLittle,
412 const CCValAssign &VA) const;
413
414 /// writeVarArgRegs - Write variable function arguments passed in registers
415 /// to the stack. Also create a stack frame object for the first variable
416 /// argument.
417 void writeVarArgRegs(std::vector<SDValue> &OutChains, SDValue Chain,
418 const SDLoc &DL, SelectionDAG &DAG,
419 CCState &State) const;
420
421 SDValue
422 LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
423 const SmallVectorImpl<ISD::InputArg> &Ins,
424 const SDLoc &dl, SelectionDAG &DAG,
425 SmallVectorImpl<SDValue> &InVals) const override;
426
427 SDValue passArgOnStack(SDValue StackPtr, unsigned Offset, SDValue Chain,
428 SDValue Arg, const SDLoc &DL, bool IsTailCall,
429 SelectionDAG &DAG) const;
430
431 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
432 SmallVectorImpl<SDValue> &InVals) const override;
433
434 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
435 bool isVarArg,
436 const SmallVectorImpl<ISD::OutputArg> &Outs,
437 LLVMContext &Context, const Type *RetTy) const override;
438
439 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
440 const SmallVectorImpl<ISD::OutputArg> &Outs,
441 const SmallVectorImpl<SDValue> &OutVals,
442 const SDLoc &dl, SelectionDAG &DAG) const override;
443
444 SDValue LowerInterruptReturn(SmallVectorImpl<SDValue> &RetOps,
445 const SDLoc &DL, SelectionDAG &DAG) const;
446
447 bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const override;
448
449 // Inline asm support
450 ConstraintType getConstraintType(StringRef Constraint) const override;
451
452 /// Examine constraint string and operand type and determine a weight value.
453 /// The operand object must already have been set up with the operand type.
454 ConstraintWeight getSingleConstraintMatchWeight(
455 AsmOperandInfo &info, const char *constraint) const override;
456
457 /// This function parses registers that appear in inline-asm constraints.
458 /// It returns pair (0, 0) on failure.
459 std::pair<unsigned, const TargetRegisterClass *>
460 parseRegForInlineAsmConstraint(StringRef C, MVT VT) const;
461
462 std::pair<unsigned, const TargetRegisterClass *>
463 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
464 StringRef Constraint, MVT VT) const override;
465
466 /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
467 /// vector. If it is invalid, don't add anything to Ops. If hasMemory is
468 /// true it means one of the asm constraint of the inline asm instruction
469 /// being processed is 'm'.
470 void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint,
471 std::vector<SDValue> &Ops,
472 SelectionDAG &DAG) const override;
473
474 InlineAsm::ConstraintCode
475 getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
476 if (ConstraintCode == "o")
477 return InlineAsm::ConstraintCode::o;
478 if (ConstraintCode == "R")
479 return InlineAsm::ConstraintCode::R;
480 if (ConstraintCode == "ZC")
481 return InlineAsm::ConstraintCode::ZC;
482 return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
483 }
484
485 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
486 Type *Ty, unsigned AS,
487 Instruction *I = nullptr) const override;
488
489 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
490
491 EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
492 const AttributeList &FuncAttributes) const override;
493
494 /// isFPImmLegal - Returns true if the target can instruction select the
495 /// specified FP immediate natively. If false, the legalizer will
496 /// materialize the FP immediate as a load from a constant pool.
497 bool isFPImmLegal(const APFloat &Imm, EVT VT,
498 bool ForCodeSize) const override;
499
500 bool isLegalICmpImmediate(int64_t Imm) const override;
501 bool isLegalAddImmediate(int64_t Imm) const override;
502
503 unsigned getJumpTableEncoding() const override;
504 SDValue getPICJumpTableRelocBase(SDValue Table,
505 SelectionDAG &DAG) const override;
506 bool useSoftFloat() const override;
507
508 bool shouldInsertFencesForAtomic(const Instruction *I) const override {
509 return true;
510 }
511
512 ArrayRef<MCPhysReg> getRoundingControlRegisters() const override;
513
514 /// Emit a sign-extension using sll/sra, seb, or seh appropriately.
515 MachineBasicBlock *emitSignExtendToI32InReg(MachineInstr &MI,
516 MachineBasicBlock *BB,
517 unsigned Size, unsigned DstReg,
518 unsigned SrcRec) const;
519
520 MachineBasicBlock *emitAtomicBinary(MachineInstr &MI,
521 MachineBasicBlock *BB) const;
522 MachineBasicBlock *emitAtomicBinaryPartword(MachineInstr &MI,
523 MachineBasicBlock *BB,
524 unsigned Size) const;
525 MachineBasicBlock *emitAtomicCmpSwap(MachineInstr &MI,
526 MachineBasicBlock *BB) const;
527 MachineBasicBlock *emitAtomicCmpSwapPartword(MachineInstr &MI,
528 MachineBasicBlock *BB,
529 unsigned Size) const;
530 MachineBasicBlock *emitPseudoSELECT(MachineInstr &MI, MachineBasicBlock *BB,
531 bool isFPCmp, unsigned Opc) const;
532 MachineBasicBlock *emitPseudoD_SELECT(MachineInstr &MI,
533 MachineBasicBlock *BB) const;
534 MachineBasicBlock *emitLDR_W(MachineInstr &MI, MachineBasicBlock *BB) const;
535 MachineBasicBlock *emitLDR_D(MachineInstr &MI, MachineBasicBlock *BB) const;
536 MachineBasicBlock *emitSTR_W(MachineInstr &MI, MachineBasicBlock *BB) const;
537 MachineBasicBlock *emitSTR_D(MachineInstr &MI, MachineBasicBlock *BB) const;
538 };
539
540 /// Create MipsTargetLowering objects.
541 const MipsTargetLowering *
542 createMips16TargetLowering(const MipsTargetMachine &TM,
543 const MipsSubtarget &STI);
544 const MipsTargetLowering *
545 createMipsSETargetLowering(const MipsTargetMachine &TM,
546 const MipsSubtarget &STI);
547
548namespace Mips {
549
550FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
551 const TargetLibraryInfo *libInfo,
552 const LibcallLoweringInfo *libcallLowering);
553
554} // end namespace Mips
555
556} // end namespace llvm
557
558#endif // LLVM_LIB_TARGET_MIPS_MIPSISELLOWERING_H
559