Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
MipsISelLowering.cpp
Go to the documentation of this file.
1//===- MipsISelLowering.cpp - Mips DAG Lowering Implementation ------------===//
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#include "MipsISelLowering.h"
15#include "MCTargetDesc/MipsBaseInfo.h"
16#include "MCTargetDesc/MipsInstPrinter.h"
17#include "MCTargetDesc/MipsMCTargetDesc.h"
18#include "MipsCCState.h"
19#include "MipsInstrInfo.h"
20#include "MipsMachineFunction.h"
21#include "MipsRegisterInfo.h"
22#include "MipsSubtarget.h"
23#include "MipsTargetMachine.h"
24#include "MipsTargetObjectFile.h"
25#include "llvm/ADT/APFloat.h"
26#include "llvm/ADT/ArrayRef.h"
27#include "llvm/ADT/SmallVector.h"
28#include "llvm/ADT/Statistic.h"
29#include "llvm/ADT/StringRef.h"
30#include "llvm/ADT/StringSwitch.h"
31#include "llvm/CodeGen/CallingConvLower.h"
32#include "llvm/CodeGen/FunctionLoweringInfo.h"
33#include "llvm/CodeGen/ISDOpcodes.h"
34#include "llvm/CodeGen/MachineBasicBlock.h"
35#include "llvm/CodeGen/MachineFrameInfo.h"
36#include "llvm/CodeGen/MachineFunction.h"
37#include "llvm/CodeGen/MachineInstr.h"
38#include "llvm/CodeGen/MachineInstrBuilder.h"
39#include "llvm/CodeGen/MachineJumpTableInfo.h"
40#include "llvm/CodeGen/MachineMemOperand.h"
41#include "llvm/CodeGen/MachineOperand.h"
42#include "llvm/CodeGen/MachineRegisterInfo.h"
43#include "llvm/CodeGen/SelectionDAG.h"
44#include "llvm/CodeGen/SelectionDAGNodes.h"
45#include "llvm/CodeGen/TargetFrameLowering.h"
46#include "llvm/CodeGen/TargetInstrInfo.h"
47#include "llvm/CodeGen/TargetRegisterInfo.h"
48#include "llvm/CodeGen/ValueTypes.h"
49#include "llvm/CodeGenTypes/MachineValueType.h"
50#include "llvm/IR/CallingConv.h"
51#include "llvm/IR/Constants.h"
52#include "llvm/IR/DataLayout.h"
53#include "llvm/IR/DebugLoc.h"
54#include "llvm/IR/DerivedTypes.h"
55#include "llvm/IR/Function.h"
56#include "llvm/IR/GlobalValue.h"
57#include "llvm/IR/Module.h"
58#include "llvm/IR/Type.h"
59#include "llvm/IR/Value.h"
60#include "llvm/MC/MCContext.h"
61#include "llvm/Support/Casting.h"
62#include "llvm/Support/CodeGen.h"
63#include "llvm/Support/CommandLine.h"
64#include "llvm/Support/Compiler.h"
65#include "llvm/Support/ErrorHandling.h"
66#include "llvm/Support/MathExtras.h"
67#include "llvm/Target/TargetMachine.h"
68#include "llvm/Target/TargetOptions.h"
69#include <algorithm>
70#include <cassert>
71#include <cctype>
72#include <cstdint>
73#include <deque>
74#include <iterator>
75#include <utility>
76#include <vector>
77
78using namespacellvm;
79
80#define DEBUG_TYPE "mips-lower"
81
82STATISTIC(NumTailCalls,"Number of tail calls");
83
84staticcl::opt<bool>
85NoZeroDivCheck("mno-check-zero-division",cl::Hidden,
86cl::desc("MIPS: Don't trap on integer division by zero."),
87cl::init(false));
88
89externcl::opt<bool>EmitJalrReloc;
90
91staticconstMCPhysRegMips64DPRegs[8] = {
92 Mips::D12_64, Mips::D13_64, Mips::D14_64, Mips::D15_64,
93 Mips::D16_64, Mips::D17_64, Mips::D18_64, Mips::D19_64
94};
95
96// The MIPS MSA ABI passes vector arguments in the integer register set.
97// The number of integer registers used is dependant on the ABI used.
98MVTMipsTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
99CallingConv::IDCC,
100EVT VT) const{
101if (!VT.isVector())
102returngetRegisterType(Context, VT);
103
104if (VT.isPow2VectorType() && VT.getVectorElementType().isRound())
105returnSubtarget.isABI_O32() || VT.getSizeInBits() == 32 ? MVT::i32
106 : MVT::i64;
107returngetRegisterType(Context, VT.getVectorElementType());
108}
109
110unsignedMipsTargetLowering::getNumRegistersForCallingConv(LLVMContext &Context,
111CallingConv::IDCC,
112EVT VT) const{
113if (VT.isVector()) {
114if (VT.isPow2VectorType() && VT.getVectorElementType().isRound())
115returndivideCeil(VT.getSizeInBits(),Subtarget.isABI_O32() ? 32 : 64);
116return VT.getVectorNumElements() *
117getNumRegisters(Context, VT.getVectorElementType());
118 }
119returnMipsTargetLowering::getNumRegisters(Context, VT);
120}
121
122unsignedMipsTargetLowering::getVectorTypeBreakdownForCallingConv(
123LLVMContext &Context,CallingConv::IDCC,EVT VT,EVT &IntermediateVT,
124unsigned &NumIntermediates,MVT &RegisterVT) const{
125if (VT.isPow2VectorType() && VT.getVectorElementType().isRound()) {
126 IntermediateVT =getRegisterTypeForCallingConv(Context,CC, VT);
127 RegisterVT = IntermediateVT.getSimpleVT();
128 NumIntermediates =getNumRegistersForCallingConv(Context,CC, VT);
129return NumIntermediates;
130 }
131 IntermediateVT = VT.getVectorElementType();
132 NumIntermediates = VT.getVectorNumElements();
133 RegisterVT =getRegisterType(Context, IntermediateVT);
134return NumIntermediates *getNumRegisters(Context, IntermediateVT);
135}
136
137SDValueMipsTargetLowering::getGlobalReg(SelectionDAG &DAG,EVT Ty) const{
138MachineFunction &MF = DAG.getMachineFunction();
139MipsFunctionInfo *FI = MF.getInfo<MipsFunctionInfo>();
140return DAG.getRegister(FI->getGlobalBaseReg(MF), Ty);
141}
142
143SDValue MipsTargetLowering::getTargetNode(GlobalAddressSDNode *N,EVT Ty,
144SelectionDAG &DAG,
145unsigned Flag) const{
146return DAG.getTargetGlobalAddress(N->getGlobal(),SDLoc(N), Ty, 0, Flag);
147}
148
149SDValue MipsTargetLowering::getTargetNode(ExternalSymbolSDNode *N,EVT Ty,
150SelectionDAG &DAG,
151unsigned Flag) const{
152return DAG.getTargetExternalSymbol(N->getSymbol(), Ty, Flag);
153}
154
155SDValue MipsTargetLowering::getTargetNode(BlockAddressSDNode *N,EVT Ty,
156SelectionDAG &DAG,
157unsigned Flag) const{
158return DAG.getTargetBlockAddress(N->getBlockAddress(), Ty, 0, Flag);
159}
160
161SDValue MipsTargetLowering::getTargetNode(JumpTableSDNode *N,EVT Ty,
162SelectionDAG &DAG,
163unsigned Flag) const{
164return DAG.getTargetJumpTable(N->getIndex(), Ty, Flag);
165}
166
167SDValue MipsTargetLowering::getTargetNode(ConstantPoolSDNode *N,EVT Ty,
168SelectionDAG &DAG,
169unsigned Flag) const{
170return DAG.getTargetConstantPool(N->getConstVal(), Ty,N->getAlign(),
171N->getOffset(), Flag);
172}
173
174constchar *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const{
175switch ((MipsISD::NodeType)Opcode) {
176caseMipsISD::FIRST_NUMBER:break;
177caseMipsISD::JmpLink:return"MipsISD::JmpLink";
178caseMipsISD::TailCall:return"MipsISD::TailCall";
179caseMipsISD::Highest:return"MipsISD::Highest";
180caseMipsISD::Higher:return"MipsISD::Higher";
181caseMipsISD::Hi:return"MipsISD::Hi";
182caseMipsISD::Lo:return"MipsISD::Lo";
183caseMipsISD::GotHi:return"MipsISD::GotHi";
184caseMipsISD::TlsHi:return"MipsISD::TlsHi";
185caseMipsISD::GPRel:return"MipsISD::GPRel";
186caseMipsISD::ThreadPointer:return"MipsISD::ThreadPointer";
187caseMipsISD::Ret:return"MipsISD::Ret";
188caseMipsISD::ERet:return"MipsISD::ERet";
189caseMipsISD::EH_RETURN:return"MipsISD::EH_RETURN";
190caseMipsISD::FAbs:return"MipsISD::FAbs";
191caseMipsISD::FMS:return"MipsISD::FMS";
192caseMipsISD::FPBrcond:return"MipsISD::FPBrcond";
193caseMipsISD::FPCmp:return"MipsISD::FPCmp";
194caseMipsISD::FSELECT:return"MipsISD::FSELECT";
195caseMipsISD::MTC1_D64:return"MipsISD::MTC1_D64";
196caseMipsISD::CMovFP_T:return"MipsISD::CMovFP_T";
197caseMipsISD::CMovFP_F:return"MipsISD::CMovFP_F";
198caseMipsISD::TruncIntFP:return"MipsISD::TruncIntFP";
199caseMipsISD::MFHI:return"MipsISD::MFHI";
200caseMipsISD::MFLO:return"MipsISD::MFLO";
201caseMipsISD::MTLOHI:return"MipsISD::MTLOHI";
202caseMipsISD::Mult:return"MipsISD::Mult";
203caseMipsISD::Multu:return"MipsISD::Multu";
204caseMipsISD::MAdd:return"MipsISD::MAdd";
205caseMipsISD::MAddu:return"MipsISD::MAddu";
206caseMipsISD::MSub:return"MipsISD::MSub";
207caseMipsISD::MSubu:return"MipsISD::MSubu";
208caseMipsISD::DivRem:return"MipsISD::DivRem";
209caseMipsISD::DivRemU:return"MipsISD::DivRemU";
210caseMipsISD::DivRem16:return"MipsISD::DivRem16";
211caseMipsISD::DivRemU16:return"MipsISD::DivRemU16";
212caseMipsISD::BuildPairF64:return"MipsISD::BuildPairF64";
213caseMipsISD::ExtractElementF64:return"MipsISD::ExtractElementF64";
214caseMipsISD::Wrapper:return"MipsISD::Wrapper";
215caseMipsISD::DynAlloc:return"MipsISD::DynAlloc";
216caseMipsISD::Sync:return"MipsISD::Sync";
217caseMipsISD::Ext:return"MipsISD::Ext";
218caseMipsISD::Ins:return"MipsISD::Ins";
219caseMipsISD::CIns:return"MipsISD::CIns";
220caseMipsISD::LWL:return"MipsISD::LWL";
221caseMipsISD::LWR:return"MipsISD::LWR";
222caseMipsISD::SWL:return"MipsISD::SWL";
223caseMipsISD::SWR:return"MipsISD::SWR";
224caseMipsISD::LDL:return"MipsISD::LDL";
225caseMipsISD::LDR:return"MipsISD::LDR";
226caseMipsISD::SDL:return"MipsISD::SDL";
227caseMipsISD::SDR:return"MipsISD::SDR";
228caseMipsISD::EXTP:return"MipsISD::EXTP";
229caseMipsISD::EXTPDP:return"MipsISD::EXTPDP";
230caseMipsISD::EXTR_S_H:return"MipsISD::EXTR_S_H";
231caseMipsISD::EXTR_W:return"MipsISD::EXTR_W";
232caseMipsISD::EXTR_R_W:return"MipsISD::EXTR_R_W";
233caseMipsISD::EXTR_RS_W:return"MipsISD::EXTR_RS_W";
234caseMipsISD::SHILO:return"MipsISD::SHILO";
235caseMipsISD::MTHLIP:return"MipsISD::MTHLIP";
236caseMipsISD::MULSAQ_S_W_PH:return"MipsISD::MULSAQ_S_W_PH";
237caseMipsISD::MAQ_S_W_PHL:return"MipsISD::MAQ_S_W_PHL";
238caseMipsISD::MAQ_S_W_PHR:return"MipsISD::MAQ_S_W_PHR";
239caseMipsISD::MAQ_SA_W_PHL:return"MipsISD::MAQ_SA_W_PHL";
240caseMipsISD::MAQ_SA_W_PHR:return"MipsISD::MAQ_SA_W_PHR";
241caseMipsISD::DOUBLE_SELECT_I:return"MipsISD::DOUBLE_SELECT_I";
242caseMipsISD::DOUBLE_SELECT_I64:return"MipsISD::DOUBLE_SELECT_I64";
243caseMipsISD::DPAU_H_QBL:return"MipsISD::DPAU_H_QBL";
244caseMipsISD::DPAU_H_QBR:return"MipsISD::DPAU_H_QBR";
245caseMipsISD::DPSU_H_QBL:return"MipsISD::DPSU_H_QBL";
246caseMipsISD::DPSU_H_QBR:return"MipsISD::DPSU_H_QBR";
247caseMipsISD::DPAQ_S_W_PH:return"MipsISD::DPAQ_S_W_PH";
248caseMipsISD::DPSQ_S_W_PH:return"MipsISD::DPSQ_S_W_PH";
249caseMipsISD::DPAQ_SA_L_W:return"MipsISD::DPAQ_SA_L_W";
250caseMipsISD::DPSQ_SA_L_W:return"MipsISD::DPSQ_SA_L_W";
251caseMipsISD::DPA_W_PH:return"MipsISD::DPA_W_PH";
252caseMipsISD::DPS_W_PH:return"MipsISD::DPS_W_PH";
253caseMipsISD::DPAQX_S_W_PH:return"MipsISD::DPAQX_S_W_PH";
254caseMipsISD::DPAQX_SA_W_PH:return"MipsISD::DPAQX_SA_W_PH";
255caseMipsISD::DPAX_W_PH:return"MipsISD::DPAX_W_PH";
256caseMipsISD::DPSX_W_PH:return"MipsISD::DPSX_W_PH";
257caseMipsISD::DPSQX_S_W_PH:return"MipsISD::DPSQX_S_W_PH";
258caseMipsISD::DPSQX_SA_W_PH:return"MipsISD::DPSQX_SA_W_PH";
259caseMipsISD::MULSA_W_PH:return"MipsISD::MULSA_W_PH";
260caseMipsISD::MULT:return"MipsISD::MULT";
261caseMipsISD::MULTU:return"MipsISD::MULTU";
262caseMipsISD::MADD_DSP:return"MipsISD::MADD_DSP";
263caseMipsISD::MADDU_DSP:return"MipsISD::MADDU_DSP";
264caseMipsISD::MSUB_DSP:return"MipsISD::MSUB_DSP";
265caseMipsISD::MSUBU_DSP:return"MipsISD::MSUBU_DSP";
266caseMipsISD::SHLL_DSP:return"MipsISD::SHLL_DSP";
267caseMipsISD::SHRA_DSP:return"MipsISD::SHRA_DSP";
268caseMipsISD::SHRL_DSP:return"MipsISD::SHRL_DSP";
269caseMipsISD::SETCC_DSP:return"MipsISD::SETCC_DSP";
270caseMipsISD::SELECT_CC_DSP:return"MipsISD::SELECT_CC_DSP";
271caseMipsISD::VALL_ZERO:return"MipsISD::VALL_ZERO";
272caseMipsISD::VANY_ZERO:return"MipsISD::VANY_ZERO";
273caseMipsISD::VALL_NONZERO:return"MipsISD::VALL_NONZERO";
274caseMipsISD::VANY_NONZERO:return"MipsISD::VANY_NONZERO";
275caseMipsISD::VCEQ:return"MipsISD::VCEQ";
276caseMipsISD::VCLE_S:return"MipsISD::VCLE_S";
277caseMipsISD::VCLE_U:return"MipsISD::VCLE_U";
278caseMipsISD::VCLT_S:return"MipsISD::VCLT_S";
279caseMipsISD::VCLT_U:return"MipsISD::VCLT_U";
280caseMipsISD::VEXTRACT_SEXT_ELT:return"MipsISD::VEXTRACT_SEXT_ELT";
281caseMipsISD::VEXTRACT_ZEXT_ELT:return"MipsISD::VEXTRACT_ZEXT_ELT";
282caseMipsISD::VNOR:return"MipsISD::VNOR";
283caseMipsISD::VSHF:return"MipsISD::VSHF";
284caseMipsISD::SHF:return"MipsISD::SHF";
285caseMipsISD::ILVEV:return"MipsISD::ILVEV";
286caseMipsISD::ILVOD:return"MipsISD::ILVOD";
287caseMipsISD::ILVL:return"MipsISD::ILVL";
288caseMipsISD::ILVR:return"MipsISD::ILVR";
289caseMipsISD::PCKEV:return"MipsISD::PCKEV";
290caseMipsISD::PCKOD:return"MipsISD::PCKOD";
291caseMipsISD::INSVE:return"MipsISD::INSVE";
292 }
293returnnullptr;
294}
295
296MipsTargetLowering::MipsTargetLowering(constMipsTargetMachine &TM,
297constMipsSubtarget &STI)
298 :TargetLowering(TM), Subtarget(STI), ABI(TM.getABI()) {
299// Mips does not have i1 type, so use i32 for
300// setcc operations results (slt, sgt, ...).
301setBooleanContents(ZeroOrOneBooleanContent);
302setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
303// The cmp.cond.fmt instruction in MIPS32r6/MIPS64r6 uses 0 and -1 like MSA
304// does. Integer booleans still use 0 and 1.
305if (Subtarget.hasMips32r6())
306setBooleanContents(ZeroOrOneBooleanContent,
307ZeroOrNegativeOneBooleanContent);
308
309// Load extented operations for i1 types must be promoted
310for (MVT VT :MVT::integer_valuetypes()) {
311setLoadExtAction(ISD::EXTLOAD, VT, MVT::i1,Promote);
312setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i1,Promote);
313setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1,Promote);
314 }
315
316// MIPS doesn't have extending float->double load/store. Set LoadExtAction
317// for f32, f16
318for (MVT VT :MVT::fp_valuetypes()) {
319setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32,Expand);
320setLoadExtAction(ISD::EXTLOAD, VT, MVT::f16,Expand);
321 }
322
323// Set LoadExtAction for f16 vectors to Expand
324for (MVT VT :MVT::fp_fixedlen_vector_valuetypes()) {
325MVT F16VT =MVT::getVectorVT(MVT::f16, VT.getVectorNumElements());
326if (F16VT.isValid())
327setLoadExtAction(ISD::EXTLOAD, VT, F16VT,Expand);
328 }
329
330setTruncStoreAction(MVT::f32, MVT::f16,Expand);
331setTruncStoreAction(MVT::f64, MVT::f16,Expand);
332
333setTruncStoreAction(MVT::f64, MVT::f32,Expand);
334
335// Used by legalize types to correctly generate the setcc result.
336// Without this, every float setcc comes with a AND/OR with the result,
337// we don't want this, since the fpcmp result goes to a flag register,
338// which is used implicitly by brcond and select operations.
339AddPromotedToType(ISD::SETCC, MVT::i1, MVT::i32);
340
341// Mips Custom Operations
342setOperationAction(ISD::BR_JT, MVT::Other,Expand);
343setOperationAction(ISD::GlobalAddress, MVT::i32,Custom);
344setOperationAction(ISD::BlockAddress, MVT::i32,Custom);
345setOperationAction(ISD::GlobalTLSAddress, MVT::i32,Custom);
346setOperationAction(ISD::JumpTable, MVT::i32,Custom);
347setOperationAction(ISD::ConstantPool, MVT::i32,Custom);
348setOperationAction(ISD::SELECT, MVT::f32,Custom);
349setOperationAction(ISD::SELECT, MVT::f64,Custom);
350setOperationAction(ISD::SELECT, MVT::i32,Custom);
351setOperationAction(ISD::SETCC, MVT::f32,Custom);
352setOperationAction(ISD::SETCC, MVT::f64,Custom);
353setOperationAction(ISD::BRCOND, MVT::Other,Custom);
354setOperationAction(ISD::FABS, MVT::f32,Custom);
355setOperationAction(ISD::FABS, MVT::f64,Custom);
356setOperationAction(ISD::FCOPYSIGN, MVT::f32,Custom);
357setOperationAction(ISD::FCOPYSIGN, MVT::f64,Custom);
358setOperationAction(ISD::FP_TO_SINT, MVT::i32,Custom);
359
360// Lower fmin/fmax/fclass operations for MIPS R6.
361if (Subtarget.hasMips32r6()) {
362setOperationAction(ISD::FMINNUM_IEEE, MVT::f32,Legal);
363setOperationAction(ISD::FMAXNUM_IEEE, MVT::f32,Legal);
364setOperationAction(ISD::FMINNUM, MVT::f32,Expand);
365setOperationAction(ISD::FMAXNUM, MVT::f32,Expand);
366setOperationAction(ISD::FMINNUM_IEEE, MVT::f64,Legal);
367setOperationAction(ISD::FMAXNUM_IEEE, MVT::f64,Legal);
368setOperationAction(ISD::FMINNUM, MVT::f64,Expand);
369setOperationAction(ISD::FMAXNUM, MVT::f64,Expand);
370setOperationAction(ISD::IS_FPCLASS, MVT::f32,Legal);
371setOperationAction(ISD::IS_FPCLASS, MVT::f64,Legal);
372 }else {
373setOperationAction(ISD::FCANONICALIZE, MVT::f32,Custom);
374setOperationAction(ISD::FCANONICALIZE, MVT::f64,Custom);
375 }
376
377if (Subtarget.isGP64bit()) {
378setOperationAction(ISD::GlobalAddress, MVT::i64,Custom);
379setOperationAction(ISD::BlockAddress, MVT::i64,Custom);
380setOperationAction(ISD::GlobalTLSAddress, MVT::i64,Custom);
381setOperationAction(ISD::JumpTable, MVT::i64,Custom);
382setOperationAction(ISD::ConstantPool, MVT::i64,Custom);
383setOperationAction(ISD::SELECT, MVT::i64,Custom);
384if (Subtarget.hasMips64r6()) {
385setOperationAction(ISD::LOAD, MVT::i64,Legal);
386setOperationAction(ISD::STORE, MVT::i64,Legal);
387 }else {
388setOperationAction(ISD::LOAD, MVT::i64,Custom);
389setOperationAction(ISD::STORE, MVT::i64,Custom);
390 }
391setOperationAction(ISD::FP_TO_SINT, MVT::i64,Custom);
392setOperationAction(ISD::SHL_PARTS, MVT::i64,Custom);
393setOperationAction(ISD::SRA_PARTS, MVT::i64,Custom);
394setOperationAction(ISD::SRL_PARTS, MVT::i64,Custom);
395 }
396
397if (!Subtarget.isGP64bit()) {
398setOperationAction(ISD::SHL_PARTS, MVT::i32,Custom);
399setOperationAction(ISD::SRA_PARTS, MVT::i32,Custom);
400setOperationAction(ISD::SRL_PARTS, MVT::i32,Custom);
401 }
402
403setOperationAction(ISD::EH_DWARF_CFA, MVT::i32,Custom);
404if (Subtarget.isGP64bit())
405setOperationAction(ISD::EH_DWARF_CFA, MVT::i64,Custom);
406
407setOperationAction(ISD::SDIV, MVT::i32,Expand);
408setOperationAction(ISD::SREM, MVT::i32,Expand);
409setOperationAction(ISD::UDIV, MVT::i32,Expand);
410setOperationAction(ISD::UREM, MVT::i32,Expand);
411setOperationAction(ISD::SDIV, MVT::i64,Expand);
412setOperationAction(ISD::SREM, MVT::i64,Expand);
413setOperationAction(ISD::UDIV, MVT::i64,Expand);
414setOperationAction(ISD::UREM, MVT::i64,Expand);
415
416// Operations not directly supported by Mips.
417setOperationAction(ISD::BR_CC, MVT::f32,Expand);
418setOperationAction(ISD::BR_CC, MVT::f64,Expand);
419setOperationAction(ISD::BR_CC, MVT::i32,Expand);
420setOperationAction(ISD::BR_CC, MVT::i64,Expand);
421setOperationAction(ISD::SELECT_CC, MVT::i32,Expand);
422setOperationAction(ISD::SELECT_CC, MVT::i64,Expand);
423setOperationAction(ISD::SELECT_CC, MVT::f32,Expand);
424setOperationAction(ISD::SELECT_CC, MVT::f64,Expand);
425setOperationAction(ISD::UINT_TO_FP, MVT::i32,Expand);
426setOperationAction(ISD::UINT_TO_FP, MVT::i64,Expand);
427setOperationAction(ISD::FP_TO_UINT, MVT::i32,Expand);
428setOperationAction(ISD::FP_TO_UINT, MVT::i64,Expand);
429setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1,Expand);
430if (Subtarget.hasCnMips()) {
431setOperationAction(ISD::CTPOP, MVT::i32,Legal);
432setOperationAction(ISD::CTPOP, MVT::i64,Legal);
433 }else {
434setOperationAction(ISD::CTPOP, MVT::i32,Expand);
435setOperationAction(ISD::CTPOP, MVT::i64,Expand);
436 }
437setOperationAction(ISD::CTTZ, MVT::i32,Expand);
438setOperationAction(ISD::CTTZ, MVT::i64,Expand);
439setOperationAction(ISD::ROTL, MVT::i32,Expand);
440setOperationAction(ISD::ROTL, MVT::i64,Expand);
441setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32,Expand);
442setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64,Expand);
443
444if (!Subtarget.hasMips32r2())
445setOperationAction(ISD::ROTR, MVT::i32,Expand);
446
447if (!Subtarget.hasMips64r2())
448setOperationAction(ISD::ROTR, MVT::i64,Expand);
449
450setOperationAction(ISD::FSIN, MVT::f32,Expand);
451setOperationAction(ISD::FSIN, MVT::f64,Expand);
452setOperationAction(ISD::FCOS, MVT::f32,Expand);
453setOperationAction(ISD::FCOS, MVT::f64,Expand);
454setOperationAction(ISD::FSINCOS, MVT::f32,Expand);
455setOperationAction(ISD::FSINCOS, MVT::f64,Expand);
456setOperationAction(ISD::FPOW, MVT::f32,Expand);
457setOperationAction(ISD::FPOW, MVT::f64,Expand);
458setOperationAction(ISD::FLOG, MVT::f32,Expand);
459setOperationAction(ISD::FLOG2, MVT::f32,Expand);
460setOperationAction(ISD::FLOG10, MVT::f32,Expand);
461setOperationAction(ISD::FEXP, MVT::f32,Expand);
462setOperationAction(ISD::FMA, MVT::f32,Expand);
463setOperationAction(ISD::FMA, MVT::f64,Expand);
464setOperationAction(ISD::FREM, MVT::f32,Expand);
465setOperationAction(ISD::FREM, MVT::f64,Expand);
466
467// Lower f16 conversion operations into library calls
468setOperationAction(ISD::FP16_TO_FP, MVT::f32,Expand);
469setOperationAction(ISD::FP_TO_FP16, MVT::f32,Expand);
470setOperationAction(ISD::FP16_TO_FP, MVT::f64,Expand);
471setOperationAction(ISD::FP_TO_FP16, MVT::f64,Expand);
472
473setOperationAction(ISD::EH_RETURN, MVT::Other,Custom);
474
475setOperationAction(ISD::VASTART, MVT::Other,Custom);
476setOperationAction(ISD::VAARG, MVT::Other,Custom);
477setOperationAction(ISD::VACOPY, MVT::Other,Expand);
478setOperationAction(ISD::VAEND, MVT::Other,Expand);
479
480// Use the default for now
481setOperationAction(ISD::STACKSAVE, MVT::Other,Expand);
482setOperationAction(ISD::STACKRESTORE, MVT::Other,Expand);
483
484if (!Subtarget.isGP64bit()) {
485setOperationAction(ISD::ATOMIC_LOAD, MVT::i64,Expand);
486setOperationAction(ISD::ATOMIC_STORE, MVT::i64,Expand);
487 }
488
489if (!Subtarget.hasMips32r2()) {
490setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8,Expand);
491setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16,Expand);
492 }
493
494// MIPS16 lacks MIPS32's clz and clo instructions.
495if (!Subtarget.hasMips32() ||Subtarget.inMips16Mode())
496setOperationAction(ISD::CTLZ, MVT::i32,Expand);
497if (!Subtarget.hasMips64())
498setOperationAction(ISD::CTLZ, MVT::i64,Expand);
499
500if (!Subtarget.hasMips32r2())
501setOperationAction(ISD::BSWAP, MVT::i32,Expand);
502if (!Subtarget.hasMips64r2())
503setOperationAction(ISD::BSWAP, MVT::i64,Expand);
504
505if (Subtarget.isGP64bit() &&Subtarget.hasMips64r6()) {
506setLoadExtAction(ISD::SEXTLOAD, MVT::i64, MVT::i32,Legal);
507setLoadExtAction(ISD::ZEXTLOAD, MVT::i64, MVT::i32,Legal);
508setLoadExtAction(ISD::EXTLOAD, MVT::i64, MVT::i32,Legal);
509setTruncStoreAction(MVT::i64, MVT::i32,Legal);
510 }elseif (Subtarget.isGP64bit()) {
511setLoadExtAction(ISD::SEXTLOAD, MVT::i64, MVT::i32,Custom);
512setLoadExtAction(ISD::ZEXTLOAD, MVT::i64, MVT::i32,Custom);
513setLoadExtAction(ISD::EXTLOAD, MVT::i64, MVT::i32,Custom);
514setTruncStoreAction(MVT::i64, MVT::i32,Custom);
515 }
516
517setOperationAction(ISD::TRAP, MVT::Other,Legal);
518
519setTargetDAGCombine({ISD::SDIVREM,ISD::UDIVREM,ISD::SELECT,ISD::AND,
520ISD::OR,ISD::ADD,ISD::SUB,ISD::AssertZext,ISD::SHL});
521
522if (Subtarget.isGP64bit())
523setMaxAtomicSizeInBitsSupported(64);
524else
525setMaxAtomicSizeInBitsSupported(32);
526
527setMinFunctionAlignment(Subtarget.isGP64bit() ?Align(8) :Align(4));
528
529// The arguments on the stack are defined in terms of 4-byte slots on O32
530// and 8-byte slots on N32/N64.
531setMinStackArgumentAlignment((ABI.IsN32() ||ABI.IsN64()) ?Align(8)
532 :Align(4));
533
534setStackPointerRegisterToSaveRestore(ABI.IsN64() ? Mips::SP_64 : Mips::SP);
535
536MaxStoresPerMemcpy = 16;
537
538 isMicroMips =Subtarget.inMicroMipsMode();
539}
540
541constMipsTargetLowering *
542MipsTargetLowering::create(constMipsTargetMachine &TM,
543constMipsSubtarget &STI) {
544if (STI.inMips16Mode())
545returncreateMips16TargetLowering(TM, STI);
546
547returncreateMipsSETargetLowering(TM, STI);
548}
549
550// Create a fast isel object.
551FastISel *
552MipsTargetLowering::createFastISel(FunctionLoweringInfo &funcInfo,
553constTargetLibraryInfo *libInfo) const{
554constMipsTargetMachine &TM =
555static_cast<constMipsTargetMachine &>(funcInfo.MF->getTarget());
556
557// We support only the standard encoding [MIPS32,MIPS32R5] ISAs.
558bool UseFastISel = TM.Options.EnableFastISel &&Subtarget.hasMips32() &&
559 !Subtarget.hasMips32r6() && !Subtarget.inMips16Mode() &&
560 !Subtarget.inMicroMipsMode();
561
562// Disable if either of the following is true:
563// We do not generate PIC, the ABI is not O32, XGOT is being used.
564if (!TM.isPositionIndependent() || !TM.getABI().IsO32() ||
565Subtarget.useXGOT())
566 UseFastISel =false;
567
568return UseFastISel ?Mips::createFastISel(funcInfo, libInfo) :nullptr;
569}
570
571EVTMipsTargetLowering::getSetCCResultType(constDataLayout &,LLVMContext &,
572EVT VT) const{
573if (!VT.isVector())
574return MVT::i32;
575return VT.changeVectorElementTypeToInteger();
576}
577
578staticSDValueperformDivRemCombine(SDNode *N,SelectionDAG &DAG,
579TargetLowering::DAGCombinerInfo &DCI,
580constMipsSubtarget &Subtarget) {
581if (DCI.isBeforeLegalizeOps())
582returnSDValue();
583
584EVT Ty =N->getValueType(0);
585unsigned LO = (Ty == MVT::i32) ? Mips::LO0 : Mips::LO0_64;
586unsigned HI = (Ty == MVT::i32) ? Mips::HI0 : Mips::HI0_64;
587unsigned Opc =N->getOpcode() ==ISD::SDIVREM ?MipsISD::DivRem16 :
588MipsISD::DivRemU16;
589SDLocDL(N);
590
591SDValue DivRem = DAG.getNode(Opc,DL, MVT::Glue,
592N->getOperand(0),N->getOperand(1));
593SDValue InChain = DAG.getEntryNode();
594SDValue InGlue = DivRem;
595
596// insert MFLO
597if (N->hasAnyUseOfValue(0)) {
598SDValue CopyFromLo = DAG.getCopyFromReg(InChain,DL, LO, Ty,
599 InGlue);
600 DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), CopyFromLo);
601 InChain = CopyFromLo.getValue(1);
602 InGlue = CopyFromLo.getValue(2);
603 }
604
605// insert MFHI
606if (N->hasAnyUseOfValue(1)) {
607SDValue CopyFromHi = DAG.getCopyFromReg(InChain,DL,
608 HI, Ty, InGlue);
609 DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), CopyFromHi);
610 }
611
612returnSDValue();
613}
614
615staticMips::CondCodecondCodeToFCC(ISD::CondCodeCC) {
616switch (CC) {
617default:llvm_unreachable("Unknown fp condition code!");
618caseISD::SETEQ:
619caseISD::SETOEQ:returnMips::FCOND_OEQ;
620caseISD::SETUNE:returnMips::FCOND_UNE;
621caseISD::SETLT:
622caseISD::SETOLT:returnMips::FCOND_OLT;
623caseISD::SETGT:
624caseISD::SETOGT:returnMips::FCOND_OGT;
625caseISD::SETLE:
626caseISD::SETOLE:returnMips::FCOND_OLE;
627caseISD::SETGE:
628caseISD::SETOGE:returnMips::FCOND_OGE;
629caseISD::SETULT:returnMips::FCOND_ULT;
630caseISD::SETULE:returnMips::FCOND_ULE;
631caseISD::SETUGT:returnMips::FCOND_UGT;
632caseISD::SETUGE:returnMips::FCOND_UGE;
633caseISD::SETUO:returnMips::FCOND_UN;
634caseISD::SETO:returnMips::FCOND_OR;
635caseISD::SETNE:
636caseISD::SETONE:returnMips::FCOND_ONE;
637caseISD::SETUEQ:returnMips::FCOND_UEQ;
638 }
639}
640
641/// This function returns true if the floating point conditional branches and
642/// conditional moves which use condition code CC should be inverted.
643staticboolinvertFPCondCodeUser(Mips::CondCodeCC) {
644if (CC >=Mips::FCOND_F &&CC <=Mips::FCOND_NGT)
645returnfalse;
646
647assert((CC >=Mips::FCOND_T &&CC <=Mips::FCOND_GT) &&
648"Illegal Condition Code");
649
650returntrue;
651}
652
653// Creates and returns an FPCmp node from a setcc node.
654// Returns Op if setcc is not a floating point comparison.
655staticSDValuecreateFPCmp(SelectionDAG &DAG,constSDValue &Op) {
656// must be a SETCC node
657if (Op.getOpcode() !=ISD::SETCC)
658returnOp;
659
660SDValueLHS =Op.getOperand(0);
661
662if (!LHS.getValueType().isFloatingPoint())
663returnOp;
664
665SDValueRHS =Op.getOperand(1);
666SDLocDL(Op);
667
668// Assume the 3rd operand is a CondCodeSDNode. Add code to check the type of
669// node if necessary.
670ISD::CondCodeCC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
671
672return DAG.getNode(MipsISD::FPCmp,DL, MVT::Glue,LHS,RHS,
673 DAG.getConstant(condCodeToFCC(CC),DL, MVT::i32));
674}
675
676// Creates and returns a CMovFPT/F node.
677staticSDValuecreateCMovFP(SelectionDAG &DAG,SDValueCond,SDValue True,
678SDValue False,constSDLoc &DL) {
679ConstantSDNode *CC = cast<ConstantSDNode>(Cond.getOperand(2));
680bool invert =invertFPCondCodeUser((Mips::CondCode)CC->getSExtValue());
681SDValue FCC0 = DAG.getRegister(Mips::FCC0, MVT::i32);
682
683return DAG.getNode((invert ?MipsISD::CMovFP_F :MipsISD::CMovFP_T),DL,
684 True.getValueType(), True, FCC0, False,Cond);
685}
686
687staticSDValueperformSELECTCombine(SDNode *N,SelectionDAG &DAG,
688TargetLowering::DAGCombinerInfo &DCI,
689constMipsSubtarget &Subtarget) {
690if (DCI.isBeforeLegalizeOps())
691returnSDValue();
692
693SDValue SetCC =N->getOperand(0);
694
695if ((SetCC.getOpcode() !=ISD::SETCC) ||
696 !SetCC.getOperand(0).getValueType().isInteger())
697returnSDValue();
698
699SDValue False =N->getOperand(2);
700EVT FalseTy = False.getValueType();
701
702if (!FalseTy.isInteger())
703returnSDValue();
704
705ConstantSDNode *FalseC = dyn_cast<ConstantSDNode>(False);
706
707// If the RHS (False) is 0, we swap the order of the operands
708// of ISD::SELECT (obviously also inverting the condition) so that we can
709// take advantage of conditional moves using the $0 register.
710// Example:
711// return (a != 0) ? x : 0;
712// load $reg, x
713// movz $reg, $0, a
714if (!FalseC)
715returnSDValue();
716
717constSDLocDL(N);
718
719if (!FalseC->getZExtValue()) {
720ISD::CondCodeCC = cast<CondCodeSDNode>(SetCC.getOperand(2))->get();
721SDValue True =N->getOperand(1);
722
723 SetCC = DAG.getSetCC(DL, SetCC.getValueType(), SetCC.getOperand(0),
724 SetCC.getOperand(1),
725ISD::getSetCCInverse(CC, SetCC.getValueType()));
726
727return DAG.getNode(ISD::SELECT,DL, FalseTy, SetCC, False, True);
728 }
729
730// If both operands are integer constants there's a possibility that we
731// can do some interesting optimizations.
732SDValue True =N->getOperand(1);
733ConstantSDNode *TrueC = dyn_cast<ConstantSDNode>(True);
734
735if (!TrueC || !True.getValueType().isInteger())
736returnSDValue();
737
738// We'll also ignore MVT::i64 operands as this optimizations proves
739// to be ineffective because of the required sign extensions as the result
740// of a SETCC operator is always MVT::i32 for non-vector types.
741if (True.getValueType() == MVT::i64)
742returnSDValue();
743
744 int64_t Diff = TrueC->getSExtValue() - FalseC->getSExtValue();
745
746// 1) (a < x) ? y : y-1
747// slti $reg1, a, x
748// addiu $reg2, $reg1, y-1
749if (Diff == 1)
750return DAG.getNode(ISD::ADD,DL, SetCC.getValueType(), SetCC, False);
751
752// 2) (a < x) ? y-1 : y
753// slti $reg1, a, x
754// xor $reg1, $reg1, 1
755// addiu $reg2, $reg1, y-1
756if (Diff == -1) {
757ISD::CondCodeCC = cast<CondCodeSDNode>(SetCC.getOperand(2))->get();
758 SetCC = DAG.getSetCC(DL, SetCC.getValueType(), SetCC.getOperand(0),
759 SetCC.getOperand(1),
760ISD::getSetCCInverse(CC, SetCC.getValueType()));
761return DAG.getNode(ISD::ADD,DL, SetCC.getValueType(), SetCC, True);
762 }
763
764// Could not optimize.
765returnSDValue();
766}
767
768staticSDValueperformCMovFPCombine(SDNode *N,SelectionDAG &DAG,
769TargetLowering::DAGCombinerInfo &DCI,
770constMipsSubtarget &Subtarget) {
771if (DCI.isBeforeLegalizeOps())
772returnSDValue();
773
774SDValue ValueIfTrue =N->getOperand(0), ValueIfFalse =N->getOperand(2);
775
776ConstantSDNode *FalseC = dyn_cast<ConstantSDNode>(ValueIfFalse);
777if (!FalseC || FalseC->getZExtValue())
778returnSDValue();
779
780// Since RHS (False) is 0, we swap the order of the True/False operands
781// (obviously also inverting the condition) so that we can
782// take advantage of conditional moves using the $0 register.
783// Example:
784// return (a != 0) ? x : 0;
785// load $reg, x
786// movz $reg, $0, a
787unsigned Opc = (N->getOpcode() ==MipsISD::CMovFP_T) ?MipsISD::CMovFP_F :
788MipsISD::CMovFP_T;
789
790SDValue FCC =N->getOperand(1), Glue =N->getOperand(3);
791return DAG.getNode(Opc,SDLoc(N), ValueIfFalse.getValueType(),
792 ValueIfFalse, FCC, ValueIfTrue, Glue);
793}
794
795staticSDValueperformANDCombine(SDNode *N,SelectionDAG &DAG,
796TargetLowering::DAGCombinerInfo &DCI,
797constMipsSubtarget &Subtarget) {
798if (DCI.isBeforeLegalizeOps() || !Subtarget.hasExtractInsert())
799returnSDValue();
800
801SDValue FirstOperand =N->getOperand(0);
802unsigned FirstOperandOpc = FirstOperand.getOpcode();
803SDValue Mask =N->getOperand(1);
804EVT ValTy =N->getValueType(0);
805SDLocDL(N);
806
807uint64_t Pos = 0;
808unsigned SMPos, SMSize;
809ConstantSDNode *CN;
810SDValue NewOperand;
811unsigned Opc;
812
813// Op's second operand must be a shifted mask.
814if (!(CN = dyn_cast<ConstantSDNode>(Mask)) ||
815 !isShiftedMask_64(CN->getZExtValue(), SMPos, SMSize))
816returnSDValue();
817
818if (FirstOperandOpc ==ISD::SRA || FirstOperandOpc ==ISD::SRL) {
819// Pattern match EXT.
820// $dst = and ((sra or srl) $src , pos), (2**size - 1)
821// => ext $dst, $src, pos, size
822
823// The second operand of the shift must be an immediate.
824if (!(CN = dyn_cast<ConstantSDNode>(FirstOperand.getOperand(1))))
825returnSDValue();
826
827 Pos = CN->getZExtValue();
828
829// Return if the shifted mask does not start at bit 0 or the sum of its size
830// and Pos exceeds the word's size.
831if (SMPos != 0 || Pos + SMSize > ValTy.getSizeInBits())
832returnSDValue();
833
834 Opc =MipsISD::Ext;
835 NewOperand = FirstOperand.getOperand(0);
836 }elseif (FirstOperandOpc ==ISD::SHL && Subtarget.hasCnMips()) {
837// Pattern match CINS.
838// $dst = and (shl $src , pos), mask
839// => cins $dst, $src, pos, size
840// mask is a shifted mask with consecutive 1's, pos = shift amount,
841// size = population count.
842
843// The second operand of the shift must be an immediate.
844if (!(CN = dyn_cast<ConstantSDNode>(FirstOperand.getOperand(1))))
845returnSDValue();
846
847 Pos = CN->getZExtValue();
848
849if (SMPos != Pos || Pos >= ValTy.getSizeInBits() || SMSize >= 32 ||
850 Pos + SMSize > ValTy.getSizeInBits())
851returnSDValue();
852
853 NewOperand = FirstOperand.getOperand(0);
854// SMSize is 'location' (position) in this case, not size.
855 SMSize--;
856 Opc =MipsISD::CIns;
857 }else {
858// Pattern match EXT.
859// $dst = and $src, (2**size - 1) , if size > 16
860// => ext $dst, $src, pos, size , pos = 0
861
862// If the mask is <= 0xffff, andi can be used instead.
863if (CN->getZExtValue() <= 0xffff)
864returnSDValue();
865
866// Return if the mask doesn't start at position 0.
867if (SMPos)
868returnSDValue();
869
870 Opc =MipsISD::Ext;
871 NewOperand = FirstOperand;
872 }
873return DAG.getNode(Opc,DL, ValTy, NewOperand,
874 DAG.getConstant(Pos,DL, MVT::i32),
875 DAG.getConstant(SMSize,DL, MVT::i32));
876}
877
878staticSDValueperformORCombine(SDNode *N,SelectionDAG &DAG,
879TargetLowering::DAGCombinerInfo &DCI,
880constMipsSubtarget &Subtarget) {
881if (DCI.isBeforeLegalizeOps() || !Subtarget.hasExtractInsert())
882returnSDValue();
883
884SDValue FirstOperand =N->getOperand(0), SecondOperand =N->getOperand(1);
885unsigned SMPos0, SMSize0, SMPos1, SMSize1;
886ConstantSDNode *CN, *CN1;
887
888if ((FirstOperand.getOpcode() ==ISD::AND &&
889 SecondOperand.getOpcode() ==ISD::SHL) ||
890 (FirstOperand.getOpcode() ==ISD::SHL &&
891 SecondOperand.getOpcode() ==ISD::AND)) {
892// Pattern match INS.
893// $dst = or (and $src1, (2**size0 - 1)), (shl $src2, size0)
894// ==> ins $src1, $src2, pos, size, pos = size0, size = 32 - pos;
895// Or:
896// $dst = or (shl $src2, size0), (and $src1, (2**size0 - 1))
897// ==> ins $src1, $src2, pos, size, pos = size0, size = 32 - pos;
898SDValue AndOperand0 = FirstOperand.getOpcode() ==ISD::AND
899 ? FirstOperand.getOperand(0)
900 : SecondOperand.getOperand(0);
901SDValue ShlOperand0 = FirstOperand.getOpcode() ==ISD::AND
902 ? SecondOperand.getOperand(0)
903 : FirstOperand.getOperand(0);
904SDValue AndMask = FirstOperand.getOpcode() ==ISD::AND
905 ? FirstOperand.getOperand(1)
906 : SecondOperand.getOperand(1);
907if (!(CN = dyn_cast<ConstantSDNode>(AndMask)) ||
908 !isShiftedMask_64(CN->getZExtValue(), SMPos0, SMSize0))
909returnSDValue();
910
911SDValue ShlShift = FirstOperand.getOpcode() ==ISD::AND
912 ? SecondOperand.getOperand(1)
913 : FirstOperand.getOperand(1);
914if (!(CN = dyn_cast<ConstantSDNode>(ShlShift)))
915returnSDValue();
916uint64_t ShlShiftValue = CN->getZExtValue();
917
918if (SMPos0 != 0 || SMSize0 != ShlShiftValue)
919returnSDValue();
920
921SDLocDL(N);
922EVT ValTy =N->getValueType(0);
923 SMPos1 = ShlShiftValue;
924assert(SMPos1 < ValTy.getSizeInBits());
925 SMSize1 = (ValTy == MVT::i64 ? 64 : 32) - SMPos1;
926return DAG.getNode(MipsISD::Ins,DL, ValTy, ShlOperand0,
927 DAG.getConstant(SMPos1,DL, MVT::i32),
928 DAG.getConstant(SMSize1,DL, MVT::i32), AndOperand0);
929 }
930
931// See if Op's first operand matches (and $src1 , mask0).
932if (FirstOperand.getOpcode() !=ISD::AND)
933returnSDValue();
934
935// Pattern match INS.
936// $dst = or (and $src1 , mask0), (and (shl $src, pos), mask1),
937// where mask1 = (2**size - 1) << pos, mask0 = ~mask1
938// => ins $dst, $src, size, pos, $src1
939if (!(CN = dyn_cast<ConstantSDNode>(FirstOperand.getOperand(1))) ||
940 !isShiftedMask_64(~CN->getSExtValue(), SMPos0, SMSize0))
941returnSDValue();
942
943// See if Op's second operand matches (and (shl $src, pos), mask1).
944if (SecondOperand.getOpcode() ==ISD::AND &&
945 SecondOperand.getOperand(0).getOpcode() ==ISD::SHL) {
946
947if (!(CN = dyn_cast<ConstantSDNode>(SecondOperand.getOperand(1))) ||
948 !isShiftedMask_64(CN->getZExtValue(), SMPos1, SMSize1))
949returnSDValue();
950
951// The shift masks must have the same position and size.
952if (SMPos0 != SMPos1 || SMSize0 != SMSize1)
953returnSDValue();
954
955SDValue Shl = SecondOperand.getOperand(0);
956
957if (!(CN = dyn_cast<ConstantSDNode>(Shl.getOperand(1))))
958returnSDValue();
959
960unsigned Shamt = CN->getZExtValue();
961
962// Return if the shift amount and the first bit position of mask are not the
963// same.
964EVT ValTy =N->getValueType(0);
965if ((Shamt != SMPos0) || (SMPos0 + SMSize0 > ValTy.getSizeInBits()))
966returnSDValue();
967
968SDLocDL(N);
969return DAG.getNode(MipsISD::Ins,DL, ValTy, Shl.getOperand(0),
970 DAG.getConstant(SMPos0,DL, MVT::i32),
971 DAG.getConstant(SMSize0,DL, MVT::i32),
972 FirstOperand.getOperand(0));
973 }else {
974// Pattern match DINS.
975// $dst = or (and $src, mask0), mask1
976// where mask0 = ((1 << SMSize0) -1) << SMPos0
977// => dins $dst, $src, pos, size
978if (~CN->getSExtValue() == ((((int64_t)1 << SMSize0) - 1) << SMPos0) &&
979 ((SMSize0 + SMPos0 <= 64 && Subtarget.hasMips64r2()) ||
980 (SMSize0 + SMPos0 <= 32))) {
981// Check if AND instruction has constant as argument
982bool isConstCase = SecondOperand.getOpcode() !=ISD::AND;
983if (SecondOperand.getOpcode() ==ISD::AND) {
984if (!(CN1 = dyn_cast<ConstantSDNode>(SecondOperand->getOperand(1))))
985returnSDValue();
986 }else {
987if (!(CN1 = dyn_cast<ConstantSDNode>(N->getOperand(1))))
988returnSDValue();
989 }
990// Don't generate INS if constant OR operand doesn't fit into bits
991// cleared by constant AND operand.
992if (CN->getSExtValue() & CN1->getSExtValue())
993returnSDValue();
994
995SDLocDL(N);
996EVT ValTy =N->getOperand(0)->getValueType(0);
997SDValue Const1;
998SDValue SrlX;
999if (!isConstCase) {
1000 Const1 = DAG.getConstant(SMPos0,DL, MVT::i32);
1001 SrlX = DAG.getNode(ISD::SRL,DL, SecondOperand->getValueType(0),
1002 SecondOperand, Const1);
1003 }
1004return DAG.getNode(
1005MipsISD::Ins,DL,N->getValueType(0),
1006 isConstCase
1007 ? DAG.getConstant(CN1->getSExtValue() >> SMPos0,DL, ValTy)
1008 : SrlX,
1009 DAG.getConstant(SMPos0,DL, MVT::i32),
1010 DAG.getConstant(ValTy.getSizeInBits() / 8 < 8 ? SMSize0 & 31
1011 : SMSize0,
1012DL, MVT::i32),
1013 FirstOperand->getOperand(0));
1014 }
1015returnSDValue();
1016 }
1017}
1018
1019staticSDValueperformMADD_MSUBCombine(SDNode *ROOTNode,SelectionDAG &CurDAG,
1020constMipsSubtarget &Subtarget) {
1021// ROOTNode must have a multiplication as an operand for the match to be
1022// successful.
1023if (ROOTNode->getOperand(0).getOpcode() !=ISD::MUL &&
1024 ROOTNode->getOperand(1).getOpcode() !=ISD::MUL)
1025returnSDValue();
1026
1027// In the case where we have a multiplication as the left operand of
1028// of a subtraction, we can't combine into a MipsISD::MSub node as the
1029// the instruction definition of msub(u) places the multiplication on
1030// on the right.
1031if (ROOTNode->getOpcode() ==ISD::SUB &&
1032 ROOTNode->getOperand(0).getOpcode() ==ISD::MUL)
1033returnSDValue();
1034
1035// We don't handle vector types here.
1036if (ROOTNode->getValueType(0).isVector())
1037returnSDValue();
1038
1039// For MIPS64, madd / msub instructions are inefficent to use with 64 bit
1040// arithmetic. E.g.
1041// (add (mul a b) c) =>
1042// let res = (madd (mthi (drotr c 32))x(mtlo c) a b) in
1043// MIPS64: (or (dsll (mfhi res) 32) (dsrl (dsll (mflo res) 32) 32)
1044// or
1045// MIPS64R2: (dins (mflo res) (mfhi res) 32 32)
1046//
1047// The overhead of setting up the Hi/Lo registers and reassembling the
1048// result makes this a dubious optimzation for MIPS64. The core of the
1049// problem is that Hi/Lo contain the upper and lower 32 bits of the
1050// operand and result.
1051//
1052// It requires a chain of 4 add/mul for MIPS64R2 to get better code
1053// density than doing it naively, 5 for MIPS64. Additionally, using
1054// madd/msub on MIPS64 requires the operands actually be 32 bit sign
1055// extended operands, not true 64 bit values.
1056//
1057// FIXME: For the moment, disable this completely for MIPS64.
1058if (Subtarget.hasMips64())
1059returnSDValue();
1060
1061SDValue Mult = ROOTNode->getOperand(0).getOpcode() ==ISD::MUL
1062 ? ROOTNode->getOperand(0)
1063 : ROOTNode->getOperand(1);
1064
1065SDValue AddOperand = ROOTNode->getOperand(0).getOpcode() ==ISD::MUL
1066 ? ROOTNode->getOperand(1)
1067 : ROOTNode->getOperand(0);
1068
1069// Transform this to a MADD only if the user of this node is the add.
1070// If there are other users of the mul, this function returns here.
1071if (!Mult.hasOneUse())
1072returnSDValue();
1073
1074// maddu and madd are unusual instructions in that on MIPS64 bits 63..31
1075// must be in canonical form, i.e. sign extended. For MIPS32, the operands
1076// of the multiply must have 32 or more sign bits, otherwise we cannot
1077// perform this optimization. We have to check this here as we're performing
1078// this optimization pre-legalization.
1079SDValue MultLHS = Mult->getOperand(0);
1080SDValue MultRHS = Mult->getOperand(1);
1081
1082bool IsSigned = MultLHS->getOpcode() ==ISD::SIGN_EXTEND &&
1083 MultRHS->getOpcode() ==ISD::SIGN_EXTEND;
1084bool IsUnsigned = MultLHS->getOpcode() ==ISD::ZERO_EXTEND &&
1085 MultRHS->getOpcode() ==ISD::ZERO_EXTEND;
1086
1087if (!IsSigned && !IsUnsigned)
1088returnSDValue();
1089
1090// Initialize accumulator.
1091SDLocDL(ROOTNode);
1092SDValue BottomHalf, TopHalf;
1093 std::tie(BottomHalf, TopHalf) =
1094 CurDAG.SplitScalar(AddOperand,DL, MVT::i32, MVT::i32);
1095SDValue ACCIn =
1096 CurDAG.getNode(MipsISD::MTLOHI,DL, MVT::Untyped, BottomHalf, TopHalf);
1097
1098// Create MipsMAdd(u) / MipsMSub(u) node.
1099bool IsAdd = ROOTNode->getOpcode() ==ISD::ADD;
1100unsigned Opcode = IsAdd ? (IsUnsigned ?MipsISD::MAddu :MipsISD::MAdd)
1101 : (IsUnsigned ?MipsISD::MSubu :MipsISD::MSub);
1102SDValue MAddOps[3] = {
1103 CurDAG.getNode(ISD::TRUNCATE,DL, MVT::i32, Mult->getOperand(0)),
1104 CurDAG.getNode(ISD::TRUNCATE,DL, MVT::i32, Mult->getOperand(1)), ACCIn};
1105SDValue MAdd = CurDAG.getNode(Opcode,DL, MVT::Untyped, MAddOps);
1106
1107SDValue ResLo = CurDAG.getNode(MipsISD::MFLO,DL, MVT::i32, MAdd);
1108SDValue ResHi = CurDAG.getNode(MipsISD::MFHI,DL, MVT::i32, MAdd);
1109SDValue Combined =
1110 CurDAG.getNode(ISD::BUILD_PAIR,DL, MVT::i64, ResLo, ResHi);
1111return Combined;
1112}
1113
1114staticSDValueperformSUBCombine(SDNode *N,SelectionDAG &DAG,
1115TargetLowering::DAGCombinerInfo &DCI,
1116constMipsSubtarget &Subtarget) {
1117// (sub v0 (mul v1, v2)) => (msub v1, v2, v0)
1118if (DCI.isBeforeLegalizeOps()) {
1119if (Subtarget.hasMips32() && !Subtarget.hasMips32r6() &&
1120 !Subtarget.inMips16Mode() &&N->getValueType(0) == MVT::i64)
1121returnperformMADD_MSUBCombine(N, DAG, Subtarget);
1122
1123returnSDValue();
1124 }
1125
1126returnSDValue();
1127}
1128
1129staticSDValueperformADDCombine(SDNode *N,SelectionDAG &DAG,
1130TargetLowering::DAGCombinerInfo &DCI,
1131constMipsSubtarget &Subtarget) {
1132// (add v0 (mul v1, v2)) => (madd v1, v2, v0)
1133if (DCI.isBeforeLegalizeOps()) {
1134if (Subtarget.hasMips32() && !Subtarget.hasMips32r6() &&
1135 !Subtarget.inMips16Mode() &&N->getValueType(0) == MVT::i64)
1136returnperformMADD_MSUBCombine(N, DAG, Subtarget);
1137
1138returnSDValue();
1139 }
1140
1141// (add v0, (add v1, abs_lo(tjt))) => (add (add v0, v1), abs_lo(tjt))
1142SDValueAdd =N->getOperand(1);
1143
1144if (Add.getOpcode() !=ISD::ADD)
1145returnSDValue();
1146
1147SDValueLo =Add.getOperand(1);
1148
1149if ((Lo.getOpcode() !=MipsISD::Lo) ||
1150 (Lo.getOperand(0).getOpcode() !=ISD::TargetJumpTable))
1151returnSDValue();
1152
1153EVT ValTy =N->getValueType(0);
1154SDLocDL(N);
1155
1156SDValue Add1 = DAG.getNode(ISD::ADD,DL, ValTy,N->getOperand(0),
1157Add.getOperand(0));
1158return DAG.getNode(ISD::ADD,DL, ValTy, Add1,Lo);
1159}
1160
1161staticSDValueperformSHLCombine(SDNode *N,SelectionDAG &DAG,
1162TargetLowering::DAGCombinerInfo &DCI,
1163constMipsSubtarget &Subtarget) {
1164// Pattern match CINS.
1165// $dst = shl (and $src , imm), pos
1166// => cins $dst, $src, pos, size
1167
1168if (DCI.isBeforeLegalizeOps() || !Subtarget.hasCnMips())
1169returnSDValue();
1170
1171SDValue FirstOperand =N->getOperand(0);
1172unsigned FirstOperandOpc = FirstOperand.getOpcode();
1173SDValue SecondOperand =N->getOperand(1);
1174EVT ValTy =N->getValueType(0);
1175SDLocDL(N);
1176
1177uint64_t Pos = 0;
1178unsigned SMPos, SMSize;
1179ConstantSDNode *CN;
1180SDValue NewOperand;
1181
1182// The second operand of the shift must be an immediate.
1183if (!(CN = dyn_cast<ConstantSDNode>(SecondOperand)))
1184returnSDValue();
1185
1186 Pos = CN->getZExtValue();
1187
1188if (Pos >= ValTy.getSizeInBits())
1189returnSDValue();
1190
1191if (FirstOperandOpc !=ISD::AND)
1192returnSDValue();
1193
1194// AND's second operand must be a shifted mask.
1195if (!(CN = dyn_cast<ConstantSDNode>(FirstOperand.getOperand(1))) ||
1196 !isShiftedMask_64(CN->getZExtValue(), SMPos, SMSize))
1197returnSDValue();
1198
1199// Return if the shifted mask does not start at bit 0 or the sum of its size
1200// and Pos exceeds the word's size.
1201if (SMPos != 0 || SMSize > 32 || Pos + SMSize > ValTy.getSizeInBits())
1202returnSDValue();
1203
1204 NewOperand = FirstOperand.getOperand(0);
1205// SMSize is 'location' (position) in this case, not size.
1206 SMSize--;
1207
1208return DAG.getNode(MipsISD::CIns,DL, ValTy, NewOperand,
1209 DAG.getConstant(Pos,DL, MVT::i32),
1210 DAG.getConstant(SMSize,DL, MVT::i32));
1211}
1212
1213SDValueMipsTargetLowering::PerformDAGCombine(SDNode *N,DAGCombinerInfo &DCI)
1214 const{
1215SelectionDAG &DAG = DCI.DAG;
1216unsigned Opc =N->getOpcode();
1217
1218switch (Opc) {
1219default:break;
1220caseISD::SDIVREM:
1221caseISD::UDIVREM:
1222returnperformDivRemCombine(N, DAG, DCI,Subtarget);
1223caseISD::SELECT:
1224returnperformSELECTCombine(N, DAG, DCI,Subtarget);
1225caseMipsISD::CMovFP_F:
1226caseMipsISD::CMovFP_T:
1227returnperformCMovFPCombine(N, DAG, DCI,Subtarget);
1228caseISD::AND:
1229returnperformANDCombine(N, DAG, DCI,Subtarget);
1230caseISD::OR:
1231returnperformORCombine(N, DAG, DCI,Subtarget);
1232caseISD::ADD:
1233returnperformADDCombine(N, DAG, DCI,Subtarget);
1234caseISD::SHL:
1235returnperformSHLCombine(N, DAG, DCI,Subtarget);
1236caseISD::SUB:
1237returnperformSUBCombine(N, DAG, DCI,Subtarget);
1238 }
1239
1240returnSDValue();
1241}
1242
1243boolMipsTargetLowering::isCheapToSpeculateCttz(Type *Ty) const{
1244returnSubtarget.hasMips32();
1245}
1246
1247boolMipsTargetLowering::isCheapToSpeculateCtlz(Type *Ty) const{
1248returnSubtarget.hasMips32();
1249}
1250
1251boolMipsTargetLowering::hasBitTest(SDValueX,SDValueY) const{
1252// We can use ANDI+SLTIU as a bit test. Y contains the bit position.
1253// For MIPSR2 or later, we may be able to use the `ext` instruction or its'
1254// double-word variants.
1255if (auto *C = dyn_cast<ConstantSDNode>(Y))
1256returnC->getAPIntValue().ule(15);
1257
1258returnfalse;
1259}
1260
1261boolMipsTargetLowering::shouldFoldConstantShiftPairToMask(
1262constSDNode *N,CombineLevel Level) const{
1263assert(((N->getOpcode() ==ISD::SHL &&
1264N->getOperand(0).getOpcode() ==ISD::SRL) ||
1265 (N->getOpcode() ==ISD::SRL &&
1266N->getOperand(0).getOpcode() ==ISD::SHL)) &&
1267"Expected shift-shift mask");
1268
1269if (N->getOperand(0).getValueType().isVector())
1270returnfalse;
1271returntrue;
1272}
1273
1274void
1275MipsTargetLowering::ReplaceNodeResults(SDNode *N,
1276SmallVectorImpl<SDValue> &Results,
1277SelectionDAG &DAG) const{
1278returnLowerOperationWrapper(N,Results, DAG);
1279}
1280
1281SDValueMipsTargetLowering::
1282LowerOperation(SDValueOp,SelectionDAG &DAG) const
1283{
1284switch (Op.getOpcode())
1285 {
1286caseISD::BRCOND:return lowerBRCOND(Op, DAG);
1287caseISD::ConstantPool:return lowerConstantPool(Op, DAG);
1288caseISD::GlobalAddress:return lowerGlobalAddress(Op, DAG);
1289caseISD::BlockAddress:return lowerBlockAddress(Op, DAG);
1290caseISD::GlobalTLSAddress:return lowerGlobalTLSAddress(Op, DAG);
1291caseISD::JumpTable:return lowerJumpTable(Op, DAG);
1292caseISD::SELECT:return lowerSELECT(Op, DAG);
1293caseISD::SETCC:return lowerSETCC(Op, DAG);
1294caseISD::VASTART:return lowerVASTART(Op, DAG);
1295caseISD::VAARG:return lowerVAARG(Op, DAG);
1296caseISD::FCOPYSIGN:return lowerFCOPYSIGN(Op, DAG);
1297caseISD::FABS:return lowerFABS(Op, DAG);
1298caseISD::FCANONICALIZE:
1299return lowerFCANONICALIZE(Op, DAG);
1300caseISD::FRAMEADDR:return lowerFRAMEADDR(Op, DAG);
1301caseISD::RETURNADDR:return lowerRETURNADDR(Op, DAG);
1302caseISD::EH_RETURN:return lowerEH_RETURN(Op, DAG);
1303caseISD::ATOMIC_FENCE:return lowerATOMIC_FENCE(Op, DAG);
1304caseISD::SHL_PARTS:return lowerShiftLeftParts(Op, DAG);
1305caseISD::SRA_PARTS:return lowerShiftRightParts(Op, DAG,true);
1306caseISD::SRL_PARTS:return lowerShiftRightParts(Op, DAG,false);
1307caseISD::LOAD:returnlowerLOAD(Op, DAG);
1308caseISD::STORE:returnlowerSTORE(Op, DAG);
1309caseISD::EH_DWARF_CFA:return lowerEH_DWARF_CFA(Op, DAG);
1310caseISD::FP_TO_SINT:return lowerFP_TO_SINT(Op, DAG);
1311 }
1312returnSDValue();
1313}
1314
1315//===----------------------------------------------------------------------===//
1316// Lower helper functions
1317//===----------------------------------------------------------------------===//
1318
1319// addLiveIn - This helper function adds the specified physical register to the
1320// MachineFunction as a live in value. It also creates a corresponding
1321// virtual register for it.
1322staticunsigned
1323addLiveIn(MachineFunction &MF,unsigned PReg,constTargetRegisterClass *RC)
1324{
1325Register VReg = MF.getRegInfo().createVirtualRegister(RC);
1326 MF.getRegInfo().addLiveIn(PReg, VReg);
1327return VReg;
1328}
1329
1330staticMachineBasicBlock *insertDivByZeroTrap(MachineInstr &MI,
1331MachineBasicBlock &MBB,
1332constTargetInstrInfo &TII,
1333bool Is64Bit,bool IsMicroMips) {
1334if (NoZeroDivCheck)
1335return &MBB;
1336
1337// Insert instruction "teq $divisor_reg, $zero, 7".
1338MachineBasicBlock::iteratorI(MI);
1339MachineInstrBuilder MIB;
1340MachineOperand &Divisor =MI.getOperand(2);
1341 MIB =BuildMI(MBB, std::next(I),MI.getDebugLoc(),
1342TII.get(IsMicroMips ? Mips::TEQ_MM : Mips::TEQ))
1343 .addReg(Divisor.getReg(),getKillRegState(Divisor.isKill()))
1344 .addReg(Mips::ZERO)
1345 .addImm(7);
1346
1347// Use the 32-bit sub-register if this is a 64-bit division.
1348if (Is64Bit)
1349 MIB->getOperand(0).setSubReg(Mips::sub_32);
1350
1351// Clear Divisor's kill flag.
1352 Divisor.setIsKill(false);
1353
1354// We would normally delete the original instruction here but in this case
1355// we only needed to inject an additional instruction rather than replace it.
1356
1357return &MBB;
1358}
1359
1360MachineBasicBlock *
1361MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
1362MachineBasicBlock *BB) const{
1363switch (MI.getOpcode()) {
1364default:
1365llvm_unreachable("Unexpected instr type to insert");
1366case Mips::ATOMIC_LOAD_ADD_I8:
1367return emitAtomicBinaryPartword(MI, BB, 1);
1368case Mips::ATOMIC_LOAD_ADD_I16:
1369return emitAtomicBinaryPartword(MI, BB, 2);
1370case Mips::ATOMIC_LOAD_ADD_I32:
1371return emitAtomicBinary(MI, BB);
1372case Mips::ATOMIC_LOAD_ADD_I64:
1373return emitAtomicBinary(MI, BB);
1374
1375case Mips::ATOMIC_LOAD_AND_I8:
1376return emitAtomicBinaryPartword(MI, BB, 1);
1377case Mips::ATOMIC_LOAD_AND_I16:
1378return emitAtomicBinaryPartword(MI, BB, 2);
1379case Mips::ATOMIC_LOAD_AND_I32:
1380return emitAtomicBinary(MI, BB);
1381case Mips::ATOMIC_LOAD_AND_I64:
1382return emitAtomicBinary(MI, BB);
1383
1384case Mips::ATOMIC_LOAD_OR_I8:
1385return emitAtomicBinaryPartword(MI, BB, 1);
1386case Mips::ATOMIC_LOAD_OR_I16:
1387return emitAtomicBinaryPartword(MI, BB, 2);
1388case Mips::ATOMIC_LOAD_OR_I32:
1389return emitAtomicBinary(MI, BB);
1390case Mips::ATOMIC_LOAD_OR_I64:
1391return emitAtomicBinary(MI, BB);
1392
1393case Mips::ATOMIC_LOAD_XOR_I8:
1394return emitAtomicBinaryPartword(MI, BB, 1);
1395case Mips::ATOMIC_LOAD_XOR_I16:
1396return emitAtomicBinaryPartword(MI, BB, 2);
1397case Mips::ATOMIC_LOAD_XOR_I32:
1398return emitAtomicBinary(MI, BB);
1399case Mips::ATOMIC_LOAD_XOR_I64:
1400return emitAtomicBinary(MI, BB);
1401
1402case Mips::ATOMIC_LOAD_NAND_I8:
1403return emitAtomicBinaryPartword(MI, BB, 1);
1404case Mips::ATOMIC_LOAD_NAND_I16:
1405return emitAtomicBinaryPartword(MI, BB, 2);
1406case Mips::ATOMIC_LOAD_NAND_I32:
1407return emitAtomicBinary(MI, BB);
1408case Mips::ATOMIC_LOAD_NAND_I64:
1409return emitAtomicBinary(MI, BB);
1410
1411case Mips::ATOMIC_LOAD_SUB_I8:
1412return emitAtomicBinaryPartword(MI, BB, 1);
1413case Mips::ATOMIC_LOAD_SUB_I16:
1414return emitAtomicBinaryPartword(MI, BB, 2);
1415case Mips::ATOMIC_LOAD_SUB_I32:
1416return emitAtomicBinary(MI, BB);
1417case Mips::ATOMIC_LOAD_SUB_I64:
1418return emitAtomicBinary(MI, BB);
1419
1420case Mips::ATOMIC_SWAP_I8:
1421return emitAtomicBinaryPartword(MI, BB, 1);
1422case Mips::ATOMIC_SWAP_I16:
1423return emitAtomicBinaryPartword(MI, BB, 2);
1424case Mips::ATOMIC_SWAP_I32:
1425return emitAtomicBinary(MI, BB);
1426case Mips::ATOMIC_SWAP_I64:
1427return emitAtomicBinary(MI, BB);
1428
1429case Mips::ATOMIC_CMP_SWAP_I8:
1430return emitAtomicCmpSwapPartword(MI, BB, 1);
1431case Mips::ATOMIC_CMP_SWAP_I16:
1432return emitAtomicCmpSwapPartword(MI, BB, 2);
1433case Mips::ATOMIC_CMP_SWAP_I32:
1434return emitAtomicCmpSwap(MI, BB);
1435case Mips::ATOMIC_CMP_SWAP_I64:
1436return emitAtomicCmpSwap(MI, BB);
1437
1438case Mips::ATOMIC_LOAD_MIN_I8:
1439return emitAtomicBinaryPartword(MI, BB, 1);
1440case Mips::ATOMIC_LOAD_MIN_I16:
1441return emitAtomicBinaryPartword(MI, BB, 2);
1442case Mips::ATOMIC_LOAD_MIN_I32:
1443return emitAtomicBinary(MI, BB);
1444case Mips::ATOMIC_LOAD_MIN_I64:
1445return emitAtomicBinary(MI, BB);
1446
1447case Mips::ATOMIC_LOAD_MAX_I8:
1448return emitAtomicBinaryPartword(MI, BB, 1);
1449case Mips::ATOMIC_LOAD_MAX_I16:
1450return emitAtomicBinaryPartword(MI, BB, 2);
1451case Mips::ATOMIC_LOAD_MAX_I32:
1452return emitAtomicBinary(MI, BB);
1453case Mips::ATOMIC_LOAD_MAX_I64:
1454return emitAtomicBinary(MI, BB);
1455
1456case Mips::ATOMIC_LOAD_UMIN_I8:
1457return emitAtomicBinaryPartword(MI, BB, 1);
1458case Mips::ATOMIC_LOAD_UMIN_I16:
1459return emitAtomicBinaryPartword(MI, BB, 2);
1460case Mips::ATOMIC_LOAD_UMIN_I32:
1461return emitAtomicBinary(MI, BB);
1462case Mips::ATOMIC_LOAD_UMIN_I64:
1463return emitAtomicBinary(MI, BB);
1464
1465case Mips::ATOMIC_LOAD_UMAX_I8:
1466return emitAtomicBinaryPartword(MI, BB, 1);
1467case Mips::ATOMIC_LOAD_UMAX_I16:
1468return emitAtomicBinaryPartword(MI, BB, 2);
1469case Mips::ATOMIC_LOAD_UMAX_I32:
1470return emitAtomicBinary(MI, BB);
1471case Mips::ATOMIC_LOAD_UMAX_I64:
1472return emitAtomicBinary(MI, BB);
1473
1474case Mips::PseudoSDIV:
1475case Mips::PseudoUDIV:
1476case Mips::DIV:
1477case Mips::DIVU:
1478case Mips::MOD:
1479case Mips::MODU:
1480returninsertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(),false,
1481false);
1482case Mips::SDIV_MM_Pseudo:
1483case Mips::UDIV_MM_Pseudo:
1484case Mips::SDIV_MM:
1485case Mips::UDIV_MM:
1486case Mips::DIV_MMR6:
1487case Mips::DIVU_MMR6:
1488case Mips::MOD_MMR6:
1489case Mips::MODU_MMR6:
1490returninsertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(),false,true);
1491case Mips::PseudoDSDIV:
1492case Mips::PseudoDUDIV:
1493case Mips::DDIV:
1494case Mips::DDIVU:
1495case Mips::DMOD:
1496case Mips::DMODU:
1497returninsertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(),true,false);
1498
1499case Mips::PseudoSELECT_I:
1500case Mips::PseudoSELECT_I64:
1501case Mips::PseudoSELECT_S:
1502case Mips::PseudoSELECT_D32:
1503case Mips::PseudoSELECT_D64:
1504return emitPseudoSELECT(MI, BB,false, Mips::BNE);
1505case Mips::PseudoSELECTFP_F_I:
1506case Mips::PseudoSELECTFP_F_I64:
1507case Mips::PseudoSELECTFP_F_S:
1508case Mips::PseudoSELECTFP_F_D32:
1509case Mips::PseudoSELECTFP_F_D64:
1510return emitPseudoSELECT(MI, BB,true, Mips::BC1F);
1511case Mips::PseudoSELECTFP_T_I:
1512case Mips::PseudoSELECTFP_T_I64:
1513case Mips::PseudoSELECTFP_T_S:
1514case Mips::PseudoSELECTFP_T_D32:
1515case Mips::PseudoSELECTFP_T_D64:
1516return emitPseudoSELECT(MI, BB,true, Mips::BC1T);
1517case Mips::PseudoD_SELECT_I:
1518case Mips::PseudoD_SELECT_I64:
1519return emitPseudoD_SELECT(MI, BB);
1520case Mips::LDR_W:
1521return emitLDR_W(MI, BB);
1522case Mips::LDR_D:
1523return emitLDR_D(MI, BB);
1524case Mips::STR_W:
1525return emitSTR_W(MI, BB);
1526case Mips::STR_D:
1527return emitSTR_D(MI, BB);
1528 }
1529}
1530
1531// This function also handles Mips::ATOMIC_SWAP_I32 (when BinOpcode == 0), and
1532// Mips::ATOMIC_LOAD_NAND_I32 (when Nand == true)
1533MachineBasicBlock *
1534MipsTargetLowering::emitAtomicBinary(MachineInstr &MI,
1535MachineBasicBlock *BB) const{
1536
1537MachineFunction *MF = BB->getParent();
1538MachineRegisterInfo &RegInfo = MF->getRegInfo();
1539constTargetInstrInfo *TII =Subtarget.getInstrInfo();
1540DebugLocDL =MI.getDebugLoc();
1541
1542unsigned AtomicOp;
1543bool NeedsAdditionalReg =false;
1544switch (MI.getOpcode()) {
1545case Mips::ATOMIC_LOAD_ADD_I32:
1546 AtomicOp = Mips::ATOMIC_LOAD_ADD_I32_POSTRA;
1547break;
1548case Mips::ATOMIC_LOAD_SUB_I32:
1549 AtomicOp = Mips::ATOMIC_LOAD_SUB_I32_POSTRA;
1550break;
1551case Mips::ATOMIC_LOAD_AND_I32:
1552 AtomicOp = Mips::ATOMIC_LOAD_AND_I32_POSTRA;
1553break;
1554case Mips::ATOMIC_LOAD_OR_I32:
1555 AtomicOp = Mips::ATOMIC_LOAD_OR_I32_POSTRA;
1556break;
1557case Mips::ATOMIC_LOAD_XOR_I32:
1558 AtomicOp = Mips::ATOMIC_LOAD_XOR_I32_POSTRA;
1559break;
1560case Mips::ATOMIC_LOAD_NAND_I32:
1561 AtomicOp = Mips::ATOMIC_LOAD_NAND_I32_POSTRA;
1562break;
1563case Mips::ATOMIC_SWAP_I32:
1564 AtomicOp = Mips::ATOMIC_SWAP_I32_POSTRA;
1565break;
1566case Mips::ATOMIC_LOAD_ADD_I64:
1567 AtomicOp = Mips::ATOMIC_LOAD_ADD_I64_POSTRA;
1568break;
1569case Mips::ATOMIC_LOAD_SUB_I64:
1570 AtomicOp = Mips::ATOMIC_LOAD_SUB_I64_POSTRA;
1571break;
1572case Mips::ATOMIC_LOAD_AND_I64:
1573 AtomicOp = Mips::ATOMIC_LOAD_AND_I64_POSTRA;
1574break;
1575case Mips::ATOMIC_LOAD_OR_I64:
1576 AtomicOp = Mips::ATOMIC_LOAD_OR_I64_POSTRA;
1577break;
1578case Mips::ATOMIC_LOAD_XOR_I64:
1579 AtomicOp = Mips::ATOMIC_LOAD_XOR_I64_POSTRA;
1580break;
1581case Mips::ATOMIC_LOAD_NAND_I64:
1582 AtomicOp = Mips::ATOMIC_LOAD_NAND_I64_POSTRA;
1583break;
1584case Mips::ATOMIC_SWAP_I64:
1585 AtomicOp = Mips::ATOMIC_SWAP_I64_POSTRA;
1586break;
1587case Mips::ATOMIC_LOAD_MIN_I32:
1588 AtomicOp = Mips::ATOMIC_LOAD_MIN_I32_POSTRA;
1589 NeedsAdditionalReg =true;
1590break;
1591case Mips::ATOMIC_LOAD_MAX_I32:
1592 AtomicOp = Mips::ATOMIC_LOAD_MAX_I32_POSTRA;
1593 NeedsAdditionalReg =true;
1594break;
1595case Mips::ATOMIC_LOAD_UMIN_I32:
1596 AtomicOp = Mips::ATOMIC_LOAD_UMIN_I32_POSTRA;
1597 NeedsAdditionalReg =true;
1598break;
1599case Mips::ATOMIC_LOAD_UMAX_I32:
1600 AtomicOp = Mips::ATOMIC_LOAD_UMAX_I32_POSTRA;
1601 NeedsAdditionalReg =true;
1602break;
1603case Mips::ATOMIC_LOAD_MIN_I64:
1604 AtomicOp = Mips::ATOMIC_LOAD_MIN_I64_POSTRA;
1605 NeedsAdditionalReg =true;
1606break;
1607case Mips::ATOMIC_LOAD_MAX_I64:
1608 AtomicOp = Mips::ATOMIC_LOAD_MAX_I64_POSTRA;
1609 NeedsAdditionalReg =true;
1610break;
1611case Mips::ATOMIC_LOAD_UMIN_I64:
1612 AtomicOp = Mips::ATOMIC_LOAD_UMIN_I64_POSTRA;
1613 NeedsAdditionalReg =true;
1614break;
1615case Mips::ATOMIC_LOAD_UMAX_I64:
1616 AtomicOp = Mips::ATOMIC_LOAD_UMAX_I64_POSTRA;
1617 NeedsAdditionalReg =true;
1618break;
1619default:
1620llvm_unreachable("Unknown pseudo atomic for replacement!");
1621 }
1622
1623Register OldVal =MI.getOperand(0).getReg();
1624RegisterPtr =MI.getOperand(1).getReg();
1625Register Incr =MI.getOperand(2).getReg();
1626Register Scratch =RegInfo.createVirtualRegister(RegInfo.getRegClass(OldVal));
1627
1628MachineBasicBlock::iteratorII(MI);
1629
1630// The scratch registers here with the EarlyClobber | Define | Implicit
1631// flags is used to persuade the register allocator and the machine
1632// verifier to accept the usage of this register. This has to be a real
1633// register which has an UNDEF value but is dead after the instruction which
1634// is unique among the registers chosen for the instruction.
1635
1636// The EarlyClobber flag has the semantic properties that the operand it is
1637// attached to is clobbered before the rest of the inputs are read. Hence it
1638// must be unique among the operands to the instruction.
1639// The Define flag is needed to coerce the machine verifier that an Undef
1640// value isn't a problem.
1641// The Dead flag is needed as the value in scratch isn't used by any other
1642// instruction. Kill isn't used as Dead is more precise.
1643// The implicit flag is here due to the interaction between the other flags
1644// and the machine verifier.
1645
1646// For correctness purpose, a new pseudo is introduced here. We need this
1647// new pseudo, so that FastRegisterAllocator does not see an ll/sc sequence
1648// that is spread over >1 basic blocks. A register allocator which
1649// introduces (or any codegen infact) a store, can violate the expectations
1650// of the hardware.
1651//
1652// An atomic read-modify-write sequence starts with a linked load
1653// instruction and ends with a store conditional instruction. The atomic
1654// read-modify-write sequence fails if any of the following conditions
1655// occur between the execution of ll and sc:
1656// * A coherent store is completed by another process or coherent I/O
1657// module into the block of synchronizable physical memory containing
1658// the word. The size and alignment of the block is
1659// implementation-dependent.
1660// * A coherent store is executed between an LL and SC sequence on the
1661// same processor to the block of synchornizable physical memory
1662// containing the word.
1663//
1664
1665Register PtrCopy =RegInfo.createVirtualRegister(RegInfo.getRegClass(Ptr));
1666Register IncrCopy =RegInfo.createVirtualRegister(RegInfo.getRegClass(Incr));
1667
1668BuildMI(*BB,II,DL,TII->get(Mips::COPY), IncrCopy).addReg(Incr);
1669BuildMI(*BB,II,DL,TII->get(Mips::COPY), PtrCopy).addReg(Ptr);
1670
1671MachineInstrBuilder MIB =
1672BuildMI(*BB,II,DL,TII->get(AtomicOp))
1673 .addReg(OldVal,RegState::Define |RegState::EarlyClobber)
1674 .addReg(PtrCopy)
1675 .addReg(IncrCopy)
1676 .addReg(Scratch,RegState::Define |RegState::EarlyClobber |
1677RegState::Implicit |RegState::Dead);
1678if (NeedsAdditionalReg) {
1679Register Scratch2 =
1680RegInfo.createVirtualRegister(RegInfo.getRegClass(OldVal));
1681 MIB.addReg(Scratch2,RegState::Define |RegState::EarlyClobber |
1682RegState::Implicit |RegState::Dead);
1683 }
1684
1685MI.eraseFromParent();
1686
1687return BB;
1688}
1689
1690MachineBasicBlock *MipsTargetLowering::emitSignExtendToI32InReg(
1691MachineInstr &MI,MachineBasicBlock *BB,unsignedSize,unsigned DstReg,
1692unsigned SrcReg) const{
1693constTargetInstrInfo *TII =Subtarget.getInstrInfo();
1694constDebugLoc &DL =MI.getDebugLoc();
1695
1696if (Subtarget.hasMips32r2() &&Size == 1) {
1697BuildMI(BB,DL,TII->get(Mips::SEB), DstReg).addReg(SrcReg);
1698return BB;
1699 }
1700
1701if (Subtarget.hasMips32r2() &&Size == 2) {
1702BuildMI(BB,DL,TII->get(Mips::SEH), DstReg).addReg(SrcReg);
1703return BB;
1704 }
1705
1706MachineFunction *MF = BB->getParent();
1707MachineRegisterInfo &RegInfo = MF->getRegInfo();
1708constTargetRegisterClass *RC =getRegClassFor(MVT::i32);
1709Register ScrReg =RegInfo.createVirtualRegister(RC);
1710
1711assert(Size < 32);
1712 int64_t ShiftImm = 32 - (Size * 8);
1713
1714BuildMI(BB,DL,TII->get(Mips::SLL), ScrReg).addReg(SrcReg).addImm(ShiftImm);
1715BuildMI(BB,DL,TII->get(Mips::SRA), DstReg).addReg(ScrReg).addImm(ShiftImm);
1716
1717return BB;
1718}
1719
1720MachineBasicBlock *MipsTargetLowering::emitAtomicBinaryPartword(
1721MachineInstr &MI,MachineBasicBlock *BB,unsignedSize) const{
1722assert((Size == 1 ||Size == 2) &&
1723"Unsupported size for EmitAtomicBinaryPartial.");
1724
1725MachineFunction *MF = BB->getParent();
1726MachineRegisterInfo &RegInfo = MF->getRegInfo();
1727constTargetRegisterClass *RC =getRegClassFor(MVT::i32);
1728constbool ArePtrs64bit =ABI.ArePtrs64bit();
1729constTargetRegisterClass *RCp =
1730getRegClassFor(ArePtrs64bit ? MVT::i64 : MVT::i32);
1731constTargetInstrInfo *TII =Subtarget.getInstrInfo();
1732DebugLocDL =MI.getDebugLoc();
1733
1734Register Dest =MI.getOperand(0).getReg();
1735RegisterPtr =MI.getOperand(1).getReg();
1736Register Incr =MI.getOperand(2).getReg();
1737
1738Register AlignedAddr =RegInfo.createVirtualRegister(RCp);
1739Register ShiftAmt =RegInfo.createVirtualRegister(RC);
1740RegisterMask =RegInfo.createVirtualRegister(RC);
1741Register Mask2 =RegInfo.createVirtualRegister(RC);
1742Register Incr2 =RegInfo.createVirtualRegister(RC);
1743Register MaskLSB2 =RegInfo.createVirtualRegister(RCp);
1744Register PtrLSB2 =RegInfo.createVirtualRegister(RC);
1745Register MaskUpper =RegInfo.createVirtualRegister(RC);
1746Register Scratch =RegInfo.createVirtualRegister(RC);
1747Register Scratch2 =RegInfo.createVirtualRegister(RC);
1748Register Scratch3 =RegInfo.createVirtualRegister(RC);
1749
1750unsigned AtomicOp = 0;
1751bool NeedsAdditionalReg =false;
1752switch (MI.getOpcode()) {
1753case Mips::ATOMIC_LOAD_NAND_I8:
1754 AtomicOp = Mips::ATOMIC_LOAD_NAND_I8_POSTRA;
1755break;
1756case Mips::ATOMIC_LOAD_NAND_I16:
1757 AtomicOp = Mips::ATOMIC_LOAD_NAND_I16_POSTRA;
1758break;
1759case Mips::ATOMIC_SWAP_I8:
1760 AtomicOp = Mips::ATOMIC_SWAP_I8_POSTRA;
1761break;
1762case Mips::ATOMIC_SWAP_I16:
1763 AtomicOp = Mips::ATOMIC_SWAP_I16_POSTRA;
1764break;
1765case Mips::ATOMIC_LOAD_ADD_I8:
1766 AtomicOp = Mips::ATOMIC_LOAD_ADD_I8_POSTRA;
1767break;
1768case Mips::ATOMIC_LOAD_ADD_I16:
1769 AtomicOp = Mips::ATOMIC_LOAD_ADD_I16_POSTRA;
1770break;
1771case Mips::ATOMIC_LOAD_SUB_I8:
1772 AtomicOp = Mips::ATOMIC_LOAD_SUB_I8_POSTRA;
1773break;
1774case Mips::ATOMIC_LOAD_SUB_I16:
1775 AtomicOp = Mips::ATOMIC_LOAD_SUB_I16_POSTRA;
1776break;
1777case Mips::ATOMIC_LOAD_AND_I8:
1778 AtomicOp = Mips::ATOMIC_LOAD_AND_I8_POSTRA;
1779break;
1780case Mips::ATOMIC_LOAD_AND_I16:
1781 AtomicOp = Mips::ATOMIC_LOAD_AND_I16_POSTRA;
1782break;
1783case Mips::ATOMIC_LOAD_OR_I8:
1784 AtomicOp = Mips::ATOMIC_LOAD_OR_I8_POSTRA;
1785break;
1786case Mips::ATOMIC_LOAD_OR_I16:
1787 AtomicOp = Mips::ATOMIC_LOAD_OR_I16_POSTRA;
1788break;
1789case Mips::ATOMIC_LOAD_XOR_I8:
1790 AtomicOp = Mips::ATOMIC_LOAD_XOR_I8_POSTRA;
1791break;
1792case Mips::ATOMIC_LOAD_XOR_I16:
1793 AtomicOp = Mips::ATOMIC_LOAD_XOR_I16_POSTRA;
1794break;
1795case Mips::ATOMIC_LOAD_MIN_I8:
1796 AtomicOp = Mips::ATOMIC_LOAD_MIN_I8_POSTRA;
1797 NeedsAdditionalReg =true;
1798break;
1799case Mips::ATOMIC_LOAD_MIN_I16:
1800 AtomicOp = Mips::ATOMIC_LOAD_MIN_I16_POSTRA;
1801 NeedsAdditionalReg =true;
1802break;
1803case Mips::ATOMIC_LOAD_MAX_I8:
1804 AtomicOp = Mips::ATOMIC_LOAD_MAX_I8_POSTRA;
1805 NeedsAdditionalReg =true;
1806break;
1807case Mips::ATOMIC_LOAD_MAX_I16:
1808 AtomicOp = Mips::ATOMIC_LOAD_MAX_I16_POSTRA;
1809 NeedsAdditionalReg =true;
1810break;
1811case Mips::ATOMIC_LOAD_UMIN_I8:
1812 AtomicOp = Mips::ATOMIC_LOAD_UMIN_I8_POSTRA;
1813 NeedsAdditionalReg =true;
1814break;
1815case Mips::ATOMIC_LOAD_UMIN_I16:
1816 AtomicOp = Mips::ATOMIC_LOAD_UMIN_I16_POSTRA;
1817 NeedsAdditionalReg =true;
1818break;
1819case Mips::ATOMIC_LOAD_UMAX_I8:
1820 AtomicOp = Mips::ATOMIC_LOAD_UMAX_I8_POSTRA;
1821 NeedsAdditionalReg =true;
1822break;
1823case Mips::ATOMIC_LOAD_UMAX_I16:
1824 AtomicOp = Mips::ATOMIC_LOAD_UMAX_I16_POSTRA;
1825 NeedsAdditionalReg =true;
1826break;
1827default:
1828llvm_unreachable("Unknown subword atomic pseudo for expansion!");
1829 }
1830
1831// insert new blocks after the current block
1832constBasicBlock *LLVM_BB = BB->getBasicBlock();
1833MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
1834MachineFunction::iterator It = ++BB->getIterator();
1835 MF->insert(It, exitMBB);
1836
1837// Transfer the remainder of BB and its successor edges to exitMBB.
1838 exitMBB->splice(exitMBB->begin(), BB,
1839 std::next(MachineBasicBlock::iterator(MI)), BB->end());
1840 exitMBB->transferSuccessorsAndUpdatePHIs(BB);
1841
1842 BB->addSuccessor(exitMBB,BranchProbability::getOne());
1843
1844// thisMBB:
1845// addiu masklsb2,$0,-4 # 0xfffffffc
1846// and alignedaddr,ptr,masklsb2
1847// andi ptrlsb2,ptr,3
1848// sll shiftamt,ptrlsb2,3
1849// ori maskupper,$0,255 # 0xff
1850// sll mask,maskupper,shiftamt
1851// nor mask2,$0,mask
1852// sll incr2,incr,shiftamt
1853
1854 int64_t MaskImm = (Size == 1) ? 255 : 65535;
1855BuildMI(BB,DL,TII->get(ABI.GetPtrAddiuOp()), MaskLSB2)
1856 .addReg(ABI.GetNullPtr()).addImm(-4);
1857BuildMI(BB,DL,TII->get(ABI.GetPtrAndOp()), AlignedAddr)
1858 .addReg(Ptr).addReg(MaskLSB2);
1859BuildMI(BB,DL,TII->get(Mips::ANDi), PtrLSB2)
1860 .addReg(Ptr, 0, ArePtrs64bit ? Mips::sub_32 : 0).addImm(3);
1861if (Subtarget.isLittle()) {
1862BuildMI(BB,DL,TII->get(Mips::SLL), ShiftAmt).addReg(PtrLSB2).addImm(3);
1863 }else {
1864RegisterOff =RegInfo.createVirtualRegister(RC);
1865BuildMI(BB,DL,TII->get(Mips::XORi), Off)
1866 .addReg(PtrLSB2).addImm((Size == 1) ? 3 : 2);
1867BuildMI(BB,DL,TII->get(Mips::SLL), ShiftAmt).addReg(Off).addImm(3);
1868 }
1869BuildMI(BB,DL,TII->get(Mips::ORi), MaskUpper)
1870 .addReg(Mips::ZERO).addImm(MaskImm);
1871BuildMI(BB,DL,TII->get(Mips::SLLV), Mask)
1872 .addReg(MaskUpper).addReg(ShiftAmt);
1873BuildMI(BB,DL,TII->get(Mips::NOR), Mask2).addReg(Mips::ZERO).addReg(Mask);
1874BuildMI(BB,DL,TII->get(Mips::SLLV), Incr2).addReg(Incr).addReg(ShiftAmt);
1875
1876
1877// The purposes of the flags on the scratch registers is explained in
1878// emitAtomicBinary. In summary, we need a scratch register which is going to
1879// be undef, that is unique among registers chosen for the instruction.
1880
1881MachineInstrBuilder MIB =
1882BuildMI(BB,DL,TII->get(AtomicOp))
1883 .addReg(Dest,RegState::Define |RegState::EarlyClobber)
1884 .addReg(AlignedAddr)
1885 .addReg(Incr2)
1886 .addReg(Mask)
1887 .addReg(Mask2)
1888 .addReg(ShiftAmt)
1889 .addReg(Scratch,RegState::EarlyClobber |RegState::Define |
1890RegState::Dead |RegState::Implicit)
1891 .addReg(Scratch2,RegState::EarlyClobber |RegState::Define |
1892RegState::Dead |RegState::Implicit)
1893 .addReg(Scratch3,RegState::EarlyClobber |RegState::Define |
1894RegState::Dead |RegState::Implicit);
1895if (NeedsAdditionalReg) {
1896Register Scratch4 =RegInfo.createVirtualRegister(RC);
1897 MIB.addReg(Scratch4,RegState::EarlyClobber |RegState::Define |
1898RegState::Dead |RegState::Implicit);
1899 }
1900
1901MI.eraseFromParent();// The instruction is gone now.
1902
1903return exitMBB;
1904}
1905
1906// Lower atomic compare and swap to a pseudo instruction, taking care to
1907// define a scratch register for the pseudo instruction's expansion. The
1908// instruction is expanded after the register allocator as to prevent
1909// the insertion of stores between the linked load and the store conditional.
1910
1911MachineBasicBlock *
1912MipsTargetLowering::emitAtomicCmpSwap(MachineInstr &MI,
1913MachineBasicBlock *BB) const{
1914
1915assert((MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I32 ||
1916MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I64) &&
1917"Unsupported atomic pseudo for EmitAtomicCmpSwap.");
1918
1919constunsignedSize =MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I32 ? 4 : 8;
1920
1921MachineFunction *MF = BB->getParent();
1922MachineRegisterInfo &MRI = MF->getRegInfo();
1923constTargetRegisterClass *RC =getRegClassFor(MVT::getIntegerVT(Size * 8));
1924constTargetInstrInfo *TII =Subtarget.getInstrInfo();
1925DebugLocDL =MI.getDebugLoc();
1926
1927unsigned AtomicOp =MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I32
1928 ? Mips::ATOMIC_CMP_SWAP_I32_POSTRA
1929 : Mips::ATOMIC_CMP_SWAP_I64_POSTRA;
1930Register Dest =MI.getOperand(0).getReg();
1931RegisterPtr =MI.getOperand(1).getReg();
1932Register OldVal =MI.getOperand(2).getReg();
1933Register NewVal =MI.getOperand(3).getReg();
1934
1935Register Scratch =MRI.createVirtualRegister(RC);
1936MachineBasicBlock::iteratorII(MI);
1937
1938// We need to create copies of the various registers and kill them at the
1939// atomic pseudo. If the copies are not made, when the atomic is expanded
1940// after fast register allocation, the spills will end up outside of the
1941// blocks that their values are defined in, causing livein errors.
1942
1943Register PtrCopy =MRI.createVirtualRegister(MRI.getRegClass(Ptr));
1944Register OldValCopy =MRI.createVirtualRegister(MRI.getRegClass(OldVal));
1945Register NewValCopy =MRI.createVirtualRegister(MRI.getRegClass(NewVal));
1946
1947BuildMI(*BB,II,DL,TII->get(Mips::COPY), PtrCopy).addReg(Ptr);
1948BuildMI(*BB,II,DL,TII->get(Mips::COPY), OldValCopy).addReg(OldVal);
1949BuildMI(*BB,II,DL,TII->get(Mips::COPY), NewValCopy).addReg(NewVal);
1950
1951// The purposes of the flags on the scratch registers is explained in
1952// emitAtomicBinary. In summary, we need a scratch register which is going to
1953// be undef, that is unique among registers chosen for the instruction.
1954
1955BuildMI(*BB,II,DL,TII->get(AtomicOp))
1956 .addReg(Dest,RegState::Define |RegState::EarlyClobber)
1957 .addReg(PtrCopy,RegState::Kill)
1958 .addReg(OldValCopy,RegState::Kill)
1959 .addReg(NewValCopy,RegState::Kill)
1960 .addReg(Scratch,RegState::EarlyClobber |RegState::Define |
1961RegState::Dead |RegState::Implicit);
1962
1963MI.eraseFromParent();// The instruction is gone now.
1964
1965return BB;
1966}
1967
1968MachineBasicBlock *MipsTargetLowering::emitAtomicCmpSwapPartword(
1969MachineInstr &MI,MachineBasicBlock *BB,unsignedSize) const{
1970assert((Size == 1 ||Size == 2) &&
1971"Unsupported size for EmitAtomicCmpSwapPartial.");
1972
1973MachineFunction *MF = BB->getParent();
1974MachineRegisterInfo &RegInfo = MF->getRegInfo();
1975constTargetRegisterClass *RC =getRegClassFor(MVT::i32);
1976constbool ArePtrs64bit =ABI.ArePtrs64bit();
1977constTargetRegisterClass *RCp =
1978getRegClassFor(ArePtrs64bit ? MVT::i64 : MVT::i32);
1979constTargetInstrInfo *TII =Subtarget.getInstrInfo();
1980DebugLocDL =MI.getDebugLoc();
1981
1982Register Dest =MI.getOperand(0).getReg();
1983RegisterPtr =MI.getOperand(1).getReg();
1984Register CmpVal =MI.getOperand(2).getReg();
1985Register NewVal =MI.getOperand(3).getReg();
1986
1987Register AlignedAddr =RegInfo.createVirtualRegister(RCp);
1988Register ShiftAmt =RegInfo.createVirtualRegister(RC);
1989RegisterMask =RegInfo.createVirtualRegister(RC);
1990Register Mask2 =RegInfo.createVirtualRegister(RC);
1991Register ShiftedCmpVal =RegInfo.createVirtualRegister(RC);
1992Register ShiftedNewVal =RegInfo.createVirtualRegister(RC);
1993Register MaskLSB2 =RegInfo.createVirtualRegister(RCp);
1994Register PtrLSB2 =RegInfo.createVirtualRegister(RC);
1995Register MaskUpper =RegInfo.createVirtualRegister(RC);
1996Register MaskedCmpVal =RegInfo.createVirtualRegister(RC);
1997Register MaskedNewVal =RegInfo.createVirtualRegister(RC);
1998unsigned AtomicOp =MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I8
1999 ? Mips::ATOMIC_CMP_SWAP_I8_POSTRA
2000 : Mips::ATOMIC_CMP_SWAP_I16_POSTRA;
2001
2002// The scratch registers here with the EarlyClobber | Define | Dead | Implicit
2003// flags are used to coerce the register allocator and the machine verifier to
2004// accept the usage of these registers.
2005// The EarlyClobber flag has the semantic properties that the operand it is
2006// attached to is clobbered before the rest of the inputs are read. Hence it
2007// must be unique among the operands to the instruction.
2008// The Define flag is needed to coerce the machine verifier that an Undef
2009// value isn't a problem.
2010// The Dead flag is needed as the value in scratch isn't used by any other
2011// instruction. Kill isn't used as Dead is more precise.
2012Register Scratch =RegInfo.createVirtualRegister(RC);
2013Register Scratch2 =RegInfo.createVirtualRegister(RC);
2014
2015// insert new blocks after the current block
2016constBasicBlock *LLVM_BB = BB->getBasicBlock();
2017MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
2018MachineFunction::iterator It = ++BB->getIterator();
2019 MF->insert(It, exitMBB);
2020
2021// Transfer the remainder of BB and its successor edges to exitMBB.
2022 exitMBB->splice(exitMBB->begin(), BB,
2023 std::next(MachineBasicBlock::iterator(MI)), BB->end());
2024 exitMBB->transferSuccessorsAndUpdatePHIs(BB);
2025
2026 BB->addSuccessor(exitMBB,BranchProbability::getOne());
2027
2028// thisMBB:
2029// addiu masklsb2,$0,-4 # 0xfffffffc
2030// and alignedaddr,ptr,masklsb2
2031// andi ptrlsb2,ptr,3
2032// xori ptrlsb2,ptrlsb2,3 # Only for BE
2033// sll shiftamt,ptrlsb2,3
2034// ori maskupper,$0,255 # 0xff
2035// sll mask,maskupper,shiftamt
2036// nor mask2,$0,mask
2037// andi maskedcmpval,cmpval,255
2038// sll shiftedcmpval,maskedcmpval,shiftamt
2039// andi maskednewval,newval,255
2040// sll shiftednewval,maskednewval,shiftamt
2041 int64_t MaskImm = (Size == 1) ? 255 : 65535;
2042BuildMI(BB,DL,TII->get(ArePtrs64bit ? Mips::DADDiu : Mips::ADDiu), MaskLSB2)
2043 .addReg(ABI.GetNullPtr()).addImm(-4);
2044BuildMI(BB,DL,TII->get(ArePtrs64bit ? Mips::AND64 : Mips::AND), AlignedAddr)
2045 .addReg(Ptr).addReg(MaskLSB2);
2046BuildMI(BB,DL,TII->get(Mips::ANDi), PtrLSB2)
2047 .addReg(Ptr, 0, ArePtrs64bit ? Mips::sub_32 : 0).addImm(3);
2048if (Subtarget.isLittle()) {
2049BuildMI(BB,DL,TII->get(Mips::SLL), ShiftAmt).addReg(PtrLSB2).addImm(3);
2050 }else {
2051RegisterOff =RegInfo.createVirtualRegister(RC);
2052BuildMI(BB,DL,TII->get(Mips::XORi), Off)
2053 .addReg(PtrLSB2).addImm((Size == 1) ? 3 : 2);
2054BuildMI(BB,DL,TII->get(Mips::SLL), ShiftAmt).addReg(Off).addImm(3);
2055 }
2056BuildMI(BB,DL,TII->get(Mips::ORi), MaskUpper)
2057 .addReg(Mips::ZERO).addImm(MaskImm);
2058BuildMI(BB,DL,TII->get(Mips::SLLV), Mask)
2059 .addReg(MaskUpper).addReg(ShiftAmt);
2060BuildMI(BB,DL,TII->get(Mips::NOR), Mask2).addReg(Mips::ZERO).addReg(Mask);
2061BuildMI(BB,DL,TII->get(Mips::ANDi), MaskedCmpVal)
2062 .addReg(CmpVal).addImm(MaskImm);
2063BuildMI(BB,DL,TII->get(Mips::SLLV), ShiftedCmpVal)
2064 .addReg(MaskedCmpVal).addReg(ShiftAmt);
2065BuildMI(BB,DL,TII->get(Mips::ANDi), MaskedNewVal)
2066 .addReg(NewVal).addImm(MaskImm);
2067BuildMI(BB,DL,TII->get(Mips::SLLV), ShiftedNewVal)
2068 .addReg(MaskedNewVal).addReg(ShiftAmt);
2069
2070// The purposes of the flags on the scratch registers are explained in
2071// emitAtomicBinary. In summary, we need a scratch register which is going to
2072// be undef, that is unique among the register chosen for the instruction.
2073
2074BuildMI(BB,DL,TII->get(AtomicOp))
2075 .addReg(Dest,RegState::Define |RegState::EarlyClobber)
2076 .addReg(AlignedAddr)
2077 .addReg(Mask)
2078 .addReg(ShiftedCmpVal)
2079 .addReg(Mask2)
2080 .addReg(ShiftedNewVal)
2081 .addReg(ShiftAmt)
2082 .addReg(Scratch,RegState::EarlyClobber |RegState::Define |
2083RegState::Dead |RegState::Implicit)
2084 .addReg(Scratch2,RegState::EarlyClobber |RegState::Define |
2085RegState::Dead |RegState::Implicit);
2086
2087MI.eraseFromParent();// The instruction is gone now.
2088
2089return exitMBB;
2090}
2091
2092SDValue MipsTargetLowering::lowerBRCOND(SDValueOp,SelectionDAG &DAG) const{
2093// The first operand is the chain, the second is the condition, the third is
2094// the block to branch to if the condition is true.
2095SDValue Chain =Op.getOperand(0);
2096SDValue Dest =Op.getOperand(2);
2097SDLocDL(Op);
2098
2099assert(!Subtarget.hasMips32r6() && !Subtarget.hasMips64r6());
2100SDValue CondRes =createFPCmp(DAG,Op.getOperand(1));
2101
2102// Return if flag is not set by a floating point comparison.
2103if (CondRes.getOpcode() !=MipsISD::FPCmp)
2104returnOp;
2105
2106SDValue CCNode = CondRes.getOperand(2);
2107Mips::CondCodeCC = (Mips::CondCode)CCNode->getAsZExtVal();
2108unsigned Opc =invertFPCondCodeUser(CC) ?Mips::BRANCH_F :Mips::BRANCH_T;
2109SDValue BrCode = DAG.getConstant(Opc,DL, MVT::i32);
2110SDValue FCC0 = DAG.getRegister(Mips::FCC0, MVT::i32);
2111return DAG.getNode(MipsISD::FPBrcond,DL,Op.getValueType(), Chain, BrCode,
2112 FCC0, Dest, CondRes);
2113}
2114
2115SDValue MipsTargetLowering::
2116lowerSELECT(SDValueOp,SelectionDAG &DAG) const
2117{
2118assert(!Subtarget.hasMips32r6() && !Subtarget.hasMips64r6());
2119SDValueCond =createFPCmp(DAG,Op.getOperand(0));
2120
2121// Return if flag is not set by a floating point comparison.
2122if (Cond.getOpcode() !=MipsISD::FPCmp)
2123returnOp;
2124
2125returncreateCMovFP(DAG,Cond,Op.getOperand(1),Op.getOperand(2),
2126SDLoc(Op));
2127}
2128
2129SDValue MipsTargetLowering::lowerSETCC(SDValueOp,SelectionDAG &DAG) const{
2130assert(!Subtarget.hasMips32r6() && !Subtarget.hasMips64r6());
2131SDValueCond =createFPCmp(DAG,Op);
2132
2133assert(Cond.getOpcode() ==MipsISD::FPCmp &&
2134"Floating point operand expected.");
2135
2136SDLocDL(Op);
2137SDValue True = DAG.getConstant(1,DL, MVT::i32);
2138SDValue False = DAG.getConstant(0,DL, MVT::i32);
2139
2140returncreateCMovFP(DAG,Cond, True, False,DL);
2141}
2142
2143SDValue MipsTargetLowering::lowerGlobalAddress(SDValueOp,
2144SelectionDAG &DAG) const{
2145EVT Ty =Op.getValueType();
2146GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
2147constGlobalValue *GV =N->getGlobal();
2148
2149if (GV->hasDLLImportStorageClass()) {
2150assert(Subtarget.isTargetWindows() &&
2151"Windows is the only supported COFF target");
2152returngetDllimportVariable(
2153N,SDLoc(N), Ty, DAG, DAG.getEntryNode(),
2154MachinePointerInfo::getGOT(DAG.getMachineFunction()));
2155 }
2156
2157if (!isPositionIndependent()) {
2158constMipsTargetObjectFile *TLOF =
2159static_cast<constMipsTargetObjectFile *>(
2160getTargetMachine().getObjFileLowering());
2161constGlobalObject *GO = GV->getAliaseeObject();
2162if (GO && TLOF->IsGlobalInSmallSection(GO,getTargetMachine()))
2163// %gp_rel relocation
2164returngetAddrGPRel(N,SDLoc(N), Ty, DAG,ABI.IsN64());
2165
2166// %hi/%lo relocation
2167returnSubtarget.hasSym32() ?getAddrNonPIC(N,SDLoc(N), Ty, DAG)
2168// %highest/%higher/%hi/%lo relocation
2169 :getAddrNonPICSym64(N,SDLoc(N), Ty, DAG);
2170 }
2171
2172// Every other architecture would use shouldAssumeDSOLocal in here, but
2173// mips is special.
2174// * In PIC code mips requires got loads even for local statics!
2175// * To save on got entries, for local statics the got entry contains the
2176// page and an additional add instruction takes care of the low bits.
2177// * It is legal to access a hidden symbol with a non hidden undefined,
2178// so one cannot guarantee that all access to a hidden symbol will know
2179// it is hidden.
2180// * Mips linkers don't support creating a page and a full got entry for
2181// the same symbol.
2182// * Given all that, we have to use a full got entry for hidden symbols :-(
2183if (GV->hasLocalLinkage())
2184returngetAddrLocal(N,SDLoc(N), Ty, DAG,ABI.IsN32() ||ABI.IsN64());
2185
2186if (Subtarget.useXGOT())
2187returngetAddrGlobalLargeGOT(
2188N,SDLoc(N), Ty, DAG,MipsII::MO_GOT_HI16,MipsII::MO_GOT_LO16,
2189 DAG.getEntryNode(),
2190MachinePointerInfo::getGOT(DAG.getMachineFunction()));
2191
2192returngetAddrGlobal(
2193N,SDLoc(N), Ty, DAG,
2194 (ABI.IsN32() ||ABI.IsN64()) ?MipsII::MO_GOT_DISP :MipsII::MO_GOT,
2195 DAG.getEntryNode(),MachinePointerInfo::getGOT(DAG.getMachineFunction()));
2196}
2197
2198SDValue MipsTargetLowering::lowerBlockAddress(SDValueOp,
2199SelectionDAG &DAG) const{
2200BlockAddressSDNode *N = cast<BlockAddressSDNode>(Op);
2201EVT Ty =Op.getValueType();
2202
2203if (!isPositionIndependent())
2204returnSubtarget.hasSym32() ?getAddrNonPIC(N,SDLoc(N), Ty, DAG)
2205 :getAddrNonPICSym64(N,SDLoc(N), Ty, DAG);
2206
2207returngetAddrLocal(N,SDLoc(N), Ty, DAG,ABI.IsN32() ||ABI.IsN64());
2208}
2209
2210SDValue MipsTargetLowering::
2211lowerGlobalTLSAddress(SDValueOp,SelectionDAG &DAG) const
2212{
2213// If the relocation model is PIC, use the General Dynamic TLS Model or
2214// Local Dynamic TLS model, otherwise use the Initial Exec or
2215// Local Exec TLS Model.
2216
2217GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
2218if (DAG.getTarget().useEmulatedTLS())
2219returnLowerToTLSEmulatedModel(GA, DAG);
2220
2221SDLocDL(GA);
2222constGlobalValue *GV = GA->getGlobal();
2223EVT PtrVT =getPointerTy(DAG.getDataLayout());
2224
2225TLSModel::Model model =getTargetMachine().getTLSModel(GV);
2226
2227if (model ==TLSModel::GeneralDynamic || model ==TLSModel::LocalDynamic) {
2228// General Dynamic and Local Dynamic TLS Model.
2229unsignedFlag = (model ==TLSModel::LocalDynamic) ?MipsII::MO_TLSLDM
2230 :MipsII::MO_TLSGD;
2231
2232SDValue TGA = DAG.getTargetGlobalAddress(GV,DL, PtrVT, 0, Flag);
2233SDValueArgument = DAG.getNode(MipsISD::Wrapper,DL, PtrVT,
2234getGlobalReg(DAG, PtrVT), TGA);
2235unsigned PtrSize = PtrVT.getSizeInBits();
2236IntegerType *PtrTy =Type::getIntNTy(*DAG.getContext(), PtrSize);
2237
2238SDValue TlsGetAddr = DAG.getExternalSymbol("__tls_get_addr", PtrVT);
2239
2240ArgListTyArgs;
2241 ArgListEntryEntry;
2242Entry.Node =Argument;
2243Entry.Ty = PtrTy;
2244Args.push_back(Entry);
2245
2246TargetLowering::CallLoweringInfo CLI(DAG);
2247 CLI.setDebugLoc(DL)
2248 .setChain(DAG.getEntryNode())
2249 .setLibCallee(CallingConv::C, PtrTy, TlsGetAddr, std::move(Args));
2250 std::pair<SDValue, SDValue> CallResult =LowerCallTo(CLI);
2251
2252SDValueRet = CallResult.first;
2253
2254if (model !=TLSModel::LocalDynamic)
2255returnRet;
2256
2257SDValue TGAHi = DAG.getTargetGlobalAddress(GV,DL, PtrVT, 0,
2258MipsII::MO_DTPREL_HI);
2259SDValueHi = DAG.getNode(MipsISD::TlsHi,DL, PtrVT, TGAHi);
2260SDValue TGALo = DAG.getTargetGlobalAddress(GV,DL, PtrVT, 0,
2261MipsII::MO_DTPREL_LO);
2262SDValueLo = DAG.getNode(MipsISD::Lo,DL, PtrVT, TGALo);
2263SDValueAdd = DAG.getNode(ISD::ADD,DL, PtrVT,Hi, Ret);
2264return DAG.getNode(ISD::ADD,DL, PtrVT,Add,Lo);
2265 }
2266
2267SDValueOffset;
2268if (model ==TLSModel::InitialExec) {
2269// Initial Exec TLS Model
2270SDValue TGA = DAG.getTargetGlobalAddress(GV,DL, PtrVT, 0,
2271MipsII::MO_GOTTPREL);
2272 TGA = DAG.getNode(MipsISD::Wrapper,DL, PtrVT,getGlobalReg(DAG, PtrVT),
2273 TGA);
2274Offset =
2275 DAG.getLoad(PtrVT,DL, DAG.getEntryNode(), TGA,MachinePointerInfo());
2276 }else {
2277// Local Exec TLS Model
2278assert(model ==TLSModel::LocalExec);
2279SDValue TGAHi = DAG.getTargetGlobalAddress(GV,DL, PtrVT, 0,
2280MipsII::MO_TPREL_HI);
2281SDValue TGALo = DAG.getTargetGlobalAddress(GV,DL, PtrVT, 0,
2282MipsII::MO_TPREL_LO);
2283SDValueHi = DAG.getNode(MipsISD::TlsHi,DL, PtrVT, TGAHi);
2284SDValueLo = DAG.getNode(MipsISD::Lo,DL, PtrVT, TGALo);
2285Offset = DAG.getNode(ISD::ADD,DL, PtrVT,Hi,Lo);
2286 }
2287
2288SDValueThreadPointer = DAG.getNode(MipsISD::ThreadPointer,DL, PtrVT);
2289return DAG.getNode(ISD::ADD,DL, PtrVT, ThreadPointer,Offset);
2290}
2291
2292SDValue MipsTargetLowering::
2293lowerJumpTable(SDValueOp,SelectionDAG &DAG) const
2294{
2295JumpTableSDNode *N = cast<JumpTableSDNode>(Op);
2296EVT Ty =Op.getValueType();
2297
2298if (!isPositionIndependent())
2299returnSubtarget.hasSym32() ?getAddrNonPIC(N,SDLoc(N), Ty, DAG)
2300 :getAddrNonPICSym64(N,SDLoc(N), Ty, DAG);
2301
2302returngetAddrLocal(N,SDLoc(N), Ty, DAG,ABI.IsN32() ||ABI.IsN64());
2303}
2304
2305SDValue MipsTargetLowering::
2306lowerConstantPool(SDValueOp,SelectionDAG &DAG) const
2307{
2308ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
2309EVT Ty =Op.getValueType();
2310
2311if (!isPositionIndependent()) {
2312constMipsTargetObjectFile *TLOF =
2313static_cast<constMipsTargetObjectFile *>(
2314getTargetMachine().getObjFileLowering());
2315
2316if (TLOF->IsConstantInSmallSection(DAG.getDataLayout(),N->getConstVal(),
2317getTargetMachine()))
2318// %gp_rel relocation
2319returngetAddrGPRel(N,SDLoc(N), Ty, DAG,ABI.IsN64());
2320
2321returnSubtarget.hasSym32() ?getAddrNonPIC(N,SDLoc(N), Ty, DAG)
2322 :getAddrNonPICSym64(N,SDLoc(N), Ty, DAG);
2323 }
2324
2325returngetAddrLocal(N,SDLoc(N), Ty, DAG,ABI.IsN32() ||ABI.IsN64());
2326}
2327
2328SDValue MipsTargetLowering::lowerVASTART(SDValueOp,SelectionDAG &DAG) const{
2329MachineFunction &MF = DAG.getMachineFunction();
2330MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
2331
2332SDLocDL(Op);
2333SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
2334getPointerTy(MF.getDataLayout()));
2335
2336// vastart just stores the address of the VarArgsFrameIndex slot into the
2337// memory location argument.
2338constValue *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
2339return DAG.getStore(Op.getOperand(0),DL, FI,Op.getOperand(1),
2340MachinePointerInfo(SV));
2341}
2342
2343SDValue MipsTargetLowering::lowerVAARG(SDValueOp,SelectionDAG &DAG) const{
2344SDNode *Node =Op.getNode();
2345EVT VT =Node->getValueType(0);
2346SDValue Chain =Node->getOperand(0);
2347SDValue VAListPtr =Node->getOperand(1);
2348constAlignAlign =
2349llvm::MaybeAlign(Node->getConstantOperandVal(3)).valueOrOne();
2350constValue *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
2351SDLocDL(Node);
2352unsigned ArgSlotSizeInBytes = (ABI.IsN32() ||ABI.IsN64()) ? 8 : 4;
2353
2354SDValue VAListLoad = DAG.getLoad(getPointerTy(DAG.getDataLayout()),DL, Chain,
2355 VAListPtr,MachinePointerInfo(SV));
2356SDValue VAList = VAListLoad;
2357
2358// Re-align the pointer if necessary.
2359// It should only ever be necessary for 64-bit types on O32 since the minimum
2360// argument alignment is the same as the maximum type alignment for N32/N64.
2361//
2362// FIXME: We currently align too often. The code generator doesn't notice
2363// when the pointer is still aligned from the last va_arg (or pair of
2364// va_args for the i64 on O32 case).
2365if (Align >getMinStackArgumentAlignment()) {
2366 VAList = DAG.getNode(
2367ISD::ADD,DL, VAList.getValueType(), VAList,
2368 DAG.getConstant(Align.value() - 1,DL, VAList.getValueType()));
2369
2370 VAList = DAG.getNode(ISD::AND,DL, VAList.getValueType(), VAList,
2371 DAG.getSignedConstant(-(int64_t)Align.value(),DL,
2372 VAList.getValueType()));
2373 }
2374
2375// Increment the pointer, VAList, to the next vaarg.
2376auto &TD = DAG.getDataLayout();
2377unsigned ArgSizeInBytes =
2378 TD.getTypeAllocSize(VT.getTypeForEVT(*DAG.getContext()));
2379SDValue Tmp3 =
2380 DAG.getNode(ISD::ADD,DL, VAList.getValueType(), VAList,
2381 DAG.getConstant(alignTo(ArgSizeInBytes, ArgSlotSizeInBytes),
2382DL, VAList.getValueType()));
2383// Store the incremented VAList to the legalized pointer
2384 Chain = DAG.getStore(VAListLoad.getValue(1),DL, Tmp3, VAListPtr,
2385MachinePointerInfo(SV));
2386
2387// In big-endian mode we must adjust the pointer when the load size is smaller
2388// than the argument slot size. We must also reduce the known alignment to
2389// match. For example in the N64 ABI, we must add 4 bytes to the offset to get
2390// the correct half of the slot, and reduce the alignment from 8 (slot
2391// alignment) down to 4 (type alignment).
2392if (!Subtarget.isLittle() && ArgSizeInBytes < ArgSlotSizeInBytes) {
2393unsigned Adjustment = ArgSlotSizeInBytes - ArgSizeInBytes;
2394 VAList = DAG.getNode(ISD::ADD,DL, VAListPtr.getValueType(), VAList,
2395 DAG.getIntPtrConstant(Adjustment,DL));
2396 }
2397// Load the actual argument out of the pointer VAList
2398return DAG.getLoad(VT,DL, Chain, VAList,MachinePointerInfo());
2399}
2400
2401staticSDValuelowerFCOPYSIGN32(SDValueOp,SelectionDAG &DAG,
2402bool HasExtractInsert) {
2403EVT TyX =Op.getOperand(0).getValueType();
2404EVT TyY =Op.getOperand(1).getValueType();
2405SDLocDL(Op);
2406SDValue Const1 = DAG.getConstant(1,DL, MVT::i32);
2407SDValue Const31 = DAG.getConstant(31,DL, MVT::i32);
2408SDValue Res;
2409
2410// If operand is of type f64, extract the upper 32-bit. Otherwise, bitcast it
2411// to i32.
2412SDValueX = (TyX == MVT::f32) ?
2413 DAG.getNode(ISD::BITCAST,DL, MVT::i32,Op.getOperand(0)) :
2414 DAG.getNode(MipsISD::ExtractElementF64,DL, MVT::i32,Op.getOperand(0),
2415 Const1);
2416SDValueY = (TyY == MVT::f32) ?
2417 DAG.getNode(ISD::BITCAST,DL, MVT::i32,Op.getOperand(1)) :
2418 DAG.getNode(MipsISD::ExtractElementF64,DL, MVT::i32,Op.getOperand(1),
2419 Const1);
2420
2421if (HasExtractInsert) {
2422// ext E, Y, 31, 1 ; extract bit31 of Y
2423// ins X, E, 31, 1 ; insert extracted bit at bit31 of X
2424SDValue E = DAG.getNode(MipsISD::Ext,DL, MVT::i32,Y, Const31, Const1);
2425 Res = DAG.getNode(MipsISD::Ins,DL, MVT::i32, E, Const31, Const1,X);
2426 }else {
2427// sll SllX, X, 1
2428// srl SrlX, SllX, 1
2429// srl SrlY, Y, 31
2430// sll SllY, SrlX, 31
2431// or Or, SrlX, SllY
2432SDValue SllX = DAG.getNode(ISD::SHL,DL, MVT::i32,X, Const1);
2433SDValue SrlX = DAG.getNode(ISD::SRL,DL, MVT::i32, SllX, Const1);
2434SDValue SrlY = DAG.getNode(ISD::SRL,DL, MVT::i32,Y, Const31);
2435SDValue SllY = DAG.getNode(ISD::SHL,DL, MVT::i32, SrlY, Const31);
2436 Res = DAG.getNode(ISD::OR,DL, MVT::i32, SrlX, SllY);
2437 }
2438
2439if (TyX == MVT::f32)
2440return DAG.getNode(ISD::BITCAST,DL,Op.getOperand(0).getValueType(), Res);
2441
2442SDValue LowX = DAG.getNode(MipsISD::ExtractElementF64,DL, MVT::i32,
2443Op.getOperand(0),
2444 DAG.getConstant(0,DL, MVT::i32));
2445return DAG.getNode(MipsISD::BuildPairF64,DL, MVT::f64, LowX, Res);
2446}
2447
2448staticSDValuelowerFCOPYSIGN64(SDValueOp,SelectionDAG &DAG,
2449bool HasExtractInsert) {
2450unsigned WidthX =Op.getOperand(0).getValueSizeInBits();
2451unsigned WidthY =Op.getOperand(1).getValueSizeInBits();
2452EVT TyX =MVT::getIntegerVT(WidthX), TyY =MVT::getIntegerVT(WidthY);
2453SDLocDL(Op);
2454SDValue Const1 = DAG.getConstant(1,DL, MVT::i32);
2455
2456// Bitcast to integer nodes.
2457SDValueX = DAG.getNode(ISD::BITCAST,DL, TyX,Op.getOperand(0));
2458SDValueY = DAG.getNode(ISD::BITCAST,DL, TyY,Op.getOperand(1));
2459
2460if (HasExtractInsert) {
2461// ext E, Y, width(Y) - 1, 1 ; extract bit width(Y)-1 of Y
2462// ins X, E, width(X) - 1, 1 ; insert extracted bit at bit width(X)-1 of X
2463SDValue E = DAG.getNode(MipsISD::Ext,DL, TyY,Y,
2464 DAG.getConstant(WidthY - 1,DL, MVT::i32), Const1);
2465
2466if (WidthX > WidthY)
2467 E = DAG.getNode(ISD::ZERO_EXTEND,DL, TyX, E);
2468elseif (WidthY > WidthX)
2469 E = DAG.getNode(ISD::TRUNCATE,DL, TyX, E);
2470
2471SDValueI = DAG.getNode(MipsISD::Ins,DL, TyX, E,
2472 DAG.getConstant(WidthX - 1,DL, MVT::i32), Const1,
2473X);
2474return DAG.getNode(ISD::BITCAST,DL,Op.getOperand(0).getValueType(),I);
2475 }
2476
2477// (d)sll SllX, X, 1
2478// (d)srl SrlX, SllX, 1
2479// (d)srl SrlY, Y, width(Y)-1
2480// (d)sll SllY, SrlX, width(Y)-1
2481// or Or, SrlX, SllY
2482SDValue SllX = DAG.getNode(ISD::SHL,DL, TyX,X, Const1);
2483SDValue SrlX = DAG.getNode(ISD::SRL,DL, TyX, SllX, Const1);
2484SDValue SrlY = DAG.getNode(ISD::SRL,DL, TyY,Y,
2485 DAG.getConstant(WidthY - 1,DL, MVT::i32));
2486
2487if (WidthX > WidthY)
2488 SrlY = DAG.getNode(ISD::ZERO_EXTEND,DL, TyX, SrlY);
2489elseif (WidthY > WidthX)
2490 SrlY = DAG.getNode(ISD::TRUNCATE,DL, TyX, SrlY);
2491
2492SDValue SllY = DAG.getNode(ISD::SHL,DL, TyX, SrlY,
2493 DAG.getConstant(WidthX - 1,DL, MVT::i32));
2494SDValueOr = DAG.getNode(ISD::OR,DL, TyX, SrlX, SllY);
2495return DAG.getNode(ISD::BITCAST,DL,Op.getOperand(0).getValueType(),Or);
2496}
2497
2498SDValue
2499MipsTargetLowering::lowerFCOPYSIGN(SDValueOp,SelectionDAG &DAG) const{
2500if (Subtarget.isGP64bit())
2501returnlowerFCOPYSIGN64(Op, DAG,Subtarget.hasExtractInsert());
2502
2503returnlowerFCOPYSIGN32(Op, DAG,Subtarget.hasExtractInsert());
2504}
2505
2506SDValue MipsTargetLowering::lowerFABS32(SDValueOp,SelectionDAG &DAG,
2507bool HasExtractInsert) const{
2508SDLocDL(Op);
2509SDValue Res, Const1 = DAG.getConstant(1,DL, MVT::i32);
2510
2511if (DAG.getTarget().Options.NoNaNsFPMath ||Subtarget.inAbs2008Mode())
2512return DAG.getNode(MipsISD::FAbs,DL,Op.getValueType(),Op.getOperand(0));
2513
2514// If operand is of type f64, extract the upper 32-bit. Otherwise, bitcast it
2515// to i32.
2516SDValueX = (Op.getValueType() == MVT::f32)
2517 ? DAG.getNode(ISD::BITCAST,DL, MVT::i32,Op.getOperand(0))
2518 : DAG.getNode(MipsISD::ExtractElementF64,DL, MVT::i32,
2519Op.getOperand(0), Const1);
2520
2521// Clear MSB.
2522if (HasExtractInsert)
2523 Res = DAG.getNode(MipsISD::Ins,DL, MVT::i32,
2524 DAG.getRegister(Mips::ZERO, MVT::i32),
2525 DAG.getConstant(31,DL, MVT::i32), Const1,X);
2526else {
2527// TODO: Provide DAG patterns which transform (and x, cst)
2528// back to a (shl (srl x (clz cst)) (clz cst)) sequence.
2529SDValue SllX = DAG.getNode(ISD::SHL,DL, MVT::i32,X, Const1);
2530 Res = DAG.getNode(ISD::SRL,DL, MVT::i32, SllX, Const1);
2531 }
2532
2533if (Op.getValueType() == MVT::f32)
2534return DAG.getNode(ISD::BITCAST,DL, MVT::f32, Res);
2535
2536// FIXME: For mips32r2, the sequence of (BuildPairF64 (ins (ExtractElementF64
2537// Op 1), $zero, 31 1) (ExtractElementF64 Op 0)) and the Op has one use, we
2538// should be able to drop the usage of mfc1/mtc1 and rewrite the register in
2539// place.
2540SDValue LowX =
2541 DAG.getNode(MipsISD::ExtractElementF64,DL, MVT::i32,Op.getOperand(0),
2542 DAG.getConstant(0,DL, MVT::i32));
2543return DAG.getNode(MipsISD::BuildPairF64,DL, MVT::f64, LowX, Res);
2544}
2545
2546SDValue MipsTargetLowering::lowerFABS64(SDValueOp,SelectionDAG &DAG,
2547bool HasExtractInsert) const{
2548SDLocDL(Op);
2549SDValue Res, Const1 = DAG.getConstant(1,DL, MVT::i32);
2550
2551if (DAG.getTarget().Options.NoNaNsFPMath ||Subtarget.inAbs2008Mode())
2552return DAG.getNode(MipsISD::FAbs,DL,Op.getValueType(),Op.getOperand(0));
2553
2554// Bitcast to integer node.
2555SDValueX = DAG.getNode(ISD::BITCAST,DL, MVT::i64,Op.getOperand(0));
2556
2557// Clear MSB.
2558if (HasExtractInsert)
2559 Res = DAG.getNode(MipsISD::Ins,DL, MVT::i64,
2560 DAG.getRegister(Mips::ZERO_64, MVT::i64),
2561 DAG.getConstant(63,DL, MVT::i32), Const1,X);
2562else {
2563SDValue SllX = DAG.getNode(ISD::SHL,DL, MVT::i64,X, Const1);
2564 Res = DAG.getNode(ISD::SRL,DL, MVT::i64, SllX, Const1);
2565 }
2566
2567return DAG.getNode(ISD::BITCAST,DL, MVT::f64, Res);
2568}
2569
2570SDValue MipsTargetLowering::lowerFABS(SDValueOp,SelectionDAG &DAG) const{
2571if ((ABI.IsN32() ||ABI.IsN64()) && (Op.getValueType() == MVT::f64))
2572return lowerFABS64(Op, DAG,Subtarget.hasExtractInsert());
2573
2574return lowerFABS32(Op, DAG,Subtarget.hasExtractInsert());
2575}
2576
2577SDValue MipsTargetLowering::lowerFCANONICALIZE(SDValueOp,
2578SelectionDAG &DAG) const{
2579SDLocDL(Op);
2580EVT VT =Op.getValueType();
2581SDValue Operand =Op.getOperand(0);
2582SDNodeFlagsFlags =Op->getFlags();
2583
2584if (Flags.hasNoNaNs() || DAG.isKnownNeverNaN(Operand))
2585return Operand;
2586
2587SDValueQuiet = DAG.getNode(ISD::FADD,DL, VT, Operand, Operand);
2588return DAG.getSelectCC(DL, Operand, Operand,Quiet, Operand,ISD::SETUO);
2589}
2590
2591SDValue MipsTargetLowering::
2592lowerFRAMEADDR(SDValueOp,SelectionDAG &DAG) const{
2593// check the depth
2594if (Op.getConstantOperandVal(0) != 0) {
2595 DAG.getContext()->emitError(
2596"return address can be determined only for current frame");
2597returnSDValue();
2598 }
2599
2600MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
2601 MFI.setFrameAddressIsTaken(true);
2602EVT VT =Op.getValueType();
2603SDLocDL(Op);
2604SDValue FrameAddr = DAG.getCopyFromReg(
2605 DAG.getEntryNode(),DL,ABI.IsN64() ? Mips::FP_64 : Mips::FP, VT);
2606return FrameAddr;
2607}
2608
2609SDValue MipsTargetLowering::lowerRETURNADDR(SDValueOp,
2610SelectionDAG &DAG) const{
2611if (verifyReturnAddressArgumentIsConstant(Op, DAG))
2612returnSDValue();
2613
2614// check the depth
2615if (Op.getConstantOperandVal(0) != 0) {
2616 DAG.getContext()->emitError(
2617"return address can be determined only for current frame");
2618returnSDValue();
2619 }
2620
2621MachineFunction &MF = DAG.getMachineFunction();
2622MachineFrameInfo &MFI = MF.getFrameInfo();
2623MVT VT =Op.getSimpleValueType();
2624unsignedRA =ABI.IsN64() ? Mips::RA_64 : Mips::RA;
2625 MFI.setReturnAddressIsTaken(true);
2626
2627// Return RA, which contains the return address. Mark it an implicit live-in.
2628RegisterReg = MF.addLiveIn(RA,getRegClassFor(VT));
2629return DAG.getCopyFromReg(DAG.getEntryNode(),SDLoc(Op), Reg, VT);
2630}
2631
2632// An EH_RETURN is the result of lowering llvm.eh.return which in turn is
2633// generated from __builtin_eh_return (offset, handler)
2634// The effect of this is to adjust the stack pointer by "offset"
2635// and then branch to "handler".
2636SDValue MipsTargetLowering::lowerEH_RETURN(SDValueOp,SelectionDAG &DAG)
2637 const{
2638MachineFunction &MF = DAG.getMachineFunction();
2639MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
2640
2641 MipsFI->setCallsEhReturn();
2642SDValue Chain =Op.getOperand(0);
2643SDValueOffset =Op.getOperand(1);
2644SDValue Handler =Op.getOperand(2);
2645SDLocDL(Op);
2646EVT Ty =ABI.IsN64() ? MVT::i64 : MVT::i32;
2647
2648// Store stack offset in V1, store jump target in V0. Glue CopyToReg and
2649// EH_RETURN nodes, so that instructions are emitted back-to-back.
2650unsigned OffsetReg =ABI.IsN64() ? Mips::V1_64 : Mips::V1;
2651unsigned AddrReg =ABI.IsN64() ? Mips::V0_64 : Mips::V0;
2652 Chain = DAG.getCopyToReg(Chain,DL, OffsetReg,Offset,SDValue());
2653 Chain = DAG.getCopyToReg(Chain,DL, AddrReg, Handler, Chain.getValue(1));
2654return DAG.getNode(MipsISD::EH_RETURN,DL, MVT::Other, Chain,
2655 DAG.getRegister(OffsetReg, Ty),
2656 DAG.getRegister(AddrReg,getPointerTy(MF.getDataLayout())),
2657 Chain.getValue(1));
2658}
2659
2660SDValue MipsTargetLowering::lowerATOMIC_FENCE(SDValueOp,
2661SelectionDAG &DAG) const{
2662// FIXME: Need pseudo-fence for 'singlethread' fences
2663// FIXME: Set SType for weaker fences where supported/appropriate.
2664unsigned SType = 0;
2665SDLocDL(Op);
2666return DAG.getNode(MipsISD::Sync,DL, MVT::Other,Op.getOperand(0),
2667 DAG.getConstant(SType,DL, MVT::i32));
2668}
2669
2670SDValue MipsTargetLowering::lowerShiftLeftParts(SDValueOp,
2671SelectionDAG &DAG) const{
2672SDLocDL(Op);
2673MVT VT =Subtarget.isGP64bit() ? MVT::i64 : MVT::i32;
2674
2675SDValueLo =Op.getOperand(0),Hi =Op.getOperand(1);
2676SDValue Shamt =Op.getOperand(2);
2677// if shamt < (VT.bits):
2678// lo = (shl lo, shamt)
2679// hi = (or (shl hi, shamt) (srl (srl lo, 1), (xor shamt, (VT.bits-1))))
2680// else:
2681// lo = 0
2682// hi = (shl lo, shamt[4:0])
2683SDValueNot =
2684 DAG.getNode(ISD::XOR,DL, MVT::i32, Shamt,
2685 DAG.getConstant(VT.getSizeInBits() - 1,DL, MVT::i32));
2686SDValue ShiftRight1Lo = DAG.getNode(ISD::SRL,DL, VT,Lo,
2687 DAG.getConstant(1,DL, VT));
2688SDValue ShiftRightLo = DAG.getNode(ISD::SRL,DL, VT, ShiftRight1Lo, Not);
2689SDValue ShiftLeftHi = DAG.getNode(ISD::SHL,DL, VT,Hi, Shamt);
2690SDValueOr = DAG.getNode(ISD::OR,DL, VT, ShiftLeftHi, ShiftRightLo);
2691SDValue ShiftLeftLo = DAG.getNode(ISD::SHL,DL, VT,Lo, Shamt);
2692SDValueCond = DAG.getNode(ISD::AND,DL, MVT::i32, Shamt,
2693 DAG.getConstant(VT.getSizeInBits(),DL, MVT::i32));
2694Lo = DAG.getNode(ISD::SELECT,DL, VT,Cond,
2695 DAG.getConstant(0,DL, VT), ShiftLeftLo);
2696Hi = DAG.getNode(ISD::SELECT,DL, VT,Cond, ShiftLeftLo,Or);
2697
2698SDValue Ops[2] = {Lo,Hi};
2699return DAG.getMergeValues(Ops,DL);
2700}
2701
2702SDValue MipsTargetLowering::lowerShiftRightParts(SDValueOp,SelectionDAG &DAG,
2703bool IsSRA) const{
2704SDLocDL(Op);
2705SDValueLo =Op.getOperand(0),Hi =Op.getOperand(1);
2706SDValue Shamt =Op.getOperand(2);
2707MVT VT =Subtarget.isGP64bit() ? MVT::i64 : MVT::i32;
2708
2709// if shamt < (VT.bits):
2710// lo = (or (shl (shl hi, 1), (xor shamt, (VT.bits-1))) (srl lo, shamt))
2711// if isSRA:
2712// hi = (sra hi, shamt)
2713// else:
2714// hi = (srl hi, shamt)
2715// else:
2716// if isSRA:
2717// lo = (sra hi, shamt[4:0])
2718// hi = (sra hi, 31)
2719// else:
2720// lo = (srl hi, shamt[4:0])
2721// hi = 0
2722SDValueNot =
2723 DAG.getNode(ISD::XOR,DL, MVT::i32, Shamt,
2724 DAG.getConstant(VT.getSizeInBits() - 1,DL, MVT::i32));
2725SDValue ShiftLeft1Hi = DAG.getNode(ISD::SHL,DL, VT,Hi,
2726 DAG.getConstant(1,DL, VT));
2727SDValue ShiftLeftHi = DAG.getNode(ISD::SHL,DL, VT, ShiftLeft1Hi, Not);
2728SDValue ShiftRightLo = DAG.getNode(ISD::SRL,DL, VT,Lo, Shamt);
2729SDValueOr = DAG.getNode(ISD::OR,DL, VT, ShiftLeftHi, ShiftRightLo);
2730SDValue ShiftRightHi = DAG.getNode(IsSRA ?ISD::SRA :ISD::SRL,
2731DL, VT,Hi, Shamt);
2732SDValueCond = DAG.getNode(ISD::AND,DL, MVT::i32, Shamt,
2733 DAG.getConstant(VT.getSizeInBits(),DL, MVT::i32));
2734SDValueExt = DAG.getNode(ISD::SRA,DL, VT,Hi,
2735 DAG.getConstant(VT.getSizeInBits() - 1,DL, VT));
2736
2737if (!(Subtarget.hasMips4() ||Subtarget.hasMips32())) {
2738SDVTList VTList = DAG.getVTList(VT, VT);
2739return DAG.getNode(Subtarget.isGP64bit() ?MipsISD::DOUBLE_SELECT_I64
2740 :MipsISD::DOUBLE_SELECT_I,
2741DL, VTList,Cond, ShiftRightHi,
2742 IsSRA ? Ext : DAG.getConstant(0,DL, VT),Or,
2743 ShiftRightHi);
2744 }
2745
2746Lo = DAG.getNode(ISD::SELECT,DL, VT,Cond, ShiftRightHi,Or);
2747Hi = DAG.getNode(ISD::SELECT,DL, VT,Cond,
2748 IsSRA ? Ext : DAG.getConstant(0,DL, VT), ShiftRightHi);
2749
2750SDValue Ops[2] = {Lo,Hi};
2751return DAG.getMergeValues(Ops,DL);
2752}
2753
2754staticSDValuecreateLoadLR(unsigned Opc,SelectionDAG &DAG,LoadSDNode *LD,
2755SDValue Chain,SDValue Src,unsignedOffset) {
2756SDValuePtr = LD->getBasePtr();
2757EVT VT = LD->getValueType(0), MemVT = LD->getMemoryVT();
2758EVT BasePtrVT =Ptr.getValueType();
2759SDLocDL(LD);
2760SDVTList VTList = DAG.getVTList(VT, MVT::Other);
2761
2762if (Offset)
2763Ptr = DAG.getNode(ISD::ADD,DL, BasePtrVT,Ptr,
2764 DAG.getConstant(Offset,DL, BasePtrVT));
2765
2766SDValue Ops[] = { Chain,Ptr, Src };
2767return DAG.getMemIntrinsicNode(Opc,DL, VTList, Ops, MemVT,
2768 LD->getMemOperand());
2769}
2770
2771// Expand an unaligned 32 or 64-bit integer load node.
2772SDValueMipsTargetLowering::lowerLOAD(SDValueOp,SelectionDAG &DAG) const{
2773LoadSDNode *LD = cast<LoadSDNode>(Op);
2774EVT MemVT = LD->getMemoryVT();
2775
2776if (Subtarget.systemSupportsUnalignedAccess())
2777returnOp;
2778
2779// Return if load is aligned or if MemVT is neither i32 nor i64.
2780if ((LD->getAlign().value() >= (MemVT.getSizeInBits() / 8)) ||
2781 ((MemVT != MVT::i32) && (MemVT != MVT::i64)))
2782returnSDValue();
2783
2784bool IsLittle =Subtarget.isLittle();
2785EVT VT =Op.getValueType();
2786ISD::LoadExtType ExtType = LD->getExtensionType();
2787SDValue Chain = LD->getChain(), Undef = DAG.getUNDEF(VT);
2788
2789assert((VT == MVT::i32) || (VT == MVT::i64));
2790
2791// Expand
2792// (set dst, (i64 (load baseptr)))
2793// to
2794// (set tmp, (ldl (add baseptr, 7), undef))
2795// (set dst, (ldr baseptr, tmp))
2796if ((VT == MVT::i64) && (ExtType ==ISD::NON_EXTLOAD)) {
2797SDValue LDL =createLoadLR(MipsISD::LDL, DAG, LD, Chain, Undef,
2798 IsLittle ? 7 : 0);
2799returncreateLoadLR(MipsISD::LDR, DAG, LD, LDL.getValue(1), LDL,
2800 IsLittle ? 0 : 7);
2801 }
2802
2803SDValue LWL =createLoadLR(MipsISD::LWL, DAG, LD, Chain, Undef,
2804 IsLittle ? 3 : 0);
2805SDValue LWR =createLoadLR(MipsISD::LWR, DAG, LD, LWL.getValue(1), LWL,
2806 IsLittle ? 0 : 3);
2807
2808// Expand
2809// (set dst, (i32 (load baseptr))) or
2810// (set dst, (i64 (sextload baseptr))) or
2811// (set dst, (i64 (extload baseptr)))
2812// to
2813// (set tmp, (lwl (add baseptr, 3), undef))
2814// (set dst, (lwr baseptr, tmp))
2815if ((VT == MVT::i32) || (ExtType ==ISD::SEXTLOAD) ||
2816 (ExtType ==ISD::EXTLOAD))
2817return LWR;
2818
2819assert((VT == MVT::i64) && (ExtType ==ISD::ZEXTLOAD));
2820
2821// Expand
2822// (set dst, (i64 (zextload baseptr)))
2823// to
2824// (set tmp0, (lwl (add baseptr, 3), undef))
2825// (set tmp1, (lwr baseptr, tmp0))
2826// (set tmp2, (shl tmp1, 32))
2827// (set dst, (srl tmp2, 32))
2828SDLocDL(LD);
2829SDValue Const32 = DAG.getConstant(32,DL, MVT::i32);
2830SDValue SLL = DAG.getNode(ISD::SHL,DL, MVT::i64, LWR, Const32);
2831SDValue SRL = DAG.getNode(ISD::SRL,DL, MVT::i64, SLL, Const32);
2832SDValue Ops[] = { SRL, LWR.getValue(1) };
2833return DAG.getMergeValues(Ops,DL);
2834}
2835
2836staticSDValuecreateStoreLR(unsigned Opc,SelectionDAG &DAG,StoreSDNode *SD,
2837SDValue Chain,unsignedOffset) {
2838SDValuePtr = SD->getBasePtr(),Value = SD->getValue();
2839EVT MemVT = SD->getMemoryVT(), BasePtrVT =Ptr.getValueType();
2840SDLocDL(SD);
2841SDVTList VTList = DAG.getVTList(MVT::Other);
2842
2843if (Offset)
2844Ptr = DAG.getNode(ISD::ADD,DL, BasePtrVT,Ptr,
2845 DAG.getConstant(Offset,DL, BasePtrVT));
2846
2847SDValue Ops[] = { Chain,Value,Ptr };
2848return DAG.getMemIntrinsicNode(Opc,DL, VTList, Ops, MemVT,
2849 SD->getMemOperand());
2850}
2851
2852// Expand an unaligned 32 or 64-bit integer store node.
2853staticSDValuelowerUnalignedIntStore(StoreSDNode *SD,SelectionDAG &DAG,
2854bool IsLittle) {
2855SDValueValue = SD->getValue(), Chain = SD->getChain();
2856EVT VT =Value.getValueType();
2857
2858// Expand
2859// (store val, baseptr) or
2860// (truncstore val, baseptr)
2861// to
2862// (swl val, (add baseptr, 3))
2863// (swr val, baseptr)
2864if ((VT == MVT::i32) || SD->isTruncatingStore()) {
2865SDValue SWL =createStoreLR(MipsISD::SWL, DAG, SD, Chain,
2866 IsLittle ? 3 : 0);
2867returncreateStoreLR(MipsISD::SWR, DAG, SD, SWL, IsLittle ? 0 : 3);
2868 }
2869
2870assert(VT == MVT::i64);
2871
2872// Expand
2873// (store val, baseptr)
2874// to
2875// (sdl val, (add baseptr, 7))
2876// (sdr val, baseptr)
2877SDValue SDL =createStoreLR(MipsISD::SDL, DAG, SD, Chain, IsLittle ? 7 : 0);
2878returncreateStoreLR(MipsISD::SDR, DAG, SD, SDL, IsLittle ? 0 : 7);
2879}
2880
2881// Lower (store (fp_to_sint $fp) $ptr) to (store (TruncIntFP $fp), $ptr).
2882staticSDValuelowerFP_TO_SINT_STORE(StoreSDNode *SD,SelectionDAG &DAG,
2883bool SingleFloat) {
2884SDValue Val = SD->getValue();
2885
2886if (Val.getOpcode() !=ISD::FP_TO_SINT ||
2887 (Val.getValueSizeInBits() > 32 && SingleFloat))
2888returnSDValue();
2889
2890EVT FPTy =EVT::getFloatingPointVT(Val.getValueSizeInBits());
2891SDValue Tr = DAG.getNode(MipsISD::TruncIntFP,SDLoc(Val), FPTy,
2892 Val.getOperand(0));
2893return DAG.getStore(SD->getChain(),SDLoc(SD), Tr, SD->getBasePtr(),
2894 SD->getPointerInfo(), SD->getAlign(),
2895 SD->getMemOperand()->getFlags());
2896}
2897
2898SDValueMipsTargetLowering::lowerSTORE(SDValueOp,SelectionDAG &DAG) const{
2899StoreSDNode *SD = cast<StoreSDNode>(Op);
2900EVT MemVT = SD->getMemoryVT();
2901
2902// Lower unaligned integer stores.
2903if (!Subtarget.systemSupportsUnalignedAccess() &&
2904 (SD->getAlign().value() < (MemVT.getSizeInBits() / 8)) &&
2905 ((MemVT == MVT::i32) || (MemVT == MVT::i64)))
2906returnlowerUnalignedIntStore(SD, DAG,Subtarget.isLittle());
2907
2908returnlowerFP_TO_SINT_STORE(SD, DAG,Subtarget.isSingleFloat());
2909}
2910
2911SDValue MipsTargetLowering::lowerEH_DWARF_CFA(SDValueOp,
2912SelectionDAG &DAG) const{
2913
2914// Return a fixed StackObject with offset 0 which points to the old stack
2915// pointer.
2916MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
2917EVT ValTy =Op->getValueType(0);
2918int FI = MFI.CreateFixedObject(Op.getValueSizeInBits() / 8, 0,false);
2919return DAG.getFrameIndex(FI, ValTy);
2920}
2921
2922SDValue MipsTargetLowering::lowerFP_TO_SINT(SDValueOp,
2923SelectionDAG &DAG) const{
2924if (Op.getValueSizeInBits() > 32 &&Subtarget.isSingleFloat())
2925returnSDValue();
2926
2927EVT FPTy =EVT::getFloatingPointVT(Op.getValueSizeInBits());
2928SDValue Trunc = DAG.getNode(MipsISD::TruncIntFP,SDLoc(Op), FPTy,
2929Op.getOperand(0));
2930return DAG.getNode(ISD::BITCAST,SDLoc(Op),Op.getValueType(), Trunc);
2931}
2932
2933//===----------------------------------------------------------------------===//
2934// Calling Convention Implementation
2935//===----------------------------------------------------------------------===//
2936
2937//===----------------------------------------------------------------------===//
2938// TODO: Implement a generic logic using tblgen that can support this.
2939// Mips O32 ABI rules:
2940// ---
2941// i32 - Passed in A0, A1, A2, A3 and stack
2942// f32 - Only passed in f32 registers if no int reg has been used yet to hold
2943// an argument. Otherwise, passed in A1, A2, A3 and stack.
2944// f64 - Only passed in two aliased f32 registers if no int reg has been used
2945// yet to hold an argument. Otherwise, use A2, A3 and stack. If A1 is
2946// not used, it must be shadowed. If only A3 is available, shadow it and
2947// go to stack.
2948// vXiX - Received as scalarized i32s, passed in A0 - A3 and the stack.
2949// vXf32 - Passed in either a pair of registers {A0, A1}, {A2, A3} or {A0 - A3}
2950// with the remainder spilled to the stack.
2951// vXf64 - Passed in either {A0, A1, A2, A3} or {A2, A3} and in both cases
2952// spilling the remainder to the stack.
2953//
2954// For vararg functions, all arguments are passed in A0, A1, A2, A3 and stack.
2955//===----------------------------------------------------------------------===//
2956
2957staticboolCC_MipsO32(unsigned ValNo,MVT ValVT,MVT LocVT,
2958CCValAssign::LocInfo LocInfo,ISD::ArgFlagsTy ArgFlags,
2959CCState &State,ArrayRef<MCPhysReg> F64Regs) {
2960constMipsSubtarget &Subtarget =static_cast<constMipsSubtarget &>(
2961 State.getMachineFunction().getSubtarget());
2962
2963staticconstMCPhysRegIntRegs[] = { Mips::A0, Mips::A1, Mips::A2, Mips::A3 };
2964
2965constMipsCCState * MipsState =static_cast<MipsCCState *>(&State);
2966
2967staticconstMCPhysRegF32Regs[] = { Mips::F12, Mips::F14 };
2968
2969staticconstMCPhysReg FloatVectorIntRegs[] = { Mips::A0, Mips::A2 };
2970
2971// Do not process byval args here.
2972if (ArgFlags.isByVal())
2973returntrue;
2974
2975// Promote i8 and i16
2976if (ArgFlags.isInReg() && !Subtarget.isLittle()) {
2977if (LocVT == MVT::i8 || LocVT == MVT::i16 || LocVT == MVT::i32) {
2978 LocVT = MVT::i32;
2979if (ArgFlags.isSExt())
2980 LocInfo =CCValAssign::SExtUpper;
2981elseif (ArgFlags.isZExt())
2982 LocInfo =CCValAssign::ZExtUpper;
2983else
2984 LocInfo =CCValAssign::AExtUpper;
2985 }
2986 }
2987
2988// Promote i8 and i16
2989if (LocVT == MVT::i8 || LocVT == MVT::i16) {
2990 LocVT = MVT::i32;
2991if (ArgFlags.isSExt())
2992 LocInfo =CCValAssign::SExt;
2993elseif (ArgFlags.isZExt())
2994 LocInfo =CCValAssign::ZExt;
2995else
2996 LocInfo =CCValAssign::AExt;
2997 }
2998
2999unsigned Reg;
3000
3001// f32 and f64 are allocated in A0, A1, A2, A3 when either of the following
3002// is true: function is vararg, argument is 3rd or higher, there is previous
3003// argument which is not f32 or f64.
3004bool AllocateFloatsInIntReg = State.isVarArg() || ValNo > 1 ||
3005 State.getFirstUnallocated(F32Regs) != ValNo;
3006Align OrigAlign = ArgFlags.getNonZeroOrigAlign();
3007bool isI64 = (ValVT == MVT::i32 && OrigAlign ==Align(8));
3008bool isVectorFloat = MipsState->WasOriginalArgVectorFloat(ValNo);
3009
3010// The MIPS vector ABI for floats passes them in a pair of registers
3011if (ValVT == MVT::i32 && isVectorFloat) {
3012// This is the start of an vector that was scalarized into an unknown number
3013// of components. It doesn't matter how many there are. Allocate one of the
3014// notional 8 byte aligned registers which map onto the argument stack, and
3015// shadow the register lost to alignment requirements.
3016if (ArgFlags.isSplit()) {
3017 Reg = State.AllocateReg(FloatVectorIntRegs);
3018if (Reg == Mips::A2)
3019 State.AllocateReg(Mips::A1);
3020elseif (Reg == 0)
3021 State.AllocateReg(Mips::A3);
3022 }else {
3023// If we're an intermediate component of the split, we can just attempt to
3024// allocate a register directly.
3025 Reg = State.AllocateReg(IntRegs);
3026 }
3027 }elseif (ValVT == MVT::i32 ||
3028 (ValVT == MVT::f32 && AllocateFloatsInIntReg)) {
3029 Reg = State.AllocateReg(IntRegs);
3030// If this is the first part of an i64 arg,
3031// the allocated register must be either A0 or A2.
3032if (isI64 && (Reg == Mips::A1 || Reg == Mips::A3))
3033 Reg = State.AllocateReg(IntRegs);
3034 LocVT = MVT::i32;
3035 }elseif (ValVT == MVT::f64 && AllocateFloatsInIntReg) {
3036// Allocate int register and shadow next int register. If first
3037// available register is Mips::A1 or Mips::A3, shadow it too.
3038 Reg = State.AllocateReg(IntRegs);
3039if (Reg == Mips::A1 || Reg == Mips::A3)
3040 Reg = State.AllocateReg(IntRegs);
3041
3042if (Reg) {
3043 LocVT = MVT::i32;
3044
3045 State.addLoc(
3046CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
3047MCRegister HiReg = State.AllocateReg(IntRegs);
3048assert(HiReg);
3049 State.addLoc(
3050CCValAssign::getCustomReg(ValNo, ValVT, HiReg, LocVT, LocInfo));
3051returnfalse;
3052 }
3053 }elseif (ValVT.isFloatingPoint() && !AllocateFloatsInIntReg) {
3054// we are guaranteed to find an available float register
3055if (ValVT == MVT::f32) {
3056 Reg = State.AllocateReg(F32Regs);
3057// Shadow int register
3058 State.AllocateReg(IntRegs);
3059 }else {
3060 Reg = State.AllocateReg(F64Regs);
3061// Shadow int registers
3062MCRegister Reg2 = State.AllocateReg(IntRegs);
3063if (Reg2 == Mips::A1 || Reg2 == Mips::A3)
3064 State.AllocateReg(IntRegs);
3065 State.AllocateReg(IntRegs);
3066 }
3067 }else
3068llvm_unreachable("Cannot handle this ValVT.");
3069
3070if (!Reg) {
3071unsignedOffset = State.AllocateStack(ValVT.getStoreSize(), OrigAlign);
3072 State.addLoc(CCValAssign::getMem(ValNo, ValVT,Offset, LocVT, LocInfo));
3073 }else
3074 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
3075
3076returnfalse;
3077}
3078
3079staticboolCC_MipsO32_FP32(unsigned ValNo,MVT ValVT,
3080MVT LocVT,CCValAssign::LocInfo LocInfo,
3081ISD::ArgFlagsTy ArgFlags,CCState &State) {
3082staticconstMCPhysReg F64Regs[] = { Mips::D6, Mips::D7 };
3083
3084returnCC_MipsO32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State, F64Regs);
3085}
3086
3087staticboolCC_MipsO32_FP64(unsigned ValNo,MVT ValVT,
3088MVT LocVT,CCValAssign::LocInfo LocInfo,
3089ISD::ArgFlagsTy ArgFlags,CCState &State) {
3090staticconstMCPhysReg F64Regs[] = { Mips::D12_64, Mips::D14_64 };
3091
3092returnCC_MipsO32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State, F64Regs);
3093}
3094
3095staticboolCC_MipsO32(unsigned ValNo,MVT ValVT,MVT LocVT,
3096CCValAssign::LocInfo LocInfo,ISD::ArgFlagsTy ArgFlags,
3097CCState &State)LLVM_ATTRIBUTE_UNUSED;
3098
3099#include "MipsGenCallingConv.inc"
3100
3101CCAssignFn *MipsTargetLowering::CCAssignFnForCall() const{
3102return CC_Mips_FixedArg;
3103 }
3104
3105CCAssignFn *MipsTargetLowering::CCAssignFnForReturn() const{
3106return RetCC_Mips;
3107 }
3108//===----------------------------------------------------------------------===//
3109// Call Calling Convention Implementation
3110//===----------------------------------------------------------------------===//
3111
3112SDValue MipsTargetLowering::passArgOnStack(SDValue StackPtr,unsignedOffset,
3113SDValue Chain,SDValue Arg,
3114constSDLoc &DL,bool IsTailCall,
3115SelectionDAG &DAG) const{
3116if (!IsTailCall) {
3117SDValue PtrOff =
3118 DAG.getNode(ISD::ADD,DL,getPointerTy(DAG.getDataLayout()), StackPtr,
3119 DAG.getIntPtrConstant(Offset,DL));
3120return DAG.getStore(Chain,DL, Arg, PtrOff,MachinePointerInfo());
3121 }
3122
3123MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
3124int FI = MFI.CreateFixedObject(Arg.getValueSizeInBits() / 8,Offset,false);
3125SDValue FIN = DAG.getFrameIndex(FI,getPointerTy(DAG.getDataLayout()));
3126return DAG.getStore(Chain,DL, Arg, FIN,MachinePointerInfo(),MaybeAlign(),
3127MachineMemOperand::MOVolatile);
3128}
3129
3130voidMipsTargetLowering::
3131getOpndList(SmallVectorImpl<SDValue> &Ops,
3132 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
3133bool IsPICCall,bool GlobalOrExternal,bool InternalLinkage,
3134bool IsCallReloc,CallLoweringInfo &CLI,SDValue Callee,
3135SDValue Chain) const{
3136// Insert node "GP copy globalreg" before call to function.
3137//
3138// R_MIPS_CALL* operators (emitted when non-internal functions are called
3139// in PIC mode) allow symbols to be resolved via lazy binding.
3140// The lazy binding stub requires GP to point to the GOT.
3141// Note that we don't need GP to point to the GOT for indirect calls
3142// (when R_MIPS_CALL* is not used for the call) because Mips linker generates
3143// lazy binding stub for a function only when R_MIPS_CALL* are the only relocs
3144// used for the function (that is, Mips linker doesn't generate lazy binding
3145// stub for a function whose address is taken in the program).
3146if (IsPICCall && !InternalLinkage && IsCallReloc) {
3147unsigned GPReg =ABI.IsN64() ? Mips::GP_64 : Mips::GP;
3148EVT Ty =ABI.IsN64() ? MVT::i64 : MVT::i32;
3149 RegsToPass.push_back(std::make_pair(GPReg,getGlobalReg(CLI.DAG, Ty)));
3150 }
3151
3152// Build a sequence of copy-to-reg nodes chained together with token
3153// chain and flag operands which copy the outgoing args into registers.
3154// The InGlue in necessary since all emitted instructions must be
3155// stuck together.
3156SDValue InGlue;
3157
3158for (auto &R : RegsToPass) {
3159 Chain = CLI.DAG.getCopyToReg(Chain, CLI.DL, R.first, R.second, InGlue);
3160 InGlue = Chain.getValue(1);
3161 }
3162
3163// Add argument registers to the end of the list so that they are
3164// known live into the call.
3165for (auto &R : RegsToPass)
3166 Ops.push_back(CLI.DAG.getRegister(R.first, R.second.getValueType()));
3167
3168// Add a register mask operand representing the call-preserved registers.
3169constTargetRegisterInfo *TRI =Subtarget.getRegisterInfo();
3170constuint32_t *Mask =
3171TRI->getCallPreservedMask(CLI.DAG.getMachineFunction(), CLI.CallConv);
3172assert(Mask &&"Missing call preserved mask for calling convention");
3173if (Subtarget.inMips16HardFloat()) {
3174if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
3175StringRefSym =G->getGlobal()->getName();
3176Function *F =G->getGlobal()->getParent()->getFunction(Sym);
3177if (F &&F->hasFnAttribute("__Mips16RetHelper")) {
3178 Mask =MipsRegisterInfo::getMips16RetHelperMask();
3179 }
3180 }
3181 }
3182 Ops.push_back(CLI.DAG.getRegisterMask(Mask));
3183
3184if (InGlue.getNode())
3185 Ops.push_back(InGlue);
3186}
3187
3188voidMipsTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI,
3189SDNode *Node) const{
3190switch (MI.getOpcode()) {
3191default:
3192return;
3193case Mips::JALR:
3194case Mips::JALRPseudo:
3195case Mips::JALR64:
3196case Mips::JALR64Pseudo:
3197case Mips::JALR16_MM:
3198case Mips::JALRC16_MMR6:
3199case Mips::TAILCALLREG:
3200case Mips::TAILCALLREG64:
3201case Mips::TAILCALLR6REG:
3202case Mips::TAILCALL64R6REG:
3203case Mips::TAILCALLREG_MM:
3204case Mips::TAILCALLREG_MMR6: {
3205if (!EmitJalrReloc ||
3206Subtarget.inMips16Mode() ||
3207 !isPositionIndependent() ||
3208 Node->getNumOperands() < 1 ||
3209 Node->getOperand(0).getNumOperands() < 2) {
3210return;
3211 }
3212// We are after the callee address, set by LowerCall().
3213// If added to MI, asm printer will emit .reloc R_MIPS_JALR for the
3214// symbol.
3215constSDValue TargetAddr = Node->getOperand(0).getOperand(1);
3216StringRefSym;
3217if (constGlobalAddressSDNode *G =
3218 dyn_cast_or_null<const GlobalAddressSDNode>(TargetAddr)) {
3219// We must not emit the R_MIPS_JALR relocation against data symbols
3220// since this will cause run-time crashes if the linker replaces the
3221// call instruction with a relative branch to the data symbol.
3222if (!isa<Function>(G->getGlobal())) {
3223LLVM_DEBUG(dbgs() <<"Not adding R_MIPS_JALR against data symbol "
3224 <<G->getGlobal()->getName() <<"\n");
3225return;
3226 }
3227Sym =G->getGlobal()->getName();
3228 }
3229elseif (constExternalSymbolSDNode *ES =
3230 dyn_cast_or_null<const ExternalSymbolSDNode>(TargetAddr)) {
3231Sym = ES->getSymbol();
3232 }
3233
3234if (Sym.empty())
3235return;
3236
3237MachineFunction *MF =MI.getParent()->getParent();
3238MCSymbol *S = MF->getContext().getOrCreateSymbol(Sym);
3239LLVM_DEBUG(dbgs() <<"Adding R_MIPS_JALR against " <<Sym <<"\n");
3240MI.addOperand(MachineOperand::CreateMCSymbol(S,MipsII::MO_JALR));
3241 }
3242 }
3243}
3244
3245/// LowerCall - functions arguments are copied from virtual regs to
3246/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
3247SDValue
3248MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
3249SmallVectorImpl<SDValue> &InVals) const{
3250SelectionDAG &DAG = CLI.DAG;
3251SDLocDL = CLI.DL;
3252SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
3253SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
3254SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
3255SDValue Chain = CLI.Chain;
3256SDValue Callee = CLI.Callee;
3257bool &IsTailCall = CLI.IsTailCall;
3258CallingConv::ID CallConv = CLI.CallConv;
3259bool IsVarArg = CLI.IsVarArg;
3260
3261MachineFunction &MF = DAG.getMachineFunction();
3262MachineFrameInfo &MFI = MF.getFrameInfo();
3263constTargetFrameLowering *TFL =Subtarget.getFrameLowering();
3264MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
3265bool IsPIC =isPositionIndependent();
3266
3267// Analyze operands of the call, assigning locations to each operand.
3268SmallVector<CCValAssign, 16> ArgLocs;
3269MipsCCState CCInfo(
3270 CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs, *DAG.getContext(),
3271MipsCCState::getSpecialCallingConvForCallee(Callee.getNode(),Subtarget));
3272
3273constExternalSymbolSDNode *ES =
3274 dyn_cast_or_null<const ExternalSymbolSDNode>(Callee.getNode());
3275
3276// There is one case where CALLSEQ_START..CALLSEQ_END can be nested, which
3277// is during the lowering of a call with a byval argument which produces
3278// a call to memcpy. For the O32 case, this causes the caller to allocate
3279// stack space for the reserved argument area for the callee, then recursively
3280// again for the memcpy call. In the NEWABI case, this doesn't occur as those
3281// ABIs mandate that the callee allocates the reserved argument area. We do
3282// still produce nested CALLSEQ_START..CALLSEQ_END with zero space though.
3283//
3284// If the callee has a byval argument and memcpy is used, we are mandated
3285// to already have produced a reserved argument area for the callee for O32.
3286// Therefore, the reserved argument area can be reused for both calls.
3287//
3288// Other cases of calling memcpy cannot have a chain with a CALLSEQ_START
3289// present, as we have yet to hook that node onto the chain.
3290//
3291// Hence, the CALLSEQ_START and CALLSEQ_END nodes can be eliminated in this
3292// case. GCC does a similar trick, in that wherever possible, it calculates
3293// the maximum out going argument area (including the reserved area), and
3294// preallocates the stack space on entrance to the caller.
3295//
3296// FIXME: We should do the same for efficiency and space.
3297
3298// Note: The check on the calling convention below must match
3299// MipsABIInfo::GetCalleeAllocdArgSizeInBytes().
3300bool MemcpyInByVal = ES &&StringRef(ES->getSymbol()) =="memcpy" &&
3301 CallConv !=CallingConv::Fast &&
3302 Chain.getOpcode() ==ISD::CALLSEQ_START;
3303
3304// Allocate the reserved argument area. It seems strange to do this from the
3305// caller side but removing it breaks the frame size calculation.
3306unsigned ReservedArgArea =
3307 MemcpyInByVal ? 0 :ABI.GetCalleeAllocdArgSizeInBytes(CallConv);
3308 CCInfo.AllocateStack(ReservedArgArea,Align(1));
3309
3310 CCInfo.AnalyzeCallOperands(Outs,CC_Mips, CLI.getArgs(),
3311 ES ? ES->getSymbol() :nullptr);
3312
3313// Get a count of how many bytes are to be pushed on the stack.
3314unsigned StackSize = CCInfo.getStackSize();
3315
3316// Call site info for function parameters tracking.
3317MachineFunction::CallSiteInfo CSInfo;
3318
3319// Check if it's really possible to do a tail call. Restrict it to functions
3320// that are part of this compilation unit.
3321bool InternalLinkage =false;
3322if (IsTailCall) {
3323 IsTailCall = isEligibleForTailCallOptimization(
3324 CCInfo, StackSize, *MF.getInfo<MipsFunctionInfo>());
3325if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
3326 InternalLinkage =G->getGlobal()->hasInternalLinkage();
3327 IsTailCall &= (InternalLinkage ||G->getGlobal()->hasLocalLinkage() ||
3328G->getGlobal()->hasPrivateLinkage() ||
3329G->getGlobal()->hasHiddenVisibility() ||
3330G->getGlobal()->hasProtectedVisibility());
3331 }
3332 }
3333if (!IsTailCall && CLI.CB && CLI.CB->isMustTailCall())
3334report_fatal_error("failed to perform tail call elimination on a call "
3335"site marked musttail");
3336
3337if (IsTailCall)
3338 ++NumTailCalls;
3339
3340// Chain is the output chain of the last Load/Store or CopyToReg node.
3341// ByValChain is the output chain of the last Memcpy node created for copying
3342// byval arguments to the stack.
3343unsigned StackAlignment = TFL->getStackAlignment();
3344 StackSize =alignTo(StackSize, StackAlignment);
3345
3346if (!(IsTailCall || MemcpyInByVal))
3347 Chain = DAG.getCALLSEQ_START(Chain, StackSize, 0,DL);
3348
3349SDValueStackPtr =
3350 DAG.getCopyFromReg(Chain,DL,ABI.IsN64() ? Mips::SP_64 : Mips::SP,
3351getPointerTy(DAG.getDataLayout()));
3352
3353 std::deque<std::pair<unsigned, SDValue>> RegsToPass;
3354SmallVector<SDValue, 8> MemOpChains;
3355
3356 CCInfo.rewindByValRegsInfo();
3357
3358// Walk the register/memloc assignments, inserting copies/loads.
3359for (unsigned i = 0, e = ArgLocs.size(), OutIdx = 0; i != e; ++i, ++OutIdx) {
3360SDValue Arg = OutVals[OutIdx];
3361CCValAssign &VA = ArgLocs[i];
3362MVT ValVT = VA.getValVT(), LocVT = VA.getLocVT();
3363ISD::ArgFlagsTyFlags = Outs[OutIdx].Flags;
3364bool UseUpperBits =false;
3365
3366// ByVal Arg.
3367if (Flags.isByVal()) {
3368unsigned FirstByValReg, LastByValReg;
3369unsigned ByValIdx = CCInfo.getInRegsParamsProcessed();
3370 CCInfo.getInRegsParamInfo(ByValIdx, FirstByValReg, LastByValReg);
3371
3372assert(Flags.getByValSize() &&
3373"ByVal args of size 0 should have been ignored by front-end.");
3374assert(ByValIdx < CCInfo.getInRegsParamsCount());
3375assert(!IsTailCall &&
3376"Do not tail-call optimize if there is a byval argument.");
3377 passByValArg(Chain,DL, RegsToPass, MemOpChains, StackPtr, MFI, DAG, Arg,
3378 FirstByValReg, LastByValReg, Flags,Subtarget.isLittle(),
3379 VA);
3380 CCInfo.nextInRegsParam();
3381continue;
3382 }
3383
3384// Promote the value if needed.
3385switch (VA.getLocInfo()) {
3386default:
3387llvm_unreachable("Unknown loc info!");
3388caseCCValAssign::Full:
3389if (VA.isRegLoc()) {
3390if ((ValVT == MVT::f32 && LocVT == MVT::i32) ||
3391 (ValVT == MVT::f64 && LocVT == MVT::i64) ||
3392 (ValVT == MVT::i64 && LocVT == MVT::f64))
3393 Arg = DAG.getNode(ISD::BITCAST,DL, LocVT, Arg);
3394elseif (ValVT == MVT::f64 && LocVT == MVT::i32) {
3395SDValueLo = DAG.getNode(MipsISD::ExtractElementF64,DL, MVT::i32,
3396 Arg, DAG.getConstant(0,DL, MVT::i32));
3397SDValueHi = DAG.getNode(MipsISD::ExtractElementF64,DL, MVT::i32,
3398 Arg, DAG.getConstant(1,DL, MVT::i32));
3399if (!Subtarget.isLittle())
3400std::swap(Lo,Hi);
3401
3402assert(VA.needsCustom());
3403
3404Register LocRegLo = VA.getLocReg();
3405Register LocRegHigh = ArgLocs[++i].getLocReg();
3406 RegsToPass.push_back(std::make_pair(LocRegLo,Lo));
3407 RegsToPass.push_back(std::make_pair(LocRegHigh,Hi));
3408continue;
3409 }
3410 }
3411break;
3412caseCCValAssign::BCvt:
3413 Arg = DAG.getNode(ISD::BITCAST,DL, LocVT, Arg);
3414break;
3415caseCCValAssign::SExtUpper:
3416 UseUpperBits =true;
3417 [[fallthrough]];
3418caseCCValAssign::SExt:
3419 Arg = DAG.getNode(ISD::SIGN_EXTEND,DL, LocVT, Arg);
3420break;
3421caseCCValAssign::ZExtUpper:
3422 UseUpperBits =true;
3423 [[fallthrough]];
3424caseCCValAssign::ZExt:
3425 Arg = DAG.getNode(ISD::ZERO_EXTEND,DL, LocVT, Arg);
3426break;
3427caseCCValAssign::AExtUpper:
3428 UseUpperBits =true;
3429 [[fallthrough]];
3430caseCCValAssign::AExt:
3431 Arg = DAG.getNode(ISD::ANY_EXTEND,DL, LocVT, Arg);
3432break;
3433 }
3434
3435if (UseUpperBits) {
3436unsigned ValSizeInBits = Outs[OutIdx].ArgVT.getSizeInBits();
3437unsigned LocSizeInBits = VA.getLocVT().getSizeInBits();
3438 Arg = DAG.getNode(
3439ISD::SHL,DL, VA.getLocVT(), Arg,
3440 DAG.getConstant(LocSizeInBits - ValSizeInBits,DL, VA.getLocVT()));
3441 }
3442
3443// Arguments that can be passed on register must be kept at
3444// RegsToPass vector
3445if (VA.isRegLoc()) {
3446 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
3447
3448// If the parameter is passed through reg $D, which splits into
3449// two physical registers, avoid creating call site info.
3450if (Mips::AFGR64RegClass.contains(VA.getLocReg()))
3451continue;
3452
3453// Collect CSInfo about which register passes which parameter.
3454constTargetOptions &Options = DAG.getTarget().Options;
3455if (Options.EmitCallSiteInfo)
3456 CSInfo.ArgRegPairs.emplace_back(VA.getLocReg(), i);
3457
3458continue;
3459 }
3460
3461// Register can't get to this point...
3462assert(VA.isMemLoc());
3463
3464// emit ISD::STORE whichs stores the
3465// parameter value to a stack Location
3466 MemOpChains.push_back(passArgOnStack(StackPtr, VA.getLocMemOffset(),
3467 Chain, Arg,DL, IsTailCall, DAG));
3468 }
3469
3470// Transform all store nodes into one single node because all store
3471// nodes are independent of each other.
3472if (!MemOpChains.empty())
3473 Chain = DAG.getNode(ISD::TokenFactor,DL, MVT::Other, MemOpChains);
3474
3475// If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
3476// direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
3477// node so that legalize doesn't hack it.
3478
3479EVT Ty =Callee.getValueType();
3480bool GlobalOrExternal =false, IsCallReloc =false;
3481
3482// The long-calls feature is ignored in case of PIC.
3483// While we do not support -mshared / -mno-shared properly,
3484// ignore long-calls in case of -mabicalls too.
3485if (!Subtarget.isABICalls() && !IsPIC) {
3486// If the function should be called using "long call",
3487// get its address into a register to prevent using
3488// of the `jal` instruction for the direct call.
3489if (auto *N = dyn_cast<ExternalSymbolSDNode>(Callee)) {
3490if (Subtarget.useLongCalls())
3491Callee =Subtarget.hasSym32()
3492 ?getAddrNonPIC(N,SDLoc(N), Ty, DAG)
3493 :getAddrNonPICSym64(N,SDLoc(N), Ty, DAG);
3494 }elseif (auto *N = dyn_cast<GlobalAddressSDNode>(Callee)) {
3495bool UseLongCalls =Subtarget.useLongCalls();
3496// If the function has long-call/far/near attribute
3497// it overrides command line switch pased to the backend.
3498if (auto *F = dyn_cast<Function>(N->getGlobal())) {
3499if (F->hasFnAttribute("long-call"))
3500 UseLongCalls =true;
3501elseif (F->hasFnAttribute("short-call"))
3502 UseLongCalls =false;
3503 }
3504if (UseLongCalls)
3505Callee =Subtarget.hasSym32()
3506 ?getAddrNonPIC(N,SDLoc(N), Ty, DAG)
3507 :getAddrNonPICSym64(N,SDLoc(N), Ty, DAG);
3508 }
3509 }
3510
3511if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
3512if (Subtarget.isTargetCOFF() &&
3513G->getGlobal()->hasDLLImportStorageClass()) {
3514assert(Subtarget.isTargetWindows() &&
3515"Windows is the only supported COFF target");
3516auto PtrInfo =MachinePointerInfo();
3517Callee = DAG.getLoad(Ty,DL, Chain,
3518getDllimportSymbol(G,SDLoc(G), Ty, DAG), PtrInfo);
3519 }elseif (IsPIC) {
3520constGlobalValue *Val =G->getGlobal();
3521 InternalLinkage = Val->hasInternalLinkage();
3522
3523if (InternalLinkage)
3524Callee =getAddrLocal(G,DL, Ty, DAG,ABI.IsN32() ||ABI.IsN64());
3525elseif (Subtarget.useXGOT()) {
3526Callee =getAddrGlobalLargeGOT(G,DL, Ty, DAG,MipsII::MO_CALL_HI16,
3527MipsII::MO_CALL_LO16, Chain,
3528 FuncInfo->callPtrInfo(MF, Val));
3529 IsCallReloc =true;
3530 }else {
3531Callee =getAddrGlobal(G,DL, Ty, DAG,MipsII::MO_GOT_CALL, Chain,
3532 FuncInfo->callPtrInfo(MF, Val));
3533 IsCallReloc =true;
3534 }
3535 }else
3536Callee = DAG.getTargetGlobalAddress(G->getGlobal(),DL,
3537getPointerTy(DAG.getDataLayout()), 0,
3538MipsII::MO_NO_FLAG);
3539 GlobalOrExternal =true;
3540 }
3541elseif (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
3542constchar *Sym = S->getSymbol();
3543
3544if (!IsPIC)// static
3545Callee = DAG.getTargetExternalSymbol(
3546Sym,getPointerTy(DAG.getDataLayout()),MipsII::MO_NO_FLAG);
3547elseif (Subtarget.useXGOT()) {
3548Callee =getAddrGlobalLargeGOT(S,DL, Ty, DAG,MipsII::MO_CALL_HI16,
3549MipsII::MO_CALL_LO16, Chain,
3550 FuncInfo->callPtrInfo(MF,Sym));
3551 IsCallReloc =true;
3552 }else {// PIC
3553Callee =getAddrGlobal(S,DL, Ty, DAG,MipsII::MO_GOT_CALL, Chain,
3554 FuncInfo->callPtrInfo(MF,Sym));
3555 IsCallReloc =true;
3556 }
3557
3558 GlobalOrExternal =true;
3559 }
3560
3561SmallVector<SDValue, 8> Ops(1, Chain);
3562SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
3563
3564getOpndList(Ops, RegsToPass, IsPIC, GlobalOrExternal, InternalLinkage,
3565 IsCallReloc, CLI, Callee, Chain);
3566
3567if (IsTailCall) {
3568 MF.getFrameInfo().setHasTailCall();
3569SDValueRet = DAG.getNode(MipsISD::TailCall,DL, MVT::Other, Ops);
3570 DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo));
3571returnRet;
3572 }
3573
3574 Chain = DAG.getNode(MipsISD::JmpLink,DL, NodeTys, Ops);
3575SDValue InGlue = Chain.getValue(1);
3576
3577 DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
3578
3579// Create the CALLSEQ_END node in the case of where it is not a call to
3580// memcpy.
3581if (!(MemcpyInByVal)) {
3582 Chain = DAG.getCALLSEQ_END(Chain, StackSize, 0, InGlue,DL);
3583 InGlue = Chain.getValue(1);
3584 }
3585
3586// Handle result values, copying them out of physregs into vregs that we
3587// return.
3588return LowerCallResult(Chain, InGlue, CallConv, IsVarArg, Ins,DL, DAG,
3589 InVals, CLI);
3590}
3591
3592/// LowerCallResult - Lower the result values of a call into the
3593/// appropriate copies out of appropriate physical registers.
3594SDValue MipsTargetLowering::LowerCallResult(
3595SDValue Chain,SDValue InGlue,CallingConv::ID CallConv,bool IsVarArg,
3596constSmallVectorImpl<ISD::InputArg> &Ins,constSDLoc &DL,
3597SelectionDAG &DAG,SmallVectorImpl<SDValue> &InVals,
3598TargetLowering::CallLoweringInfo &CLI) const{
3599// Assign locations to each value returned by this call.
3600SmallVector<CCValAssign, 16> RVLocs;
3601MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
3602 *DAG.getContext());
3603
3604constExternalSymbolSDNode *ES =
3605 dyn_cast_or_null<const ExternalSymbolSDNode>(CLI.Callee.getNode());
3606 CCInfo.AnalyzeCallResult(Ins, RetCC_Mips, CLI.RetTy,
3607 ES ? ES->getSymbol() :nullptr);
3608
3609// Copy all of the result registers out of their specified physreg.
3610for (unsigned i = 0; i != RVLocs.size(); ++i) {
3611CCValAssign &VA = RVLocs[i];
3612assert(VA.isRegLoc() &&"Can only return in registers!");
3613
3614SDValue Val = DAG.getCopyFromReg(Chain,DL, RVLocs[i].getLocReg(),
3615 RVLocs[i].getLocVT(), InGlue);
3616 Chain = Val.getValue(1);
3617 InGlue = Val.getValue(2);
3618
3619if (VA.isUpperBitsInLoc()) {
3620unsigned ValSizeInBits =Ins[i].ArgVT.getSizeInBits();
3621unsigned LocSizeInBits = VA.getLocVT().getSizeInBits();
3622unsigned Shift =
3623 VA.getLocInfo() ==CCValAssign::ZExtUpper ?ISD::SRL :ISD::SRA;
3624 Val = DAG.getNode(
3625 Shift,DL, VA.getLocVT(), Val,
3626 DAG.getConstant(LocSizeInBits - ValSizeInBits,DL, VA.getLocVT()));
3627 }
3628
3629switch (VA.getLocInfo()) {
3630default:
3631llvm_unreachable("Unknown loc info!");
3632caseCCValAssign::Full:
3633break;
3634caseCCValAssign::BCvt:
3635 Val = DAG.getNode(ISD::BITCAST,DL, VA.getValVT(), Val);
3636break;
3637caseCCValAssign::AExt:
3638caseCCValAssign::AExtUpper:
3639 Val = DAG.getNode(ISD::TRUNCATE,DL, VA.getValVT(), Val);
3640break;
3641caseCCValAssign::ZExt:
3642caseCCValAssign::ZExtUpper:
3643 Val = DAG.getNode(ISD::AssertZext,DL, VA.getLocVT(), Val,
3644 DAG.getValueType(VA.getValVT()));
3645 Val = DAG.getNode(ISD::TRUNCATE,DL, VA.getValVT(), Val);
3646break;
3647caseCCValAssign::SExt:
3648caseCCValAssign::SExtUpper:
3649 Val = DAG.getNode(ISD::AssertSext,DL, VA.getLocVT(), Val,
3650 DAG.getValueType(VA.getValVT()));
3651 Val = DAG.getNode(ISD::TRUNCATE,DL, VA.getValVT(), Val);
3652break;
3653 }
3654
3655 InVals.push_back(Val);
3656 }
3657
3658return Chain;
3659}
3660
3661staticSDValueUnpackFromArgumentSlot(SDValue Val,constCCValAssign &VA,
3662EVT ArgVT,constSDLoc &DL,
3663SelectionDAG &DAG) {
3664MVT LocVT = VA.getLocVT();
3665EVT ValVT = VA.getValVT();
3666
3667// Shift into the upper bits if necessary.
3668switch (VA.getLocInfo()) {
3669default:
3670break;
3671caseCCValAssign::AExtUpper:
3672caseCCValAssign::SExtUpper:
3673caseCCValAssign::ZExtUpper: {
3674unsigned ValSizeInBits = ArgVT.getSizeInBits();
3675unsigned LocSizeInBits = VA.getLocVT().getSizeInBits();
3676unsigned Opcode =
3677 VA.getLocInfo() ==CCValAssign::ZExtUpper ?ISD::SRL :ISD::SRA;
3678 Val = DAG.getNode(
3679 Opcode,DL, VA.getLocVT(), Val,
3680 DAG.getConstant(LocSizeInBits - ValSizeInBits,DL, VA.getLocVT()));
3681break;
3682 }
3683 }
3684
3685// If this is an value smaller than the argument slot size (32-bit for O32,
3686// 64-bit for N32/N64), it has been promoted in some way to the argument slot
3687// size. Extract the value and insert any appropriate assertions regarding
3688// sign/zero extension.
3689switch (VA.getLocInfo()) {
3690default:
3691llvm_unreachable("Unknown loc info!");
3692caseCCValAssign::Full:
3693break;
3694caseCCValAssign::AExtUpper:
3695caseCCValAssign::AExt:
3696 Val = DAG.getNode(ISD::TRUNCATE,DL, ValVT, Val);
3697break;
3698caseCCValAssign::SExtUpper:
3699caseCCValAssign::SExt:
3700 Val = DAG.getNode(ISD::AssertSext,DL, LocVT, Val, DAG.getValueType(ValVT));
3701 Val = DAG.getNode(ISD::TRUNCATE,DL, ValVT, Val);
3702break;
3703caseCCValAssign::ZExtUpper:
3704caseCCValAssign::ZExt:
3705 Val = DAG.getNode(ISD::AssertZext,DL, LocVT, Val, DAG.getValueType(ValVT));
3706 Val = DAG.getNode(ISD::TRUNCATE,DL, ValVT, Val);
3707break;
3708caseCCValAssign::BCvt:
3709 Val = DAG.getNode(ISD::BITCAST,DL, ValVT, Val);
3710break;
3711 }
3712
3713return Val;
3714}
3715
3716//===----------------------------------------------------------------------===//
3717// Formal Arguments Calling Convention Implementation
3718//===----------------------------------------------------------------------===//
3719/// LowerFormalArguments - transform physical registers into virtual registers
3720/// and generate load operations for arguments places on the stack.
3721SDValue MipsTargetLowering::LowerFormalArguments(
3722SDValue Chain,CallingConv::ID CallConv,bool IsVarArg,
3723constSmallVectorImpl<ISD::InputArg> &Ins,constSDLoc &DL,
3724SelectionDAG &DAG,SmallVectorImpl<SDValue> &InVals) const{
3725MachineFunction &MF = DAG.getMachineFunction();
3726MachineFrameInfo &MFI = MF.getFrameInfo();
3727MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
3728
3729 MipsFI->setVarArgsFrameIndex(0);
3730
3731// Used with vargs to acumulate store chains.
3732 std::vector<SDValue> OutChains;
3733
3734// Assign locations to all of the incoming arguments.
3735SmallVector<CCValAssign, 16> ArgLocs;
3736MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
3737 *DAG.getContext());
3738 CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(CallConv),Align(1));
3739constFunction &Func = DAG.getMachineFunction().getFunction();
3740Function::const_arg_iterator FuncArg =Func.arg_begin();
3741
3742if (Func.hasFnAttribute("interrupt") && !Func.arg_empty())
3743report_fatal_error(
3744"Functions with the interrupt attribute cannot have arguments!");
3745
3746 CCInfo.AnalyzeFormalArguments(Ins, CC_Mips_FixedArg);
3747 MipsFI->setFormalArgInfo(CCInfo.getStackSize(),
3748 CCInfo.getInRegsParamsCount() > 0);
3749
3750unsigned CurArgIdx = 0;
3751 CCInfo.rewindByValRegsInfo();
3752
3753for (unsigned i = 0, e = ArgLocs.size(), InsIdx = 0; i != e; ++i, ++InsIdx) {
3754CCValAssign &VA = ArgLocs[i];
3755if (Ins[InsIdx].isOrigArg()) {
3756 std::advance(FuncArg, Ins[InsIdx].getOrigArgIndex() - CurArgIdx);
3757 CurArgIdx =Ins[InsIdx].getOrigArgIndex();
3758 }
3759EVT ValVT = VA.getValVT();
3760ISD::ArgFlagsTyFlags =Ins[InsIdx].Flags;
3761bool IsRegLoc = VA.isRegLoc();
3762
3763if (Flags.isByVal()) {
3764assert(Ins[InsIdx].isOrigArg() &&"Byval arguments cannot be implicit");
3765unsigned FirstByValReg, LastByValReg;
3766unsigned ByValIdx = CCInfo.getInRegsParamsProcessed();
3767 CCInfo.getInRegsParamInfo(ByValIdx, FirstByValReg, LastByValReg);
3768
3769assert(Flags.getByValSize() &&
3770"ByVal args of size 0 should have been ignored by front-end.");
3771assert(ByValIdx < CCInfo.getInRegsParamsCount());
3772 copyByValRegs(Chain,DL, OutChains, DAG, Flags, InVals, &*FuncArg,
3773 FirstByValReg, LastByValReg, VA, CCInfo);
3774 CCInfo.nextInRegsParam();
3775continue;
3776 }
3777
3778// Arguments stored on registers
3779if (IsRegLoc) {
3780MVT RegVT = VA.getLocVT();
3781Register ArgReg = VA.getLocReg();
3782constTargetRegisterClass *RC =getRegClassFor(RegVT);
3783
3784// Transform the arguments stored on
3785// physical registers into virtual ones
3786unsignedReg =addLiveIn(DAG.getMachineFunction(), ArgReg, RC);
3787SDValue ArgValue = DAG.getCopyFromReg(Chain,DL, Reg, RegVT);
3788
3789 ArgValue =
3790UnpackFromArgumentSlot(ArgValue, VA, Ins[InsIdx].ArgVT,DL, DAG);
3791
3792// Handle floating point arguments passed in integer registers and
3793// long double arguments passed in floating point registers.
3794if ((RegVT == MVT::i32 && ValVT == MVT::f32) ||
3795 (RegVT == MVT::i64 && ValVT == MVT::f64) ||
3796 (RegVT == MVT::f64 && ValVT == MVT::i64))
3797 ArgValue = DAG.getNode(ISD::BITCAST,DL, ValVT, ArgValue);
3798elseif (ABI.IsO32() && RegVT == MVT::i32 &&
3799 ValVT == MVT::f64) {
3800assert(VA.needsCustom() &&"Expected custom argument for f64 split");
3801CCValAssign &NextVA = ArgLocs[++i];
3802unsigned Reg2 =
3803addLiveIn(DAG.getMachineFunction(), NextVA.getLocReg(), RC);
3804SDValue ArgValue2 = DAG.getCopyFromReg(Chain,DL, Reg2, RegVT);
3805if (!Subtarget.isLittle())
3806std::swap(ArgValue, ArgValue2);
3807 ArgValue = DAG.getNode(MipsISD::BuildPairF64,DL, MVT::f64,
3808 ArgValue, ArgValue2);
3809 }
3810
3811 InVals.push_back(ArgValue);
3812 }else {// VA.isRegLoc()
3813MVT LocVT = VA.getLocVT();
3814
3815assert(!VA.needsCustom() &&"unexpected custom memory argument");
3816
3817// Only arguments pased on the stack should make it here.
3818assert(VA.isMemLoc());
3819
3820// The stack pointer offset is relative to the caller stack frame.
3821int FI = MFI.CreateFixedObject(LocVT.getSizeInBits() / 8,
3822 VA.getLocMemOffset(),true);
3823
3824// Create load nodes to retrieve arguments from the stack
3825SDValue FIN = DAG.getFrameIndex(FI,getPointerTy(DAG.getDataLayout()));
3826SDValue ArgValue = DAG.getLoad(
3827 LocVT,DL, Chain, FIN,
3828MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI));
3829 OutChains.push_back(ArgValue.getValue(1));
3830
3831 ArgValue =
3832UnpackFromArgumentSlot(ArgValue, VA, Ins[InsIdx].ArgVT,DL, DAG);
3833
3834 InVals.push_back(ArgValue);
3835 }
3836 }
3837
3838for (unsigned i = 0, e = ArgLocs.size(), InsIdx = 0; i != e; ++i, ++InsIdx) {
3839
3840if (ArgLocs[i].needsCustom()) {
3841 ++i;
3842continue;
3843 }
3844
3845// The mips ABIs for returning structs by value requires that we copy
3846// the sret argument into $v0 for the return. Save the argument into
3847// a virtual register so that we can access it from the return points.
3848if (Ins[InsIdx].Flags.isSRet()) {
3849unsignedReg = MipsFI->getSRetReturnReg();
3850if (!Reg) {
3851Reg = MF.getRegInfo().createVirtualRegister(
3852getRegClassFor(ABI.IsN64() ? MVT::i64 : MVT::i32));
3853 MipsFI->setSRetReturnReg(Reg);
3854 }
3855SDValueCopy = DAG.getCopyToReg(DAG.getEntryNode(),DL, Reg, InVals[i]);
3856 Chain = DAG.getNode(ISD::TokenFactor,DL, MVT::Other, Copy, Chain);
3857break;
3858 }
3859 }
3860
3861if (IsVarArg)
3862 writeVarArgRegs(OutChains, Chain,DL, DAG, CCInfo);
3863
3864// All stores are grouped in one node to allow the matching between
3865// the size of Ins and InVals. This only happens when on varg functions
3866if (!OutChains.empty()) {
3867 OutChains.push_back(Chain);
3868 Chain = DAG.getNode(ISD::TokenFactor,DL, MVT::Other, OutChains);
3869 }
3870
3871return Chain;
3872}
3873
3874//===----------------------------------------------------------------------===//
3875// Return Value Calling Convention Implementation
3876//===----------------------------------------------------------------------===//
3877
3878bool
3879MipsTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
3880MachineFunction &MF,bool IsVarArg,
3881constSmallVectorImpl<ISD::OutputArg> &Outs,
3882LLVMContext &Context,constType *RetTy) const{
3883SmallVector<CCValAssign, 16> RVLocs;
3884MipsCCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
3885return CCInfo.CheckCallReturn(Outs, RetCC_Mips,RetTy);
3886}
3887
3888bool MipsTargetLowering::shouldSignExtendTypeInLibCall(Type *Ty,
3889bool IsSigned) const{
3890if ((ABI.IsN32() ||ABI.IsN64()) && Ty->isIntegerTy(32))
3891returntrue;
3892
3893return IsSigned;
3894}
3895
3896SDValue
3897MipsTargetLowering::LowerInterruptReturn(SmallVectorImpl<SDValue> &RetOps,
3898constSDLoc &DL,
3899SelectionDAG &DAG) const{
3900MachineFunction &MF = DAG.getMachineFunction();
3901MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
3902
3903 MipsFI->setISR();
3904
3905return DAG.getNode(MipsISD::ERet,DL, MVT::Other, RetOps);
3906}
3907
3908SDValue
3909MipsTargetLowering::LowerReturn(SDValue Chain,CallingConv::ID CallConv,
3910bool IsVarArg,
3911constSmallVectorImpl<ISD::OutputArg> &Outs,
3912constSmallVectorImpl<SDValue> &OutVals,
3913constSDLoc &DL,SelectionDAG &DAG) const{
3914// CCValAssign - represent the assignment of
3915// the return value to a location
3916SmallVector<CCValAssign, 16> RVLocs;
3917MachineFunction &MF = DAG.getMachineFunction();
3918
3919// CCState - Info about the registers and stack slot.
3920MipsCCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());
3921
3922// Analyze return values.
3923 CCInfo.AnalyzeReturn(Outs, RetCC_Mips);
3924
3925SDValue Glue;
3926SmallVector<SDValue, 4> RetOps(1, Chain);
3927
3928// Copy the result values into the output registers.
3929for (unsigned i = 0; i != RVLocs.size(); ++i) {
3930SDValue Val = OutVals[i];
3931CCValAssign &VA = RVLocs[i];
3932assert(VA.isRegLoc() &&"Can only return in registers!");
3933bool UseUpperBits =false;
3934
3935switch (VA.getLocInfo()) {
3936default:
3937llvm_unreachable("Unknown loc info!");
3938caseCCValAssign::Full:
3939break;
3940caseCCValAssign::BCvt:
3941 Val = DAG.getNode(ISD::BITCAST,DL, VA.getLocVT(), Val);
3942break;
3943caseCCValAssign::AExtUpper:
3944 UseUpperBits =true;
3945 [[fallthrough]];
3946caseCCValAssign::AExt:
3947 Val = DAG.getNode(ISD::ANY_EXTEND,DL, VA.getLocVT(), Val);
3948break;
3949caseCCValAssign::ZExtUpper:
3950 UseUpperBits =true;
3951 [[fallthrough]];
3952caseCCValAssign::ZExt:
3953 Val = DAG.getNode(ISD::ZERO_EXTEND,DL, VA.getLocVT(), Val);
3954break;
3955caseCCValAssign::SExtUpper:
3956 UseUpperBits =true;
3957 [[fallthrough]];
3958caseCCValAssign::SExt:
3959 Val = DAG.getNode(ISD::SIGN_EXTEND,DL, VA.getLocVT(), Val);
3960break;
3961 }
3962
3963if (UseUpperBits) {
3964unsigned ValSizeInBits = Outs[i].ArgVT.getSizeInBits();
3965unsigned LocSizeInBits = VA.getLocVT().getSizeInBits();
3966 Val = DAG.getNode(
3967ISD::SHL,DL, VA.getLocVT(), Val,
3968 DAG.getConstant(LocSizeInBits - ValSizeInBits,DL, VA.getLocVT()));
3969 }
3970
3971 Chain = DAG.getCopyToReg(Chain,DL, VA.getLocReg(), Val, Glue);
3972
3973// Guarantee that all emitted copies are stuck together with flags.
3974 Glue = Chain.getValue(1);
3975 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
3976 }
3977
3978// The mips ABIs for returning structs by value requires that we copy
3979// the sret argument into $v0 for the return. We saved the argument into
3980// a virtual register in the entry block, so now we copy the value out
3981// and into $v0.
3982if (MF.getFunction().hasStructRetAttr()) {
3983MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
3984unsignedReg = MipsFI->getSRetReturnReg();
3985
3986if (!Reg)
3987llvm_unreachable("sret virtual register not created in the entry block");
3988SDValue Val =
3989 DAG.getCopyFromReg(Chain,DL, Reg,getPointerTy(DAG.getDataLayout()));
3990unsigned V0 =ABI.IsN64() ? Mips::V0_64 : Mips::V0;
3991
3992 Chain = DAG.getCopyToReg(Chain,DL, V0, Val, Glue);
3993 Glue = Chain.getValue(1);
3994 RetOps.push_back(DAG.getRegister(V0,getPointerTy(DAG.getDataLayout())));
3995 }
3996
3997 RetOps[0] = Chain;// Update chain.
3998
3999// Add the glue if we have it.
4000if (Glue.getNode())
4001 RetOps.push_back(Glue);
4002
4003// ISRs must use "eret".
4004if (DAG.getMachineFunction().getFunction().hasFnAttribute("interrupt"))
4005return LowerInterruptReturn(RetOps,DL, DAG);
4006
4007// Standard return on Mips is a "jr $ra"
4008return DAG.getNode(MipsISD::Ret,DL, MVT::Other, RetOps);
4009}
4010
4011//===----------------------------------------------------------------------===//
4012// Mips Inline Assembly Support
4013//===----------------------------------------------------------------------===//
4014
4015/// getConstraintType - Given a constraint letter, return the type of
4016/// constraint it is for this target.
4017MipsTargetLowering::ConstraintType
4018MipsTargetLowering::getConstraintType(StringRef Constraint) const{
4019// Mips specific constraints
4020// GCC config/mips/constraints.md
4021//
4022// 'd' : An address register. Equivalent to r
4023// unless generating MIPS16 code.
4024// 'y' : Equivalent to r; retained for
4025// backwards compatibility.
4026// 'c' : A register suitable for use in an indirect
4027// jump. This will always be $25 for -mabicalls.
4028// 'l' : The lo register. 1 word storage.
4029// 'x' : The hilo register pair. Double word storage.
4030if (Constraint.size() == 1) {
4031switch (Constraint[0]) {
4032 default :break;
4033case'd':
4034case'y':
4035case'f':
4036case'c':
4037case'l':
4038case'x':
4039returnC_RegisterClass;
4040case'R':
4041returnC_Memory;
4042 }
4043 }
4044
4045if (Constraint =="ZC")
4046returnC_Memory;
4047
4048returnTargetLowering::getConstraintType(Constraint);
4049}
4050
4051/// Examine constraint type and operand type and determine a weight value.
4052/// This object must already have been set up with the operand type
4053/// and the current alternative constraint selected.
4054TargetLowering::ConstraintWeight
4055MipsTargetLowering::getSingleConstraintMatchWeight(
4056 AsmOperandInfo &info,constchar *constraint) const{
4057ConstraintWeight weight =CW_Invalid;
4058Value *CallOperandVal =info.CallOperandVal;
4059// If we don't have a value, we can't do a match,
4060// but allow it at the lowest weight.
4061if (!CallOperandVal)
4062returnCW_Default;
4063Type *type = CallOperandVal->getType();
4064// Look at the constraint type.
4065switch (*constraint) {
4066default:
4067 weight =TargetLowering::getSingleConstraintMatchWeight(info, constraint);
4068break;
4069case'd':
4070case'y':
4071if (type->isIntegerTy())
4072 weight =CW_Register;
4073break;
4074case'f':// FPU or MSA register
4075if (Subtarget.hasMSA() && type->isVectorTy() &&
4076 type->getPrimitiveSizeInBits().getFixedValue() == 128)
4077 weight =CW_Register;
4078elseif (type->isFloatTy())
4079 weight =CW_Register;
4080break;
4081case'c':// $25 for indirect jumps
4082case'l':// lo register
4083case'x':// hilo register pair
4084if (type->isIntegerTy())
4085 weight =CW_SpecificReg;
4086break;
4087case'I':// signed 16 bit immediate
4088case'J':// integer zero
4089case'K':// unsigned 16 bit immediate
4090case'L':// signed 32 bit immediate where lower 16 bits are 0
4091case'N':// immediate in the range of -65535 to -1 (inclusive)
4092case'O':// signed 15 bit immediate (+- 16383)
4093case'P':// immediate in the range of 65535 to 1 (inclusive)
4094if (isa<ConstantInt>(CallOperandVal))
4095 weight =CW_Constant;
4096break;
4097case'R':
4098 weight =CW_Memory;
4099break;
4100 }
4101return weight;
4102}
4103
4104/// This is a helper function to parse a physical register string and split it
4105/// into non-numeric and numeric parts (Prefix and Reg). The first boolean flag
4106/// that is returned indicates whether parsing was successful. The second flag
4107/// is true if the numeric part exists.
4108static std::pair<bool, bool>parsePhysicalReg(StringRefC,StringRef &Prefix,
4109unsignedlonglong &Reg) {
4110if (C.front() !='{' ||C.back() !='}')
4111return std::make_pair(false,false);
4112
4113// Search for the first numeric character.
4114StringRef::const_iteratorI,B =C.begin() + 1, E =C.end() - 1;
4115I = std::find_if(B, E, isdigit);
4116
4117 Prefix =StringRef(B,I -B);
4118
4119// The second flag is set to false if no numeric characters were found.
4120if (I == E)
4121return std::make_pair(true,false);
4122
4123// Parse the numeric characters.
4124return std::make_pair(!getAsUnsignedInteger(StringRef(I, E -I), 10, Reg),
4125true);
4126}
4127
4128EVTMipsTargetLowering::getTypeForExtReturn(LLVMContext &Context,EVT VT,
4129ISD::NodeType) const{
4130boolCond = !Subtarget.isABI_O32() && VT.getSizeInBits() == 32;
4131EVT MinVT =getRegisterType(Cond ? MVT::i64 : MVT::i32);
4132return VT.bitsLT(MinVT) ? MinVT : VT;
4133}
4134
4135std::pair<unsigned, const TargetRegisterClass *> MipsTargetLowering::
4136parseRegForInlineAsmConstraint(StringRefC,MVT VT) const{
4137constTargetRegisterInfo *TRI =
4138Subtarget.getRegisterInfo();
4139constTargetRegisterClass *RC;
4140StringRef Prefix;
4141unsignedlonglong Reg;
4142
4143 std::pair<bool, bool> R =parsePhysicalReg(C, Prefix, Reg);
4144
4145if (!R.first)
4146return std::make_pair(0U,nullptr);
4147
4148if ((Prefix =="hi" || Prefix =="lo")) {// Parse hi/lo.
4149// No numeric characters follow "hi" or "lo".
4150if (R.second)
4151return std::make_pair(0U,nullptr);
4152
4153 RC =TRI->getRegClass(Prefix =="hi" ?
4154 Mips::HI32RegClassID : Mips::LO32RegClassID);
4155return std::make_pair(*(RC->begin()), RC);
4156 }elseif (Prefix.starts_with("$msa")) {
4157// Parse $msa(ir|csr|access|save|modify|request|map|unmap)
4158
4159// No numeric characters follow the name.
4160if (R.second)
4161return std::make_pair(0U,nullptr);
4162
4163 Reg =StringSwitch<unsigned long long>(Prefix)
4164 .Case("$msair", Mips::MSAIR)
4165 .Case("$msacsr", Mips::MSACSR)
4166 .Case("$msaaccess", Mips::MSAAccess)
4167 .Case("$msasave", Mips::MSASave)
4168 .Case("$msamodify", Mips::MSAModify)
4169 .Case("$msarequest", Mips::MSARequest)
4170 .Case("$msamap", Mips::MSAMap)
4171 .Case("$msaunmap", Mips::MSAUnmap)
4172 .Default(0);
4173
4174if (!Reg)
4175return std::make_pair(0U,nullptr);
4176
4177 RC =TRI->getRegClass(Mips::MSACtrlRegClassID);
4178return std::make_pair(Reg, RC);
4179 }
4180
4181if (!R.second)
4182return std::make_pair(0U,nullptr);
4183
4184if (Prefix =="$f") {// Parse $f0-$f31.
4185// If the size of FP registers is 64-bit or Reg is an even number, select
4186// the 64-bit register class. Otherwise, select the 32-bit register class.
4187if (VT == MVT::Other)
4188 VT = (Subtarget.isFP64bit() || !(Reg % 2)) ? MVT::f64 : MVT::f32;
4189
4190 RC =getRegClassFor(VT);
4191
4192if (RC == &Mips::AFGR64RegClass) {
4193assert(Reg % 2 == 0);
4194Reg >>= 1;
4195 }
4196 }elseif (Prefix =="$fcc")// Parse $fcc0-$fcc7.
4197 RC =TRI->getRegClass(Mips::FCCRegClassID);
4198elseif (Prefix =="$w") {// Parse $w0-$w31.
4199 RC =getRegClassFor((VT == MVT::Other) ? MVT::v16i8 : VT);
4200 }else {// Parse $0-$31.
4201assert(Prefix =="$");
4202 RC =getRegClassFor((VT == MVT::Other) ? MVT::i32 : VT);
4203 }
4204
4205assert(Reg < RC->getNumRegs());
4206return std::make_pair(*(RC->begin() + Reg), RC);
4207}
4208
4209/// Given a register class constraint, like 'r', if this corresponds directly
4210/// to an LLVM register class, return a register of 0 and the register class
4211/// pointer.
4212std::pair<unsigned, const TargetRegisterClass *>
4213MipsTargetLowering::getRegForInlineAsmConstraint(constTargetRegisterInfo *TRI,
4214StringRef Constraint,
4215MVT VT) const{
4216if (Constraint.size() == 1) {
4217switch (Constraint[0]) {
4218case'd':// Address register. Same as 'r' unless generating MIPS16 code.
4219case'y':// Same as 'r'. Exists for compatibility.
4220case'r':
4221if ((VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8 ||
4222 VT == MVT::i1) ||
4223 (VT == MVT::f32 &&Subtarget.useSoftFloat())) {
4224if (Subtarget.inMips16Mode())
4225return std::make_pair(0U, &Mips::CPU16RegsRegClass);
4226return std::make_pair(0U, &Mips::GPR32RegClass);
4227 }
4228if ((VT == MVT::i64 || (VT == MVT::f64 &&Subtarget.useSoftFloat())) &&
4229 !Subtarget.isGP64bit())
4230return std::make_pair(0U, &Mips::GPR32RegClass);
4231if ((VT == MVT::i64 || (VT == MVT::f64 &&Subtarget.useSoftFloat())) &&
4232Subtarget.isGP64bit())
4233return std::make_pair(0U, &Mips::GPR64RegClass);
4234// This will generate an error message
4235return std::make_pair(0U,nullptr);
4236case'f':// FPU or MSA register
4237if (VT == MVT::v16i8)
4238return std::make_pair(0U, &Mips::MSA128BRegClass);
4239elseif (VT == MVT::v8i16 || VT == MVT::v8f16)
4240return std::make_pair(0U, &Mips::MSA128HRegClass);
4241elseif (VT == MVT::v4i32 || VT == MVT::v4f32)
4242return std::make_pair(0U, &Mips::MSA128WRegClass);
4243elseif (VT == MVT::v2i64 || VT == MVT::v2f64)
4244return std::make_pair(0U, &Mips::MSA128DRegClass);
4245elseif (VT == MVT::f32)
4246return std::make_pair(0U, &Mips::FGR32RegClass);
4247elseif ((VT == MVT::f64) && (!Subtarget.isSingleFloat())) {
4248if (Subtarget.isFP64bit())
4249return std::make_pair(0U, &Mips::FGR64RegClass);
4250return std::make_pair(0U, &Mips::AFGR64RegClass);
4251 }
4252break;
4253case'c':// register suitable for indirect jump
4254if (VT == MVT::i32)
4255return std::make_pair((unsigned)Mips::T9, &Mips::GPR32RegClass);
4256if (VT == MVT::i64)
4257return std::make_pair((unsigned)Mips::T9_64, &Mips::GPR64RegClass);
4258// This will generate an error message
4259return std::make_pair(0U,nullptr);
4260case'l':// use the `lo` register to store values
4261// that are no bigger than a word
4262if (VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8)
4263return std::make_pair((unsigned)Mips::LO0, &Mips::LO32RegClass);
4264return std::make_pair((unsigned)Mips::LO0_64, &Mips::LO64RegClass);
4265case'x':// use the concatenated `hi` and `lo` registers
4266// to store doubleword values
4267// Fixme: Not triggering the use of both hi and low
4268// This will generate an error message
4269return std::make_pair(0U,nullptr);
4270 }
4271 }
4272
4273if (!Constraint.empty()) {
4274 std::pair<unsigned, const TargetRegisterClass *>R;
4275R = parseRegForInlineAsmConstraint(Constraint, VT);
4276
4277if (R.second)
4278returnR;
4279 }
4280
4281returnTargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
4282}
4283
4284/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
4285/// vector. If it is invalid, don't add anything to Ops.
4286void MipsTargetLowering::LowerAsmOperandForConstraint(SDValueOp,
4287StringRef Constraint,
4288 std::vector<SDValue> &Ops,
4289SelectionDAG &DAG) const{
4290SDLocDL(Op);
4291SDValueResult;
4292
4293// Only support length 1 constraints for now.
4294if (Constraint.size() > 1)
4295return;
4296
4297char ConstraintLetter = Constraint[0];
4298switch (ConstraintLetter) {
4299default:break;// This will fall through to the generic implementation
4300case'I':// Signed 16 bit constant
4301// If this fails, the parent routine will give an error
4302if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
4303EVTType =Op.getValueType();
4304 int64_t Val =C->getSExtValue();
4305if (isInt<16>(Val)) {
4306Result = DAG.getSignedTargetConstant(Val,DL,Type);
4307break;
4308 }
4309 }
4310return;
4311case'J':// integer zero
4312if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
4313EVTType =Op.getValueType();
4314 int64_t Val =C->getZExtValue();
4315if (Val == 0) {
4316Result = DAG.getTargetConstant(0,DL,Type);
4317break;
4318 }
4319 }
4320return;
4321case'K':// unsigned 16 bit immediate
4322if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
4323EVTType =Op.getValueType();
4324uint64_t Val = (uint64_t)C->getZExtValue();
4325if (isUInt<16>(Val)) {
4326Result = DAG.getTargetConstant(Val,DL,Type);
4327break;
4328 }
4329 }
4330return;
4331case'L':// signed 32 bit immediate where lower 16 bits are 0
4332if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
4333EVTType =Op.getValueType();
4334 int64_t Val =C->getSExtValue();
4335if ((isInt<32>(Val)) && ((Val & 0xffff) == 0)){
4336Result = DAG.getSignedTargetConstant(Val,DL,Type);
4337break;
4338 }
4339 }
4340return;
4341case'N':// immediate in the range of -65535 to -1 (inclusive)
4342if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
4343EVTType =Op.getValueType();
4344 int64_t Val =C->getSExtValue();
4345if ((Val >= -65535) && (Val <= -1)) {
4346Result = DAG.getSignedTargetConstant(Val,DL,Type);
4347break;
4348 }
4349 }
4350return;
4351case'O':// signed 15 bit immediate
4352if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
4353EVTType =Op.getValueType();
4354 int64_t Val =C->getSExtValue();
4355if ((isInt<15>(Val))) {
4356Result = DAG.getSignedTargetConstant(Val,DL,Type);
4357break;
4358 }
4359 }
4360return;
4361case'P':// immediate in the range of 1 to 65535 (inclusive)
4362if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
4363EVTType =Op.getValueType();
4364 int64_t Val =C->getSExtValue();
4365if ((Val <= 65535) && (Val >= 1)) {
4366Result = DAG.getTargetConstant(Val,DL,Type);
4367break;
4368 }
4369 }
4370return;
4371 }
4372
4373if (Result.getNode()) {
4374 Ops.push_back(Result);
4375return;
4376 }
4377
4378TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
4379}
4380
4381bool MipsTargetLowering::isLegalAddressingMode(constDataLayout &DL,
4382constAddrMode &AM,Type *Ty,
4383unsigned AS,
4384Instruction *I) const{
4385// No global is ever allowed as a base.
4386if (AM.BaseGV)
4387returnfalse;
4388
4389switch (AM.Scale) {
4390case 0:// "r+i" or just "i", depending on HasBaseReg.
4391break;
4392case 1:
4393if (!AM.HasBaseReg)// allow "r+i".
4394break;
4395returnfalse;// disallow "r+r" or "r+r+i".
4396default:
4397returnfalse;
4398 }
4399
4400returntrue;
4401}
4402
4403bool
4404MipsTargetLowering::isOffsetFoldingLegal(constGlobalAddressSDNode *GA) const{
4405// The Mips target isn't yet aware of offsets.
4406returnfalse;
4407}
4408
4409EVT MipsTargetLowering::getOptimalMemOpType(
4410constMemOp &Op,constAttributeList &FuncAttributes) const{
4411if (Subtarget.hasMips64())
4412return MVT::i64;
4413
4414return MVT::i32;
4415}
4416
4417bool MipsTargetLowering::isFPImmLegal(constAPFloat &Imm,EVT VT,
4418bool ForCodeSize) const{
4419if (VT != MVT::f32 && VT != MVT::f64)
4420returnfalse;
4421if (Imm.isNegZero())
4422returnfalse;
4423returnImm.isZero();
4424}
4425
4426unsigned MipsTargetLowering::getJumpTableEncoding() const{
4427
4428// FIXME: For space reasons this should be: EK_GPRel32BlockAddress.
4429if (ABI.IsN64() &&isPositionIndependent())
4430returnMachineJumpTableInfo::EK_GPRel64BlockAddress;
4431
4432returnTargetLowering::getJumpTableEncoding();
4433}
4434
4435bool MipsTargetLowering::useSoftFloat() const{
4436returnSubtarget.useSoftFloat();
4437}
4438
4439void MipsTargetLowering::copyByValRegs(
4440SDValue Chain,constSDLoc &DL, std::vector<SDValue> &OutChains,
4441SelectionDAG &DAG,constISD::ArgFlagsTy &Flags,
4442SmallVectorImpl<SDValue> &InVals,constArgument *FuncArg,
4443unsigned FirstReg,unsigned LastReg,constCCValAssign &VA,
4444MipsCCState &State) const{
4445MachineFunction &MF = DAG.getMachineFunction();
4446MachineFrameInfo &MFI = MF.getFrameInfo();
4447unsigned GPRSizeInBytes =Subtarget.getGPRSizeInBytes();
4448unsigned NumRegs = LastReg - FirstReg;
4449unsigned RegAreaSize = NumRegs * GPRSizeInBytes;
4450unsigned FrameObjSize = std::max(Flags.getByValSize(), RegAreaSize);
4451int FrameObjOffset;
4452ArrayRef<MCPhysReg> ByValArgRegs =ABI.GetByValArgRegs();
4453
4454if (RegAreaSize)
4455 FrameObjOffset =
4456 (int)ABI.GetCalleeAllocdArgSizeInBytes(State.getCallingConv()) -
4457 (int)((ByValArgRegs.size() - FirstReg) * GPRSizeInBytes);
4458else
4459 FrameObjOffset = VA.getLocMemOffset();
4460
4461// Create frame object.
4462EVT PtrTy =getPointerTy(DAG.getDataLayout());
4463// Make the fixed object stored to mutable so that the load instructions
4464// referencing it have their memory dependencies added.
4465// Set the frame object as isAliased which clears the underlying objects
4466// vector in ScheduleDAGInstrs::buildSchedGraph() resulting in addition of all
4467// stores as dependencies for loads referencing this fixed object.
4468int FI = MFI.CreateFixedObject(FrameObjSize, FrameObjOffset,false,true);
4469SDValue FIN = DAG.getFrameIndex(FI, PtrTy);
4470 InVals.push_back(FIN);
4471
4472if (!NumRegs)
4473return;
4474
4475// Copy arg registers.
4476MVT RegTy =MVT::getIntegerVT(GPRSizeInBytes * 8);
4477constTargetRegisterClass *RC =getRegClassFor(RegTy);
4478
4479for (unsignedI = 0;I < NumRegs; ++I) {
4480unsigned ArgReg = ByValArgRegs[FirstReg +I];
4481unsigned VReg =addLiveIn(MF, ArgReg, RC);
4482unsignedOffset =I * GPRSizeInBytes;
4483SDValue StorePtr = DAG.getNode(ISD::ADD,DL, PtrTy, FIN,
4484 DAG.getConstant(Offset,DL, PtrTy));
4485SDValueStore = DAG.getStore(Chain,DL, DAG.getRegister(VReg, RegTy),
4486 StorePtr,MachinePointerInfo(FuncArg,Offset));
4487 OutChains.push_back(Store);
4488 }
4489}
4490
4491// Copy byVal arg to registers and stack.
4492void MipsTargetLowering::passByValArg(
4493SDValue Chain,constSDLoc &DL,
4494 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
4495SmallVectorImpl<SDValue> &MemOpChains,SDValue StackPtr,
4496MachineFrameInfo &MFI,SelectionDAG &DAG,SDValue Arg,unsigned FirstReg,
4497unsigned LastReg,constISD::ArgFlagsTy &Flags,bool isLittle,
4498constCCValAssign &VA) const{
4499unsigned ByValSizeInBytes =Flags.getByValSize();
4500unsigned OffsetInBytes = 0;// From beginning of struct
4501unsigned RegSizeInBytes =Subtarget.getGPRSizeInBytes();
4502Align Alignment =
4503 std::min(Flags.getNonZeroByValAlign(),Align(RegSizeInBytes));
4504EVT PtrTy =getPointerTy(DAG.getDataLayout()),
4505 RegTy =MVT::getIntegerVT(RegSizeInBytes * 8);
4506unsigned NumRegs = LastReg - FirstReg;
4507
4508if (NumRegs) {
4509ArrayRef<MCPhysReg> ArgRegs =ABI.GetByValArgRegs();
4510bool LeftoverBytes = (NumRegs * RegSizeInBytes > ByValSizeInBytes);
4511unsignedI = 0;
4512
4513// Copy words to registers.
4514for (;I < NumRegs - LeftoverBytes; ++I, OffsetInBytes += RegSizeInBytes) {
4515SDValue LoadPtr = DAG.getNode(ISD::ADD,DL, PtrTy, Arg,
4516 DAG.getConstant(OffsetInBytes,DL, PtrTy));
4517SDValue LoadVal = DAG.getLoad(RegTy,DL, Chain, LoadPtr,
4518MachinePointerInfo(), Alignment);
4519 MemOpChains.push_back(LoadVal.getValue(1));
4520unsigned ArgReg = ArgRegs[FirstReg +I];
4521 RegsToPass.push_back(std::make_pair(ArgReg, LoadVal));
4522 }
4523
4524// Return if the struct has been fully copied.
4525if (ByValSizeInBytes == OffsetInBytes)
4526return;
4527
4528// Copy the remainder of the byval argument with sub-word loads and shifts.
4529if (LeftoverBytes) {
4530SDValue Val;
4531
4532for (unsigned LoadSizeInBytes = RegSizeInBytes / 2, TotalBytesLoaded = 0;
4533 OffsetInBytes < ByValSizeInBytes; LoadSizeInBytes /= 2) {
4534unsigned RemainingSizeInBytes = ByValSizeInBytes - OffsetInBytes;
4535
4536if (RemainingSizeInBytes < LoadSizeInBytes)
4537continue;
4538
4539// Load subword.
4540SDValue LoadPtr = DAG.getNode(ISD::ADD,DL, PtrTy, Arg,
4541 DAG.getConstant(OffsetInBytes,DL,
4542 PtrTy));
4543SDValue LoadVal = DAG.getExtLoad(
4544ISD::ZEXTLOAD,DL, RegTy, Chain, LoadPtr,MachinePointerInfo(),
4545MVT::getIntegerVT(LoadSizeInBytes * 8), Alignment);
4546 MemOpChains.push_back(LoadVal.getValue(1));
4547
4548// Shift the loaded value.
4549unsigned Shamt;
4550
4551if (isLittle)
4552 Shamt = TotalBytesLoaded * 8;
4553else
4554 Shamt = (RegSizeInBytes - (TotalBytesLoaded + LoadSizeInBytes)) * 8;
4555
4556SDValue Shift = DAG.getNode(ISD::SHL,DL, RegTy, LoadVal,
4557 DAG.getConstant(Shamt,DL, MVT::i32));
4558
4559if (Val.getNode())
4560 Val = DAG.getNode(ISD::OR,DL, RegTy, Val, Shift);
4561else
4562 Val = Shift;
4563
4564 OffsetInBytes += LoadSizeInBytes;
4565 TotalBytesLoaded += LoadSizeInBytes;
4566 Alignment = std::min(Alignment,Align(LoadSizeInBytes));
4567 }
4568
4569unsigned ArgReg = ArgRegs[FirstReg +I];
4570 RegsToPass.push_back(std::make_pair(ArgReg, Val));
4571return;
4572 }
4573 }
4574
4575// Copy remainder of byval arg to it with memcpy.
4576unsigned MemCpySize = ByValSizeInBytes - OffsetInBytes;
4577SDValue Src = DAG.getNode(ISD::ADD,DL, PtrTy, Arg,
4578 DAG.getConstant(OffsetInBytes,DL, PtrTy));
4579SDValue Dst = DAG.getNode(ISD::ADD,DL, PtrTy, StackPtr,
4580 DAG.getIntPtrConstant(VA.getLocMemOffset(),DL));
4581 Chain = DAG.getMemcpy(
4582 Chain,DL, Dst, Src, DAG.getConstant(MemCpySize,DL, PtrTy),
4583Align(Alignment),/*isVolatile=*/false,/*AlwaysInline=*/false,
4584/*CI=*/nullptr, std::nullopt,MachinePointerInfo(),MachinePointerInfo());
4585 MemOpChains.push_back(Chain);
4586}
4587
4588void MipsTargetLowering::writeVarArgRegs(std::vector<SDValue> &OutChains,
4589SDValue Chain,constSDLoc &DL,
4590SelectionDAG &DAG,
4591CCState &State) const{
4592ArrayRef<MCPhysReg> ArgRegs =ABI.GetVarArgRegs();
4593unsignedIdx = State.getFirstUnallocated(ArgRegs);
4594unsigned RegSizeInBytes =Subtarget.getGPRSizeInBytes();
4595MVT RegTy =MVT::getIntegerVT(RegSizeInBytes * 8);
4596constTargetRegisterClass *RC =getRegClassFor(RegTy);
4597MachineFunction &MF = DAG.getMachineFunction();
4598MachineFrameInfo &MFI = MF.getFrameInfo();
4599MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
4600
4601// Offset of the first variable argument from stack pointer.
4602int VaArgOffset;
4603
4604if (ArgRegs.size() ==Idx)
4605 VaArgOffset =alignTo(State.getStackSize(), RegSizeInBytes);
4606else {
4607 VaArgOffset =
4608 (int)ABI.GetCalleeAllocdArgSizeInBytes(State.getCallingConv()) -
4609 (int)(RegSizeInBytes * (ArgRegs.size() -Idx));
4610 }
4611
4612// Record the frame index of the first variable argument
4613// which is a value necessary to VASTART.
4614int FI = MFI.CreateFixedObject(RegSizeInBytes, VaArgOffset,true);
4615 MipsFI->setVarArgsFrameIndex(FI);
4616
4617// Copy the integer registers that have not been used for argument passing
4618// to the argument register save area. For O32, the save area is allocated
4619// in the caller's stack frame, while for N32/64, it is allocated in the
4620// callee's stack frame.
4621for (unsignedI =Idx;I < ArgRegs.size();
4622 ++I, VaArgOffset += RegSizeInBytes) {
4623unsignedReg =addLiveIn(MF, ArgRegs[I], RC);
4624SDValue ArgValue = DAG.getCopyFromReg(Chain,DL, Reg, RegTy);
4625 FI = MFI.CreateFixedObject(RegSizeInBytes, VaArgOffset,true);
4626SDValue PtrOff = DAG.getFrameIndex(FI,getPointerTy(DAG.getDataLayout()));
4627SDValueStore =
4628 DAG.getStore(Chain,DL, ArgValue, PtrOff,MachinePointerInfo());
4629 cast<StoreSDNode>(Store.getNode())->getMemOperand()->setValue(
4630 (Value *)nullptr);
4631 OutChains.push_back(Store);
4632 }
4633}
4634
4635voidMipsTargetLowering::HandleByVal(CCState *State,unsigned &Size,
4636Align Alignment) const{
4637constTargetFrameLowering *TFL =Subtarget.getFrameLowering();
4638
4639assert(Size &&"Byval argument's size shouldn't be 0.");
4640
4641 Alignment = std::min(Alignment, TFL->getStackAlign());
4642
4643unsigned FirstReg = 0;
4644unsigned NumRegs = 0;
4645
4646if (State->getCallingConv() !=CallingConv::Fast) {
4647unsigned RegSizeInBytes =Subtarget.getGPRSizeInBytes();
4648ArrayRef<MCPhysReg> IntArgRegs =ABI.GetByValArgRegs();
4649// FIXME: The O32 case actually describes no shadow registers.
4650constMCPhysReg *ShadowRegs =
4651ABI.IsO32() ? IntArgRegs.data() :Mips64DPRegs;
4652
4653// We used to check the size as well but we can't do that anymore since
4654// CCState::HandleByVal() rounds up the size after calling this function.
4655assert(
4656 Alignment >=Align(RegSizeInBytes) &&
4657"Byval argument's alignment should be a multiple of RegSizeInBytes.");
4658
4659 FirstReg = State->getFirstUnallocated(IntArgRegs);
4660
4661// If Alignment > RegSizeInBytes, the first arg register must be even.
4662// FIXME: This condition happens to do the right thing but it's not the
4663// right way to test it. We want to check that the stack frame offset
4664// of the register is aligned.
4665if ((Alignment > RegSizeInBytes) && (FirstReg % 2)) {
4666 State->AllocateReg(IntArgRegs[FirstReg], ShadowRegs[FirstReg]);
4667 ++FirstReg;
4668 }
4669
4670// Mark the registers allocated.
4671Size =alignTo(Size, RegSizeInBytes);
4672for (unsignedI = FirstReg;Size > 0 && (I < IntArgRegs.size());
4673Size -= RegSizeInBytes, ++I, ++NumRegs)
4674 State->AllocateReg(IntArgRegs[I], ShadowRegs[I]);
4675 }
4676
4677 State->addInRegsParamInfo(FirstReg, FirstReg + NumRegs);
4678}
4679
4680MachineBasicBlock *MipsTargetLowering::emitPseudoSELECT(MachineInstr &MI,
4681MachineBasicBlock *BB,
4682bool isFPCmp,
4683unsigned Opc) const{
4684assert(!(Subtarget.hasMips4() ||Subtarget.hasMips32()) &&
4685"Subtarget already supports SELECT nodes with the use of"
4686"conditional-move instructions.");
4687
4688constTargetInstrInfo *TII =
4689Subtarget.getInstrInfo();
4690DebugLocDL =MI.getDebugLoc();
4691
4692// To "insert" a SELECT instruction, we actually have to insert the
4693// diamond control-flow pattern. The incoming instruction knows the
4694// destination vreg to set, the condition code register to branch on, the
4695// true/false values to select between, and a branch opcode to use.
4696constBasicBlock *LLVM_BB = BB->getBasicBlock();
4697MachineFunction::iterator It = ++BB->getIterator();
4698
4699// thisMBB:
4700// ...
4701// TrueVal = ...
4702// setcc r1, r2, r3
4703// bNE r1, r0, copy1MBB
4704// fallthrough --> copy0MBB
4705MachineBasicBlock *thisMBB = BB;
4706MachineFunction *F = BB->getParent();
4707MachineBasicBlock *copy0MBB =F->CreateMachineBasicBlock(LLVM_BB);
4708MachineBasicBlock *sinkMBB =F->CreateMachineBasicBlock(LLVM_BB);
4709F->insert(It, copy0MBB);
4710F->insert(It, sinkMBB);
4711
4712// Transfer the remainder of BB and its successor edges to sinkMBB.
4713 sinkMBB->splice(sinkMBB->begin(), BB,
4714 std::next(MachineBasicBlock::iterator(MI)), BB->end());
4715 sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
4716
4717// Next, add the true and fallthrough blocks as its successors.
4718 BB->addSuccessor(copy0MBB);
4719 BB->addSuccessor(sinkMBB);
4720
4721if (isFPCmp) {
4722// bc1[tf] cc, sinkMBB
4723BuildMI(BB,DL,TII->get(Opc))
4724 .addReg(MI.getOperand(1).getReg())
4725 .addMBB(sinkMBB);
4726 }else {
4727// bne rs, $0, sinkMBB
4728BuildMI(BB,DL,TII->get(Opc))
4729 .addReg(MI.getOperand(1).getReg())
4730 .addReg(Mips::ZERO)
4731 .addMBB(sinkMBB);
4732 }
4733
4734// copy0MBB:
4735// %FalseValue = ...
4736// # fallthrough to sinkMBB
4737 BB = copy0MBB;
4738
4739// Update machine-CFG edges
4740 BB->addSuccessor(sinkMBB);
4741
4742// sinkMBB:
4743// %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
4744// ...
4745 BB = sinkMBB;
4746
4747BuildMI(*BB, BB->begin(),DL,TII->get(Mips::PHI),MI.getOperand(0).getReg())
4748 .addReg(MI.getOperand(2).getReg())
4749 .addMBB(thisMBB)
4750 .addReg(MI.getOperand(3).getReg())
4751 .addMBB(copy0MBB);
4752
4753MI.eraseFromParent();// The pseudo instruction is gone now.
4754
4755return BB;
4756}
4757
4758MachineBasicBlock *
4759MipsTargetLowering::emitPseudoD_SELECT(MachineInstr &MI,
4760MachineBasicBlock *BB) const{
4761assert(!(Subtarget.hasMips4() ||Subtarget.hasMips32()) &&
4762"Subtarget already supports SELECT nodes with the use of"
4763"conditional-move instructions.");
4764
4765constTargetInstrInfo *TII =Subtarget.getInstrInfo();
4766DebugLocDL =MI.getDebugLoc();
4767
4768// D_SELECT substitutes two SELECT nodes that goes one after another and
4769// have the same condition operand. On machines which don't have
4770// conditional-move instruction, it reduces unnecessary branch instructions
4771// which are result of using two diamond patterns that are result of two
4772// SELECT pseudo instructions.
4773constBasicBlock *LLVM_BB = BB->getBasicBlock();
4774MachineFunction::iterator It = ++BB->getIterator();
4775
4776// thisMBB:
4777// ...
4778// TrueVal = ...
4779// setcc r1, r2, r3
4780// bNE r1, r0, copy1MBB
4781// fallthrough --> copy0MBB
4782MachineBasicBlock *thisMBB = BB;
4783MachineFunction *F = BB->getParent();
4784MachineBasicBlock *copy0MBB =F->CreateMachineBasicBlock(LLVM_BB);
4785MachineBasicBlock *sinkMBB =F->CreateMachineBasicBlock(LLVM_BB);
4786F->insert(It, copy0MBB);
4787F->insert(It, sinkMBB);
4788
4789// Transfer the remainder of BB and its successor edges to sinkMBB.
4790 sinkMBB->splice(sinkMBB->begin(), BB,
4791 std::next(MachineBasicBlock::iterator(MI)), BB->end());
4792 sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
4793
4794// Next, add the true and fallthrough blocks as its successors.
4795 BB->addSuccessor(copy0MBB);
4796 BB->addSuccessor(sinkMBB);
4797
4798// bne rs, $0, sinkMBB
4799BuildMI(BB,DL,TII->get(Mips::BNE))
4800 .addReg(MI.getOperand(2).getReg())
4801 .addReg(Mips::ZERO)
4802 .addMBB(sinkMBB);
4803
4804// copy0MBB:
4805// %FalseValue = ...
4806// # fallthrough to sinkMBB
4807 BB = copy0MBB;
4808
4809// Update machine-CFG edges
4810 BB->addSuccessor(sinkMBB);
4811
4812// sinkMBB:
4813// %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
4814// ...
4815 BB = sinkMBB;
4816
4817// Use two PHI nodes to select two reults
4818BuildMI(*BB, BB->begin(),DL,TII->get(Mips::PHI),MI.getOperand(0).getReg())
4819 .addReg(MI.getOperand(3).getReg())
4820 .addMBB(thisMBB)
4821 .addReg(MI.getOperand(5).getReg())
4822 .addMBB(copy0MBB);
4823BuildMI(*BB, BB->begin(),DL,TII->get(Mips::PHI),MI.getOperand(1).getReg())
4824 .addReg(MI.getOperand(4).getReg())
4825 .addMBB(thisMBB)
4826 .addReg(MI.getOperand(6).getReg())
4827 .addMBB(copy0MBB);
4828
4829MI.eraseFromParent();// The pseudo instruction is gone now.
4830
4831return BB;
4832}
4833
4834// FIXME? Maybe this could be a TableGen attribute on some registers and
4835// this table could be generated automatically from RegInfo.
4836Register
4837MipsTargetLowering::getRegisterByName(constchar *RegName,LLT VT,
4838constMachineFunction &MF) const{
4839// The Linux kernel uses $28 and sp.
4840if (Subtarget.isGP64bit()) {
4841Register Reg =StringSwitch<Register>(RegName)
4842 .Case("$28", Mips::GP_64)
4843 .Case("sp", Mips::SP_64)
4844 .Default(Register());
4845if (Reg)
4846return Reg;
4847 }else {
4848Register Reg =StringSwitch<Register>(RegName)
4849 .Case("$28", Mips::GP)
4850 .Case("sp", Mips::SP)
4851 .Default(Register());
4852if (Reg)
4853return Reg;
4854 }
4855report_fatal_error("Invalid register name global variable");
4856}
4857
4858MachineBasicBlock *MipsTargetLowering::emitLDR_W(MachineInstr &MI,
4859MachineBasicBlock *BB) const{
4860MachineFunction *MF = BB->getParent();
4861MachineRegisterInfo &MRI = MF->getRegInfo();
4862constTargetInstrInfo *TII =Subtarget.getInstrInfo();
4863constbool IsLittle =Subtarget.isLittle();
4864DebugLocDL =MI.getDebugLoc();
4865
4866Register Dest =MI.getOperand(0).getReg();
4867RegisterAddress =MI.getOperand(1).getReg();
4868unsigned Imm =MI.getOperand(2).getImm();
4869
4870MachineBasicBlock::iteratorI(MI);
4871
4872if (Subtarget.hasMips32r6() ||Subtarget.hasMips64r6()) {
4873// Mips release 6 can load from adress that is not naturally-aligned.
4874Register Temp =MRI.createVirtualRegister(&Mips::GPR32RegClass);
4875BuildMI(*BB,I,DL,TII->get(Mips::LW))
4876 .addDef(Temp)
4877 .addUse(Address)
4878 .addImm(Imm);
4879BuildMI(*BB,I,DL,TII->get(Mips::FILL_W)).addDef(Dest).addUse(Temp);
4880 }else {
4881// Mips release 5 needs to use instructions that can load from an unaligned
4882// memory address.
4883Register LoadHalf =MRI.createVirtualRegister(&Mips::GPR32RegClass);
4884Register LoadFull =MRI.createVirtualRegister(&Mips::GPR32RegClass);
4885Register Undef =MRI.createVirtualRegister(&Mips::GPR32RegClass);
4886BuildMI(*BB,I,DL,TII->get(Mips::IMPLICIT_DEF)).addDef(Undef);
4887BuildMI(*BB,I,DL,TII->get(Mips::LWR))
4888 .addDef(LoadHalf)
4889 .addUse(Address)
4890 .addImm(Imm + (IsLittle ? 0 : 3))
4891 .addUse(Undef);
4892BuildMI(*BB,I,DL,TII->get(Mips::LWL))
4893 .addDef(LoadFull)
4894 .addUse(Address)
4895 .addImm(Imm + (IsLittle ? 3 : 0))
4896 .addUse(LoadHalf);
4897BuildMI(*BB,I,DL,TII->get(Mips::FILL_W)).addDef(Dest).addUse(LoadFull);
4898 }
4899
4900MI.eraseFromParent();
4901return BB;
4902}
4903
4904MachineBasicBlock *MipsTargetLowering::emitLDR_D(MachineInstr &MI,
4905MachineBasicBlock *BB) const{
4906MachineFunction *MF = BB->getParent();
4907MachineRegisterInfo &MRI = MF->getRegInfo();
4908constTargetInstrInfo *TII =Subtarget.getInstrInfo();
4909constbool IsLittle =Subtarget.isLittle();
4910DebugLocDL =MI.getDebugLoc();
4911
4912Register Dest =MI.getOperand(0).getReg();
4913RegisterAddress =MI.getOperand(1).getReg();
4914unsignedImm =MI.getOperand(2).getImm();
4915
4916MachineBasicBlock::iteratorI(MI);
4917
4918if (Subtarget.hasMips32r6() ||Subtarget.hasMips64r6()) {
4919// Mips release 6 can load from adress that is not naturally-aligned.
4920if (Subtarget.isGP64bit()) {
4921Register Temp =MRI.createVirtualRegister(&Mips::GPR64RegClass);
4922BuildMI(*BB,I,DL,TII->get(Mips::LD))
4923 .addDef(Temp)
4924 .addUse(Address)
4925 .addImm(Imm);
4926BuildMI(*BB,I,DL,TII->get(Mips::FILL_D)).addDef(Dest).addUse(Temp);
4927 }else {
4928Register Wtemp =MRI.createVirtualRegister(&Mips::MSA128WRegClass);
4929RegisterLo =MRI.createVirtualRegister(&Mips::GPR32RegClass);
4930RegisterHi =MRI.createVirtualRegister(&Mips::GPR32RegClass);
4931BuildMI(*BB,I,DL,TII->get(Mips::LW))
4932 .addDef(Lo)
4933 .addUse(Address)
4934 .addImm(Imm + (IsLittle ? 0 : 4));
4935BuildMI(*BB,I,DL,TII->get(Mips::LW))
4936 .addDef(Hi)
4937 .addUse(Address)
4938 .addImm(Imm + (IsLittle ? 4 : 0));
4939BuildMI(*BB,I,DL,TII->get(Mips::FILL_W)).addDef(Wtemp).addUse(Lo);
4940BuildMI(*BB,I,DL,TII->get(Mips::INSERT_W), Dest)
4941 .addUse(Wtemp)
4942 .addUse(Hi)
4943 .addImm(1);
4944 }
4945 }else {
4946// Mips release 5 needs to use instructions that can load from an unaligned
4947// memory address.
4948Register LoHalf =MRI.createVirtualRegister(&Mips::GPR32RegClass);
4949Register LoFull =MRI.createVirtualRegister(&Mips::GPR32RegClass);
4950Register LoUndef =MRI.createVirtualRegister(&Mips::GPR32RegClass);
4951Register HiHalf =MRI.createVirtualRegister(&Mips::GPR32RegClass);
4952Register HiFull =MRI.createVirtualRegister(&Mips::GPR32RegClass);
4953Register HiUndef =MRI.createVirtualRegister(&Mips::GPR32RegClass);
4954Register Wtemp =MRI.createVirtualRegister(&Mips::MSA128WRegClass);
4955BuildMI(*BB,I,DL,TII->get(Mips::IMPLICIT_DEF)).addDef(LoUndef);
4956BuildMI(*BB,I,DL,TII->get(Mips::LWR))
4957 .addDef(LoHalf)
4958 .addUse(Address)
4959 .addImm(Imm + (IsLittle ? 0 : 7))
4960 .addUse(LoUndef);
4961BuildMI(*BB,I,DL,TII->get(Mips::LWL))
4962 .addDef(LoFull)
4963 .addUse(Address)
4964 .addImm(Imm + (IsLittle ? 3 : 4))
4965 .addUse(LoHalf);
4966BuildMI(*BB,I,DL,TII->get(Mips::IMPLICIT_DEF)).addDef(HiUndef);
4967BuildMI(*BB,I,DL,TII->get(Mips::LWR))
4968 .addDef(HiHalf)
4969 .addUse(Address)
4970 .addImm(Imm + (IsLittle ? 4 : 3))
4971 .addUse(HiUndef);
4972BuildMI(*BB,I,DL,TII->get(Mips::LWL))
4973 .addDef(HiFull)
4974 .addUse(Address)
4975 .addImm(Imm + (IsLittle ? 7 : 0))
4976 .addUse(HiHalf);
4977BuildMI(*BB,I,DL,TII->get(Mips::FILL_W)).addDef(Wtemp).addUse(LoFull);
4978BuildMI(*BB,I,DL,TII->get(Mips::INSERT_W), Dest)
4979 .addUse(Wtemp)
4980 .addUse(HiFull)
4981 .addImm(1);
4982 }
4983
4984MI.eraseFromParent();
4985return BB;
4986}
4987
4988MachineBasicBlock *MipsTargetLowering::emitSTR_W(MachineInstr &MI,
4989MachineBasicBlock *BB) const{
4990MachineFunction *MF = BB->getParent();
4991MachineRegisterInfo &MRI = MF->getRegInfo();
4992constTargetInstrInfo *TII =Subtarget.getInstrInfo();
4993constbool IsLittle =Subtarget.isLittle();
4994DebugLocDL =MI.getDebugLoc();
4995
4996Register StoreVal =MI.getOperand(0).getReg();
4997RegisterAddress =MI.getOperand(1).getReg();
4998unsignedImm =MI.getOperand(2).getImm();
4999
5000MachineBasicBlock::iteratorI(MI);
5001
5002if (Subtarget.hasMips32r6() ||Subtarget.hasMips64r6()) {
5003// Mips release 6 can store to adress that is not naturally-aligned.
5004Register BitcastW =MRI.createVirtualRegister(&Mips::MSA128WRegClass);
5005Register Tmp =MRI.createVirtualRegister(&Mips::GPR32RegClass);
5006BuildMI(*BB,I,DL,TII->get(Mips::COPY)).addDef(BitcastW).addUse(StoreVal);
5007BuildMI(*BB,I,DL,TII->get(Mips::COPY_S_W))
5008 .addDef(Tmp)
5009 .addUse(BitcastW)
5010 .addImm(0);
5011BuildMI(*BB,I,DL,TII->get(Mips::SW))
5012 .addUse(Tmp)
5013 .addUse(Address)
5014 .addImm(Imm);
5015 }else {
5016// Mips release 5 needs to use instructions that can store to an unaligned
5017// memory address.
5018Register Tmp =MRI.createVirtualRegister(&Mips::GPR32RegClass);
5019BuildMI(*BB,I,DL,TII->get(Mips::COPY_S_W))
5020 .addDef(Tmp)
5021 .addUse(StoreVal)
5022 .addImm(0);
5023BuildMI(*BB,I,DL,TII->get(Mips::SWR))
5024 .addUse(Tmp)
5025 .addUse(Address)
5026 .addImm(Imm + (IsLittle ? 0 : 3));
5027BuildMI(*BB,I,DL,TII->get(Mips::SWL))
5028 .addUse(Tmp)
5029 .addUse(Address)
5030 .addImm(Imm + (IsLittle ? 3 : 0));
5031 }
5032
5033MI.eraseFromParent();
5034
5035return BB;
5036}
5037
5038MachineBasicBlock *MipsTargetLowering::emitSTR_D(MachineInstr &MI,
5039MachineBasicBlock *BB) const{
5040MachineFunction *MF = BB->getParent();
5041MachineRegisterInfo &MRI = MF->getRegInfo();
5042constTargetInstrInfo *TII =Subtarget.getInstrInfo();
5043constbool IsLittle =Subtarget.isLittle();
5044DebugLocDL =MI.getDebugLoc();
5045
5046Register StoreVal =MI.getOperand(0).getReg();
5047RegisterAddress =MI.getOperand(1).getReg();
5048unsignedImm =MI.getOperand(2).getImm();
5049
5050MachineBasicBlock::iteratorI(MI);
5051
5052if (Subtarget.hasMips32r6() ||Subtarget.hasMips64r6()) {
5053// Mips release 6 can store to adress that is not naturally-aligned.
5054if (Subtarget.isGP64bit()) {
5055Register BitcastD =MRI.createVirtualRegister(&Mips::MSA128DRegClass);
5056RegisterLo =MRI.createVirtualRegister(&Mips::GPR64RegClass);
5057BuildMI(*BB,I,DL,TII->get(Mips::COPY))
5058 .addDef(BitcastD)
5059 .addUse(StoreVal);
5060BuildMI(*BB,I,DL,TII->get(Mips::COPY_S_D))
5061 .addDef(Lo)
5062 .addUse(BitcastD)
5063 .addImm(0);
5064BuildMI(*BB,I,DL,TII->get(Mips::SD))
5065 .addUse(Lo)
5066 .addUse(Address)
5067 .addImm(Imm);
5068 }else {
5069Register BitcastW =MRI.createVirtualRegister(&Mips::MSA128WRegClass);
5070RegisterLo =MRI.createVirtualRegister(&Mips::GPR32RegClass);
5071RegisterHi =MRI.createVirtualRegister(&Mips::GPR32RegClass);
5072BuildMI(*BB,I,DL,TII->get(Mips::COPY))
5073 .addDef(BitcastW)
5074 .addUse(StoreVal);
5075BuildMI(*BB,I,DL,TII->get(Mips::COPY_S_W))
5076 .addDef(Lo)
5077 .addUse(BitcastW)
5078 .addImm(0);
5079BuildMI(*BB,I,DL,TII->get(Mips::COPY_S_W))
5080 .addDef(Hi)
5081 .addUse(BitcastW)
5082 .addImm(1);
5083BuildMI(*BB,I,DL,TII->get(Mips::SW))
5084 .addUse(Lo)
5085 .addUse(Address)
5086 .addImm(Imm + (IsLittle ? 0 : 4));
5087BuildMI(*BB,I,DL,TII->get(Mips::SW))
5088 .addUse(Hi)
5089 .addUse(Address)
5090 .addImm(Imm + (IsLittle ? 4 : 0));
5091 }
5092 }else {
5093// Mips release 5 needs to use instructions that can store to an unaligned
5094// memory address.
5095RegisterBitcast =MRI.createVirtualRegister(&Mips::MSA128WRegClass);
5096RegisterLo =MRI.createVirtualRegister(&Mips::GPR32RegClass);
5097RegisterHi =MRI.createVirtualRegister(&Mips::GPR32RegClass);
5098BuildMI(*BB,I,DL,TII->get(Mips::COPY)).addDef(Bitcast).addUse(StoreVal);
5099BuildMI(*BB,I,DL,TII->get(Mips::COPY_S_W))
5100 .addDef(Lo)
5101 .addUse(Bitcast)
5102 .addImm(0);
5103BuildMI(*BB,I,DL,TII->get(Mips::COPY_S_W))
5104 .addDef(Hi)
5105 .addUse(Bitcast)
5106 .addImm(1);
5107BuildMI(*BB,I,DL,TII->get(Mips::SWR))
5108 .addUse(Lo)
5109 .addUse(Address)
5110 .addImm(Imm + (IsLittle ? 0 : 3));
5111BuildMI(*BB,I,DL,TII->get(Mips::SWL))
5112 .addUse(Lo)
5113 .addUse(Address)
5114 .addImm(Imm + (IsLittle ? 3 : 0));
5115BuildMI(*BB,I,DL,TII->get(Mips::SWR))
5116 .addUse(Hi)
5117 .addUse(Address)
5118 .addImm(Imm + (IsLittle ? 4 : 7));
5119BuildMI(*BB,I,DL,TII->get(Mips::SWL))
5120 .addUse(Hi)
5121 .addUse(Address)
5122 .addImm(Imm + (IsLittle ? 7 : 4));
5123 }
5124
5125MI.eraseFromParent();
5126return BB;
5127}
MRI
unsigned const MachineRegisterInfo * MRI
Definition:AArch64AdvSIMDScalarPass.cpp:105
performSHLCombine
static SDValue performSHLCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, SelectionDAG &DAG)
If the operand is a bitwise AND with a constant RHS, and the shift has a constant RHS and is the only...
Definition:AArch64ISelLowering.cpp:26350
performORCombine
static SDValue performORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const AArch64Subtarget *Subtarget, const AArch64TargetLowering &TLI)
Definition:AArch64ISelLowering.cpp:19359
performANDCombine
static SDValue performANDCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
Definition:AArch64ISelLowering.cpp:19567
APFloat.h
This file declares a class to represent arbitrary precision floating point values and provide a varie...
MBB
MachineBasicBlock & MBB
Definition:ARMSLSHardening.cpp:71
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition:ARMSLSHardening.cpp:73
Results
Function Alias Analysis Results
Definition:AliasAnalysis.cpp:731
ArrayRef.h
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
CallingConvLower.h
CallingConv.h
Casting.h
CodeGen.h
CommandLine.h
Compiler.h
LLVM_ATTRIBUTE_UNUSED
#define LLVM_ATTRIBUTE_UNUSED
Definition:Compiler.h:282
Constants.h
This file contains the declarations for the subclasses of Constant, which represent the different fla...
DataLayout.h
RetTy
return RetTy
Definition:DeadArgumentElimination.cpp:361
Idx
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Definition:DeadArgumentElimination.cpp:353
DebugLoc.h
LLVM_DEBUG
#define LLVM_DEBUG(...)
Definition:Debug.h:106
DerivedTypes.h
Size
uint64_t Size
Definition:ELFObjHandler.cpp:81
Sym
Symbol * Sym
Definition:ELF_riscv.cpp:479
X
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
FunctionLoweringInfo.h
GlobalValue.h
TII
const HexagonInstrInfo * TII
Definition:HexagonCopyToCombine.cpp:125
MI
IRTranslator LLVM IR MI
Definition:IRTranslator.cpp:112
Function.h
Module.h
Module.h This file contains the declarations for the Module class.
Type.h
Value.h
ISDOpcodes.h
RegName
#define RegName(no)
Options
static LVOptions Options
Definition:LVOptions.cpp:25
info
lazy value info
Definition:LazyValueInfo.cpp:61
insertDivByZeroTrap
static MachineBasicBlock * insertDivByZeroTrap(MachineInstr &MI, MachineBasicBlock *MBB)
Definition:LoongArchISelLowering.cpp:4418
MCContext.h
F
#define F(x, y, z)
Definition:MD5.cpp:55
I
#define I(x, y, z)
Definition:MD5.cpp:58
G
#define G(x, y, z)
Definition:MD5.cpp:56
AddrMode
AddrMode
Definition:MSP430Disassembler.cpp:141
MachineBasicBlock.h
MachineFrameInfo.h
MachineFunction.h
MachineInstrBuilder.h
MachineInstr.h
MachineJumpTableInfo.h
MachineMemOperand.h
MachineOperand.h
MachineRegisterInfo.h
TRI
unsigned const TargetRegisterInfo * TRI
Definition:MachineSink.cpp:2029
MachineValueType.h
MathExtras.h
EmitJalrReloc
cl::opt< bool > EmitJalrReloc
MipsBaseInfo.h
MipsCCState.h
CC_MipsO32_FP64
static bool CC_MipsO32_FP64(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
Definition:MipsFastISel.cpp:277
CC_Mips
static bool CC_Mips(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State) LLVM_ATTRIBUTE_UNUSED
CC_MipsO32_FP32
static bool CC_MipsO32_FP32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
Definition:MipsFastISel.cpp:271
CC_MipsO32
static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State, ArrayRef< MCPhysReg > F64Regs)
Definition:MipsISelLowering.cpp:2957
performMADD_MSUBCombine
static SDValue performMADD_MSUBCombine(SDNode *ROOTNode, SelectionDAG &CurDAG, const MipsSubtarget &Subtarget)
Definition:MipsISelLowering.cpp:1019
invertFPCondCodeUser
static bool invertFPCondCodeUser(Mips::CondCode CC)
This function returns true if the floating point conditional branches and conditional moves which use...
Definition:MipsISelLowering.cpp:643
lowerFP_TO_SINT_STORE
static SDValue lowerFP_TO_SINT_STORE(StoreSDNode *SD, SelectionDAG &DAG, bool SingleFloat)
Definition:MipsISelLowering.cpp:2882
performDivRemCombine
static SDValue performDivRemCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)
Definition:MipsISelLowering.cpp:578
Mips64DPRegs
static const MCPhysReg Mips64DPRegs[8]
Definition:MipsISelLowering.cpp:91
lowerUnalignedIntStore
static SDValue lowerUnalignedIntStore(StoreSDNode *SD, SelectionDAG &DAG, bool IsLittle)
Definition:MipsISelLowering.cpp:2853
createStoreLR
static SDValue createStoreLR(unsigned Opc, SelectionDAG &DAG, StoreSDNode *SD, SDValue Chain, unsigned Offset)
Definition:MipsISelLowering.cpp:2836
addLiveIn
static unsigned addLiveIn(MachineFunction &MF, unsigned PReg, const TargetRegisterClass *RC)
Definition:MipsISelLowering.cpp:1323
parsePhysicalReg
static std::pair< bool, bool > parsePhysicalReg(StringRef C, StringRef &Prefix, unsigned long long &Reg)
This is a helper function to parse a physical register string and split it into non-numeric and numer...
Definition:MipsISelLowering.cpp:4108
createLoadLR
static SDValue createLoadLR(unsigned Opc, SelectionDAG &DAG, LoadSDNode *LD, SDValue Chain, SDValue Src, unsigned Offset)
Definition:MipsISelLowering.cpp:2754
lowerFCOPYSIGN64
static SDValue lowerFCOPYSIGN64(SDValue Op, SelectionDAG &DAG, bool HasExtractInsert)
Definition:MipsISelLowering.cpp:2448
performADDCombine
static SDValue performADDCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)
Definition:MipsISelLowering.cpp:1129
EmitJalrReloc
cl::opt< bool > EmitJalrReloc
performSUBCombine
static SDValue performSUBCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)
Definition:MipsISelLowering.cpp:1114
createFPCmp
static SDValue createFPCmp(SelectionDAG &DAG, const SDValue &Op)
Definition:MipsISelLowering.cpp:655
lowerFCOPYSIGN32
static SDValue lowerFCOPYSIGN32(SDValue Op, SelectionDAG &DAG, bool HasExtractInsert)
Definition:MipsISelLowering.cpp:2401
NoZeroDivCheck
static cl::opt< bool > NoZeroDivCheck("mno-check-zero-division", cl::Hidden, cl::desc("MIPS: Don't trap on integer division by zero."), cl::init(false))
performSELECTCombine
static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)
Definition:MipsISelLowering.cpp:687
performCMovFPCombine
static SDValue performCMovFPCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)
Definition:MipsISelLowering.cpp:768
UnpackFromArgumentSlot
static SDValue UnpackFromArgumentSlot(SDValue Val, const CCValAssign &VA, EVT ArgVT, const SDLoc &DL, SelectionDAG &DAG)
Definition:MipsISelLowering.cpp:3661
condCodeToFCC
static Mips::CondCode condCodeToFCC(ISD::CondCode CC)
Definition:MipsISelLowering.cpp:615
createCMovFP
static SDValue createCMovFP(SelectionDAG &DAG, SDValue Cond, SDValue True, SDValue False, const SDLoc &DL)
Definition:MipsISelLowering.cpp:677
MipsISelLowering.h
MipsInstPrinter.h
MipsInstrInfo.h
MipsMCTargetDesc.h
MipsMachineFunction.h
MipsRegisterInfo.h
MipsSubtarget.h
MipsTargetMachine.h
MipsTargetObjectFile.h
II
uint64_t IntrinsicInst * II
Definition:NVVMIntrRange.cpp:51
Y
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
Cond
const SmallVectorImpl< MachineOperand > & Cond
Definition:RISCVRedundantCopyElimination.cpp:75
CC
auto CC
Definition:RISCVRedundantCopyElimination.cpp:79
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
RA
SI optimize exec mask operations pre RA
Definition:SIOptimizeExecMaskingPreRA.cpp:71
contains
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition:Value.cpp:469
SelectionDAGNodes.h
SelectionDAG.h
SmallVector.h
This file defines the SmallVector class.
IntRegs
static const MCPhysReg IntRegs[32]
Definition:SparcAsmParser.cpp:158
Statistic.h
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
STATISTIC
#define STATISTIC(VARNAME, DESC)
Definition:Statistic.h:166
StringRef.h
StringSwitch.h
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
TargetFrameLowering.h
TargetInstrInfo.h
Ptr
@ Ptr
Definition:TargetLibraryInfo.cpp:77
TargetOptions.h
TargetRegisterInfo.h
F32Regs
static const MCPhysReg F32Regs[64]
Definition:VEAsmParser.cpp:110
ValueTypes.h
RHS
Value * RHS
Definition:X86PartialReduction.cpp:74
LHS
Value * LHS
Definition:X86PartialReduction.cpp:73
Node
Definition:ItaniumDemangle.h:163
T
char
llvm::APFloat
Definition:APFloat.h:904
llvm::Argument
This class represents an incoming formal argument to a Function.
Definition:Argument.h:31
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition:ArrayRef.h:41
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition:ArrayRef.h:168
llvm::ArrayRef::data
const T * data() const
Definition:ArrayRef.h:165
llvm::AttributeList
Definition:Attributes.h:490
llvm::BasicBlock
LLVM Basic Block Representation.
Definition:BasicBlock.h:61
llvm::BlockAddressSDNode
Definition:SelectionDAGNodes.h:2314
llvm::BranchProbability::getOne
static BranchProbability getOne()
Definition:BranchProbability.h:50
llvm::CCState
CCState - This class holds information needed while lowering arguments and return values.
Definition:CallingConvLower.h:170
llvm::CCState::getMachineFunction
MachineFunction & getMachineFunction() const
Definition:CallingConvLower.h:240
llvm::CCState::getFirstUnallocated
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
Definition:CallingConvLower.h:315
llvm::CCState::getCallingConv
CallingConv::ID getCallingConv() const
Definition:CallingConvLower.h:241
llvm::CCState::AllocateReg
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
Definition:CallingConvLower.h:330
llvm::CCState::AllocateStack
int64_t AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
Definition:CallingConvLower.h:405
llvm::CCState::getStackSize
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
Definition:CallingConvLower.h:245
llvm::CCState::isVarArg
bool isVarArg() const
Definition:CallingConvLower.h:242
llvm::CCState::addInRegsParamInfo
void addInRegsParamInfo(unsigned RegBegin, unsigned RegEnd)
Definition:CallingConvLower.h:457
llvm::CCState::addLoc
void addLoc(const CCValAssign &V)
Definition:CallingConvLower.h:235
llvm::CCValAssign
CCValAssign - Represent assignment of one arg/retval to a location.
Definition:CallingConvLower.h:33
llvm::CCValAssign::isRegLoc
bool isRegLoc() const
Definition:CallingConvLower.h:122
llvm::CCValAssign::getLocReg
Register getLocReg() const
Definition:CallingConvLower.h:128
llvm::CCValAssign::getLocInfo
LocInfo getLocInfo() const
Definition:CallingConvLower.h:134
llvm::CCValAssign::getReg
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
Definition:CallingConvLower.h:84
llvm::CCValAssign::LocInfo
LocInfo
Definition:CallingConvLower.h:35
llvm::CCValAssign::BCvt
@ BCvt
Definition:CallingConvLower.h:46
llvm::CCValAssign::ZExtUpper
@ ZExtUpper
Definition:CallingConvLower.h:42
llvm::CCValAssign::SExt
@ SExt
Definition:CallingConvLower.h:37
llvm::CCValAssign::ZExt
@ ZExt
Definition:CallingConvLower.h:38
llvm::CCValAssign::Full
@ Full
Definition:CallingConvLower.h:36
llvm::CCValAssign::AExt
@ AExt
Definition:CallingConvLower.h:39
llvm::CCValAssign::AExtUpper
@ AExtUpper
Definition:CallingConvLower.h:44
llvm::CCValAssign::SExtUpper
@ SExtUpper
Definition:CallingConvLower.h:40
llvm::CCValAssign::getCustomReg
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP)
Definition:CallingConvLower.h:91
llvm::CCValAssign::isUpperBitsInLoc
bool isUpperBitsInLoc() const
Definition:CallingConvLower.h:139
llvm::CCValAssign::getMem
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
Definition:CallingConvLower.h:96
llvm::CCValAssign::needsCustom
bool needsCustom() const
Definition:CallingConvLower.h:126
llvm::CCValAssign::getValVT
MVT getValVT() const
Definition:CallingConvLower.h:120
llvm::CCValAssign::isMemLoc
bool isMemLoc() const
Definition:CallingConvLower.h:123
llvm::CCValAssign::getLocMemOffset
int64_t getLocMemOffset() const
Definition:CallingConvLower.h:129
llvm::CCValAssign::getLocVT
MVT getLocVT() const
Definition:CallingConvLower.h:132
llvm::CallBase::isMustTailCall
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Definition:Instructions.cpp:343
llvm::ConstantPoolSDNode
Definition:SelectionDAGNodes.h:2002
llvm::ConstantSDNode
Definition:SelectionDAGNodes.h:1684
llvm::ConstantSDNode::getZExtValue
uint64_t getZExtValue() const
Definition:SelectionDAGNodes.h:1701
llvm::ConstantSDNode::getSExtValue
int64_t getSExtValue() const
Definition:SelectionDAGNodes.h:1702
llvm::DWARFExpression::Operation
This class represents an Operation in the Expression.
Definition:DWARFExpression.h:32
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition:DataLayout.h:63
llvm::DataLayout::getTypeAllocSize
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Definition:DataLayout.h:457
llvm::DebugLoc
A debug info location.
Definition:DebugLoc.h:33
llvm::ExternalSymbolSDNode
Definition:SelectionDAGNodes.h:2356
llvm::ExternalSymbolSDNode::getSymbol
const char * getSymbol() const
Definition:SelectionDAGNodes.h:2369
llvm::FastISel
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
Definition:FastISel.h:66
llvm::FunctionLoweringInfo
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
Definition:FunctionLoweringInfo.h:57
llvm::FunctionLoweringInfo::MF
MachineFunction * MF
Definition:FunctionLoweringInfo.h:60
llvm::Function
Definition:Function.h:63
llvm::Function::hasStructRetAttr
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
Definition:Function.h:688
llvm::Function::hasFnAttribute
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition:Function.cpp:731
llvm::GlobalAddressSDNode
Definition:SelectionDAGNodes.h:1876
llvm::GlobalAddressSDNode::getGlobal
const GlobalValue * getGlobal() const
Definition:SelectionDAGNodes.h:1890
llvm::GlobalObject
Definition:GlobalObject.h:27
llvm::GlobalValue
Definition:GlobalValue.h:48
llvm::GlobalValue::hasLocalLinkage
bool hasLocalLinkage() const
Definition:GlobalValue.h:529
llvm::GlobalValue::hasDLLImportStorageClass
bool hasDLLImportStorageClass() const
Definition:GlobalValue.h:279
llvm::GlobalValue::getAliaseeObject
const GlobalObject * getAliaseeObject() const
Definition:Globals.cpp:400
llvm::GlobalValue::hasInternalLinkage
bool hasInternalLinkage() const
Definition:GlobalValue.h:527
llvm::Instruction
Definition:Instruction.h:68
llvm::IntegerType
Class to represent integer types.
Definition:DerivedTypes.h:42
llvm::JumpTableSDNode
Definition:SelectionDAGNodes.h:1981
llvm::LLT
Definition:LowLevelType.h:39
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition:LLVMContext.h:67
llvm::LLVMContext::emitError
void emitError(const Instruction *I, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
Definition:LLVMContext.cpp:210
llvm::LoadSDNode
This class is used to represent ISD::LOAD nodes.
Definition:SelectionDAGNodes.h:2464
llvm::MCContext::getOrCreateSymbol
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition:MCContext.cpp:212
llvm::MCRegister
Wrapper class representing physical registers. Should be passed by value.
Definition:MCRegister.h:33
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition:MCSymbol.h:41
llvm::MVT
Machine Value Type.
Definition:MachineValueType.h:35
llvm::MVT::integer_valuetypes
static auto integer_valuetypes()
Definition:MachineValueType.h:525
llvm::MVT::getSizeInBits
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
Definition:MachineValueType.h:308
llvm::MVT::getStoreSize
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
Definition:MachineValueType.h:356
llvm::MVT::getVectorVT
static MVT getVectorVT(MVT VT, unsigned NumElements)
Definition:MachineValueType.h:451
llvm::MVT::isFloatingPoint
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
Definition:MachineValueType.h:80
llvm::MVT::isValid
bool isValid() const
Return true if this is a valid simple valuetype.
Definition:MachineValueType.h:74
llvm::MVT::getIntegerVT
static MVT getIntegerVT(unsigned BitWidth)
Definition:MachineValueType.h:441
llvm::MVT::fp_valuetypes
static auto fp_valuetypes()
Definition:MachineValueType.h:531
llvm::MVT::fp_fixedlen_vector_valuetypes
static auto fp_fixedlen_vector_valuetypes()
Definition:MachineValueType.h:560
llvm::MachineBasicBlock
Definition:MachineBasicBlock.h:125
llvm::MachineBasicBlock::transferSuccessorsAndUpdatePHIs
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
Definition:MachineBasicBlock.cpp:937
llvm::MachineBasicBlock::getBasicBlock
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
Definition:MachineBasicBlock.h:256
llvm::MachineBasicBlock::addSuccessor
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
Definition:MachineBasicBlock.cpp:798
llvm::MachineBasicBlock::begin
iterator begin()
Definition:MachineBasicBlock.h:355
llvm::MachineBasicBlock::end
iterator end()
Definition:MachineBasicBlock.h:357
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition:MachineBasicBlock.h:311
llvm::MachineBasicBlock::splice
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
Definition:MachineBasicBlock.h:1109
llvm::MachineFrameInfo
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Definition:MachineFrameInfo.h:106
llvm::MachineFrameInfo::CreateFixedObject
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
Definition:MachineFrameInfo.cpp:83
llvm::MachineFrameInfo::setFrameAddressIsTaken
void setFrameAddressIsTaken(bool T)
Definition:MachineFrameInfo.h:374
llvm::MachineFrameInfo::setHasTailCall
void setHasTailCall(bool V=true)
Definition:MachineFrameInfo.h:647
llvm::MachineFrameInfo::setReturnAddressIsTaken
void setReturnAddressIsTaken(bool s)
Definition:MachineFrameInfo.h:380
llvm::MachineFunction
Definition:MachineFunction.h:267
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition:MachineFunction.h:733
llvm::MachineFunction::getFrameInfo
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Definition:MachineFunction.h:749
llvm::MachineFunction::getContext
MCContext & getContext() const
Definition:MachineFunction.h:690
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition:MachineFunction.h:743
llvm::MachineFunction::getDataLayout
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Definition:MachineFunction.cpp:309
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition:MachineFunction.h:704
llvm::MachineFunction::getInfo
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Definition:MachineFunction.h:831
llvm::MachineFunction::addLiveIn
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
Definition:MachineFunction.cpp:762
llvm::MachineFunction::CreateMachineBasicBlock
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
Definition:MachineFunction.cpp:499
llvm::MachineFunction::insert
void insert(iterator MBBI, MachineBasicBlock *MBB)
Definition:MachineFunction.h:966
llvm::MachineFunction::getTarget
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Definition:MachineFunction.h:729
llvm::MachineInstrBuilder
Definition:MachineInstrBuilder.h:71
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition:MachineInstrBuilder.h:133
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition:MachineInstrBuilder.h:99
llvm::MachineInstrBuilder::addMBB
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Definition:MachineInstrBuilder.h:148
llvm::MachineInstrBuilder::addUse
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
Definition:MachineInstrBuilder.h:125
llvm::MachineInstrBuilder::addDef
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Definition:MachineInstrBuilder.h:118
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::MachineInstr
Representation of each machine instruction.
Definition:MachineInstr.h:71
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition:MachineInstr.h:587
llvm::MachineJumpTableInfo::EK_GPRel64BlockAddress
@ EK_GPRel64BlockAddress
EK_GPRel64BlockAddress - Each entry is an address of block, encoded with a relocation as gp-relative,...
Definition:MachineJumpTableInfo.h:58
llvm::MachineMemOperand::MOVolatile
@ MOVolatile
The memory access is volatile.
Definition:MachineMemOperand.h:140
llvm::MachineMemOperand::getFlags
Flags getFlags() const
Return the raw flags of the source value,.
Definition:MachineMemOperand.h:224
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition:MachineOperand.h:48
llvm::MachineOperand::setSubReg
void setSubReg(unsigned subReg)
Definition:MachineOperand.h:490
llvm::MachineOperand::CreateMCSymbol
static MachineOperand CreateMCSymbol(MCSymbol *Sym, unsigned TargetFlags=0)
Definition:MachineOperand.h:951
llvm::MachineOperand::isKill
bool isKill() const
Definition:MachineOperand.h:399
llvm::MachineOperand::setIsKill
void setIsKill(bool Val=true)
Definition:MachineOperand.h:519
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition:MachineOperand.h:369
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition:MachineRegisterInfo.h:51
llvm::MachineRegisterInfo::createVirtualRegister
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Definition:MachineRegisterInfo.cpp:156
llvm::MachineRegisterInfo::addLiveIn
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
Definition:MachineRegisterInfo.h:1006
llvm::MemSDNode::getAlign
Align getAlign() const
Definition:SelectionDAGNodes.h:1370
llvm::MemSDNode::getMemOperand
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
Definition:SelectionDAGNodes.h:1436
llvm::MemSDNode::getPointerInfo
const MachinePointerInfo & getPointerInfo() const
Definition:SelectionDAGNodes.h:1438
llvm::MemSDNode::getChain
const SDValue & getChain() const
Definition:SelectionDAGNodes.h:1455
llvm::MemSDNode::getMemoryVT
EVT getMemoryVT() const
Return the type of the in-memory value.
Definition:SelectionDAGNodes.h:1432
llvm::MipsABIInfo::IsN64
bool IsN64() const
Definition:MipsABIInfo.h:42
llvm::MipsABIInfo::GetVarArgRegs
ArrayRef< MCPhysReg > GetVarArgRegs() const
The registers to use for the variable argument list.
Definition:MipsABIInfo.cpp:40
llvm::MipsABIInfo::ArePtrs64bit
bool ArePtrs64bit() const
Definition:MipsABIInfo.h:73
llvm::MipsABIInfo::GetCalleeAllocdArgSizeInBytes
unsigned GetCalleeAllocdArgSizeInBytes(CallingConv::ID CC) const
Obtain the size of the area allocated by the callee for arguments.
Definition:MipsABIInfo.cpp:48
llvm::MipsABIInfo::GetPtrAddiuOp
unsigned GetPtrAddiuOp() const
Definition:MipsABIInfo.cpp:101
llvm::MipsABIInfo::GetPtrAndOp
unsigned GetPtrAndOp() const
Definition:MipsABIInfo.cpp:109
llvm::MipsABIInfo::GetByValArgRegs
ArrayRef< MCPhysReg > GetByValArgRegs() const
The registers to use for byval arguments.
Definition:MipsABIInfo.cpp:32
llvm::MipsABIInfo::GetNullPtr
unsigned GetNullPtr() const
Definition:MipsABIInfo.cpp:89
llvm::MipsABIInfo::IsN32
bool IsN32() const
Definition:MipsABIInfo.h:41
llvm::MipsABIInfo::IsO32
bool IsO32() const
Definition:MipsABIInfo.h:40
llvm::MipsCCState
Definition:MipsCCState.h:20
llvm::MipsCCState::WasOriginalArgVectorFloat
bool WasOriginalArgVectorFloat(unsigned ValNo) const
Definition:MipsCCState.h:210
llvm::MipsCCState::getSpecialCallingConvForCallee
static SpecialCallingConvType getSpecialCallingConvForCallee(const SDNode *Callee, const MipsSubtarget &Subtarget)
Determine the SpecialCallingConvType for the given callee.
Definition:MipsCCState.cpp:70
llvm::MipsFunctionInfo
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
Definition:MipsMachineFunction.h:25
llvm::MipsFunctionInfo::setVarArgsFrameIndex
void setVarArgsFrameIndex(int Index)
Definition:MipsMachineFunction.h:48
llvm::MipsFunctionInfo::setCallsEhReturn
void setCallsEhReturn()
Definition:MipsMachineFunction.h:59
llvm::MipsFunctionInfo::getSRetReturnReg
unsigned getSRetReturnReg() const
Definition:MipsMachineFunction.h:36
llvm::MipsFunctionInfo::getVarArgsFrameIndex
int getVarArgsFrameIndex() const
Definition:MipsMachineFunction.h:47
llvm::MipsFunctionInfo::callPtrInfo
MachinePointerInfo callPtrInfo(MachineFunction &MF, const char *ES)
Create a MachinePointerInfo that has an ExternalSymbolPseudoSourceValue object representing a GOT ent...
Definition:MipsMachineFunction.cpp:191
llvm::MipsFunctionInfo::getGlobalBaseReg
Register getGlobalBaseReg(MachineFunction &MF)
Definition:MipsMachineFunction.cpp:55
llvm::MipsFunctionInfo::setISR
void setISR()
Definition:MipsMachineFunction.h:72
llvm::MipsFunctionInfo::setSRetReturnReg
void setSRetReturnReg(unsigned Reg)
Definition:MipsMachineFunction.h:37
llvm::MipsFunctionInfo::setFormalArgInfo
void setFormalArgInfo(unsigned Size, bool HasByval)
Definition:MipsMachineFunction.h:51
llvm::MipsRegisterInfo::getMips16RetHelperMask
static const uint32_t * getMips16RetHelperMask()
Definition:MipsRegisterInfo.cpp:145
llvm::MipsSubtarget
Definition:MipsSubtarget.h:37
llvm::MipsSubtarget::hasMips32r6
bool hasMips32r6() const
Definition:MipsSubtarget.h:274
llvm::MipsSubtarget::hasMips4
bool hasMips4() const
Definition:MipsSubtarget.h:254
llvm::MipsSubtarget::hasMips64r2
bool hasMips64r2() const
Definition:MipsSubtarget.h:279
llvm::MipsSubtarget::isFP64bit
bool isFP64bit() const
Definition:MipsSubtarget.h:290
llvm::MipsSubtarget::isLittle
bool isLittle() const
Definition:MipsSubtarget.h:287
llvm::MipsSubtarget::inMicroMipsMode
bool inMicroMipsMode() const
Definition:MipsSubtarget.h:318
llvm::MipsSubtarget::useSoftFloat
bool useSoftFloat() const
Definition:MipsSubtarget.h:340
llvm::MipsSubtarget::getInstrInfo
const MipsInstrInfo * getInstrInfo() const override
Definition:MipsSubtarget.h:391
llvm::MipsSubtarget::hasMips64r6
bool hasMips64r6() const
Definition:MipsSubtarget.h:282
llvm::MipsSubtarget::inMips16Mode
bool inMips16Mode() const
Definition:MipsSubtarget.h:307
llvm::MipsSubtarget::hasMips64
bool hasMips64() const
Definition:MipsSubtarget.h:278
llvm::MipsSubtarget::hasMips32
bool hasMips32() const
Definition:MipsSubtarget.h:258
llvm::MipsSubtarget::hasSym32
bool hasSym32() const
Definition:MipsSubtarget.h:300
llvm::MipsSubtarget::useXGOT
bool useXGOT() const
Definition:MipsSubtarget.h:344
llvm::MipsSubtarget::inAbs2008Mode
bool inAbs2008Mode() const
Definition:MipsSubtarget.h:294
llvm::MipsSubtarget::getRegisterInfo
const MipsRegisterInfo * getRegisterInfo() const override
Definition:MipsSubtarget.h:395
llvm::MipsSubtarget::isABICalls
bool isABICalls() const
Definition:MipsSubtarget.h:288
llvm::MipsSubtarget::hasCnMips
bool hasCnMips() const
Definition:MipsSubtarget.h:284
llvm::MipsSubtarget::systemSupportsUnalignedAccess
bool systemSupportsUnalignedAccess() const
Does the system support unaligned memory access.
Definition:MipsSubtarget.h:381
llvm::MipsSubtarget::isGP64bit
bool isGP64bit() const
Definition:MipsSubtarget.h:295
llvm::MipsSubtarget::hasExtractInsert
bool hasExtractInsert() const
Features related to the presence of specific instructions.
Definition:MipsSubtarget.h:351
llvm::MipsSubtarget::hasMips32r2
bool hasMips32r2() const
Definition:MipsSubtarget.h:262
llvm::MipsSubtarget::isTargetCOFF
bool isTargetCOFF() const
Definition:MipsSubtarget.h:304
llvm::MipsSubtarget::isTargetWindows
bool isTargetWindows() const
Definition:MipsSubtarget.h:360
llvm::MipsSubtarget::hasMSA
bool hasMSA() const
Definition:MipsSubtarget.h:326
llvm::MipsSubtarget::isSingleFloat
bool isSingleFloat() const
Definition:MipsSubtarget.h:303
llvm::MipsSubtarget::isABI_O32
bool isABI_O32() const
Definition:MipsSubtarget.cpp:286
llvm::MipsSubtarget::useLongCalls
bool useLongCalls() const
Definition:MipsSubtarget.h:342
llvm::MipsSubtarget::getGPRSizeInBytes
unsigned getGPRSizeInBytes() const
Definition:MipsSubtarget.h:297
llvm::MipsSubtarget::inMips16HardFloat
bool inMips16HardFloat() const
Definition:MipsSubtarget.h:315
llvm::MipsSubtarget::getFrameLowering
const TargetFrameLowering * getFrameLowering() const override
Definition:MipsSubtarget.h:392
llvm::MipsTargetLowering
Definition:MipsISelLowering.h:268
llvm::MipsTargetLowering::getRegisterTypeForCallingConv
MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Return the register type for a given MVT, ensuring vectors are treated as a series of gpr sized integ...
Definition:MipsISelLowering.cpp:98
llvm::MipsTargetLowering::hasBitTest
bool hasBitTest(SDValue X, SDValue Y) const override
Return true if the target has a bit-test instruction: (X & (1 << Y)) ==/!= 0 This knowledge can be us...
Definition:MipsISelLowering.cpp:1251
llvm::MipsTargetLowering::create
static const MipsTargetLowering * create(const MipsTargetMachine &TM, const MipsSubtarget &STI)
Definition:MipsISelLowering.cpp:542
llvm::MipsTargetLowering::getAddrGPRel
SDValue getAddrGPRel(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, bool IsN64) const
Definition:MipsISelLowering.h:483
llvm::MipsTargetLowering::getVectorTypeBreakdownForCallingConv
unsigned getVectorTypeBreakdownForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const override
Break down vectors to the correct number of gpr sized integers.
Definition:MipsISelLowering.cpp:122
llvm::MipsTargetLowering::getRegisterByName
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
Definition:MipsISelLowering.cpp:4837
llvm::MipsTargetLowering::getTargetNodeName
const char * getTargetNodeName(unsigned Opcode) const override
getTargetNodeName - This method returns the name of a target specific
Definition:MipsISelLowering.cpp:174
llvm::MipsTargetLowering::getAddrNonPICSym64
SDValue getAddrNonPICSym64(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG) const
Definition:MipsISelLowering.h:456
llvm::MipsTargetLowering::getSetCCResultType
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - get the ISD::SETCC result ValueType
Definition:MipsISelLowering.cpp:571
llvm::MipsTargetLowering::getAddrGlobal
SDValue getAddrGlobal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, unsigned Flag, SDValue Chain, const MachinePointerInfo &PtrInfo) const
Definition:MipsISelLowering.h:407
llvm::MipsTargetLowering::createFastISel
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo) const override
createFastISel - This method returns a target specific FastISel object, or null if the target does no...
Definition:MipsISelLowering.cpp:552
llvm::MipsTargetLowering::MipsTargetLowering
MipsTargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
Definition:MipsISelLowering.cpp:296
llvm::MipsTargetLowering::ABI
const MipsABIInfo & ABI
Definition:MipsISelLowering.h:536
llvm::MipsTargetLowering::getAddrGlobalLargeGOT
SDValue getAddrGlobalLargeGOT(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, unsigned HiFlag, unsigned LoFlag, SDValue Chain, const MachinePointerInfo &PtrInfo) const
Definition:MipsISelLowering.h:420
llvm::MipsTargetLowering::getDllimportVariable
SDValue getDllimportVariable(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, SDValue Chain, const MachinePointerInfo &PtrInfo) const
Definition:MipsISelLowering.h:512
llvm::MipsTargetLowering::PerformDAGCombine
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
Definition:MipsISelLowering.cpp:1213
llvm::MipsTargetLowering::CCAssignFnForReturn
CCAssignFn * CCAssignFnForReturn() const
Definition:MipsISelLowering.cpp:3105
llvm::MipsTargetLowering::ReplaceNodeResults
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
Definition:MipsISelLowering.cpp:1275
llvm::MipsTargetLowering::EmitInstrWithCustomInserter
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
Definition:MipsISelLowering.cpp:1361
llvm::MipsTargetLowering::getDllimportSymbol
SDValue getDllimportSymbol(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG) const
Definition:MipsISelLowering.h:497
llvm::MipsTargetLowering::CCAssignFnForCall
CCAssignFn * CCAssignFnForCall() const
Definition:MipsISelLowering.cpp:3101
llvm::MipsTargetLowering::getNumRegistersForCallingConv
unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Return the number of registers for a given MVT, ensuring vectors are treated as a series of gpr sized...
Definition:MipsISelLowering.cpp:110
llvm::MipsTargetLowering::getAddrNonPIC
SDValue getAddrNonPIC(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG) const
Definition:MipsISelLowering.h:439
llvm::MipsTargetLowering::lowerSTORE
SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const
Definition:MipsISelLowering.cpp:2898
llvm::MipsTargetLowering::AdjustInstrPostInstrSelection
void AdjustInstrPostInstrSelection(MachineInstr &MI, SDNode *Node) const override
This method should be implemented by targets that mark instructions with the 'hasPostISelHook' flag.
Definition:MipsISelLowering.cpp:3188
llvm::MipsTargetLowering::getOpndList
virtual void getOpndList(SmallVectorImpl< SDValue > &Ops, std::deque< std::pair< unsigned, SDValue > > &RegsToPass, bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const
This function fills Ops, which is the list of operands that will later be used when a function call n...
Definition:MipsISelLowering.cpp:3131
llvm::MipsTargetLowering::getTypeForExtReturn
EVT getTypeForExtReturn(LLVMContext &Context, EVT VT, ISD::NodeType) const override
Return the type that should be used to zero or sign extend a zeroext/signext integer return value.
Definition:MipsISelLowering.cpp:4128
llvm::MipsTargetLowering::isCheapToSpeculateCtlz
bool isCheapToSpeculateCtlz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic ctlz.
Definition:MipsISelLowering.cpp:1247
llvm::MipsTargetLowering::LowerOperation
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
Definition:MipsISelLowering.cpp:1282
llvm::MipsTargetLowering::isCheapToSpeculateCttz
bool isCheapToSpeculateCttz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic cttz.
Definition:MipsISelLowering.cpp:1243
llvm::MipsTargetLowering::shouldFoldConstantShiftPairToMask
bool shouldFoldConstantShiftPairToMask(const SDNode *N, CombineLevel Level) const override
Return true if it is profitable to fold a pair of shifts into a mask.
Definition:MipsISelLowering.cpp:1261
llvm::MipsTargetLowering::getAddrLocal
SDValue getAddrLocal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, bool IsN32OrN64) const
Definition:MipsISelLowering.h:388
llvm::MipsTargetLowering::getGlobalReg
SDValue getGlobalReg(SelectionDAG &DAG, EVT Ty) const
Definition:MipsISelLowering.cpp:137
llvm::MipsTargetLowering::Subtarget
const MipsSubtarget & Subtarget
Definition:MipsISelLowering.h:534
llvm::MipsTargetLowering::HandleByVal
void HandleByVal(CCState *, unsigned &, Align) const override
Target-specific cleanup for formal ByVal parameters.
Definition:MipsISelLowering.cpp:4635
llvm::MipsTargetLowering::lowerLOAD
SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const
Definition:MipsISelLowering.cpp:2772
llvm::MipsTargetMachine
Definition:MipsTargetMachine.h:27
llvm::MipsTargetObjectFile
Definition:MipsTargetObjectFile.h:16
llvm::MipsTargetObjectFile::IsConstantInSmallSection
bool IsConstantInSmallSection(const DataLayout &DL, const Constant *CN, const TargetMachine &TM) const
Return true if this constant should be placed into small data section.
Definition:MipsTargetObjectFile.cpp:166
llvm::Register
Wrapper class representing virtual and physical registers.
Definition:Register.h:19
llvm::SDLoc
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Definition:SelectionDAGNodes.h:1182
llvm::SDNode
Represents one node in the SelectionDAG.
Definition:SelectionDAGNodes.h:496
llvm::SDNode::getOpcode
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
Definition:SelectionDAGNodes.h:687
llvm::SDNode::getAsZExtVal
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
Definition:SelectionDAGNodes.h:1727
llvm::SDNode::getOperand
const SDValue & getOperand(unsigned Num) const
Definition:SelectionDAGNodes.h:992
llvm::SDNode::getValueType
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Definition:SelectionDAGNodes.h:1062
llvm::SDValue
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
Definition:SelectionDAGNodes.h:145
llvm::SDValue::getNode
SDNode * getNode() const
get the SDNode which holds the desired result
Definition:SelectionDAGNodes.h:159
llvm::SDValue::getValue
SDValue getValue(unsigned R) const
Definition:SelectionDAGNodes.h:179
llvm::SDValue::getValueType
EVT getValueType() const
Return the ValueType of the referenced return value.
Definition:SelectionDAGNodes.h:1217
llvm::SDValue::getValueSizeInBits
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
Definition:SelectionDAGNodes.h:199
llvm::SDValue::getOperand
const SDValue & getOperand(unsigned i) const
Definition:SelectionDAGNodes.h:1225
llvm::SDValue::getOpcode
unsigned getOpcode() const
Definition:SelectionDAGNodes.h:1213
llvm::SelectionDAG
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition:SelectionDAG.h:228
llvm::SelectionDAG::getExtLoad
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Definition:SelectionDAG.cpp:9287
llvm::SelectionDAG::getTargetGlobalAddress
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
Definition:SelectionDAG.h:751
llvm::SelectionDAG::getCopyToReg
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
Definition:SelectionDAG.h:802
llvm::SelectionDAG::getMergeValues
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
Definition:SelectionDAG.cpp:9034
llvm::SelectionDAG::getVTList
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
Definition:SelectionDAG.cpp:10708
llvm::SelectionDAG::getSetCC
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
Definition:SelectionDAG.h:1251
llvm::SelectionDAG::getRegister
SDValue getRegister(Register Reg, EVT VT)
Definition:SelectionDAG.cpp:2328
llvm::SelectionDAG::getLoad
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
Definition:SelectionDAG.cpp:9270
llvm::SelectionDAG::getMemcpy
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
Definition:SelectionDAG.cpp:8581
llvm::SelectionDAG::getTargetJumpTable
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
Definition:SelectionDAG.h:761
llvm::SelectionDAG::getUNDEF
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
Definition:SelectionDAG.h:1129
llvm::SelectionDAG::getCALLSEQ_END
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
Definition:SelectionDAG.h:1106
llvm::SelectionDAG::getCopyFromReg
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
Definition:SelectionDAG.h:828
llvm::SelectionDAG::getDataLayout
const DataLayout & getDataLayout() const
Definition:SelectionDAG.h:497
llvm::SelectionDAG::getConstant
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
Definition:SelectionDAG.cpp:1666
llvm::SelectionDAG::getSignedTargetConstant
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition:SelectionDAG.h:713
llvm::SelectionDAG::getStore
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
Definition:SelectionDAG.cpp:9320
llvm::SelectionDAG::getSignedConstant
SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Definition:SelectionDAG.cpp:1794
llvm::SelectionDAG::getCALLSEQ_START
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
Definition:SelectionDAG.h:1094
llvm::SelectionDAG::getExternalSymbol
SDValue getExternalSymbol(const char *Sym, EVT VT)
Definition:SelectionDAG.cpp:2052
llvm::SelectionDAG::getTarget
const TargetMachine & getTarget() const
Definition:SelectionDAG.h:498
llvm::SelectionDAG::getSelectCC
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond)
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
Definition:SelectionDAG.h:1290
llvm::SelectionDAG::getIntPtrConstant
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
Definition:SelectionDAG.cpp:1806
llvm::SelectionDAG::getValueType
SDValue getValueType(EVT)
Definition:SelectionDAG.cpp:2038
llvm::SelectionDAG::getNode
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
Definition:SelectionDAG.cpp:10327
llvm::SelectionDAG::isKnownNeverNaN
bool isKnownNeverNaN(SDValue Op, bool SNaN=false, unsigned Depth=0) const
Test whether the given SDValue (or all elements of it, if it is a vector) is known to never be NaN.
Definition:SelectionDAG.cpp:5672
llvm::SelectionDAG::getTargetConstant
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition:SelectionDAG.h:701
llvm::SelectionDAG::getTargetBlockAddress
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
Definition:SelectionDAG.h:797
llvm::SelectionDAG::ReplaceAllUsesOfValueWith
void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
Definition:SelectionDAG.cpp:11814
llvm::SelectionDAG::getMachineFunction
MachineFunction & getMachineFunction() const
Definition:SelectionDAG.h:492
llvm::SelectionDAG::getFrameIndex
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
Definition:SelectionDAG.cpp:1925
llvm::SelectionDAG::getRegisterMask
SDValue getRegisterMask(const uint32_t *RegMask)
Definition:SelectionDAG.cpp:2344
llvm::SelectionDAG::addCallSiteInfo
void addCallSiteInfo(const SDNode *Node, CallSiteInfo &&CallInfo)
Set CallSiteInfo to be associated with Node.
Definition:SelectionDAG.h:2345
llvm::SelectionDAG::getContext
LLVMContext * getContext() const
Definition:SelectionDAG.h:510
llvm::SelectionDAG::getMemIntrinsicNode
SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=0, const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
Definition:SelectionDAG.cpp:9045
llvm::SelectionDAG::getTargetExternalSymbol
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
Definition:SelectionDAG.cpp:2069
llvm::SelectionDAG::getTargetConstantPool
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
Definition:SelectionDAG.h:768
llvm::SelectionDAG::getEntryNode
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition:SelectionDAG.h:580
llvm::SelectionDAG::SplitScalar
std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
Definition:SelectionDAG.cpp:12946
llvm::SmallVectorBase::empty
bool empty() const
Definition:SmallVector.h:81
llvm::SmallVectorBase::size
size_t size() const
Definition:SmallVector.h:78
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition:SmallVector.h:573
llvm::SmallVectorTemplateBase::push_back
void push_back(const T &Elt)
Definition:SmallVector.h:413
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition:SmallVector.h:1196
llvm::StoreSDNode
This class is used to represent ISD::STORE nodes.
Definition:SelectionDAGNodes.h:2492
llvm::StoreSDNode::getBasePtr
const SDValue & getBasePtr() const
Definition:SelectionDAGNodes.h:2514
llvm::StoreSDNode::getValue
const SDValue & getValue() const
Definition:SelectionDAGNodes.h:2513
llvm::StoreSDNode::isTruncatingStore
bool isTruncatingStore() const
Return true if the op does a truncation before store.
Definition:SelectionDAGNodes.h:2508
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition:StringRef.h:147
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition:StringRef.h:150
llvm::StringSwitch
A switch()-like statement whose cases are string literals.
Definition:StringSwitch.h:44
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition:StringSwitch.h:69
llvm::StringSwitch::Default
R Default(T Value)
Definition:StringSwitch.h:182
llvm::TargetFrameLowering
Information about stack frame layout on the target.
Definition:TargetFrameLowering.h:45
llvm::TargetFrameLowering::getStackAlignment
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
Definition:TargetFrameLowering.h:100
llvm::TargetFrameLowering::getStackAlign
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
Definition:TargetFrameLowering.h:105
llvm::TargetInstrInfo
TargetInstrInfo - Interface to description of machine instruction set.
Definition:TargetInstrInfo.h:112
llvm::TargetLibraryInfo
Provides information about what library functions are available for the current target.
Definition:TargetLibraryInfo.h:280
llvm::TargetLoweringBase::setBooleanVectorContents
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
Definition:TargetLowering.h:2493
llvm::TargetLoweringBase::setOperationAction
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
Definition:TargetLowering.h:2562
llvm::TargetLoweringBase::Custom
@ Custom
Definition:TargetLowering.h:204
llvm::TargetLoweringBase::Expand
@ Expand
Definition:TargetLowering.h:202
llvm::TargetLoweringBase::Promote
@ Promote
Definition:TargetLowering.h:201
llvm::TargetLoweringBase::getRegClassFor
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
Definition:TargetLowering.h:1042
llvm::TargetLoweringBase::setMinStackArgumentAlignment
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
Definition:TargetLowering.h:2758
llvm::TargetLoweringBase::getTargetMachine
const TargetMachine & getTargetMachine() const
Definition:TargetLowering.h:364
llvm::TargetLoweringBase::getNumRegisters
virtual unsigned getNumRegisters(LLVMContext &Context, EVT VT, std::optional< MVT > RegisterVT=std::nullopt) const
Return the number of registers that this ValueType will eventually require.
Definition:TargetLowering.h:1763
llvm::TargetLoweringBase::setMaxAtomicSizeInBitsSupported
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Definition:TargetLowering.h:2766
llvm::TargetLoweringBase::setMinFunctionAlignment
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
Definition:TargetLowering.h:2739
llvm::TargetLoweringBase::setBooleanContents
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
Definition:TargetLowering.h:2479
llvm::TargetLoweringBase::getPointerTy
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
Definition:TargetLowering.h:371
llvm::TargetLoweringBase::setTruncStoreAction
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
Definition:TargetLowering.h:2625
llvm::TargetLoweringBase::ZeroOrOneBooleanContent
@ ZeroOrOneBooleanContent
Definition:TargetLowering.h:236
llvm::TargetLoweringBase::ZeroOrNegativeOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
Definition:TargetLowering.h:237
llvm::TargetLoweringBase::setStackPointerRegisterToSaveRestore
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
Definition:TargetLowering.h:2511
llvm::TargetLoweringBase::AddPromotedToType
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
Definition:TargetLowering.h:2710
llvm::TargetLoweringBase::setTargetDAGCombine
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
Definition:TargetLowering.h:2731
llvm::TargetLoweringBase::getMinStackArgumentAlignment
Align getMinStackArgumentAlignment() const
Return the minimum stack alignment of an argument.
Definition:TargetLowering.h:2038
llvm::TargetLoweringBase::setLoadExtAction
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
Definition:TargetLowering.h:2579
llvm::TargetLoweringBase::ArgListTy
std::vector< ArgListEntry > ArgListTy
Definition:TargetLowering.h:329
llvm::TargetLoweringBase::MaxStoresPerMemcpy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
Definition:TargetLowering.h:3716
llvm::TargetLoweringBase::getRegisterType
MVT getRegisterType(MVT VT) const
Return the type of registers that this ValueType will eventually require.
Definition:TargetLowering.h:1728
llvm::TargetLowering
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Definition:TargetLowering.h:3780
llvm::TargetLowering::ConstraintType
ConstraintType
Definition:TargetLowering.h:4950
llvm::TargetLowering::C_RegisterClass
@ C_RegisterClass
Definition:TargetLowering.h:4952
llvm::TargetLowering::C_Memory
@ C_Memory
Definition:TargetLowering.h:4953
llvm::TargetLowering::getConstraintType
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
Definition:TargetLowering.cpp:5525
llvm::TargetLowering::LowerToTLSEmulatedModel
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
Definition:TargetLowering.cpp:10526
llvm::TargetLowering::ConstraintWeight
ConstraintWeight
Definition:TargetLowering.h:4960
llvm::TargetLowering::CW_Invalid
@ CW_Invalid
Definition:TargetLowering.h:4962
llvm::TargetLowering::CW_Memory
@ CW_Memory
Definition:TargetLowering.h:4971
llvm::TargetLowering::CW_Constant
@ CW_Constant
Definition:TargetLowering.h:4972
llvm::TargetLowering::CW_SpecificReg
@ CW_SpecificReg
Definition:TargetLowering.h:4969
llvm::TargetLowering::CW_Register
@ CW_Register
Definition:TargetLowering.h:4970
llvm::TargetLowering::CW_Default
@ CW_Default
Definition:TargetLowering.h:4973
llvm::TargetLowering::LowerCallTo
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
Definition:SelectionDAGBuilder.cpp:10958
llvm::TargetLowering::isPositionIndependent
bool isPositionIndependent() const
Definition:TargetLowering.cpp:47
llvm::TargetLowering::getSingleConstraintMatchWeight
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
Definition:TargetLowering.cpp:5969
llvm::TargetLowering::getRegForInlineAsmConstraint
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
Definition:TargetLowering.cpp:5669
llvm::TargetLowering::verifyReturnAddressArgumentIsConstant
bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const
Definition:TargetLowering.cpp:7260
llvm::TargetLowering::LowerAsmOperandForConstraint
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
Definition:TargetLowering.cpp:5587
llvm::TargetLowering::getJumpTableEncoding
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
Definition:TargetLowering.cpp:444
llvm::TargetLowering::LowerOperationWrapper
virtual void LowerOperationWrapper(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const
This callback is invoked by the type legalizer to legalize nodes with an illegal operand type but leg...
Definition:SelectionDAGBuilder.cpp:11347
llvm::TargetMachine::getTLSModel
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
Definition:TargetMachine.cpp:238
llvm::TargetMachine::useEmulatedTLS
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
Definition:TargetMachine.cpp:235
llvm::TargetMachine::getObjFileLowering
virtual TargetLoweringObjectFile * getObjFileLowering() const
Definition:TargetMachine.h:136
llvm::TargetMachine::Options
TargetOptions Options
Definition:TargetMachine.h:118
llvm::TargetOptions
Definition:TargetOptions.h:132
llvm::TargetOptions::NoNaNsFPMath
unsigned NoNaNsFPMath
NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...
Definition:TargetOptions.h:188
llvm::TargetRegisterClass
Definition:TargetRegisterInfo.h:44
llvm::TargetRegisterClass::begin
iterator begin() const
begin/end - Return all of the registers in this class.
Definition:TargetRegisterInfo.h:77
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition:TargetRegisterInfo.h:235
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition:Type.h:45
llvm::Type::isVectorTy
bool isVectorTy() const
True if this is an instance of VectorType.
Definition:Type.h:270
llvm::Type::isFloatTy
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Definition:Type.h:153
llvm::Type::getIntNTy
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
llvm::Type::isIntegerTy
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition:Type.h:237
llvm::Type::getPrimitiveSizeInBits
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
llvm::Value
LLVM Value Representation.
Definition:Value.h:74
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition:Value.h:255
llvm::cl::opt
Definition:CommandLine.h:1423
llvm::details::FixedOrScalableQuantity::getFixedValue
constexpr ScalarTy getFixedValue() const
Definition:TypeSize.h:202
llvm::ilist_node_impl::getIterator
self_iterator getIterator()
Definition:ilist_node.h:132
uint16_t
uint32_t
uint64_t
unsigned
ErrorHandling.h
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition:ErrorHandling.h:143
TargetMachine.h
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition:AMDGPUMetadata.h:395
llvm::AMDGPU::IsaInfo::TargetIDSetting::Off
@ Off
llvm::AMDGPU::Imm
@ Imm
Definition:AMDGPURegBankLegalizeRules.h:105
llvm::BitmaskEnumDetail::Mask
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition:BitmaskEnum.h:125
llvm::COFF::Entry
@ Entry
Definition:COFF.h:844
llvm::CallingConv::Fast
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition:CallingConv.h:41
llvm::CallingConv::C
@ C
The default llvm calling convention, compatible with C.
Definition:CallingConv.h:34
llvm::IRSimilarity::Legal
@ Legal
Definition:IRSimilarityIdentifier.h:76
llvm::ISD::NodeType
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
Definition:ISDOpcodes.h:40
llvm::ISD::SETCC
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition:ISDOpcodes.h:780
llvm::ISD::STACKRESTORE
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
Definition:ISDOpcodes.h:1197
llvm::ISD::STACKSAVE
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition:ISDOpcodes.h:1193
llvm::ISD::STORE
@ STORE
Definition:ISDOpcodes.h:1103
llvm::ISD::JumpTable
@ JumpTable
Definition:ISDOpcodes.h:81
llvm::ISD::FLOG10
@ FLOG10
Definition:ISDOpcodes.h:1008
llvm::ISD::SREM
@ SREM
Definition:ISDOpcodes.h:251
llvm::ISD::UDIV
@ UDIV
Definition:ISDOpcodes.h:250
llvm::ISD::UINT_TO_FP
@ UINT_TO_FP
Definition:ISDOpcodes.h:842
llvm::ISD::BSWAP
@ BSWAP
Byte Swap and Counting operators.
Definition:ISDOpcodes.h:744
llvm::ISD::ROTR
@ ROTR
Definition:ISDOpcodes.h:739
llvm::ISD::FPOW
@ FPOW
Definition:ISDOpcodes.h:994
llvm::ISD::VAEND
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
Definition:ISDOpcodes.h:1226
llvm::ISD::ATOMIC_STORE
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
Definition:ISDOpcodes.h:1312
llvm::ISD::SDIV
@ SDIV
Definition:ISDOpcodes.h:249
llvm::ISD::FMAXNUM_IEEE
@ FMAXNUM_IEEE
Definition:ISDOpcodes.h:1045
llvm::ISD::ADD
@ ADD
Simple integer binary arithmetic operators.
Definition:ISDOpcodes.h:246
llvm::ISD::LOAD
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition:ISDOpcodes.h:1102
llvm::ISD::ANY_EXTEND
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition:ISDOpcodes.h:814
llvm::ISD::FMA
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition:ISDOpcodes.h:498
llvm::ISD::FABS
@ FABS
Definition:ISDOpcodes.h:982
llvm::ISD::RETURNADDR
@ RETURNADDR
Definition:ISDOpcodes.h:101
llvm::ISD::GlobalAddress
@ GlobalAddress
Definition:ISDOpcodes.h:78
llvm::ISD::FADD
@ FADD
Simple binary floating point operators.
Definition:ISDOpcodes.h:397
llvm::ISD::ATOMIC_FENCE
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
Definition:ISDOpcodes.h:1304
llvm::ISD::FP_TO_FP16
@ FP_TO_FP16
Definition:ISDOpcodes.h:965
llvm::ISD::UDIVREM
@ UDIVREM
Definition:ISDOpcodes.h:263
llvm::ISD::SDIVREM
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition:ISDOpcodes.h:262
llvm::ISD::SRL
@ SRL
Definition:ISDOpcodes.h:737
llvm::ISD::FP16_TO_FP
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
Definition:ISDOpcodes.h:964
llvm::ISD::BITCAST
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
Definition:ISDOpcodes.h:954
llvm::ISD::BUILD_PAIR
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
Definition:ISDOpcodes.h:236
llvm::ISD::GlobalTLSAddress
@ GlobalTLSAddress
Definition:ISDOpcodes.h:79
llvm::ISD::SRA
@ SRA
Definition:ISDOpcodes.h:736
llvm::ISD::EH_RETURN
@ EH_RETURN
OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents 'eh_return' gcc dwarf builtin,...
Definition:ISDOpcodes.h:141
llvm::ISD::SIGN_EXTEND
@ SIGN_EXTEND
Conversion operators.
Definition:ISDOpcodes.h:805
llvm::ISD::FLOG2
@ FLOG2
Definition:ISDOpcodes.h:1007
llvm::ISD::TargetJumpTable
@ TargetJumpTable
Definition:ISDOpcodes.h:173
llvm::ISD::FMAXNUM
@ FMAXNUM
Definition:ISDOpcodes.h:1032
llvm::ISD::FSINCOS
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
Definition:ISDOpcodes.h:1059
llvm::ISD::BR_CC
@ BR_CC
BR_CC - Conditional branch.
Definition:ISDOpcodes.h:1148
llvm::ISD::CTTZ
@ CTTZ
Definition:ISDOpcodes.h:745
llvm::ISD::FP_TO_UINT
@ FP_TO_UINT
Definition:ISDOpcodes.h:888
llvm::ISD::BR_JT
@ BR_JT
BR_JT - Jumptable branch.
Definition:ISDOpcodes.h:1127
llvm::ISD::OR
@ OR
Definition:ISDOpcodes.h:710
llvm::ISD::FCANONICALIZE
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
Definition:ISDOpcodes.h:515
llvm::ISD::IS_FPCLASS
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
Definition:ISDOpcodes.h:522
llvm::ISD::SRA_PARTS
@ SRA_PARTS
Definition:ISDOpcodes.h:795
llvm::ISD::SELECT
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition:ISDOpcodes.h:757
llvm::ISD::ATOMIC_LOAD
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
Definition:ISDOpcodes.h:1308
llvm::ISD::VACOPY
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
Definition:ISDOpcodes.h:1222
llvm::ISD::SHL
@ SHL
Shift and rotation operations.
Definition:ISDOpcodes.h:735
llvm::ISD::FMINNUM_IEEE
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
Definition:ISDOpcodes.h:1044
llvm::ISD::FCOS
@ FCOS
Definition:ISDOpcodes.h:986
llvm::ISD::XOR
@ XOR
Definition:ISDOpcodes.h:711
llvm::ISD::ZERO_EXTEND
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition:ISDOpcodes.h:811
llvm::ISD::CTPOP
@ CTPOP
Definition:ISDOpcodes.h:747
llvm::ISD::SELECT_CC
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition:ISDOpcodes.h:772
llvm::ISD::SRL_PARTS
@ SRL_PARTS
Definition:ISDOpcodes.h:796
llvm::ISD::FMINNUM
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two values.
Definition:ISDOpcodes.h:1031
llvm::ISD::SUB
@ SUB
Definition:ISDOpcodes.h:247
llvm::ISD::DYNAMIC_STACKALLOC
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition:ISDOpcodes.h:1112
llvm::ISD::ConstantPool
@ ConstantPool
Definition:ISDOpcodes.h:82
llvm::ISD::SIGN_EXTEND_INREG
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition:ISDOpcodes.h:849
llvm::ISD::EH_DWARF_CFA
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
Definition:ISDOpcodes.h:135
llvm::ISD::FRAMEADDR
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition:ISDOpcodes.h:100
llvm::ISD::FREM
@ FREM
Definition:ISDOpcodes.h:401
llvm::ISD::FP_TO_SINT
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition:ISDOpcodes.h:887
llvm::ISD::AND
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition:ISDOpcodes.h:709
llvm::ISD::TRAP
@ TRAP
TRAP - Trapping instruction.
Definition:ISDOpcodes.h:1279
llvm::ISD::FLOG
@ FLOG
Definition:ISDOpcodes.h:1006
llvm::ISD::UREM
@ UREM
Definition:ISDOpcodes.h:252
llvm::ISD::TokenFactor
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition:ISDOpcodes.h:52
llvm::ISD::FSIN
@ FSIN
Definition:ISDOpcodes.h:985
llvm::ISD::FEXP
@ FEXP
Definition:ISDOpcodes.h:1009
llvm::ISD::MUL
@ MUL
Definition:ISDOpcodes.h:248
llvm::ISD::CTLZ
@ CTLZ
Definition:ISDOpcodes.h:746
llvm::ISD::VASTART
@ VASTART
Definition:ISDOpcodes.h:1227
llvm::ISD::TRUNCATE
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition:ISDOpcodes.h:817
llvm::ISD::VAARG
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition:ISDOpcodes.h:1217
llvm::ISD::BRCOND
@ BRCOND
BRCOND - Conditional branch.
Definition:ISDOpcodes.h:1141
llvm::ISD::ROTL
@ ROTL
Definition:ISDOpcodes.h:738
llvm::ISD::BlockAddress
@ BlockAddress
Definition:ISDOpcodes.h:84
llvm::ISD::SHL_PARTS
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition:ISDOpcodes.h:794
llvm::ISD::AssertSext
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition:ISDOpcodes.h:61
llvm::ISD::FCOPYSIGN
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition:ISDOpcodes.h:508
llvm::ISD::AssertZext
@ AssertZext
Definition:ISDOpcodes.h:62
llvm::ISD::CALLSEQ_START
@ CALLSEQ_START
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence,...
Definition:ISDOpcodes.h:1211
llvm::ISD::getSetCCInverse
CondCode getSetCCInverse(CondCode Operation, EVT Type)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
Definition:SelectionDAG.cpp:639
llvm::ISD::CondCode
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Definition:ISDOpcodes.h:1610
llvm::ISD::SETOEQ
@ SETOEQ
Definition:ISDOpcodes.h:1613
llvm::ISD::SETUNE
@ SETUNE
Definition:ISDOpcodes.h:1626
llvm::ISD::SETUEQ
@ SETUEQ
Definition:ISDOpcodes.h:1621
llvm::ISD::SETOLE
@ SETOLE
Definition:ISDOpcodes.h:1617
llvm::ISD::SETOLT
@ SETOLT
Definition:ISDOpcodes.h:1616
llvm::ISD::SETNE
@ SETNE
Definition:ISDOpcodes.h:1635
llvm::ISD::SETUGT
@ SETUGT
Definition:ISDOpcodes.h:1622
llvm::ISD::SETOGT
@ SETOGT
Definition:ISDOpcodes.h:1614
llvm::ISD::SETULT
@ SETULT
Definition:ISDOpcodes.h:1624
llvm::ISD::SETUO
@ SETUO
Definition:ISDOpcodes.h:1620
llvm::ISD::SETONE
@ SETONE
Definition:ISDOpcodes.h:1618
llvm::ISD::SETGT
@ SETGT
Definition:ISDOpcodes.h:1631
llvm::ISD::SETLT
@ SETLT
Definition:ISDOpcodes.h:1633
llvm::ISD::SETO
@ SETO
Definition:ISDOpcodes.h:1619
llvm::ISD::SETGE
@ SETGE
Definition:ISDOpcodes.h:1632
llvm::ISD::SETUGE
@ SETUGE
Definition:ISDOpcodes.h:1623
llvm::ISD::SETLE
@ SETLE
Definition:ISDOpcodes.h:1634
llvm::ISD::SETULE
@ SETULE
Definition:ISDOpcodes.h:1625
llvm::ISD::SETOGE
@ SETOGE
Definition:ISDOpcodes.h:1615
llvm::ISD::SETEQ
@ SETEQ
Definition:ISDOpcodes.h:1630
llvm::ISD::LoadExtType
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
Definition:ISDOpcodes.h:1590
llvm::ISD::NON_EXTLOAD
@ NON_EXTLOAD
Definition:ISDOpcodes.h:1590
llvm::ISD::SEXTLOAD
@ SEXTLOAD
Definition:ISDOpcodes.h:1590
llvm::ISD::ZEXTLOAD
@ ZEXTLOAD
Definition:ISDOpcodes.h:1590
llvm::ISD::EXTLOAD
@ EXTLOAD
Definition:ISDOpcodes.h:1590
llvm::LegacyLegalizeActions::Bitcast
@ Bitcast
Perform the operation on a different, but equivalently sized type.
Definition:LegacyLegalizerInfo.h:55
llvm::MCID::Flag
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition:MCInstrDesc.h:148
llvm::MipsII::MO_TPREL_LO
@ MO_TPREL_LO
Definition:MipsBaseInfo.h:74
llvm::MipsII::MO_GOT_CALL
@ MO_GOT_CALL
MO_GOT_CALL - Represents the offset into the global offset table at which the address of a call site ...
Definition:MipsBaseInfo.h:44
llvm::MipsII::MO_TPREL_HI
@ MO_TPREL_HI
MO_TPREL_HI/LO - Represents the hi and low part of the offset from.
Definition:MipsBaseInfo.h:73
llvm::MipsII::MO_GOT
@ MO_GOT
MO_GOT - Represents the offset into the global offset table at which the address the relocation entry...
Definition:MipsBaseInfo.h:38
llvm::MipsII::MO_JALR
@ MO_JALR
Helper operand used to generate R_MIPS_JALR.
Definition:MipsBaseInfo.h:95
llvm::MipsII::MO_GOT_LO16
@ MO_GOT_LO16
Definition:MipsBaseInfo.h:90
llvm::MipsII::MO_NO_FLAG
@ MO_NO_FLAG
Definition:MipsBaseInfo.h:34
llvm::MipsII::MO_GOTTPREL
@ MO_GOTTPREL
MO_GOTTPREL - Represents the offset from the thread pointer (Initial.
Definition:MipsBaseInfo.h:69
llvm::MipsII::MO_DTPREL_HI
@ MO_DTPREL_HI
Definition:MipsBaseInfo.h:64
llvm::MipsII::MO_GOT_HI16
@ MO_GOT_HI16
MO_GOT_HI16/LO16, MO_CALL_HI16/LO16 - Relocations used for large GOTs.
Definition:MipsBaseInfo.h:89
llvm::MipsII::MO_GOT_DISP
@ MO_GOT_DISP
Definition:MipsBaseInfo.h:79
llvm::MipsII::MO_TLSLDM
@ MO_TLSLDM
MO_TLSLDM - Represents the offset into the global offset table at which.
Definition:MipsBaseInfo.h:63
llvm::MipsII::MO_CALL_HI16
@ MO_CALL_HI16
Definition:MipsBaseInfo.h:91
llvm::MipsII::MO_TLSGD
@ MO_TLSGD
MO_TLSGD - Represents the offset into the global offset table at which.
Definition:MipsBaseInfo.h:58
llvm::MipsII::MO_DTPREL_LO
@ MO_DTPREL_LO
Definition:MipsBaseInfo.h:65
llvm::MipsII::MO_CALL_LO16
@ MO_CALL_LO16
Definition:MipsBaseInfo.h:92
llvm::MipsISD::NodeType
NodeType
Definition:MipsISelLowering.h:55
llvm::MipsISD::LWR
@ LWR
Definition:MipsISelLowering.h:252
llvm::MipsISD::DynAlloc
@ DynAlloc
Definition:MipsISelLowering.h:153
llvm::MipsISD::MAddu
@ MAddu
Definition:MipsISelLowering.h:138
llvm::MipsISD::PCKOD
@ PCKOD
Definition:MipsISelLowering.h:233
llvm::MipsISD::DivRemU
@ DivRemU
Definition:MipsISelLowering.h:144
llvm::MipsISD::DPAQ_SA_L_W
@ DPAQ_SA_L_W
Definition:MipsISelLowering.h:183
llvm::MipsISD::MAQ_S_W_PHL
@ MAQ_S_W_PHL
Definition:MipsISelLowering.h:173
llvm::MipsISD::ExtractElementF64
@ ExtractElementF64
Definition:MipsISelLowering.h:149
llvm::MipsISD::ILVL
@ ILVL
Definition:MipsISelLowering.h:230
llvm::MipsISD::EXTPDP
@ EXTPDP
Definition:MipsISelLowering.h:163
llvm::MipsISD::MADD_DSP
@ MADD_DSP
Definition:MipsISelLowering.h:197
llvm::MipsISD::Highest
@ Highest
Definition:MipsISelLowering.h:66
llvm::MipsISD::SHILO
@ SHILO
Definition:MipsISelLowering.h:168
llvm::MipsISD::MULSAQ_S_W_PH
@ MULSAQ_S_W_PH
Definition:MipsISelLowering.h:172
llvm::MipsISD::MFHI
@ MFHI
Definition:MipsISelLowering.h:126
llvm::MipsISD::SHRL_DSP
@ SHRL_DSP
Definition:MipsISelLowering.h:205
llvm::MipsISD::MULT
@ MULT
Definition:MipsISelLowering.h:195
llvm::MipsISD::DPSX_W_PH
@ DPSX_W_PH
Definition:MipsISelLowering.h:190
llvm::MipsISD::DivRem16
@ DivRem16
Definition:MipsISelLowering.h:145
llvm::MipsISD::DPSU_H_QBR
@ DPSU_H_QBR
Definition:MipsISelLowering.h:180
llvm::MipsISD::Higher
@ Higher
Definition:MipsISelLowering.h:69
llvm::MipsISD::SELECT_CC_DSP
@ SELECT_CC_DSP
Definition:MipsISelLowering.h:209
llvm::MipsISD::DPAQX_SA_W_PH
@ DPAQX_SA_W_PH
Definition:MipsISelLowering.h:188
llvm::MipsISD::MTC1_D64
@ MTC1_D64
Definition:MipsISelLowering.h:107
llvm::MipsISD::Ret
@ Ret
Definition:MipsISelLowering.h:117
llvm::MipsISD::DOUBLE_SELECT_I64
@ DOUBLE_SELECT_I64
Definition:MipsISelLowering.h:247
llvm::MipsISD::CMovFP_F
@ CMovFP_F
Definition:MipsISelLowering.h:111
llvm::MipsISD::MTHLIP
@ MTHLIP
Definition:MipsISelLowering.h:169
llvm::MipsISD::FPCmp
@ FPCmp
Definition:MipsISelLowering.h:98
llvm::MipsISD::GotHi
@ GotHi
Definition:MipsISelLowering.h:80
llvm::MipsISD::GPRel
@ GPRel
Definition:MipsISelLowering.h:86
llvm::MipsISD::Mult
@ Mult
Definition:MipsISelLowering.h:133
llvm::MipsISD::TlsHi
@ TlsHi
Definition:MipsISelLowering.h:83
llvm::MipsISD::ILVR
@ ILVR
Definition:MipsISelLowering.h:231
llvm::MipsISD::FAbs
@ FAbs
Definition:MipsISelLowering.h:101
llvm::MipsISD::DPA_W_PH
@ DPA_W_PH
Definition:MipsISelLowering.h:185
llvm::MipsISD::DPAU_H_QBR
@ DPAU_H_QBR
Definition:MipsISelLowering.h:178
llvm::MipsISD::MAQ_S_W_PHR
@ MAQ_S_W_PHR
Definition:MipsISelLowering.h:174
llvm::MipsISD::MSub
@ MSub
Definition:MipsISelLowering.h:139
llvm::MipsISD::VCEQ
@ VCEQ
Definition:MipsISelLowering.h:219
llvm::MipsISD::DPS_W_PH
@ DPS_W_PH
Definition:MipsISelLowering.h:186
llvm::MipsISD::SWL
@ SWL
Definition:MipsISelLowering.h:253
llvm::MipsISD::DivRemU16
@ DivRemU16
Definition:MipsISelLowering.h:146
llvm::MipsISD::ThreadPointer
@ ThreadPointer
Definition:MipsISelLowering.h:89
llvm::MipsISD::ILVEV
@ ILVEV
Definition:MipsISelLowering.h:228
llvm::MipsISD::VEXTRACT_ZEXT_ELT
@ VEXTRACT_ZEXT_ELT
Definition:MipsISelLowering.h:243
llvm::MipsISD::DPSQ_S_W_PH
@ DPSQ_S_W_PH
Definition:MipsISelLowering.h:182
llvm::MipsISD::EXTP
@ EXTP
Definition:MipsISelLowering.h:162
llvm::MipsISD::JmpLink
@ JmpLink
Definition:MipsISelLowering.h:60
llvm::MipsISD::MSUB_DSP
@ MSUB_DSP
Definition:MipsISelLowering.h:199
llvm::MipsISD::Hi
@ Hi
Definition:MipsISelLowering.h:73
llvm::MipsISD::PCKEV
@ PCKEV
Definition:MipsISelLowering.h:232
llvm::MipsISD::ILVOD
@ ILVOD
Definition:MipsISelLowering.h:229
llvm::MipsISD::VCLT_U
@ VCLT_U
Definition:MipsISelLowering.h:223
llvm::MipsISD::VCLT_S
@ VCLT_S
Definition:MipsISelLowering.h:222
llvm::MipsISD::DPSQX_S_W_PH
@ DPSQX_S_W_PH
Definition:MipsISelLowering.h:191
llvm::MipsISD::DivRem
@ DivRem
Definition:MipsISelLowering.h:143
llvm::MipsISD::LDL
@ LDL
Definition:MipsISelLowering.h:255
llvm::MipsISD::SDL
@ SDL
Definition:MipsISelLowering.h:257
llvm::MipsISD::CMovFP_T
@ CMovFP_T
Definition:MipsISelLowering.h:110
llvm::MipsISD::TailCall
@ TailCall
Definition:MipsISelLowering.h:63
llvm::MipsISD::MAQ_SA_W_PHR
@ MAQ_SA_W_PHR
Definition:MipsISelLowering.h:176
llvm::MipsISD::VALL_ZERO
@ VALL_ZERO
Definition:MipsISelLowering.h:213
llvm::MipsISD::Ext
@ Ext
Definition:MipsISelLowering.h:157
llvm::MipsISD::BuildPairF64
@ BuildPairF64
Definition:MipsISelLowering.h:148
llvm::MipsISD::MADDU_DSP
@ MADDU_DSP
Definition:MipsISelLowering.h:198
llvm::MipsISD::SETCC_DSP
@ SETCC_DSP
Definition:MipsISelLowering.h:208
llvm::MipsISD::SHLL_DSP
@ SHLL_DSP
Definition:MipsISelLowering.h:203
llvm::MipsISD::SWR
@ SWR
Definition:MipsISelLowering.h:254
llvm::MipsISD::FIRST_NUMBER
@ FIRST_NUMBER
Definition:MipsISelLowering.h:57
llvm::MipsISD::FPBrcond
@ FPBrcond
Definition:MipsISelLowering.h:95
llvm::MipsISD::MSUBU_DSP
@ MSUBU_DSP
Definition:MipsISelLowering.h:200
llvm::MipsISD::VALL_NONZERO
@ VALL_NONZERO
Definition:MipsISelLowering.h:215
llvm::MipsISD::SDR
@ SDR
Definition:MipsISelLowering.h:258
llvm::MipsISD::FMS
@ FMS
Definition:MipsISelLowering.h:92
llvm::MipsISD::SHRA_DSP
@ SHRA_DSP
Definition:MipsISelLowering.h:204
llvm::MipsISD::EXTR_RS_W
@ EXTR_RS_W
Definition:MipsISelLowering.h:167
llvm::MipsISD::VCLE_S
@ VCLE_S
Definition:MipsISelLowering.h:220
llvm::MipsISD::CIns
@ CIns
Definition:MipsISelLowering.h:159
llvm::MipsISD::LDR
@ LDR
Definition:MipsISelLowering.h:256
llvm::MipsISD::Multu
@ Multu
Definition:MipsISelLowering.h:134
llvm::MipsISD::MTLOHI
@ MTLOHI
Definition:MipsISelLowering.h:130
llvm::MipsISD::TruncIntFP
@ TruncIntFP
Definition:MipsISelLowering.h:114
llvm::MipsISD::EH_RETURN
@ EH_RETURN
Definition:MipsISelLowering.h:123
llvm::MipsISD::SHF
@ SHF
Definition:MipsISelLowering.h:227
llvm::MipsISD::EXTR_R_W
@ EXTR_R_W
Definition:MipsISelLowering.h:166
llvm::MipsISD::DPSU_H_QBL
@ DPSU_H_QBL
Definition:MipsISelLowering.h:179
llvm::MipsISD::Sync
@ Sync
Definition:MipsISelLowering.h:155
llvm::MipsISD::Wrapper
@ Wrapper
Definition:MipsISelLowering.h:151
llvm::MipsISD::DPAQX_S_W_PH
@ DPAQX_S_W_PH
Definition:MipsISelLowering.h:187
llvm::MipsISD::DPSQ_SA_L_W
@ DPSQ_SA_L_W
Definition:MipsISelLowering.h:184
llvm::MipsISD::VANY_ZERO
@ VANY_ZERO
Definition:MipsISelLowering.h:214
llvm::MipsISD::DPAX_W_PH
@ DPAX_W_PH
Definition:MipsISelLowering.h:189
llvm::MipsISD::MSubu
@ MSubu
Definition:MipsISelLowering.h:140
llvm::MipsISD::DOUBLE_SELECT_I
@ DOUBLE_SELECT_I
Definition:MipsISelLowering.h:246
llvm::MipsISD::FSELECT
@ FSELECT
Definition:MipsISelLowering.h:104
llvm::MipsISD::EXTR_S_H
@ EXTR_S_H
Definition:MipsISelLowering.h:164
llvm::MipsISD::Ins
@ Ins
Definition:MipsISelLowering.h:158
llvm::MipsISD::INSVE
@ INSVE
Definition:MipsISelLowering.h:236
llvm::MipsISD::VNOR
@ VNOR
Definition:MipsISelLowering.h:239
llvm::MipsISD::MFLO
@ MFLO
Definition:MipsISelLowering.h:127
llvm::MipsISD::DPAU_H_QBL
@ DPAU_H_QBL
Definition:MipsISelLowering.h:177
llvm::MipsISD::MAdd
@ MAdd
Definition:MipsISelLowering.h:137
llvm::MipsISD::Lo
@ Lo
Definition:MipsISelLowering.h:77
llvm::MipsISD::VEXTRACT_SEXT_ELT
@ VEXTRACT_SEXT_ELT
Definition:MipsISelLowering.h:242
llvm::MipsISD::MAQ_SA_W_PHL
@ MAQ_SA_W_PHL
Definition:MipsISelLowering.h:175
llvm::MipsISD::MULTU
@ MULTU
Definition:MipsISelLowering.h:196
llvm::MipsISD::MULSA_W_PH
@ MULSA_W_PH
Definition:MipsISelLowering.h:193
llvm::MipsISD::VANY_NONZERO
@ VANY_NONZERO
Definition:MipsISelLowering.h:216
llvm::MipsISD::EXTR_W
@ EXTR_W
Definition:MipsISelLowering.h:165
llvm::MipsISD::ERet
@ ERet
Definition:MipsISelLowering.h:120
llvm::MipsISD::DPSQX_SA_W_PH
@ DPSQX_SA_W_PH
Definition:MipsISelLowering.h:192
llvm::MipsISD::DPAQ_S_W_PH
@ DPAQ_S_W_PH
Definition:MipsISelLowering.h:181
llvm::MipsISD::VSHF
@ VSHF
Definition:MipsISelLowering.h:226
llvm::MipsISD::VCLE_U
@ VCLE_U
Definition:MipsISelLowering.h:221
llvm::MipsISD::LWL
@ LWL
Definition:MipsISelLowering.h:251
llvm::Mips::CondCode
CondCode
Definition:MipsInstPrinter.h:32
llvm::Mips::FCOND_ULE
@ FCOND_ULE
Definition:MipsInstPrinter.h:41
llvm::Mips::FCOND_UEQ
@ FCOND_UEQ
Definition:MipsInstPrinter.h:37
llvm::Mips::FCOND_OGE
@ FCOND_OGE
Definition:MipsInstPrinter.h:59
llvm::Mips::FCOND_F
@ FCOND_F
Definition:MipsInstPrinter.h:34
llvm::Mips::FCOND_OEQ
@ FCOND_OEQ
Definition:MipsInstPrinter.h:36
llvm::Mips::FCOND_UNE
@ FCOND_UNE
Definition:MipsInstPrinter.h:56
llvm::Mips::FCOND_OR
@ FCOND_OR
Definition:MipsInstPrinter.h:55
llvm::Mips::FCOND_OLE
@ FCOND_OLE
Definition:MipsInstPrinter.h:40
llvm::Mips::FCOND_UGT
@ FCOND_UGT
Definition:MipsInstPrinter.h:60
llvm::Mips::FCOND_GT
@ FCOND_GT
Definition:MipsInstPrinter.h:69
llvm::Mips::FCOND_UN
@ FCOND_UN
Definition:MipsInstPrinter.h:35
llvm::Mips::FCOND_ULT
@ FCOND_ULT
Definition:MipsInstPrinter.h:39
llvm::Mips::FCOND_OGT
@ FCOND_OGT
Definition:MipsInstPrinter.h:61
llvm::Mips::FCOND_NGT
@ FCOND_NGT
Definition:MipsInstPrinter.h:49
llvm::Mips::FCOND_ONE
@ FCOND_ONE
Definition:MipsInstPrinter.h:57
llvm::Mips::FCOND_T
@ FCOND_T
Definition:MipsInstPrinter.h:54
llvm::Mips::FCOND_OLT
@ FCOND_OLT
Definition:MipsInstPrinter.h:38
llvm::Mips::FCOND_UGE
@ FCOND_UGE
Definition:MipsInstPrinter.h:58
llvm::Mips::BRANCH_T
@ BRANCH_T
Definition:MipsInstPrinter.h:25
llvm::Mips::BRANCH_F
@ BRANCH_F
Definition:MipsInstPrinter.h:24
llvm::Mips::createFastISel
FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo)
Definition:MipsFastISel.cpp:2155
llvm::RISCVFenceField::R
@ R
Definition:RISCVBaseInfo.h:373
llvm::RegState::Implicit
@ Implicit
Not emitted register (e.g. carry, or temporary result).
Definition:MachineInstrBuilder.h:48
llvm::RegState::Dead
@ Dead
Unused definition.
Definition:MachineInstrBuilder.h:52
llvm::RegState::Define
@ Define
Register definition.
Definition:MachineInstrBuilder.h:46
llvm::RegState::Kill
@ Kill
The last use of a register.
Definition:MachineInstrBuilder.h:50
llvm::RegState::EarlyClobber
@ EarlyClobber
Register definition happens before uses.
Definition:MachineInstrBuilder.h:56
llvm::SDPatternMatch::Not
Not(const Pred &P) -> Not< Pred >
llvm::SPII::Store
@ Store
Definition:SparcInstrInfo.h:33
llvm::TLSModel::Model
Model
Definition:CodeGen.h:45
llvm::TLSModel::LocalDynamic
@ LocalDynamic
Definition:CodeGen.h:47
llvm::TLSModel::InitialExec
@ InitialExec
Definition:CodeGen.h:48
llvm::TLSModel::GeneralDynamic
@ GeneralDynamic
Definition:CodeGen.h:46
llvm::TLSModel::LocalExec
@ LocalExec
Definition:CodeGen.h:49
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition:X86DisassemblerDecoder.h:621
llvm::cl::Hidden
@ Hidden
Definition:CommandLine.h:137
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition:CommandLine.h:443
llvm::codeview::EncodedFramePtrReg::StackPtr
@ StackPtr
llvm::codeview::FrameCookieKind::Copy
@ Copy
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::omp::RTLDependInfoFields::Flags
@ Flags
llvm::pdb::PDB_SymType::Callee
@ Callee
llvm::rdf::Func
NodeAddr< FuncNode * > Func
Definition:RDFGraph.h:393
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::Offset
@ Offset
Definition:DWP.cpp:480
llvm::ChangePrinter::Quiet
@ Quiet
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition:MachineInstrBuilder.h:373
llvm::isShiftedMask_64
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
Definition:MathExtras.h:286
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition:Debug.cpp:163
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition:Error.cpp:167
llvm::CaptureComponents::Address
@ Address
llvm::PackElem::Hi
@ Hi
llvm::PackElem::Lo
@ Lo
llvm::divideCeil
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition:MathExtras.h:404
llvm::CCAssignFn
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
Definition:CallingConvLower.h:156
llvm::CombineLevel
CombineLevel
Definition:DAGCombine.h:15
llvm::createMips16TargetLowering
const MipsTargetLowering * createMips16TargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
Create MipsTargetLowering objects.
Definition:Mips16ISelLowering.cpp:153
llvm::RecurKind::Or
@ Or
Bitwise or logical OR of integers.
llvm::RecurKind::Add
@ Add
Sum of integers.
llvm::getKillRegState
unsigned getKillRegState(bool B)
Definition:MachineInstrBuilder.h:555
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition:Alignment.h:155
llvm::Op
DWARFExpression::Operation Op
Definition:DWARFExpression.cpp:22
llvm::createMipsSETargetLowering
const MipsTargetLowering * createMipsSETargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
Definition:MipsSEISelLowering.cpp:339
llvm::getAsUnsignedInteger
bool getAsUnsignedInteger(StringRef Str, unsigned Radix, unsigned long long &Result)
Helper functions for StringRef::getAsInteger.
Definition:StringRef.cpp:488
std::swap
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition:BitVector.h:860
N
#define N
RegInfo
Definition:AMDGPUAsmParser.cpp:2770
llvm::Align
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition:Alignment.h:39
llvm::Align::value
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition:Alignment.h:85
llvm::EVT
Extended Value Type.
Definition:ValueTypes.h:35
llvm::EVT::changeVectorElementTypeToInteger
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
Definition:ValueTypes.h:94
llvm::EVT::bitsLT
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
Definition:ValueTypes.h:295
llvm::EVT::getSizeInBits
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition:ValueTypes.h:368
llvm::EVT::isPow2VectorType
bool isPow2VectorType() const
Returns true if the given vector is a power of 2.
Definition:ValueTypes.h:465
llvm::EVT::getSimpleVT
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition:ValueTypes.h:311
llvm::EVT::getFloatingPointVT
static EVT getFloatingPointVT(unsigned BitWidth)
Returns the EVT that represents a floating-point type with the given number of bits.
Definition:ValueTypes.h:59
llvm::EVT::isVector
bool isVector() const
Return true if this is a vector value type.
Definition:ValueTypes.h:168
llvm::EVT::getTypeForEVT
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
Definition:ValueTypes.cpp:210
llvm::EVT::isRound
bool isRound() const
Return true if the size is a power-of-two number of bytes.
Definition:ValueTypes.h:243
llvm::EVT::getVectorElementType
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition:ValueTypes.h:323
llvm::EVT::getVectorNumElements
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition:ValueTypes.h:331
llvm::EVT::isInteger
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition:ValueTypes.h:152
llvm::ISD::ArgFlagsTy
Definition:TargetCallingConv.h:27
llvm::ISD::ArgFlagsTy::isInReg
bool isInReg() const
Definition:TargetCallingConv.h:83
llvm::ISD::ArgFlagsTy::getNonZeroOrigAlign
Align getNonZeroOrigAlign() const
Definition:TargetCallingConv.h:164
llvm::ISD::ArgFlagsTy::isZExt
bool isZExt() const
Definition:TargetCallingConv.h:74
llvm::ISD::ArgFlagsTy::isSplit
bool isSplit() const
Definition:TargetCallingConv.h:136
llvm::ISD::ArgFlagsTy::isSExt
bool isSExt() const
Definition:TargetCallingConv.h:77
llvm::ISD::ArgFlagsTy::isByVal
bool isByVal() const
Definition:TargetCallingConv.h:89
llvm::MachineFunction::CallSiteInfo
Definition:MachineFunction.h:496
llvm::MachineFunction::CallSiteInfo::ArgRegPairs
SmallVector< ArgRegPair, 1 > ArgRegPairs
Vector of call argument and its forwarding register.
Definition:MachineFunction.h:498
llvm::MachinePointerInfo
This class contains a discriminated union of information about pointers in memory operands,...
Definition:MachineMemOperand.h:41
llvm::MachinePointerInfo::getGOT
static MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
Definition:MachineOperand.cpp:1081
llvm::MachinePointerInfo::getFixedStack
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
Definition:MachineOperand.cpp:1072
llvm::MaybeAlign
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition:Alignment.h:117
llvm::MaybeAlign::valueOrOne
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Definition:Alignment.h:141
llvm::MemOp
Definition:TargetLowering.h:115
llvm::SDNodeFlags
These are IR-level optimization flags that may be propagated to SDNodes.
Definition:SelectionDAGNodes.h:381
llvm::SDVTList
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
Definition:SelectionDAGNodes.h:79
llvm::TargetLowering::CallLoweringInfo
This structure contains all information that is necessary for lowering calls.
Definition:TargetLowering.h:4529
llvm::TargetLowering::CallLoweringInfo::IsTailCall
bool IsTailCall
Definition:TargetLowering.h:4545
llvm::TargetLowering::CallLoweringInfo::Callee
SDValue Callee
Definition:TargetLowering.h:4552
llvm::TargetLowering::CallLoweringInfo::DL
SDLoc DL
Definition:TargetLowering.h:4555
llvm::TargetLowering::CallLoweringInfo::IsVarArg
bool IsVarArg
Definition:TargetLowering.h:4534
llvm::TargetLowering::CallLoweringInfo::Ins
SmallVector< ISD::InputArg, 32 > Ins
Definition:TargetLowering.h:4559
llvm::TargetLowering::CallLoweringInfo::Chain
SDValue Chain
Definition:TargetLowering.h:4530
llvm::TargetLowering::CallLoweringInfo::getArgs
ArgListTy & getArgs()
Definition:TargetLowering.h:4708
llvm::TargetLowering::CallLoweringInfo::CB
const CallBase * CB
Definition:TargetLowering.h:4556
llvm::TargetLowering::CallLoweringInfo::Outs
SmallVector< ISD::OutputArg, 32 > Outs
Definition:TargetLowering.h:4557
llvm::TargetLowering::CallLoweringInfo::OutVals
SmallVector< SDValue, 32 > OutVals
Definition:TargetLowering.h:4558
llvm::TargetLowering::CallLoweringInfo::RetTy
Type * RetTy
Definition:TargetLowering.h:4531
llvm::TargetLowering::CallLoweringInfo::CallConv
CallingConv::ID CallConv
Definition:TargetLowering.h:4551
llvm::TargetLowering::CallLoweringInfo::DAG
SelectionDAG & DAG
Definition:TargetLowering.h:4554
llvm::TargetLowering::DAGCombinerInfo
Definition:TargetLowering.h:4228
llvm::TargetLowering::DAGCombinerInfo::isBeforeLegalizeOps
bool isBeforeLegalizeOps() const
Definition:TargetLowering.h:4240
llvm::TargetLowering::DAGCombinerInfo::DAG
SelectionDAG & DAG
Definition:TargetLowering.h:4234
llvm::cl::desc
Definition:CommandLine.h:409

Generated on Thu Jul 17 2025 15:08:33 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp