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