Coverage Report

Created: 2019-07-24 05:18

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