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