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