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