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(const Constant *PersonalityFn) const override {
148 return ABI.IsN64() ? Mips::A0_64 : Mips::A0;
149 }
150
151 /// If a physical register, this returns the register that receives the
152 /// exception typeid on entry to a landing pad.
153 Register
154 getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
155 return ABI.IsN64() ? Mips::A1_64 : Mips::A1;
156 }
157
158 bool isJumpTableRelative() const override {
159 return getTargetMachine().isPositionIndependent();
160 }
161
162 CCAssignFn *CCAssignFnForCall() const;
163
164 CCAssignFn *CCAssignFnForReturn() const;
165
166 protected:
167 SDValue getGlobalReg(SelectionDAG &DAG, EVT Ty) const;
168
169 // This method creates the following nodes, which are necessary for
170 // computing a local symbol's address:
171 //
172 // (add (load (wrapper $gp, %got(sym)), %lo(sym))
173 template <class NodeTy>
174 SDValue getAddrLocal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG,
175 bool IsN32OrN64) const {
176 unsigned GOTFlag = IsN32OrN64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT;
177 SDValue GOT = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty),
178 getTargetNode(N, Ty, DAG, GOTFlag));
179 SDValue Load =
180 DAG.getLoad(VT: Ty, dl: DL, Chain: DAG.getEntryNode(), Ptr: GOT,
181 PtrInfo: MachinePointerInfo::getGOT(MF&: DAG.getMachineFunction()));
182 unsigned LoFlag = IsN32OrN64 ? MipsII::MO_GOT_OFST : MipsII::MO_ABS_LO;
183 SDValue Lo = DAG.getNode(MipsISD::Lo, DL, Ty,
184 getTargetNode(N, Ty, DAG, LoFlag));
185 return DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty, N1: Load, N2: Lo);
186 }
187
188 // This method creates the following nodes, which are necessary for
189 // computing a global symbol's address:
190 //
191 // (load (wrapper $gp, %got(sym)))
192 template <class NodeTy>
193 SDValue getAddrGlobal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG,
194 unsigned Flag, SDValue Chain,
195 const MachinePointerInfo &PtrInfo) const {
196 SDValue Tgt = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty),
197 getTargetNode(N, Ty, DAG, Flag));
198 return DAG.getLoad(VT: Ty, dl: DL, Chain, Ptr: Tgt, PtrInfo);
199 }
200
201 // This method creates the following nodes, which are necessary for
202 // computing a global symbol's address in large-GOT mode:
203 //
204 // (load (wrapper (add %hi(sym), $gp), %lo(sym)))
205 template <class NodeTy>
206 SDValue getAddrGlobalLargeGOT(NodeTy *N, const SDLoc &DL, EVT Ty,
207 SelectionDAG &DAG, unsigned HiFlag,
208 unsigned LoFlag, SDValue Chain,
209 const MachinePointerInfo &PtrInfo) const {
210 SDValue Hi = DAG.getNode(MipsISD::GotHi, DL, Ty,
211 getTargetNode(N, Ty, DAG, HiFlag));
212 Hi = DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty, N1: Hi, N2: getGlobalReg(DAG, Ty));
213 SDValue Wrapper = DAG.getNode(MipsISD::Wrapper, DL, Ty, Hi,
214 getTargetNode(N, Ty, DAG, LoFlag));
215 return DAG.getLoad(VT: Ty, dl: DL, Chain, Ptr: Wrapper, PtrInfo);
216 }
217
218 // This method creates the following nodes, which are necessary for
219 // computing a symbol's address in non-PIC mode:
220 //
221 // (add %hi(sym), %lo(sym))
222 //
223 // This method covers O32, N32 and N64 in sym32 mode.
224 template <class NodeTy>
225 SDValue getAddrNonPIC(NodeTy *N, const SDLoc &DL, EVT Ty,
226 SelectionDAG &DAG) const {
227 SDValue Hi = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI);
228 SDValue Lo = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO);
229 return DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty,
230 N1: DAG.getNode(Opcode: MipsISD::Hi, DL, VT: Ty, Operand: Hi),
231 N2: DAG.getNode(Opcode: MipsISD::Lo, DL, VT: Ty, Operand: Lo));
232 }
233
234 // This method creates the following nodes, which are necessary for
235 // computing a symbol's address in non-PIC mode for N64.
236 //
237 // (add (shl (add (shl (add %highest(sym), %higher(sim)), 16), %high(sym)),
238 // 16), %lo(%sym))
239 //
240 // FIXME: This method is not efficent for (micro)MIPS64R6.
241 template <class NodeTy>
242 SDValue getAddrNonPICSym64(NodeTy *N, const SDLoc &DL, EVT Ty,
243 SelectionDAG &DAG) const {
244 SDValue Hi = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI);
245 SDValue Lo = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO);
246
247 SDValue Highest =
248 DAG.getNode(MipsISD::Highest, DL, Ty,
249 getTargetNode(N, Ty, DAG, MipsII::MO_HIGHEST));
250 SDValue Higher = getTargetNode(N, Ty, DAG, MipsII::MO_HIGHER);
251 SDValue HigherPart =
252 DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty, N1: Highest,
253 N2: DAG.getNode(Opcode: MipsISD::Higher, DL, VT: Ty, Operand: Higher));
254 SDValue Cst = DAG.getConstant(Val: 16, DL, VT: MVT::i32);
255 SDValue Shift = DAG.getNode(Opcode: ISD::SHL, DL, VT: Ty, N1: HigherPart, N2: Cst);
256 SDValue Add = DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty, N1: Shift,
257 N2: DAG.getNode(Opcode: MipsISD::Hi, DL, VT: Ty, Operand: Hi));
258 SDValue Shift2 = DAG.getNode(Opcode: ISD::SHL, DL, VT: Ty, N1: Add, N2: Cst);
259
260 return DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty, N1: Shift2,
261 N2: DAG.getNode(Opcode: MipsISD::Lo, DL, VT: Ty, Operand: Lo));
262 }
263
264 // This method creates the following nodes, which are necessary for
265 // computing a symbol's address using gp-relative addressing:
266 //
267 // (add $gp, %gp_rel(sym))
268 template <class NodeTy>
269 SDValue getAddrGPRel(NodeTy *N, const SDLoc &DL, EVT Ty,
270 SelectionDAG &DAG, bool IsN64) const {
271 SDValue GPRel = getTargetNode(N, Ty, DAG, MipsII::MO_GPREL);
272 return DAG.getNode(
273 Opcode: ISD::ADD, DL, VT: Ty,
274 N1: DAG.getRegister(Reg: IsN64 ? Mips::GP_64 : Mips::GP, VT: Ty),
275 N2: DAG.getNode(Opcode: MipsISD::GPRel, DL, VTList: DAG.getVTList(VT: Ty), N: GPRel));
276 }
277
278 // This method creates the following nodes, which are necessary for
279 // loading a dllimported symbol:
280 //
281 // (lw (add (shl(%high(sym), 16), %low(sym)))
282 template <class NodeTy>
283 SDValue getDllimportSymbol(NodeTy *N, const SDLoc &DL, EVT Ty,
284 SelectionDAG &DAG) const {
285 SDValue Hi =
286 getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI | MipsII::MO_DLLIMPORT);
287 SDValue Lo =
288 getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO | MipsII::MO_DLLIMPORT);
289 return DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty, N1: DAG.getNode(Opcode: MipsISD::Lo, DL, VT: Ty, Operand: Lo),
290 N2: DAG.getNode(Opcode: MipsISD::Hi, DL, VT: Ty, Operand: Hi));
291 }
292
293 // This method creates the following nodes, which are necessary for
294 // loading a dllimported global variable:
295 //
296 // (lw (lw (add (shl(%high(sym), 16), %low(sym))))
297 template <class NodeTy>
298 SDValue getDllimportVariable(NodeTy *N, const SDLoc &DL, EVT Ty,
299 SelectionDAG &DAG, SDValue Chain,
300 const MachinePointerInfo &PtrInfo) const {
301 return DAG.getLoad(Ty, DL, Chain, getDllimportSymbol(N, DL, Ty, DAG),
302 PtrInfo);
303 }
304
305 /// This function fills Ops, which is the list of operands that will later
306 /// be used when a function call node is created. It also generates
307 /// copyToReg nodes to set up argument registers.
308 virtual void
309 getOpndList(SmallVectorImpl<SDValue> &Ops,
310 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
311 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
312 bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
313 SDValue Chain) const;
314
315 protected:
316 SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const;
317 SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const;
318
319 // Subtarget Info
320 const MipsSubtarget &Subtarget;
321 // Cache the ABI from the TargetMachine, we use it everywhere.
322 const MipsABIInfo &ABI;
323
324 private:
325 // Create a TargetGlobalAddress node.
326 SDValue getTargetNode(GlobalAddressSDNode *N, EVT Ty, SelectionDAG &DAG,
327 unsigned Flag) const;
328
329 // Create a TargetExternalSymbol node.
330 SDValue getTargetNode(ExternalSymbolSDNode *N, EVT Ty, SelectionDAG &DAG,
331 unsigned Flag) const;
332
333 // Create a TargetBlockAddress node.
334 SDValue getTargetNode(BlockAddressSDNode *N, EVT Ty, SelectionDAG &DAG,
335 unsigned Flag) const;
336
337 // Create a TargetJumpTable node.
338 SDValue getTargetNode(JumpTableSDNode *N, EVT Ty, SelectionDAG &DAG,
339 unsigned Flag) const;
340
341 // Create a TargetConstantPool node.
342 SDValue getTargetNode(ConstantPoolSDNode *N, EVT Ty, SelectionDAG &DAG,
343 unsigned Flag) const;
344
345 // Lower Operand helpers
346 SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
347 CallingConv::ID CallConv, bool isVarArg,
348 const SmallVectorImpl<ISD::InputArg> &Ins,
349 const SDLoc &dl, SelectionDAG &DAG,
350 SmallVectorImpl<SDValue> &InVals,
351 TargetLowering::CallLoweringInfo &CLI) const;
352
353 // Lower Operand specifics
354 SDValue lowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
355 SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
356 SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
357 SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
358 SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
359 SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
360 SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const;
361 SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const;
362 SDValue lowerFSETCC(SDValue Op, SelectionDAG &DAG) const;
363 SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
364 SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const;
365 SDValue lowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const;
366 SDValue lowerFABS(SDValue Op, SelectionDAG &DAG) const;
367 SDValue lowerFABS32(SDValue Op, SelectionDAG &DAG,
368 bool HasExtractInsert) const;
369 SDValue lowerFABS64(SDValue Op, SelectionDAG &DAG,
370 bool HasExtractInsert) const;
371 SDValue lowerFCANONICALIZE(SDValue Op, SelectionDAG &DAG) const;
372 SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
373 SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
374 SDValue lowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
375 SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
376 SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG& DAG) const;
377 SDValue lowerShiftRightParts(SDValue Op, SelectionDAG& DAG,
378 bool IsSRA) const;
379 SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const;
380 SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const;
381 SDValue lowerSTRICT_FP_TO_INT(SDValue Op, SelectionDAG &DAG) const;
382 SDValue lowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const;
383
384 /// isEligibleForTailCallOptimization - Check whether the call is eligible
385 /// for tail call optimization.
386 virtual bool
387 isEligibleForTailCallOptimization(const CCState &CCInfo,
388 unsigned NextStackOffset,
389 const MipsFunctionInfo &FI) const = 0;
390
391 /// copyByValArg - Copy argument registers which were used to pass a byval
392 /// argument to the stack. Create a stack frame object for the byval
393 /// argument.
394 void copyByValRegs(SDValue Chain, const SDLoc &DL,
395 std::vector<SDValue> &OutChains, SelectionDAG &DAG,
396 const ISD::ArgFlagsTy &Flags,
397 SmallVectorImpl<SDValue> &InVals,
398 const Argument *FuncArg, unsigned FirstReg,
399 unsigned LastReg, const CCValAssign &VA,
400 MipsCCState &State) const;
401
402 /// passByValArg - Pass a byval argument in registers or on stack.
403 void passByValArg(SDValue Chain, const SDLoc &DL,
404 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
405 SmallVectorImpl<SDValue> &MemOpChains, SDValue StackPtr,
406 MachineFrameInfo &MFI, SelectionDAG &DAG, SDValue Arg,
407 unsigned FirstReg, unsigned LastReg,
408 const ISD::ArgFlagsTy &Flags, bool isLittle,
409 const CCValAssign &VA) const;
410
411 /// writeVarArgRegs - Write variable function arguments passed in registers
412 /// to the stack. Also create a stack frame object for the first variable
413 /// argument.
414 void writeVarArgRegs(std::vector<SDValue> &OutChains, SDValue Chain,
415 const SDLoc &DL, SelectionDAG &DAG,
416 CCState &State) const;
417
418 SDValue
419 LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
420 const SmallVectorImpl<ISD::InputArg> &Ins,
421 const SDLoc &dl, SelectionDAG &DAG,
422 SmallVectorImpl<SDValue> &InVals) const override;
423
424 SDValue passArgOnStack(SDValue StackPtr, unsigned Offset, SDValue Chain,
425 SDValue Arg, const SDLoc &DL, bool IsTailCall,
426 SelectionDAG &DAG) const;
427
428 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
429 SmallVectorImpl<SDValue> &InVals) const override;
430
431 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
432 bool isVarArg,
433 const SmallVectorImpl<ISD::OutputArg> &Outs,
434 LLVMContext &Context, const Type *RetTy) const override;
435
436 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
437 const SmallVectorImpl<ISD::OutputArg> &Outs,
438 const SmallVectorImpl<SDValue> &OutVals,
439 const SDLoc &dl, SelectionDAG &DAG) const override;
440
441 SDValue LowerInterruptReturn(SmallVectorImpl<SDValue> &RetOps,
442 const SDLoc &DL, SelectionDAG &DAG) const;
443
444 bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const override;
445
446 // Inline asm support
447 ConstraintType getConstraintType(StringRef Constraint) const override;
448
449 /// Examine constraint string and operand type and determine a weight value.
450 /// The operand object must already have been set up with the operand type.
451 ConstraintWeight getSingleConstraintMatchWeight(
452 AsmOperandInfo &info, const char *constraint) const override;
453
454 /// This function parses registers that appear in inline-asm constraints.
455 /// It returns pair (0, 0) on failure.
456 std::pair<unsigned, const TargetRegisterClass *>
457 parseRegForInlineAsmConstraint(StringRef C, MVT VT) const;
458
459 std::pair<unsigned, const TargetRegisterClass *>
460 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
461 StringRef Constraint, MVT VT) const override;
462
463 /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
464 /// vector. If it is invalid, don't add anything to Ops. If hasMemory is
465 /// true it means one of the asm constraint of the inline asm instruction
466 /// being processed is 'm'.
467 void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint,
468 std::vector<SDValue> &Ops,
469 SelectionDAG &DAG) const override;
470
471 InlineAsm::ConstraintCode
472 getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
473 if (ConstraintCode == "o")
474 return InlineAsm::ConstraintCode::o;
475 if (ConstraintCode == "R")
476 return InlineAsm::ConstraintCode::R;
477 if (ConstraintCode == "ZC")
478 return InlineAsm::ConstraintCode::ZC;
479 return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
480 }
481
482 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
483 Type *Ty, unsigned AS,
484 Instruction *I = nullptr) const override;
485
486 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
487
488 EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
489 const AttributeList &FuncAttributes) const override;
490
491 /// isFPImmLegal - Returns true if the target can instruction select the
492 /// specified FP immediate natively. If false, the legalizer will
493 /// materialize the FP immediate as a load from a constant pool.
494 bool isFPImmLegal(const APFloat &Imm, EVT VT,
495 bool ForCodeSize) const override;
496
497 bool isLegalICmpImmediate(int64_t Imm) const override;
498 bool isLegalAddImmediate(int64_t Imm) const override;
499
500 unsigned getJumpTableEncoding() const override;
501 SDValue getPICJumpTableRelocBase(SDValue Table,
502 SelectionDAG &DAG) const override;
503 bool useSoftFloat() const override;
504
505 bool shouldInsertFencesForAtomic(const Instruction *I) const override {
506 return true;
507 }
508
509 int getCPURegisterIndex(StringRef Name) const;
510
511 ArrayRef<MCPhysReg> getRoundingControlRegisters() const override;
512
513 /// Emit a sign-extension using sll/sra, seb, or seh appropriately.
514 MachineBasicBlock *emitSignExtendToI32InReg(MachineInstr &MI,
515 MachineBasicBlock *BB,
516 unsigned Size, unsigned DstReg,
517 unsigned SrcRec) const;
518
519 MachineBasicBlock *emitAtomicBinary(MachineInstr &MI,
520 MachineBasicBlock *BB) const;
521 MachineBasicBlock *emitAtomicBinaryPartword(MachineInstr &MI,
522 MachineBasicBlock *BB,
523 unsigned Size) const;
524 MachineBasicBlock *emitAtomicCmpSwap(MachineInstr &MI,
525 MachineBasicBlock *BB) const;
526 MachineBasicBlock *emitAtomicCmpSwapPartword(MachineInstr &MI,
527 MachineBasicBlock *BB,
528 unsigned Size) const;
529 MachineBasicBlock *emitSEL_D(MachineInstr &MI, MachineBasicBlock *BB) 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