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#include "MipsGenCallingConv.inc"
3143
3144 CCAssignFn *MipsTargetLowering::CCAssignFnForCall() const{
3145 return CC_Mips_FixedArg;
3146 }
3147
3148 CCAssignFn *MipsTargetLowering::CCAssignFnForReturn() const{
3149 return RetCC_Mips;
3150 }
3151//===----------------------------------------------------------------------===//
3152// Call Calling Convention Implementation
3153//===----------------------------------------------------------------------===//
3154
3155SDValue MipsTargetLowering::passArgOnStack(SDValue StackPtr, unsigned Offset,
3156 SDValue Chain, SDValue Arg,
3157 const SDLoc &DL, bool IsTailCall,
3158 SelectionDAG &DAG) const {
3159 if (!IsTailCall) {
3160 SDValue PtrOff =
3161 DAG.getNode(Opcode: ISD::ADD, DL, VT: getPointerTy(DL: DAG.getDataLayout()), N1: StackPtr,
3162 N2: DAG.getIntPtrConstant(Val: Offset, DL));
3163 return DAG.getStore(Chain, dl: DL, Val: Arg, Ptr: PtrOff, PtrInfo: MachinePointerInfo());
3164 }
3165
3166 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
3167 int FI = MFI.CreateFixedObject(Size: Arg.getValueSizeInBits() / 8, SPOffset: Offset, IsImmutable: false);
3168 SDValue FIN = DAG.getFrameIndex(FI, VT: getPointerTy(DL: DAG.getDataLayout()));
3169 return DAG.getStore(Chain, dl: DL, Val: Arg, Ptr: FIN, PtrInfo: MachinePointerInfo(), Alignment: MaybeAlign(),
3170 MMOFlags: MachineMemOperand::MOVolatile);
3171}
3172
3173void MipsTargetLowering::
3174getOpndList(SmallVectorImpl<SDValue> &Ops,
3175 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
3176 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
3177 bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
3178 SDValue Chain) const {
3179 // Insert node "GP copy globalreg" before call to function.
3180 //
3181 // R_MIPS_CALL* operators (emitted when non-internal functions are called
3182 // in PIC mode) allow symbols to be resolved via lazy binding.
3183 // The lazy binding stub requires GP to point to the GOT.
3184 // Note that we don't need GP to point to the GOT for indirect calls
3185 // (when R_MIPS_CALL* is not used for the call) because Mips linker generates
3186 // lazy binding stub for a function only when R_MIPS_CALL* are the only relocs
3187 // used for the function (that is, Mips linker doesn't generate lazy binding
3188 // stub for a function whose address is taken in the program).
3189 if (IsPICCall && !InternalLinkage && IsCallReloc) {
3190 unsigned GPReg = ABI.IsN64() ? Mips::GP_64 : Mips::GP;
3191 EVT Ty = ABI.IsN64() ? MVT::i64 : MVT::i32;
3192 RegsToPass.push_back(x: std::make_pair(x&: GPReg, y: getGlobalReg(DAG&: CLI.DAG, Ty)));
3193 }
3194
3195 // Build a sequence of copy-to-reg nodes chained together with token
3196 // chain and flag operands which copy the outgoing args into registers.
3197 // The InGlue in necessary since all emitted instructions must be
3198 // stuck together.
3199 SDValue InGlue;
3200
3201 for (auto &R : RegsToPass) {
3202 Chain = CLI.DAG.getCopyToReg(Chain, dl: CLI.DL, Reg: R.first, N: R.second, Glue: InGlue);
3203 InGlue = Chain.getValue(R: 1);
3204 }
3205
3206 // Add argument registers to the end of the list so that they are
3207 // known live into the call.
3208 for (auto &R : RegsToPass)
3209 Ops.push_back(Elt: CLI.DAG.getRegister(Reg: R.first, VT: R.second.getValueType()));
3210
3211 // Add a register mask operand representing the call-preserved registers.
3212 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
3213 const uint32_t *Mask =
3214 TRI->getCallPreservedMask(MF: CLI.DAG.getMachineFunction(), CLI.CallConv);
3215 assert(Mask && "Missing call preserved mask for calling convention");
3216 if (Subtarget.inMips16HardFloat()) {
3217 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Val&: CLI.Callee)) {
3218 StringRef Sym = G->getGlobal()->getName();
3219 Function *F = G->getGlobal()->getParent()->getFunction(Name: Sym);
3220 if (F && F->hasFnAttribute(Kind: "__Mips16RetHelper")) {
3221 Mask = MipsRegisterInfo::getMips16RetHelperMask();
3222 }
3223 }
3224 }
3225 Ops.push_back(Elt: CLI.DAG.getRegisterMask(RegMask: Mask));
3226
3227 if (InGlue.getNode())
3228 Ops.push_back(Elt: InGlue);
3229}
3230
3231void MipsTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI,
3232 SDNode *Node) const {
3233 switch (MI.getOpcode()) {
3234 default:
3235 return;
3236 case Mips::JALR:
3237 case Mips::JALRPseudo:
3238 case Mips::JALR64:
3239 case Mips::JALR64Pseudo:
3240 case Mips::JALR16_MM:
3241 case Mips::JALRC16_MMR6:
3242 case Mips::TAILCALLREG:
3243 case Mips::TAILCALLREG64:
3244 case Mips::TAILCALLR6REG:
3245 case Mips::TAILCALL64R6REG:
3246 case Mips::TAILCALLREG_MM:
3247 case Mips::TAILCALLREG_MMR6: {
3248 if (!EmitJalrReloc ||
3249 Subtarget.inMips16Mode() ||
3250 !isPositionIndependent() ||
3251 Node->getNumOperands() < 1 ||
3252 Node->getOperand(Num: 0).getNumOperands() < 2) {
3253 return;
3254 }
3255 // We are after the callee address, set by LowerCall().
3256 // If added to MI, asm printer will emit .reloc R_MIPS_JALR for the
3257 // symbol.
3258 const SDValue TargetAddr = Node->getOperand(Num: 0).getOperand(i: 1);
3259 StringRef Sym;
3260 if (const GlobalAddressSDNode *G =
3261 dyn_cast_or_null<const GlobalAddressSDNode>(Val: TargetAddr)) {
3262 // We must not emit the R_MIPS_JALR relocation against data symbols
3263 // since this will cause run-time crashes if the linker replaces the
3264 // call instruction with a relative branch to the data symbol.
3265 if (!isa<Function>(Val: G->getGlobal())) {
3266 LLVM_DEBUG(dbgs() << "Not adding R_MIPS_JALR against data symbol "
3267 << G->getGlobal()->getName() << "\n");
3268 return;
3269 }
3270 Sym = G->getGlobal()->getName();
3271 }
3272 else if (const ExternalSymbolSDNode *ES =
3273 dyn_cast_or_null<const ExternalSymbolSDNode>(Val: TargetAddr)) {
3274 Sym = ES->getSymbol();
3275 }
3276
3277 if (Sym.empty())
3278 return;
3279
3280 MachineFunction *MF = MI.getParent()->getParent();
3281 MCSymbol *S = MF->getContext().getOrCreateSymbol(Name: Sym);
3282 LLVM_DEBUG(dbgs() << "Adding R_MIPS_JALR against " << Sym << "\n");
3283 MI.addOperand(Op: MachineOperand::CreateMCSymbol(Sym: S, TargetFlags: MipsII::MO_JALR));
3284 }
3285 }
3286}
3287
3288/// LowerCall - functions arguments are copied from virtual regs to
3289/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
3290SDValue
3291MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
3292 SmallVectorImpl<SDValue> &InVals) const {
3293 SelectionDAG &DAG = CLI.DAG;
3294 SDLoc DL = CLI.DL;
3295 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
3296 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
3297 SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
3298 SDValue Chain = CLI.Chain;
3299 SDValue Callee = CLI.Callee;
3300 bool &IsTailCall = CLI.IsTailCall;
3301 CallingConv::ID CallConv = CLI.CallConv;
3302 bool IsVarArg = CLI.IsVarArg;
3303 const CallBase *CB = CLI.CB;
3304
3305 MachineFunction &MF = DAG.getMachineFunction();
3306 MachineFrameInfo &MFI = MF.getFrameInfo();
3307 const TargetFrameLowering *TFL = Subtarget.getFrameLowering();
3308 MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
3309 bool IsPIC = isPositionIndependent();
3310
3311 // Analyze operands of the call, assigning locations to each operand.
3312 SmallVector<CCValAssign, 16> ArgLocs;
3313 MipsCCState CCInfo(
3314 CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs, *DAG.getContext(),
3315 MipsCCState::getSpecialCallingConvForCallee(Callee: Callee.getNode(), Subtarget));
3316
3317 const ExternalSymbolSDNode *ES =
3318 dyn_cast_or_null<const ExternalSymbolSDNode>(Val: Callee.getNode());
3319
3320 // There is one case where CALLSEQ_START..CALLSEQ_END can be nested, which
3321 // is during the lowering of a call with a byval argument which produces
3322 // a call to memcpy. For the O32 case, this causes the caller to allocate
3323 // stack space for the reserved argument area for the callee, then recursively
3324 // again for the memcpy call. In the NEWABI case, this doesn't occur as those
3325 // ABIs mandate that the callee allocates the reserved argument area. We do
3326 // still produce nested CALLSEQ_START..CALLSEQ_END with zero space though.
3327 //
3328 // If the callee has a byval argument and memcpy is used, we are mandated
3329 // to already have produced a reserved argument area for the callee for O32.
3330 // Therefore, the reserved argument area can be reused for both calls.
3331 //
3332 // Other cases of calling memcpy cannot have a chain with a CALLSEQ_START
3333 // present, as we have yet to hook that node onto the chain.
3334 //
3335 // Hence, the CALLSEQ_START and CALLSEQ_END nodes can be eliminated in this
3336 // case. GCC does a similar trick, in that wherever possible, it calculates
3337 // the maximum out going argument area (including the reserved area), and
3338 // preallocates the stack space on entrance to the caller.
3339 //
3340 // FIXME: We should do the same for efficiency and space.
3341
3342 // Note: The check on the calling convention below must match
3343 // MipsABIInfo::GetCalleeAllocdArgSizeInBytes().
3344 bool MemcpyInByVal = ES && StringRef(ES->getSymbol()) == "memcpy" &&
3345 CallConv != CallingConv::Fast &&
3346 Chain.getOpcode() == ISD::CALLSEQ_START;
3347
3348 // Allocate the reserved argument area. It seems strange to do this from the
3349 // caller side but removing it breaks the frame size calculation.
3350 unsigned ReservedArgArea =
3351 MemcpyInByVal ? 0 : ABI.GetCalleeAllocdArgSizeInBytes(CC: CallConv);
3352 CCInfo.AllocateStack(Size: ReservedArgArea, Alignment: Align(1));
3353
3354 CCInfo.AnalyzeCallOperands(Outs, Fn: CC_Mips);
3355
3356 // Get a count of how many bytes are to be pushed on the stack.
3357 unsigned StackSize = CCInfo.getStackSize();
3358
3359 // Call site info for function parameters tracking and call base type info.
3360 MachineFunction::CallSiteInfo CSInfo;
3361 // Set type id for call site info.
3362 setTypeIdForCallsiteInfo(CB, MF, CSInfo);
3363
3364 // Check if it's really possible to do a tail call.
3365 // For non-musttail calls, restrict to functions that won't require $gp
3366 // restoration. In PIC mode, calling external functions via tail call can
3367 // cause issues with $gp register handling (see D24763).
3368 bool IsMustTail = CLI.CB && CLI.CB->isMustTailCall();
3369 bool CalleeIsLocal = true;
3370 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Val&: Callee)) {
3371 const GlobalValue *GV = G->getGlobal();
3372 bool HasLocalLinkage = GV->hasLocalLinkage() || GV->hasPrivateLinkage();
3373 bool HasHiddenVisibility =
3374 GV->hasHiddenVisibility() || GV->hasProtectedVisibility();
3375 if (GV->isDeclarationForLinker())
3376 CalleeIsLocal = HasLocalLinkage || HasHiddenVisibility;
3377 else
3378 CalleeIsLocal = GV->isDSOLocal();
3379 }
3380
3381 if (IsTailCall) {
3382 if (!UseMipsTailCalls) {
3383 IsTailCall = false;
3384 if (IsMustTail)
3385 report_fatal_error(reason: "failed to perform tail call elimination on a call "
3386 "site marked musttail");
3387 } else {
3388 bool Eligible = isEligibleForTailCallOptimization(
3389 CCInfo, NextStackOffset: StackSize, FI: *MF.getInfo<MipsFunctionInfo>());
3390 if (!Eligible || !CalleeIsLocal) {
3391 IsTailCall = false;
3392 if (IsMustTail)
3393 report_fatal_error(
3394 reason: "failed to perform tail call elimination on a call "
3395 "site marked musttail");
3396 }
3397 }
3398 }
3399
3400 if (IsTailCall)
3401 ++NumTailCalls;
3402
3403 // Chain is the output chain of the last Load/Store or CopyToReg node.
3404 // ByValChain is the output chain of the last Memcpy node created for copying
3405 // byval arguments to the stack.
3406 unsigned StackAlignment = TFL->getStackAlignment();
3407 StackSize = alignTo(Value: StackSize, Align: StackAlignment);
3408
3409 if (!(IsTailCall || MemcpyInByVal))
3410 Chain = DAG.getCALLSEQ_START(Chain, InSize: StackSize, OutSize: 0, DL);
3411
3412 SDValue StackPtr =
3413 DAG.getCopyFromReg(Chain, dl: DL, Reg: ABI.IsN64() ? Mips::SP_64 : Mips::SP,
3414 VT: getPointerTy(DL: DAG.getDataLayout()));
3415 std::deque<std::pair<unsigned, SDValue>> RegsToPass;
3416 SmallVector<SDValue, 8> MemOpChains;
3417
3418 CCInfo.rewindByValRegsInfo();
3419
3420 // Walk the register/memloc assignments, inserting copies/loads.
3421 for (unsigned i = 0, e = ArgLocs.size(), OutIdx = 0; i != e; ++i, ++OutIdx) {
3422 SDValue Arg = OutVals[OutIdx];
3423 CCValAssign &VA = ArgLocs[i];
3424 MVT ValVT = VA.getValVT(), LocVT = VA.getLocVT();
3425 ISD::ArgFlagsTy Flags = Outs[OutIdx].Flags;
3426 bool UseUpperBits = false;
3427
3428 // ByVal Arg.
3429 if (Flags.isByVal()) {
3430 unsigned FirstByValReg, LastByValReg;
3431 unsigned ByValIdx = CCInfo.getInRegsParamsProcessed();
3432 CCInfo.getInRegsParamInfo(InRegsParamRecordIndex: ByValIdx, BeginReg&: FirstByValReg, EndReg&: LastByValReg);
3433
3434 assert(Flags.getByValSize() &&
3435 "ByVal args of size 0 should have been ignored by front-end.");
3436 assert(ByValIdx < CCInfo.getInRegsParamsCount());
3437 assert(!IsTailCall &&
3438 "Do not tail-call optimize if there is a byval argument.");
3439 passByValArg(Chain, DL, RegsToPass, MemOpChains, StackPtr, MFI, DAG, Arg,
3440 FirstReg: FirstByValReg, LastReg: LastByValReg, Flags, isLittle: Subtarget.isLittle(),
3441 VA);
3442 CCInfo.nextInRegsParam();
3443 continue;
3444 }
3445
3446 // Promote the value if needed.
3447 switch (VA.getLocInfo()) {
3448 default:
3449 llvm_unreachable("Unknown loc info!");
3450 case CCValAssign::Full:
3451 if (VA.isRegLoc()) {
3452 if ((ValVT == MVT::f32 && LocVT == MVT::i32) ||
3453 (ValVT == MVT::f64 && LocVT == MVT::i64) ||
3454 (ValVT == MVT::i64 && LocVT == MVT::f64))
3455 Arg = DAG.getNode(Opcode: ISD::BITCAST, DL, VT: LocVT, Operand: Arg);
3456 else if (ValVT == MVT::f64 && LocVT == MVT::i32) {
3457 SDValue Lo = DAG.getNode(Opcode: MipsISD::ExtractElementF64, DL, VT: MVT::i32,
3458 N1: Arg, N2: DAG.getConstant(Val: 0, DL, VT: MVT::i32));
3459 SDValue Hi = DAG.getNode(Opcode: MipsISD::ExtractElementF64, DL, VT: MVT::i32,
3460 N1: Arg, N2: DAG.getConstant(Val: 1, DL, VT: MVT::i32));
3461 if (!Subtarget.isLittle())
3462 std::swap(a&: Lo, b&: Hi);
3463
3464 assert(VA.needsCustom());
3465
3466 Register LocRegLo = VA.getLocReg();
3467 Register LocRegHigh = ArgLocs[++i].getLocReg();
3468 RegsToPass.push_back(x: std::make_pair(x&: LocRegLo, y&: Lo));
3469 RegsToPass.push_back(x: std::make_pair(x&: LocRegHigh, y&: Hi));
3470 continue;
3471 }
3472 }
3473 break;
3474 case CCValAssign::BCvt:
3475 Arg = DAG.getNode(Opcode: ISD::BITCAST, DL, VT: LocVT, Operand: Arg);
3476 break;
3477 case CCValAssign::SExtUpper:
3478 UseUpperBits = true;
3479 [[fallthrough]];
3480 case CCValAssign::SExt:
3481 Arg = DAG.getNode(Opcode: ISD::SIGN_EXTEND, DL, VT: LocVT, Operand: Arg);
3482 break;
3483 case CCValAssign::ZExtUpper:
3484 UseUpperBits = true;
3485 [[fallthrough]];
3486 case CCValAssign::ZExt:
3487 Arg = DAG.getNode(Opcode: ISD::ZERO_EXTEND, DL, VT: LocVT, Operand: Arg);
3488 break;
3489 case CCValAssign::AExtUpper:
3490 UseUpperBits = true;
3491 [[fallthrough]];
3492 case CCValAssign::AExt:
3493 Arg = DAG.getNode(Opcode: ISD::ANY_EXTEND, DL, VT: LocVT, Operand: Arg);
3494 break;
3495 }
3496
3497 if (UseUpperBits) {
3498 unsigned ValSizeInBits = Outs[OutIdx].ArgVT.getSizeInBits();
3499 unsigned LocSizeInBits = VA.getLocVT().getSizeInBits();
3500 Arg = DAG.getNode(
3501 Opcode: ISD::SHL, DL, VT: VA.getLocVT(), N1: Arg,
3502 N2: DAG.getConstant(Val: LocSizeInBits - ValSizeInBits, DL, VT: VA.getLocVT()));
3503 }
3504
3505 // Arguments that can be passed on register must be kept at
3506 // RegsToPass vector
3507 if (VA.isRegLoc()) {
3508 RegsToPass.push_back(x: std::make_pair(x: VA.getLocReg(), y&: Arg));
3509
3510 // If the parameter is passed through reg $D, which splits into
3511 // two physical registers, avoid creating call site info.
3512 if (Mips::AFGR64RegClass.contains(Reg: VA.getLocReg()))
3513 continue;
3514
3515 // Collect CSInfo about which register passes which parameter.
3516 const TargetOptions &Options = DAG.getTarget().Options;
3517 if (Options.EmitCallSiteInfo)
3518 CSInfo.ArgRegPairs.emplace_back(Args: VA.getLocReg(), Args&: i);
3519
3520 continue;
3521 }
3522
3523 // Register can't get to this point...
3524 assert(VA.isMemLoc());
3525
3526 // emit ISD::STORE whichs stores the
3527 // parameter value to a stack Location
3528 MemOpChains.push_back(Elt: passArgOnStack(StackPtr, Offset: VA.getLocMemOffset(),
3529 Chain, Arg, DL, IsTailCall, DAG));
3530 }
3531
3532 // Transform all store nodes into one single node because all store
3533 // nodes are independent of each other.
3534 if (!MemOpChains.empty())
3535 Chain = DAG.getNode(Opcode: ISD::TokenFactor, DL, VT: MVT::Other, Ops: MemOpChains);
3536
3537 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
3538 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
3539 // node so that legalize doesn't hack it.
3540
3541 EVT Ty = Callee.getValueType();
3542 bool GlobalOrExternal = false, IsCallReloc = false;
3543
3544 // The long-calls feature is ignored in case of PIC.
3545 // While we do not support -mshared / -mno-shared properly,
3546 // ignore long-calls in case of -mabicalls too.
3547 if (!Subtarget.isABICalls() && !IsPIC) {
3548 // If the function should be called using "long call",
3549 // get its address into a register to prevent using
3550 // of the `jal` instruction for the direct call.
3551 if (auto *N = dyn_cast<ExternalSymbolSDNode>(Val&: Callee)) {
3552 if (Subtarget.useLongCalls())
3553 Callee = Subtarget.hasSym32()
3554 ? getAddrNonPIC(N, DL: SDLoc(N), Ty, DAG)
3555 : getAddrNonPICSym64(N, DL: SDLoc(N), Ty, DAG);
3556 } else if (auto *N = dyn_cast<GlobalAddressSDNode>(Val&: Callee)) {
3557 bool UseLongCalls = Subtarget.useLongCalls();
3558 // If the function has long-call/far/near attribute
3559 // it overrides command line switch pased to the backend.
3560 if (auto *F = dyn_cast<Function>(Val: N->getGlobal())) {
3561 if (F->hasFnAttribute(Kind: "long-call"))
3562 UseLongCalls = true;
3563 else if (F->hasFnAttribute(Kind: "short-call"))
3564 UseLongCalls = false;
3565 }
3566 if (UseLongCalls)
3567 Callee = Subtarget.hasSym32()
3568 ? getAddrNonPIC(N, DL: SDLoc(N), Ty, DAG)
3569 : getAddrNonPICSym64(N, DL: SDLoc(N), Ty, DAG);
3570 }
3571 }
3572
3573 bool InternalLinkage = false;
3574 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Val&: Callee)) {
3575 if (Subtarget.isTargetCOFF() &&
3576 G->getGlobal()->hasDLLImportStorageClass()) {
3577 assert(Subtarget.isTargetWindows() &&
3578 "Windows is the only supported COFF target");
3579 auto PtrInfo = MachinePointerInfo();
3580 Callee = DAG.getLoad(VT: Ty, dl: DL, Chain,
3581 Ptr: getDllimportSymbol(N: G, DL: SDLoc(G), Ty, DAG), PtrInfo);
3582 } else if (IsPIC) {
3583 const GlobalValue *Val = G->getGlobal();
3584 InternalLinkage = Val->hasInternalLinkage();
3585
3586 if (InternalLinkage)
3587 Callee = getAddrLocal(N: G, DL, Ty, DAG, IsN32OrN64: ABI.IsN32() || ABI.IsN64());
3588 else if (Subtarget.useXGOT()) {
3589 Callee = getAddrGlobalLargeGOT(N: G, DL, Ty, DAG, HiFlag: MipsII::MO_CALL_HI16,
3590 LoFlag: MipsII::MO_CALL_LO16, Chain,
3591 PtrInfo: FuncInfo->callPtrInfo(MF, GV: Val));
3592 IsCallReloc = true;
3593 } else {
3594 Callee = getAddrGlobal(N: G, DL, Ty, DAG, Flag: MipsII::MO_GOT_CALL, Chain,
3595 PtrInfo: FuncInfo->callPtrInfo(MF, GV: Val));
3596 IsCallReloc = true;
3597 }
3598 } else
3599 Callee = DAG.getTargetGlobalAddress(GV: G->getGlobal(), DL,
3600 VT: getPointerTy(DL: DAG.getDataLayout()), offset: 0,
3601 TargetFlags: MipsII::MO_NO_FLAG);
3602 GlobalOrExternal = true;
3603 }
3604 else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Val&: Callee)) {
3605 const char *Sym = S->getSymbol();
3606
3607 if (!IsPIC) // static
3608 Callee = DAG.getTargetExternalSymbol(
3609 Sym, VT: getPointerTy(DL: DAG.getDataLayout()), TargetFlags: MipsII::MO_NO_FLAG);
3610 else if (Subtarget.useXGOT()) {
3611 Callee = getAddrGlobalLargeGOT(N: S, DL, Ty, DAG, HiFlag: MipsII::MO_CALL_HI16,
3612 LoFlag: MipsII::MO_CALL_LO16, Chain,
3613 PtrInfo: FuncInfo->callPtrInfo(MF, ES: Sym));
3614 IsCallReloc = true;
3615 } else { // PIC
3616 Callee = getAddrGlobal(N: S, DL, Ty, DAG, Flag: MipsII::MO_GOT_CALL, Chain,
3617 PtrInfo: FuncInfo->callPtrInfo(MF, ES: Sym));
3618 IsCallReloc = true;
3619 }
3620
3621 GlobalOrExternal = true;
3622 }
3623
3624 SmallVector<SDValue, 8> Ops(1, Chain);
3625 SDVTList NodeTys = DAG.getVTList(VT1: MVT::Other, VT2: MVT::Glue);
3626
3627 getOpndList(Ops, RegsToPass, IsPICCall: IsPIC, GlobalOrExternal, InternalLinkage,
3628 IsCallReloc, CLI, Callee, Chain);
3629
3630 if (IsTailCall) {
3631 MF.getFrameInfo().setHasTailCall();
3632 SDValue Ret = DAG.getNode(Opcode: MipsISD::TailCall, DL, VT: MVT::Other, Ops);
3633 DAG.addCallSiteInfo(Node: Ret.getNode(), CallInfo: std::move(CSInfo));
3634 return Ret;
3635 }
3636
3637 Chain = DAG.getNode(Opcode: MipsISD::JmpLink, DL, VTList: NodeTys, Ops);
3638 SDValue InGlue = Chain.getValue(R: 1);
3639
3640 DAG.addCallSiteInfo(Node: Chain.getNode(), CallInfo: std::move(CSInfo));
3641
3642 // Create the CALLSEQ_END node in the case of where it is not a call to
3643 // memcpy.
3644 if (!(MemcpyInByVal)) {
3645 Chain = DAG.getCALLSEQ_END(Chain, Size1: StackSize, Size2: 0, Glue: InGlue, DL);
3646 InGlue = Chain.getValue(R: 1);
3647 }
3648
3649 // Handle result values, copying them out of physregs into vregs that we
3650 // return.
3651 return LowerCallResult(Chain, InGlue, CallConv, isVarArg: IsVarArg, Ins, dl: DL, DAG,
3652 InVals, CLI);
3653}
3654
3655/// LowerCallResult - Lower the result values of a call into the
3656/// appropriate copies out of appropriate physical registers.
3657SDValue MipsTargetLowering::LowerCallResult(
3658 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool IsVarArg,
3659 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
3660 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
3661 TargetLowering::CallLoweringInfo &CLI) const {
3662 // Assign locations to each value returned by this call.
3663 SmallVector<CCValAssign, 16> RVLocs;
3664 MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
3665 *DAG.getContext());
3666
3667 CCInfo.AnalyzeCallResult(Ins, Fn: RetCC_Mips);
3668
3669 // Copy all of the result registers out of their specified physreg.
3670 for (unsigned i = 0; i != RVLocs.size(); ++i) {
3671 CCValAssign &VA = RVLocs[i];
3672 assert(VA.isRegLoc() && "Can only return in registers!");
3673
3674 SDValue Val = DAG.getCopyFromReg(Chain, dl: DL, Reg: RVLocs[i].getLocReg(),
3675 VT: RVLocs[i].getLocVT(), Glue: InGlue);
3676 Chain = Val.getValue(R: 1);
3677 InGlue = Val.getValue(R: 2);
3678
3679 if (VA.isUpperBitsInLoc()) {
3680 unsigned ValSizeInBits = Ins[i].ArgVT.getSizeInBits();
3681 unsigned LocSizeInBits = VA.getLocVT().getSizeInBits();
3682 unsigned Shift =
3683 VA.getLocInfo() == CCValAssign::ZExtUpper ? ISD::SRL : ISD::SRA;
3684 Val = DAG.getNode(
3685 Opcode: Shift, DL, VT: VA.getLocVT(), N1: Val,
3686 N2: DAG.getConstant(Val: LocSizeInBits - ValSizeInBits, DL, VT: VA.getLocVT()));
3687 }
3688
3689 switch (VA.getLocInfo()) {
3690 default:
3691 llvm_unreachable("Unknown loc info!");
3692 case CCValAssign::Full:
3693 break;
3694 case CCValAssign::BCvt:
3695 Val = DAG.getNode(Opcode: ISD::BITCAST, DL, VT: VA.getValVT(), Operand: Val);
3696 break;
3697 case CCValAssign::AExt:
3698 case CCValAssign::AExtUpper:
3699 Val = DAG.getNode(Opcode: ISD::TRUNCATE, DL, VT: VA.getValVT(), Operand: Val);
3700 break;
3701 case CCValAssign::ZExt:
3702 case CCValAssign::ZExtUpper:
3703 Val = DAG.getNode(Opcode: ISD::AssertZext, DL, VT: VA.getLocVT(), N1: Val,
3704 N2: DAG.getValueType(VA.getValVT()));
3705 Val = DAG.getNode(Opcode: ISD::TRUNCATE, DL, VT: VA.getValVT(), Operand: Val);
3706 break;
3707 case CCValAssign::SExt:
3708 case CCValAssign::SExtUpper:
3709 Val = DAG.getNode(Opcode: ISD::AssertSext, DL, VT: VA.getLocVT(), N1: Val,
3710 N2: DAG.getValueType(VA.getValVT()));
3711 Val = DAG.getNode(Opcode: ISD::TRUNCATE, DL, VT: VA.getValVT(), Operand: Val);
3712 break;
3713 }
3714
3715 InVals.push_back(Elt: Val);
3716 }
3717
3718 return Chain;
3719}
3720
3721static SDValue UnpackFromArgumentSlot(SDValue Val, const CCValAssign &VA,
3722 EVT ArgVT, const SDLoc &DL,
3723 SelectionDAG &DAG) {
3724 MVT LocVT = VA.getLocVT();
3725 EVT ValVT = VA.getValVT();
3726
3727 // Shift into the upper bits if necessary.
3728 switch (VA.getLocInfo()) {
3729 default:
3730 break;
3731 case CCValAssign::AExtUpper:
3732 case CCValAssign::SExtUpper:
3733 case CCValAssign::ZExtUpper: {
3734 unsigned ValSizeInBits = ArgVT.getSizeInBits();
3735 unsigned LocSizeInBits = VA.getLocVT().getSizeInBits();
3736 unsigned Opcode =
3737 VA.getLocInfo() == CCValAssign::ZExtUpper ? ISD::SRL : ISD::SRA;
3738 Val = DAG.getNode(
3739 Opcode, DL, VT: VA.getLocVT(), N1: Val,
3740 N2: DAG.getConstant(Val: LocSizeInBits - ValSizeInBits, DL, VT: VA.getLocVT()));
3741 break;
3742 }
3743 }
3744
3745 // If this is an value smaller than the argument slot size (32-bit for O32,
3746 // 64-bit for N32/N64), it has been promoted in some way to the argument slot
3747 // size. Extract the value and insert any appropriate assertions regarding
3748 // sign/zero extension.
3749 switch (VA.getLocInfo()) {
3750 default:
3751 llvm_unreachable("Unknown loc info!");
3752 case CCValAssign::Full:
3753 break;
3754 case CCValAssign::AExtUpper:
3755 case CCValAssign::AExt:
3756 Val = DAG.getNode(Opcode: ISD::TRUNCATE, DL, VT: ValVT, Operand: Val);
3757 break;
3758 case CCValAssign::SExtUpper:
3759 case CCValAssign::SExt:
3760 Val = DAG.getNode(Opcode: ISD::AssertSext, DL, VT: LocVT, N1: Val, N2: DAG.getValueType(ValVT));
3761 Val = DAG.getNode(Opcode: ISD::TRUNCATE, DL, VT: ValVT, Operand: Val);
3762 break;
3763 case CCValAssign::ZExtUpper:
3764 case CCValAssign::ZExt:
3765 Val = DAG.getNode(Opcode: ISD::AssertZext, DL, VT: LocVT, N1: Val, N2: DAG.getValueType(ValVT));
3766 Val = DAG.getNode(Opcode: ISD::TRUNCATE, DL, VT: ValVT, Operand: Val);
3767 break;
3768 case CCValAssign::BCvt:
3769 Val = DAG.getNode(Opcode: ISD::BITCAST, DL, VT: ValVT, Operand: Val);
3770 break;
3771 }
3772
3773 return Val;
3774}
3775
3776//===----------------------------------------------------------------------===//
3777// Formal Arguments Calling Convention Implementation
3778//===----------------------------------------------------------------------===//
3779/// LowerFormalArguments - transform physical registers into virtual registers
3780/// and generate load operations for arguments places on the stack.
3781SDValue MipsTargetLowering::LowerFormalArguments(
3782 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
3783 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
3784 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
3785 MachineFunction &MF = DAG.getMachineFunction();
3786 MachineFrameInfo &MFI = MF.getFrameInfo();
3787 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
3788
3789 MipsFI->setVarArgsFrameIndex(0);
3790
3791 // Used with vargs to acumulate store chains.
3792 std::vector<SDValue> OutChains;
3793
3794 // Assign locations to all of the incoming arguments.
3795 SmallVector<CCValAssign, 16> ArgLocs;
3796 MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
3797 *DAG.getContext());
3798 CCInfo.AllocateStack(Size: ABI.GetCalleeAllocdArgSizeInBytes(CC: CallConv), Alignment: Align(1));
3799 const Function &Func = DAG.getMachineFunction().getFunction();
3800 Function::const_arg_iterator FuncArg = Func.arg_begin();
3801
3802 if (Func.hasFnAttribute(Kind: "interrupt") && !Func.arg_empty())
3803 report_fatal_error(
3804 reason: "Functions with the interrupt attribute cannot have arguments!");
3805
3806 CCInfo.AnalyzeFormalArguments(Ins, Fn: CC_Mips_FixedArg);
3807 MipsFI->setFormalArgInfo(Size: CCInfo.getStackSize(),
3808 HasByval: CCInfo.getInRegsParamsCount() > 0);
3809
3810 unsigned CurArgIdx = 0;
3811 CCInfo.rewindByValRegsInfo();
3812
3813 for (unsigned i = 0, e = ArgLocs.size(), InsIdx = 0; i != e; ++i, ++InsIdx) {
3814 CCValAssign &VA = ArgLocs[i];
3815 if (Ins[InsIdx].isOrigArg()) {
3816 std::advance(i&: FuncArg, n: Ins[InsIdx].getOrigArgIndex() - CurArgIdx);
3817 CurArgIdx = Ins[InsIdx].getOrigArgIndex();
3818 }
3819 EVT ValVT = VA.getValVT();
3820 ISD::ArgFlagsTy Flags = Ins[InsIdx].Flags;
3821 bool IsRegLoc = VA.isRegLoc();
3822
3823 if (Flags.isByVal()) {
3824 assert(Ins[InsIdx].isOrigArg() && "Byval arguments cannot be implicit");
3825 unsigned FirstByValReg, LastByValReg;
3826 unsigned ByValIdx = CCInfo.getInRegsParamsProcessed();
3827 CCInfo.getInRegsParamInfo(InRegsParamRecordIndex: ByValIdx, BeginReg&: FirstByValReg, EndReg&: LastByValReg);
3828
3829 assert(Flags.getByValSize() &&
3830 "ByVal args of size 0 should have been ignored by front-end.");
3831 assert(ByValIdx < CCInfo.getInRegsParamsCount());
3832 copyByValRegs(Chain, DL, OutChains, DAG, Flags, InVals, FuncArg: &*FuncArg,
3833 FirstReg: FirstByValReg, LastReg: LastByValReg, VA, State&: CCInfo);
3834 CCInfo.nextInRegsParam();
3835 continue;
3836 }
3837
3838 // Arguments stored on registers
3839 if (IsRegLoc) {
3840 MVT RegVT = VA.getLocVT();
3841 Register ArgReg = VA.getLocReg();
3842 const TargetRegisterClass *RC = getRegClassFor(VT: RegVT);
3843
3844 // Transform the arguments stored on
3845 // physical registers into virtual ones
3846 unsigned Reg = addLiveIn(MF&: DAG.getMachineFunction(), PReg: ArgReg, RC);
3847 SDValue ArgValue = DAG.getCopyFromReg(Chain, dl: DL, Reg, VT: RegVT);
3848
3849 ArgValue =
3850 UnpackFromArgumentSlot(Val: ArgValue, VA, ArgVT: Ins[InsIdx].ArgVT, DL, DAG);
3851
3852 // Handle floating point arguments passed in integer registers and
3853 // long double arguments passed in floating point registers.
3854 if ((RegVT == MVT::i32 && ValVT == MVT::f32) ||
3855 (RegVT == MVT::i64 && ValVT == MVT::f64) ||
3856 (RegVT == MVT::f64 && ValVT == MVT::i64))
3857 ArgValue = DAG.getNode(Opcode: ISD::BITCAST, DL, VT: ValVT, Operand: ArgValue);
3858 else if (ABI.IsO32() && RegVT == MVT::i32 &&
3859 ValVT == MVT::f64) {
3860 assert(VA.needsCustom() && "Expected custom argument for f64 split");
3861 CCValAssign &NextVA = ArgLocs[++i];
3862 unsigned Reg2 =
3863 addLiveIn(MF&: DAG.getMachineFunction(), PReg: NextVA.getLocReg(), RC);
3864 SDValue ArgValue2 = DAG.getCopyFromReg(Chain, dl: DL, Reg: Reg2, VT: RegVT);
3865 if (!Subtarget.isLittle())
3866 std::swap(a&: ArgValue, b&: ArgValue2);
3867 ArgValue = DAG.getNode(Opcode: MipsISD::BuildPairF64, DL, VT: MVT::f64,
3868 N1: ArgValue, N2: ArgValue2);
3869 }
3870
3871 InVals.push_back(Elt: ArgValue);
3872 } else { // VA.isRegLoc()
3873 MVT LocVT = VA.getLocVT();
3874
3875 assert(!VA.needsCustom() && "unexpected custom memory argument");
3876
3877 // Only arguments pased on the stack should make it here.
3878 assert(VA.isMemLoc());
3879
3880 // The stack pointer offset is relative to the caller stack frame.
3881 int FI = MFI.CreateFixedObject(Size: LocVT.getSizeInBits() / 8,
3882 SPOffset: VA.getLocMemOffset(), IsImmutable: true);
3883
3884 // Create load nodes to retrieve arguments from the stack
3885 SDValue FIN = DAG.getFrameIndex(FI, VT: getPointerTy(DL: DAG.getDataLayout()));
3886 SDValue ArgValue = DAG.getLoad(
3887 VT: LocVT, dl: DL, Chain, Ptr: FIN,
3888 PtrInfo: MachinePointerInfo::getFixedStack(MF&: DAG.getMachineFunction(), FI));
3889 OutChains.push_back(x: ArgValue.getValue(R: 1));
3890
3891 ArgValue =
3892 UnpackFromArgumentSlot(Val: ArgValue, VA, ArgVT: Ins[InsIdx].ArgVT, DL, DAG);
3893
3894 InVals.push_back(Elt: ArgValue);
3895 }
3896 }
3897
3898 for (unsigned i = 0, e = ArgLocs.size(), InsIdx = 0; i != e; ++i, ++InsIdx) {
3899
3900 if (ArgLocs[i].needsCustom()) {
3901 ++i;
3902 continue;
3903 }
3904
3905 // The mips ABIs for returning structs by value requires that we copy
3906 // the sret argument into $v0 for the return. Save the argument into
3907 // a virtual register so that we can access it from the return points.
3908 if (Ins[InsIdx].Flags.isSRet()) {
3909 unsigned Reg = MipsFI->getSRetReturnReg();
3910 if (!Reg) {
3911 Reg = MF.getRegInfo().createVirtualRegister(
3912 RegClass: getRegClassFor(VT: ABI.IsN64() ? MVT::i64 : MVT::i32));
3913 MipsFI->setSRetReturnReg(Reg);
3914 }
3915 SDValue Copy = DAG.getCopyToReg(Chain: DAG.getEntryNode(), dl: DL, Reg, N: InVals[i]);
3916 Chain = DAG.getNode(Opcode: ISD::TokenFactor, DL, VT: MVT::Other, N1: Copy, N2: Chain);
3917 break;
3918 }
3919 }
3920
3921 if (IsVarArg)
3922 writeVarArgRegs(OutChains, Chain, DL, DAG, State&: CCInfo);
3923
3924 // All stores are grouped in one node to allow the matching between
3925 // the size of Ins and InVals. This only happens when on varg functions
3926 if (!OutChains.empty()) {
3927 OutChains.push_back(x: Chain);
3928 Chain = DAG.getNode(Opcode: ISD::TokenFactor, DL, VT: MVT::Other, Ops: OutChains);
3929 }
3930
3931 return Chain;
3932}
3933
3934//===----------------------------------------------------------------------===//
3935// Return Value Calling Convention Implementation
3936//===----------------------------------------------------------------------===//
3937
3938bool
3939MipsTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
3940 MachineFunction &MF, bool IsVarArg,
3941 const SmallVectorImpl<ISD::OutputArg> &Outs,
3942 LLVMContext &Context, const Type *RetTy) const {
3943 SmallVector<CCValAssign, 16> RVLocs;
3944 MipsCCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
3945 return CCInfo.CheckReturn(Outs, Fn: RetCC_Mips);
3946}
3947
3948bool MipsTargetLowering::shouldSignExtendTypeInLibCall(Type *Ty,
3949 bool IsSigned) const {
3950 if ((ABI.IsN32() || ABI.IsN64()) && Ty->isIntegerTy(BitWidth: 32))
3951 return true;
3952
3953 return IsSigned;
3954}
3955
3956SDValue
3957MipsTargetLowering::LowerInterruptReturn(SmallVectorImpl<SDValue> &RetOps,
3958 const SDLoc &DL,
3959 SelectionDAG &DAG) const {
3960 MachineFunction &MF = DAG.getMachineFunction();
3961 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
3962
3963 MipsFI->setISR();
3964
3965 return DAG.getNode(Opcode: MipsISD::ERet, DL, VT: MVT::Other, Ops: RetOps);
3966}
3967
3968SDValue
3969MipsTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
3970 bool IsVarArg,
3971 const SmallVectorImpl<ISD::OutputArg> &Outs,
3972 const SmallVectorImpl<SDValue> &OutVals,
3973 const SDLoc &DL, SelectionDAG &DAG) const {
3974 // CCValAssign - represent the assignment of
3975 // the return value to a location
3976 SmallVector<CCValAssign, 16> RVLocs;
3977 MachineFunction &MF = DAG.getMachineFunction();
3978
3979 // CCState - Info about the registers and stack slot.
3980 MipsCCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());
3981
3982 // Analyze return values.
3983 CCInfo.AnalyzeReturn(Outs, Fn: RetCC_Mips);
3984
3985 SDValue Glue;
3986 SmallVector<SDValue, 4> RetOps(1, Chain);
3987
3988 // Copy the result values into the output registers.
3989 for (unsigned i = 0; i != RVLocs.size(); ++i) {
3990 SDValue Val = OutVals[i];
3991 CCValAssign &VA = RVLocs[i];
3992 assert(VA.isRegLoc() && "Can only return in registers!");
3993 bool UseUpperBits = false;
3994
3995 switch (VA.getLocInfo()) {
3996 default:
3997 llvm_unreachable("Unknown loc info!");
3998 case CCValAssign::Full:
3999 break;
4000 case CCValAssign::BCvt:
4001 Val = DAG.getNode(Opcode: ISD::BITCAST, DL, VT: VA.getLocVT(), Operand: Val);
4002 break;
4003 case CCValAssign::AExtUpper:
4004 UseUpperBits = true;
4005 [[fallthrough]];
4006 case CCValAssign::AExt:
4007 Val = DAG.getNode(Opcode: ISD::ANY_EXTEND, DL, VT: VA.getLocVT(), Operand: Val);
4008 break;
4009 case CCValAssign::ZExtUpper:
4010 UseUpperBits = true;
4011 [[fallthrough]];
4012 case CCValAssign::ZExt:
4013 Val = DAG.getNode(Opcode: ISD::ZERO_EXTEND, DL, VT: VA.getLocVT(), Operand: Val);
4014 break;
4015 case CCValAssign::SExtUpper:
4016 UseUpperBits = true;
4017 [[fallthrough]];
4018 case CCValAssign::SExt:
4019 Val = DAG.getNode(Opcode: ISD::SIGN_EXTEND, DL, VT: VA.getLocVT(), Operand: Val);
4020 break;
4021 }
4022
4023 if (UseUpperBits) {
4024 unsigned ValSizeInBits = Outs[i].ArgVT.getSizeInBits();
4025 unsigned LocSizeInBits = VA.getLocVT().getSizeInBits();
4026 Val = DAG.getNode(
4027 Opcode: ISD::SHL, DL, VT: VA.getLocVT(), N1: Val,
4028 N2: DAG.getConstant(Val: LocSizeInBits - ValSizeInBits, DL, VT: VA.getLocVT()));
4029 }
4030
4031 Chain = DAG.getCopyToReg(Chain, dl: DL, Reg: VA.getLocReg(), N: Val, Glue);
4032
4033 // Guarantee that all emitted copies are stuck together with flags.
4034 Glue = Chain.getValue(R: 1);
4035 RetOps.push_back(Elt: DAG.getRegister(Reg: VA.getLocReg(), VT: VA.getLocVT()));
4036 }
4037
4038 // The mips ABIs for returning structs by value requires that we copy
4039 // the sret argument into $v0 for the return. We saved the argument into
4040 // a virtual register in the entry block, so now we copy the value out
4041 // and into $v0.
4042 if (MF.getFunction().hasStructRetAttr()) {
4043 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
4044 unsigned Reg = MipsFI->getSRetReturnReg();
4045
4046 if (!Reg)
4047 llvm_unreachable("sret virtual register not created in the entry block");
4048 SDValue Val =
4049 DAG.getCopyFromReg(Chain, dl: DL, Reg, VT: getPointerTy(DL: DAG.getDataLayout()));
4050 unsigned V0 = ABI.IsN64() ? Mips::V0_64 : Mips::V0;
4051
4052 Chain = DAG.getCopyToReg(Chain, dl: DL, Reg: V0, N: Val, Glue);
4053 Glue = Chain.getValue(R: 1);
4054 RetOps.push_back(Elt: DAG.getRegister(Reg: V0, VT: getPointerTy(DL: DAG.getDataLayout())));
4055 }
4056
4057 RetOps[0] = Chain; // Update chain.
4058
4059 // Add the glue if we have it.
4060 if (Glue.getNode())
4061 RetOps.push_back(Elt: Glue);
4062
4063 // ISRs must use "eret".
4064 if (DAG.getMachineFunction().getFunction().hasFnAttribute(Kind: "interrupt"))
4065 return LowerInterruptReturn(RetOps, DL, DAG);
4066
4067 // Standard return on Mips is a "jr $ra"
4068 return DAG.getNode(Opcode: MipsISD::Ret, DL, VT: MVT::Other, Ops: RetOps);
4069}
4070
4071//===----------------------------------------------------------------------===//
4072// Mips Inline Assembly Support
4073//===----------------------------------------------------------------------===//
4074
4075/// getConstraintType - Given a constraint letter, return the type of
4076/// constraint it is for this target.
4077MipsTargetLowering::ConstraintType
4078MipsTargetLowering::getConstraintType(StringRef Constraint) const {
4079 // Mips specific constraints
4080 // GCC config/mips/constraints.md
4081 //
4082 // 'd' : An address register. Equivalent to r
4083 // unless generating MIPS16 code.
4084 // 'y' : Equivalent to r; retained for
4085 // backwards compatibility.
4086 // 'c' : A register suitable for use in an indirect
4087 // jump. This will always be $25 for -mabicalls.
4088 // 'l' : The lo register. 1 word storage.
4089 // 'x' : The hilo register pair. Double word storage.
4090 if (Constraint.size() == 1) {
4091 switch (Constraint[0]) {
4092 default : break;
4093 case 'd':
4094 case 'y':
4095 case 'f':
4096 case 'c':
4097 case 'l':
4098 case 'x':
4099 return C_RegisterClass;
4100 case 'R':
4101 return C_Memory;
4102 }
4103 }
4104
4105 if (Constraint == "ZC")
4106 return C_Memory;
4107
4108 return TargetLowering::getConstraintType(Constraint);
4109}
4110
4111/// Examine constraint type and operand type and determine a weight value.
4112/// This object must already have been set up with the operand type
4113/// and the current alternative constraint selected.
4114TargetLowering::ConstraintWeight
4115MipsTargetLowering::getSingleConstraintMatchWeight(
4116 AsmOperandInfo &info, const char *constraint) const {
4117 ConstraintWeight weight = CW_Invalid;
4118 Value *CallOperandVal = info.CallOperandVal;
4119 // If we don't have a value, we can't do a match,
4120 // but allow it at the lowest weight.
4121 if (!CallOperandVal)
4122 return CW_Default;
4123 Type *type = CallOperandVal->getType();
4124 // Look at the constraint type.
4125 switch (*constraint) {
4126 default:
4127 weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);
4128 break;
4129 case 'd':
4130 case 'y':
4131 if (type->isIntegerTy())
4132 weight = CW_Register;
4133 break;
4134 case 'f': // FPU or MSA register
4135 if (Subtarget.hasMSA() && type->isVectorTy() &&
4136 type->getPrimitiveSizeInBits().getFixedValue() == 128)
4137 weight = CW_Register;
4138 else if (type->isFloatTy())
4139 weight = CW_Register;
4140 break;
4141 case 'c': // $25 for indirect jumps
4142 case 'l': // lo register
4143 case 'x': // hilo register pair
4144 if (type->isIntegerTy())
4145 weight = CW_SpecificReg;
4146 break;
4147 case 'I': // signed 16 bit immediate
4148 case 'J': // integer zero
4149 case 'K': // unsigned 16 bit immediate
4150 case 'L': // signed 32 bit immediate where lower 16 bits are 0
4151 case 'N': // immediate in the range of -65535 to -1 (inclusive)
4152 case 'O': // signed 15 bit immediate (+- 16383)
4153 case 'P': // immediate in the range of 65535 to 1 (inclusive)
4154 if (isa<ConstantInt>(Val: CallOperandVal))
4155 weight = CW_Constant;
4156 break;
4157 case 'R':
4158 weight = CW_Memory;
4159 break;
4160 }
4161 return weight;
4162}
4163
4164/// This is a helper function to parse a physical register string and split it
4165/// into non-numeric and numeric parts (Prefix and Reg). The first boolean flag
4166/// that is returned indicates whether parsing was successful. The second flag
4167/// is true if the numeric part exists.
4168static std::pair<bool, bool> parsePhysicalReg(StringRef C, StringRef &Prefix,
4169 unsigned long long &Reg) {
4170 if (C.front() != '{' || C.back() != '}')
4171 return std::make_pair(x: false, y: false);
4172
4173 // Search for the first numeric character.
4174 StringRef::const_iterator I, B = C.begin() + 1, E = C.end() - 1;
4175 I = std::find_if(first: B, last: E, pred: isdigit);
4176
4177 Prefix = StringRef(B, I - B);
4178
4179 // The second flag is set to false if no numeric characters were found.
4180 if (I == E)
4181 return std::make_pair(x: true, y: false);
4182
4183 // Parse the numeric characters.
4184 return std::make_pair(x: !getAsUnsignedInteger(Str: StringRef(I, E - I), Radix: 10, Result&: Reg),
4185 y: true);
4186}
4187
4188EVT MipsTargetLowering::getTypeForExtReturn(LLVMContext &Context, EVT VT,
4189 ISD::NodeType) const {
4190 bool Cond = !Subtarget.isABI_O32() && VT.getSizeInBits() == 32;
4191 EVT MinVT = getRegisterType(VT: Cond ? MVT::i64 : MVT::i32);
4192 return VT.bitsLT(VT: MinVT) ? MinVT : VT;
4193}
4194
4195std::pair<unsigned, const TargetRegisterClass *> MipsTargetLowering::
4196parseRegForInlineAsmConstraint(StringRef C, MVT VT) const {
4197 const TargetRegisterInfo *TRI =
4198 Subtarget.getRegisterInfo();
4199 const TargetRegisterClass *RC;
4200 StringRef Prefix;
4201 unsigned long long Reg;
4202
4203 std::pair<bool, bool> R = parsePhysicalReg(C, Prefix, Reg);
4204
4205 if (!R.first)
4206 return std::make_pair(x: 0U, y: nullptr);
4207
4208 if ((Prefix == "hi" || Prefix == "lo")) { // Parse hi/lo.
4209 // No numeric characters follow "hi" or "lo".
4210 if (R.second)
4211 return std::make_pair(x: 0U, y: nullptr);
4212
4213 RC = TRI->getRegClass(i: Prefix == "hi" ?
4214 Mips::HI32RegClassID : Mips::LO32RegClassID);
4215 return std::make_pair(x: *(RC->begin()), y&: RC);
4216 } else if (Prefix.starts_with(Prefix: "$msa")) {
4217 // Parse $msa(ir|csr|access|save|modify|request|map|unmap)
4218
4219 // No numeric characters follow the name.
4220 if (R.second)
4221 return std::make_pair(x: 0U, y: nullptr);
4222
4223 Reg = StringSwitch<unsigned long long>(Prefix)
4224 .Case(S: "$msair", Value: Mips::MSAIR)
4225 .Case(S: "$msacsr", Value: Mips::MSACSR)
4226 .Case(S: "$msaaccess", Value: Mips::MSAAccess)
4227 .Case(S: "$msasave", Value: Mips::MSASave)
4228 .Case(S: "$msamodify", Value: Mips::MSAModify)
4229 .Case(S: "$msarequest", Value: Mips::MSARequest)
4230 .Case(S: "$msamap", Value: Mips::MSAMap)
4231 .Case(S: "$msaunmap", Value: Mips::MSAUnmap)
4232 .Default(Value: 0);
4233
4234 if (!Reg)
4235 return std::make_pair(x: 0U, y: nullptr);
4236
4237 RC = TRI->getRegClass(i: Mips::MSACtrlRegClassID);
4238 return std::make_pair(x&: Reg, y&: RC);
4239 }
4240
4241 if (!R.second)
4242 return std::make_pair(x: 0U, y: nullptr);
4243
4244 if (Prefix == "$f") { // Parse $f0-$f31.
4245 // If the targets is single float only, always select 32-bit registers,
4246 // otherwise if the size of FP registers is 64-bit or Reg is an even number,
4247 // select the 64-bit register class. Otherwise, select the 32-bit register
4248 // class.
4249 if (VT == MVT::Other) {
4250 if (Subtarget.isSingleFloat())
4251 VT = MVT::f32;
4252 else
4253 VT = (Subtarget.isFP64bit() || !(Reg % 2)) ? MVT::f64 : MVT::f32;
4254 }
4255
4256 RC = getRegClassFor(VT);
4257
4258 if (RC == &Mips::AFGR64RegClass) {
4259 assert(Reg % 2 == 0);
4260 Reg >>= 1;
4261 }
4262 } else if (Prefix == "$fcc") // Parse $fcc0-$fcc7.
4263 RC = TRI->getRegClass(i: Mips::FCCRegClassID);
4264 else if (Prefix == "$w") { // Parse $w0-$w31.
4265 RC = getRegClassFor(VT: (VT == MVT::Other) ? MVT::v16i8 : VT);
4266 } else { // Parse $0-$31.
4267 assert(Prefix == "$");
4268 RC = getRegClassFor(VT: (VT == MVT::Other) ? MVT::i32 : VT);
4269 }
4270
4271 assert(Reg < RC->getNumRegs());
4272 return std::make_pair(x: *(RC->begin() + Reg), y&: RC);
4273}
4274
4275/// Given a register class constraint, like 'r', if this corresponds directly
4276/// to an LLVM register class, return a register of 0 and the register class
4277/// pointer.
4278std::pair<unsigned, const TargetRegisterClass *>
4279MipsTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
4280 StringRef Constraint,
4281 MVT VT) const {
4282 if (Constraint.size() == 1) {
4283 switch (Constraint[0]) {
4284 case 'd': // Address register. Same as 'r' unless generating MIPS16 code.
4285 case 'y': // Same as 'r'. Exists for compatibility.
4286 case 'r':
4287 if ((VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8 ||
4288 VT == MVT::i1) ||
4289 (VT == MVT::f32 && Subtarget.useSoftFloat())) {
4290 if (Subtarget.inMips16Mode())
4291 return std::make_pair(x: 0U, y: &Mips::CPU16RegsRegClass);
4292 return std::make_pair(x: 0U, y: &Mips::GPR32RegClass);
4293 }
4294 if ((VT == MVT::i64 || (VT == MVT::f64 && Subtarget.useSoftFloat()) ||
4295 (VT == MVT::f64 && Subtarget.isSingleFloat())) &&
4296 !Subtarget.isGP64bit())
4297 return std::make_pair(x: 0U, y: &Mips::GPR32RegClass);
4298 if ((VT == MVT::i64 || (VT == MVT::f64 && Subtarget.useSoftFloat()) ||
4299 (VT == MVT::f64 && Subtarget.isSingleFloat())) &&
4300 Subtarget.isGP64bit())
4301 return std::make_pair(x: 0U, y: &Mips::GPR64RegClass);
4302 // This will generate an error message
4303 return std::make_pair(x: 0U, y: nullptr);
4304 case 'f': // FPU or MSA register
4305 if (VT == MVT::v16i8)
4306 return std::make_pair(x: 0U, y: &Mips::MSA128BRegClass);
4307 else if (VT == MVT::v8i16 || VT == MVT::v8f16)
4308 return std::make_pair(x: 0U, y: &Mips::MSA128HRegClass);
4309 else if (VT == MVT::v4i32 || VT == MVT::v4f32)
4310 return std::make_pair(x: 0U, y: &Mips::MSA128WRegClass);
4311 else if (VT == MVT::v2i64 || VT == MVT::v2f64)
4312 return std::make_pair(x: 0U, y: &Mips::MSA128DRegClass);
4313 else if (VT == MVT::f32)
4314 return std::make_pair(x: 0U, y: &Mips::FGR32RegClass);
4315 else if ((VT == MVT::f64) && (!Subtarget.isSingleFloat())) {
4316 if (Subtarget.isFP64bit())
4317 return std::make_pair(x: 0U, y: &Mips::FGR64RegClass);
4318 return std::make_pair(x: 0U, y: &Mips::AFGR64RegClass);
4319 }
4320 break;
4321 case 'c': // register suitable for indirect jump
4322 if (VT == MVT::i32)
4323 return std::make_pair(x: (unsigned)Mips::T9, y: &Mips::GPR32RegClass);
4324 if (VT == MVT::i64)
4325 return std::make_pair(x: (unsigned)Mips::T9_64, y: &Mips::GPR64RegClass);
4326 // This will generate an error message
4327 return std::make_pair(x: 0U, y: nullptr);
4328 case 'l': // use the `lo` register to store values
4329 // that are no bigger than a word
4330 if (VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8)
4331 return std::make_pair(x: (unsigned)Mips::LO0, y: &Mips::LO32RegClass);
4332 return std::make_pair(x: (unsigned)Mips::LO0_64, y: &Mips::LO64RegClass);
4333 case 'x': // use the concatenated `hi` and `lo` registers
4334 // to store doubleword values
4335 // Fixme: Not triggering the use of both hi and low
4336 // This will generate an error message
4337 return std::make_pair(x: 0U, y: nullptr);
4338 }
4339 }
4340
4341 if (!Constraint.empty()) {
4342 std::pair<unsigned, const TargetRegisterClass *> R;
4343 R = parseRegForInlineAsmConstraint(C: Constraint, VT);
4344
4345 if (R.second)
4346 return R;
4347 }
4348
4349 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
4350}
4351
4352/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
4353/// vector. If it is invalid, don't add anything to Ops.
4354void MipsTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
4355 StringRef Constraint,
4356 std::vector<SDValue> &Ops,
4357 SelectionDAG &DAG) const {
4358 SDLoc DL(Op);
4359 SDValue Result;
4360
4361 // Only support length 1 constraints for now.
4362 if (Constraint.size() > 1)
4363 return;
4364
4365 char ConstraintLetter = Constraint[0];
4366 switch (ConstraintLetter) {
4367 default: break; // This will fall through to the generic implementation
4368 case 'I': // Signed 16 bit constant
4369 // If this fails, the parent routine will give an error
4370 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val&: Op)) {
4371 EVT Type = Op.getValueType();
4372 int64_t Val = C->getSExtValue();
4373 if (isInt<16>(x: Val)) {
4374 Result = DAG.getSignedTargetConstant(Val, DL, VT: Type);
4375 break;
4376 }
4377 }
4378 return;
4379 case 'J': // integer zero
4380 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val&: Op)) {
4381 EVT Type = Op.getValueType();
4382 int64_t Val = C->getZExtValue();
4383 if (Val == 0) {
4384 Result = DAG.getTargetConstant(Val: 0, DL, VT: Type);
4385 break;
4386 }
4387 }
4388 return;
4389 case 'K': // unsigned 16 bit immediate
4390 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val&: Op)) {
4391 EVT Type = Op.getValueType();
4392 uint64_t Val = C->getZExtValue();
4393 if (isUInt<16>(x: Val)) {
4394 Result = DAG.getTargetConstant(Val, DL, VT: Type);
4395 break;
4396 }
4397 }
4398 return;
4399 case 'L': // signed 32 bit immediate where lower 16 bits are 0
4400 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val&: Op)) {
4401 EVT Type = Op.getValueType();
4402 int64_t Val = C->getSExtValue();
4403 if ((isInt<32>(x: Val)) && ((Val & 0xffff) == 0)){
4404 Result = DAG.getSignedTargetConstant(Val, DL, VT: Type);
4405 break;
4406 }
4407 }
4408 return;
4409 case 'N': // immediate in the range of -65535 to -1 (inclusive)
4410 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val&: Op)) {
4411 EVT Type = Op.getValueType();
4412 int64_t Val = C->getSExtValue();
4413 if ((Val >= -65535) && (Val <= -1)) {
4414 Result = DAG.getSignedTargetConstant(Val, DL, VT: Type);
4415 break;
4416 }
4417 }
4418 return;
4419 case 'O': // signed 15 bit immediate
4420 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val&: Op)) {
4421 EVT Type = Op.getValueType();
4422 int64_t Val = C->getSExtValue();
4423 if ((isInt<15>(x: Val))) {
4424 Result = DAG.getSignedTargetConstant(Val, DL, VT: Type);
4425 break;
4426 }
4427 }
4428 return;
4429 case 'P': // immediate in the range of 1 to 65535 (inclusive)
4430 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val&: Op)) {
4431 EVT Type = Op.getValueType();
4432 int64_t Val = C->getSExtValue();
4433 if ((Val <= 65535) && (Val >= 1)) {
4434 Result = DAG.getTargetConstant(Val, DL, VT: Type);
4435 break;
4436 }
4437 }
4438 return;
4439 }
4440
4441 if (Result.getNode()) {
4442 Ops.push_back(x: Result);
4443 return;
4444 }
4445
4446 TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
4447}
4448
4449bool MipsTargetLowering::isLegalAddressingMode(const DataLayout &DL,
4450 const AddrMode &AM, Type *Ty,
4451 unsigned AS,
4452 Instruction *I) const {
4453 // No global is ever allowed as a base.
4454 if (AM.BaseGV)
4455 return false;
4456
4457 switch (AM.Scale) {
4458 case 0: // "r+i" or just "i", depending on HasBaseReg.
4459 break;
4460 case 1:
4461 if (!AM.HasBaseReg) // allow "r+i".
4462 break;
4463 return false; // disallow "r+r" or "r+r+i".
4464 default:
4465 return false;
4466 }
4467
4468 return true;
4469}
4470
4471bool
4472MipsTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
4473 // The Mips target isn't yet aware of offsets.
4474 return false;
4475}
4476
4477EVT MipsTargetLowering::getOptimalMemOpType(
4478 LLVMContext &Context, const MemOp &Op,
4479 const AttributeList &FuncAttributes) const {
4480 if (Subtarget.hasMips64())
4481 return MVT::i64;
4482
4483 return MVT::i32;
4484}
4485
4486bool MipsTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
4487 bool ForCodeSize) const {
4488 if (VT != MVT::f32 && VT != MVT::f64)
4489 return false;
4490 if (Imm.isNegZero())
4491 return false;
4492 return Imm.isZero();
4493}
4494
4495bool MipsTargetLowering::isLegalICmpImmediate(int64_t Imm) const {
4496 return isInt<16>(x: Imm);
4497}
4498
4499bool MipsTargetLowering::isLegalAddImmediate(int64_t Imm) const {
4500 return isInt<16>(x: Imm);
4501}
4502
4503unsigned MipsTargetLowering::getJumpTableEncoding() const {
4504 if (!isPositionIndependent())
4505 return MachineJumpTableInfo::EK_BlockAddress;
4506 if (ABI.IsN64())
4507 return MachineJumpTableInfo::EK_GPRel64BlockAddress;
4508 return MachineJumpTableInfo::EK_GPRel32BlockAddress;
4509}
4510
4511SDValue MipsTargetLowering::getPICJumpTableRelocBase(SDValue Table,
4512 SelectionDAG &DAG) const {
4513 if (!isPositionIndependent())
4514 return Table;
4515 return DAG.getGLOBAL_OFFSET_TABLE(VT: getPointerTy(DL: DAG.getDataLayout()));
4516}
4517
4518bool MipsTargetLowering::useSoftFloat() const {
4519 return Subtarget.useSoftFloat();
4520}
4521
4522void MipsTargetLowering::copyByValRegs(
4523 SDValue Chain, const SDLoc &DL, std::vector<SDValue> &OutChains,
4524 SelectionDAG &DAG, const ISD::ArgFlagsTy &Flags,
4525 SmallVectorImpl<SDValue> &InVals, const Argument *FuncArg,
4526 unsigned FirstReg, unsigned LastReg, const CCValAssign &VA,
4527 MipsCCState &State) const {
4528 MachineFunction &MF = DAG.getMachineFunction();
4529 MachineFrameInfo &MFI = MF.getFrameInfo();
4530 unsigned GPRSizeInBytes = Subtarget.getGPRSizeInBytes();
4531 unsigned NumRegs = LastReg - FirstReg;
4532 unsigned RegAreaSize = NumRegs * GPRSizeInBytes;
4533 unsigned FrameObjSize = std::max(a: Flags.getByValSize(), b: RegAreaSize);
4534 int FrameObjOffset;
4535 ArrayRef<MCPhysReg> ByValArgRegs = ABI.GetByValArgRegs();
4536
4537 if (RegAreaSize)
4538 FrameObjOffset =
4539 (int)ABI.GetCalleeAllocdArgSizeInBytes(CC: State.getCallingConv()) -
4540 (int)((ByValArgRegs.size() - FirstReg) * GPRSizeInBytes);
4541 else
4542 FrameObjOffset = VA.getLocMemOffset();
4543
4544 // Create frame object.
4545 EVT PtrTy = getPointerTy(DL: DAG.getDataLayout());
4546 // Make the fixed object stored to mutable so that the load instructions
4547 // referencing it have their memory dependencies added.
4548 // Set the frame object as isAliased which clears the underlying objects
4549 // vector in ScheduleDAGInstrs::buildSchedGraph() resulting in addition of all
4550 // stores as dependencies for loads referencing this fixed object.
4551 int FI = MFI.CreateFixedObject(Size: FrameObjSize, SPOffset: FrameObjOffset, IsImmutable: false, isAliased: true);
4552 SDValue FIN = DAG.getFrameIndex(FI, VT: PtrTy);
4553 InVals.push_back(Elt: FIN);
4554
4555 if (!NumRegs)
4556 return;
4557
4558 // Copy arg registers.
4559 MVT RegTy = MVT::getIntegerVT(BitWidth: GPRSizeInBytes * 8);
4560 const TargetRegisterClass *RC = getRegClassFor(VT: RegTy);
4561
4562 for (unsigned I = 0; I < NumRegs; ++I) {
4563 unsigned ArgReg = ByValArgRegs[FirstReg + I];
4564 unsigned VReg = addLiveIn(MF, PReg: ArgReg, RC);
4565 unsigned Offset = I * GPRSizeInBytes;
4566 SDValue StorePtr = DAG.getNode(Opcode: ISD::ADD, DL, VT: PtrTy, N1: FIN,
4567 N2: DAG.getConstant(Val: Offset, DL, VT: PtrTy));
4568 SDValue Store = DAG.getStore(Chain, dl: DL, Val: DAG.getRegister(Reg: VReg, VT: RegTy),
4569 Ptr: StorePtr, PtrInfo: MachinePointerInfo(FuncArg, Offset));
4570 OutChains.push_back(x: Store);
4571 }
4572}
4573
4574// Copy byVal arg to registers and stack.
4575void MipsTargetLowering::passByValArg(
4576 SDValue Chain, const SDLoc &DL,
4577 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
4578 SmallVectorImpl<SDValue> &MemOpChains, SDValue StackPtr,
4579 MachineFrameInfo &MFI, SelectionDAG &DAG, SDValue Arg, unsigned FirstReg,
4580 unsigned LastReg, const ISD::ArgFlagsTy &Flags, bool isLittle,
4581 const CCValAssign &VA) const {
4582 unsigned ByValSizeInBytes = Flags.getByValSize();
4583 unsigned OffsetInBytes = 0; // From beginning of struct
4584 unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes();
4585 Align Alignment =
4586 std::min(a: Flags.getNonZeroByValAlign(), b: Align(RegSizeInBytes));
4587 EVT PtrTy = getPointerTy(DL: DAG.getDataLayout()),
4588 RegTy = MVT::getIntegerVT(BitWidth: RegSizeInBytes * 8);
4589 unsigned NumRegs = LastReg - FirstReg;
4590
4591 if (NumRegs) {
4592 ArrayRef<MCPhysReg> ArgRegs = ABI.GetByValArgRegs();
4593 bool LeftoverBytes = (NumRegs * RegSizeInBytes > ByValSizeInBytes);
4594 unsigned I = 0;
4595
4596 // Copy words to registers.
4597 for (; I < NumRegs - LeftoverBytes; ++I, OffsetInBytes += RegSizeInBytes) {
4598 SDValue LoadPtr = DAG.getNode(Opcode: ISD::ADD, DL, VT: PtrTy, N1: Arg,
4599 N2: DAG.getConstant(Val: OffsetInBytes, DL, VT: PtrTy));
4600 SDValue LoadVal = DAG.getLoad(VT: RegTy, dl: DL, Chain, Ptr: LoadPtr,
4601 PtrInfo: MachinePointerInfo(), Alignment);
4602 MemOpChains.push_back(Elt: LoadVal.getValue(R: 1));
4603 unsigned ArgReg = ArgRegs[FirstReg + I];
4604 RegsToPass.push_back(x: std::make_pair(x&: ArgReg, y&: LoadVal));
4605 }
4606
4607 // Return if the struct has been fully copied.
4608 if (ByValSizeInBytes == OffsetInBytes)
4609 return;
4610
4611 // Copy the remainder of the byval argument with sub-word loads and shifts.
4612 if (LeftoverBytes) {
4613 SDValue Val;
4614
4615 for (unsigned LoadSizeInBytes = RegSizeInBytes / 2, TotalBytesLoaded = 0;
4616 OffsetInBytes < ByValSizeInBytes; LoadSizeInBytes /= 2) {
4617 unsigned RemainingSizeInBytes = ByValSizeInBytes - OffsetInBytes;
4618
4619 if (RemainingSizeInBytes < LoadSizeInBytes)
4620 continue;
4621
4622 // Load subword.
4623 SDValue LoadPtr = DAG.getNode(Opcode: ISD::ADD, DL, VT: PtrTy, N1: Arg,
4624 N2: DAG.getConstant(Val: OffsetInBytes, DL,
4625 VT: PtrTy));
4626 SDValue LoadVal = DAG.getExtLoad(
4627 ExtType: ISD::ZEXTLOAD, dl: DL, VT: RegTy, Chain, Ptr: LoadPtr, PtrInfo: MachinePointerInfo(),
4628 MemVT: MVT::getIntegerVT(BitWidth: LoadSizeInBytes * 8), Alignment);
4629 MemOpChains.push_back(Elt: LoadVal.getValue(R: 1));
4630
4631 // Shift the loaded value.
4632 unsigned Shamt;
4633
4634 if (isLittle)
4635 Shamt = TotalBytesLoaded * 8;
4636 else
4637 Shamt = (RegSizeInBytes - (TotalBytesLoaded + LoadSizeInBytes)) * 8;
4638
4639 SDValue Shift = DAG.getNode(Opcode: ISD::SHL, DL, VT: RegTy, N1: LoadVal,
4640 N2: DAG.getConstant(Val: Shamt, DL, VT: MVT::i32));
4641
4642 if (Val.getNode())
4643 Val = DAG.getNode(Opcode: ISD::OR, DL, VT: RegTy, N1: Val, N2: Shift);
4644 else
4645 Val = Shift;
4646
4647 OffsetInBytes += LoadSizeInBytes;
4648 TotalBytesLoaded += LoadSizeInBytes;
4649 Alignment = std::min(a: Alignment, b: Align(LoadSizeInBytes));
4650 }
4651
4652 unsigned ArgReg = ArgRegs[FirstReg + I];
4653 RegsToPass.push_back(x: std::make_pair(x&: ArgReg, y&: Val));
4654 return;
4655 }
4656 }
4657
4658 // Copy remainder of byval arg to it with memcpy.
4659 unsigned MemCpySize = ByValSizeInBytes - OffsetInBytes;
4660 SDValue Src = DAG.getNode(Opcode: ISD::ADD, DL, VT: PtrTy, N1: Arg,
4661 N2: DAG.getConstant(Val: OffsetInBytes, DL, VT: PtrTy));
4662 SDValue Dst = DAG.getNode(Opcode: ISD::ADD, DL, VT: PtrTy, N1: StackPtr,
4663 N2: DAG.getIntPtrConstant(Val: VA.getLocMemOffset(), DL));
4664 Chain = DAG.getMemcpy(
4665 Chain, dl: DL, Dst, Src, Size: DAG.getConstant(Val: MemCpySize, DL, VT: PtrTy), DstAlign: Alignment,
4666 SrcAlign: Alignment, /*isVolatile=*/isVol: false, /*AlwaysInline=*/false,
4667 /*CI=*/nullptr, OverrideTailCall: std::nullopt, DstPtrInfo: MachinePointerInfo(), SrcPtrInfo: MachinePointerInfo());
4668 MemOpChains.push_back(Elt: Chain);
4669}
4670
4671void MipsTargetLowering::writeVarArgRegs(std::vector<SDValue> &OutChains,
4672 SDValue Chain, const SDLoc &DL,
4673 SelectionDAG &DAG,
4674 CCState &State) const {
4675 ArrayRef<MCPhysReg> ArgRegs = ABI.getVarArgRegs(isGP64bit: Subtarget.isGP64bit());
4676 unsigned Idx = State.getFirstUnallocated(Regs: ArgRegs);
4677 unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes();
4678 MVT RegTy = MVT::getIntegerVT(BitWidth: RegSizeInBytes * 8);
4679 const TargetRegisterClass *RC = getRegClassFor(VT: RegTy);
4680 MachineFunction &MF = DAG.getMachineFunction();
4681 MachineFrameInfo &MFI = MF.getFrameInfo();
4682 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
4683
4684 // Offset of the first variable argument from stack pointer.
4685 int VaArgOffset;
4686
4687 if (ArgRegs.size() == Idx)
4688 VaArgOffset = alignTo(Value: State.getStackSize(), Align: RegSizeInBytes);
4689 else {
4690 VaArgOffset =
4691 (int)ABI.GetCalleeAllocdArgSizeInBytes(CC: State.getCallingConv()) -
4692 (int)(RegSizeInBytes * (ArgRegs.size() - Idx));
4693 }
4694
4695 // Record the frame index of the first variable argument
4696 // which is a value necessary to VASTART.
4697 int FI = MFI.CreateFixedObject(Size: RegSizeInBytes, SPOffset: VaArgOffset, IsImmutable: true);
4698 MipsFI->setVarArgsFrameIndex(FI);
4699
4700 // Copy the integer registers that have not been used for argument passing
4701 // to the argument register save area. For O32, the save area is allocated
4702 // in the caller's stack frame, while for N32/64, it is allocated in the
4703 // callee's stack frame.
4704 for (unsigned I = Idx; I < ArgRegs.size();
4705 ++I, VaArgOffset += RegSizeInBytes) {
4706 unsigned Reg = addLiveIn(MF, PReg: ArgRegs[I], RC);
4707 SDValue ArgValue = DAG.getCopyFromReg(Chain, dl: DL, Reg, VT: RegTy);
4708 FI = MFI.CreateFixedObject(Size: RegSizeInBytes, SPOffset: VaArgOffset, IsImmutable: true);
4709 SDValue PtrOff = DAG.getFrameIndex(FI, VT: getPointerTy(DL: DAG.getDataLayout()));
4710 SDValue Store =
4711 DAG.getStore(Chain, dl: DL, Val: ArgValue, Ptr: PtrOff, PtrInfo: MachinePointerInfo());
4712 cast<StoreSDNode>(Val: Store.getNode())->getMemOperand()->setValue(
4713 (Value *)nullptr);
4714 OutChains.push_back(x: Store);
4715 }
4716}
4717
4718void MipsTargetLowering::HandleByVal(CCState *State, unsigned &Size,
4719 Align Alignment) const {
4720 const TargetFrameLowering *TFL = Subtarget.getFrameLowering();
4721
4722 assert(Size && "Byval argument's size shouldn't be 0.");
4723
4724 Alignment = std::min(a: Alignment, b: TFL->getStackAlign());
4725
4726 unsigned FirstReg = 0;
4727 unsigned NumRegs = 0;
4728
4729 if (State->getCallingConv() != CallingConv::Fast) {
4730 unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes();
4731 ArrayRef<MCPhysReg> IntArgRegs = ABI.GetByValArgRegs();
4732 // FIXME: The O32 case actually describes no shadow registers.
4733 const MCPhysReg *ShadowRegs =
4734 ABI.IsO32() ? IntArgRegs.data() : Mips64DPRegs;
4735
4736 // We used to check the size as well but we can't do that anymore since
4737 // CCState::HandleByVal() rounds up the size after calling this function.
4738 assert(
4739 Alignment >= Align(RegSizeInBytes) &&
4740 "Byval argument's alignment should be a multiple of RegSizeInBytes.");
4741
4742 FirstReg = State->getFirstUnallocated(Regs: IntArgRegs);
4743
4744 // If Alignment > RegSizeInBytes, the first arg register must be even.
4745 // FIXME: This condition happens to do the right thing but it's not the
4746 // right way to test it. We want to check that the stack frame offset
4747 // of the register is aligned.
4748 if ((Alignment > RegSizeInBytes) && (FirstReg % 2)) {
4749 State->AllocateReg(Reg: IntArgRegs[FirstReg], ShadowReg: ShadowRegs[FirstReg]);
4750 ++FirstReg;
4751 }
4752
4753 // Mark the registers allocated.
4754 Size = alignTo(Value: Size, Align: RegSizeInBytes);
4755 for (unsigned I = FirstReg; Size > 0 && (I < IntArgRegs.size());
4756 Size -= RegSizeInBytes, ++I, ++NumRegs)
4757 State->AllocateReg(Reg: IntArgRegs[I], ShadowReg: ShadowRegs[I]);
4758 }
4759
4760 State->addInRegsParamInfo(RegBegin: FirstReg, RegEnd: FirstReg + NumRegs);
4761}
4762
4763MachineBasicBlock *MipsTargetLowering::emitPseudoSELECT(MachineInstr &MI,
4764 MachineBasicBlock *BB,
4765 bool isFPCmp,
4766 unsigned Opc) const {
4767 assert(!(Subtarget.hasMips4() || Subtarget.hasMips32()) &&
4768 "Subtarget already supports SELECT nodes with the use of"
4769 "conditional-move instructions.");
4770
4771 const TargetInstrInfo *TII =
4772 Subtarget.getInstrInfo();
4773 DebugLoc DL = MI.getDebugLoc();
4774
4775 // To "insert" a SELECT instruction, we actually have to insert the
4776 // diamond control-flow pattern. The incoming instruction knows the
4777 // destination vreg to set, the condition code register to branch on, the
4778 // true/false values to select between, and a branch opcode to use.
4779 const BasicBlock *LLVM_BB = BB->getBasicBlock();
4780 MachineFunction::iterator It = ++BB->getIterator();
4781
4782 // thisMBB:
4783 // ...
4784 // TrueVal = ...
4785 // setcc r1, r2, r3
4786 // bNE r1, r0, copy1MBB
4787 // fallthrough --> copy0MBB
4788 MachineBasicBlock *thisMBB = BB;
4789 MachineFunction *F = BB->getParent();
4790 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(BB: LLVM_BB);
4791 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(BB: LLVM_BB);
4792 F->insert(MBBI: It, MBB: copy0MBB);
4793 F->insert(MBBI: It, MBB: sinkMBB);
4794
4795 // Transfer the remainder of BB and its successor edges to sinkMBB.
4796 sinkMBB->splice(Where: sinkMBB->begin(), Other: BB,
4797 From: std::next(x: MachineBasicBlock::iterator(MI)), To: BB->end());
4798 sinkMBB->transferSuccessorsAndUpdatePHIs(FromMBB: BB);
4799
4800 // Next, add the true and fallthrough blocks as its successors.
4801 BB->addSuccessor(Succ: copy0MBB);
4802 BB->addSuccessor(Succ: sinkMBB);
4803
4804 if (isFPCmp) {
4805 // bc1[tf] cc, sinkMBB
4806 BuildMI(BB, MIMD: DL, MCID: TII->get(Opcode: Opc))
4807 .addReg(RegNo: MI.getOperand(i: 1).getReg())
4808 .addMBB(MBB: sinkMBB);
4809 } else {
4810 // bne rs, $0, sinkMBB
4811 BuildMI(BB, MIMD: DL, MCID: TII->get(Opcode: Opc))
4812 .addReg(RegNo: MI.getOperand(i: 1).getReg())
4813 .addReg(RegNo: Mips::ZERO)
4814 .addMBB(MBB: sinkMBB);
4815 }
4816
4817 // copy0MBB:
4818 // %FalseValue = ...
4819 // # fallthrough to sinkMBB
4820 BB = copy0MBB;
4821
4822 // Update machine-CFG edges
4823 BB->addSuccessor(Succ: sinkMBB);
4824
4825 // sinkMBB:
4826 // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
4827 // ...
4828 BB = sinkMBB;
4829
4830 BuildMI(BB&: *BB, I: BB->begin(), MIMD: DL, MCID: TII->get(Opcode: Mips::PHI), DestReg: MI.getOperand(i: 0).getReg())
4831 .addReg(RegNo: MI.getOperand(i: 2).getReg())
4832 .addMBB(MBB: thisMBB)
4833 .addReg(RegNo: MI.getOperand(i: 3).getReg())
4834 .addMBB(MBB: copy0MBB);
4835
4836 MI.eraseFromParent(); // The pseudo instruction is gone now.
4837
4838 return BB;
4839}
4840
4841MachineBasicBlock *
4842MipsTargetLowering::emitPseudoD_SELECT(MachineInstr &MI,
4843 MachineBasicBlock *BB) const {
4844 assert(!(Subtarget.hasMips4() || Subtarget.hasMips32()) &&
4845 "Subtarget already supports SELECT nodes with the use of"
4846 "conditional-move instructions.");
4847
4848 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
4849 DebugLoc DL = MI.getDebugLoc();
4850
4851 // D_SELECT substitutes two SELECT nodes that goes one after another and
4852 // have the same condition operand. On machines which don't have
4853 // conditional-move instruction, it reduces unnecessary branch instructions
4854 // which are result of using two diamond patterns that are result of two
4855 // SELECT pseudo instructions.
4856 const BasicBlock *LLVM_BB = BB->getBasicBlock();
4857 MachineFunction::iterator It = ++BB->getIterator();
4858
4859 // thisMBB:
4860 // ...
4861 // TrueVal = ...
4862 // setcc r1, r2, r3
4863 // bNE r1, r0, copy1MBB
4864 // fallthrough --> copy0MBB
4865 MachineBasicBlock *thisMBB = BB;
4866 MachineFunction *F = BB->getParent();
4867 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(BB: LLVM_BB);
4868 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(BB: LLVM_BB);
4869 F->insert(MBBI: It, MBB: copy0MBB);
4870 F->insert(MBBI: It, MBB: sinkMBB);
4871
4872 // Transfer the remainder of BB and its successor edges to sinkMBB.
4873 sinkMBB->splice(Where: sinkMBB->begin(), Other: BB,
4874 From: std::next(x: MachineBasicBlock::iterator(MI)), To: BB->end());
4875 sinkMBB->transferSuccessorsAndUpdatePHIs(FromMBB: BB);
4876
4877 // Next, add the true and fallthrough blocks as its successors.
4878 BB->addSuccessor(Succ: copy0MBB);
4879 BB->addSuccessor(Succ: sinkMBB);
4880
4881 // bne rs, $0, sinkMBB
4882 BuildMI(BB, MIMD: DL, MCID: TII->get(Opcode: Mips::BNE))
4883 .addReg(RegNo: MI.getOperand(i: 2).getReg())
4884 .addReg(RegNo: Mips::ZERO)
4885 .addMBB(MBB: sinkMBB);
4886
4887 // copy0MBB:
4888 // %FalseValue = ...
4889 // # fallthrough to sinkMBB
4890 BB = copy0MBB;
4891
4892 // Update machine-CFG edges
4893 BB->addSuccessor(Succ: sinkMBB);
4894
4895 // sinkMBB:
4896 // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
4897 // ...
4898 BB = sinkMBB;
4899
4900 // Use two PHI nodes to select two reults
4901 BuildMI(BB&: *BB, I: BB->begin(), MIMD: DL, MCID: TII->get(Opcode: Mips::PHI), DestReg: MI.getOperand(i: 0).getReg())
4902 .addReg(RegNo: MI.getOperand(i: 3).getReg())
4903 .addMBB(MBB: thisMBB)
4904 .addReg(RegNo: MI.getOperand(i: 5).getReg())
4905 .addMBB(MBB: copy0MBB);
4906 BuildMI(BB&: *BB, I: BB->begin(), MIMD: DL, MCID: TII->get(Opcode: Mips::PHI), DestReg: MI.getOperand(i: 1).getReg())
4907 .addReg(RegNo: MI.getOperand(i: 4).getReg())
4908 .addMBB(MBB: thisMBB)
4909 .addReg(RegNo: MI.getOperand(i: 6).getReg())
4910 .addMBB(MBB: copy0MBB);
4911
4912 MI.eraseFromParent(); // The pseudo instruction is gone now.
4913
4914 return BB;
4915}
4916
4917// Copies the function MipsAsmParser::matchCPURegisterName.
4918int MipsTargetLowering::getCPURegisterIndex(StringRef Name) const {
4919 int CC;
4920
4921 CC = StringSwitch<unsigned>(Name)
4922 .Case(S: "zero", Value: 0)
4923 .Case(S: "at", Value: 1)
4924 .Case(S: "AT", Value: 1)
4925 .Case(S: "a0", Value: 4)
4926 .Case(S: "a1", Value: 5)
4927 .Case(S: "a2", Value: 6)
4928 .Case(S: "a3", Value: 7)
4929 .Case(S: "v0", Value: 2)
4930 .Case(S: "v1", Value: 3)
4931 .Case(S: "s0", Value: 16)
4932 .Case(S: "s1", Value: 17)
4933 .Case(S: "s2", Value: 18)
4934 .Case(S: "s3", Value: 19)
4935 .Case(S: "s4", Value: 20)
4936 .Case(S: "s5", Value: 21)
4937 .Case(S: "s6", Value: 22)
4938 .Case(S: "s7", Value: 23)
4939 .Case(S: "k0", Value: 26)
4940 .Case(S: "k1", Value: 27)
4941 .Case(S: "gp", Value: 28)
4942 .Case(S: "sp", Value: 29)
4943 .Case(S: "fp", Value: 30)
4944 .Case(S: "s8", Value: 30)
4945 .Case(S: "ra", Value: 31)
4946 .Case(S: "t0", Value: 8)
4947 .Case(S: "t1", Value: 9)
4948 .Case(S: "t2", Value: 10)
4949 .Case(S: "t3", Value: 11)
4950 .Case(S: "t4", Value: 12)
4951 .Case(S: "t5", Value: 13)
4952 .Case(S: "t6", Value: 14)
4953 .Case(S: "t7", Value: 15)
4954 .Case(S: "t8", Value: 24)
4955 .Case(S: "t9", Value: 25)
4956 .Default(Value: -1);
4957
4958 if (!(ABI.IsN32() || ABI.IsN64()))
4959 return CC;
4960
4961 // Although SGI documentation just cuts out t0-t3 for n32/n64,
4962 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
4963 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
4964 if (8 <= CC && CC <= 11)
4965 CC += 4;
4966
4967 if (CC == -1)
4968 CC = StringSwitch<unsigned>(Name)
4969 .Case(S: "a4", Value: 8)
4970 .Case(S: "a5", Value: 9)
4971 .Case(S: "a6", Value: 10)
4972 .Case(S: "a7", Value: 11)
4973 .Case(S: "kt0", Value: 26)
4974 .Case(S: "kt1", Value: 27)
4975 .Default(Value: -1);
4976
4977 return CC;
4978}
4979
4980// FIXME? Maybe this could be a TableGen attribute on some registers and
4981// this table could be generated automatically from RegInfo.
4982Register
4983MipsTargetLowering::getRegisterByName(const char *RegName, LLT VT,
4984 const MachineFunction &MF) const {
4985 // 1. Delete symbol '$'.
4986 std::string newRegName = RegName;
4987 if (StringRef(RegName).starts_with(Prefix: "$"))
4988 newRegName = StringRef(RegName).substr(Start: 1);
4989
4990 // 2. Get register index value.
4991 std::smatch matchResult;
4992 int regIdx;
4993 static const std::regex matchStr("^[0-9]*$");
4994 if (std::regex_match(s: newRegName, m&: matchResult, re: matchStr))
4995 regIdx = std::stoi(str: newRegName);
4996 else {
4997 newRegName = StringRef(newRegName).lower();
4998 regIdx = getCPURegisterIndex(Name: StringRef(newRegName));
4999 }
5000
5001 // 3. Get register.
5002 if (regIdx >= 0 && regIdx < 32) {
5003 const MCRegisterInfo *MRI = MF.getContext().getRegisterInfo();
5004 const MCRegisterClass &RC = Subtarget.isGP64bit()
5005 ? MRI->getRegClass(i: Mips::GPR64RegClassID)
5006 : MRI->getRegClass(i: Mips::GPR32RegClassID);
5007 return RC.getRegister(i: regIdx);
5008 }
5009
5010 report_fatal_error(
5011 reason: Twine("Invalid register name \"" + StringRef(RegName) + "\"."));
5012}
5013
5014MachineBasicBlock *MipsTargetLowering::emitLDR_W(MachineInstr &MI,
5015 MachineBasicBlock *BB) const {
5016 MachineFunction *MF = BB->getParent();
5017 MachineRegisterInfo &MRI = MF->getRegInfo();
5018 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
5019 const bool IsLittle = Subtarget.isLittle();
5020 DebugLoc DL = MI.getDebugLoc();
5021
5022 Register Dest = MI.getOperand(i: 0).getReg();
5023 Register Address = MI.getOperand(i: 1).getReg();
5024 unsigned Imm = MI.getOperand(i: 2).getImm();
5025
5026 MachineBasicBlock::iterator I(MI);
5027
5028 if (Subtarget.hasMips32r6() || Subtarget.hasMips64r6()) {
5029 // Mips release 6 can load from adress that is not naturally-aligned.
5030 Register Temp = MRI.createVirtualRegister(RegClass: &Mips::GPR32RegClass);
5031 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::LW))
5032 .addDef(RegNo: Temp)
5033 .addUse(RegNo: Address)
5034 .addImm(Val: Imm);
5035 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::FILL_W)).addDef(RegNo: Dest).addUse(RegNo: Temp);
5036 } else {
5037 // Mips release 5 needs to use instructions that can load from an unaligned
5038 // memory address.
5039 Register LoadHalf = MRI.createVirtualRegister(RegClass: &Mips::GPR32RegClass);
5040 Register LoadFull = MRI.createVirtualRegister(RegClass: &Mips::GPR32RegClass);
5041 Register Undef = MRI.createVirtualRegister(RegClass: &Mips::GPR32RegClass);
5042 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::IMPLICIT_DEF)).addDef(RegNo: Undef);
5043 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::LWR))
5044 .addDef(RegNo: LoadHalf)
5045 .addUse(RegNo: Address)
5046 .addImm(Val: Imm + (IsLittle ? 0 : 3))
5047 .addUse(RegNo: Undef);
5048 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::LWL))
5049 .addDef(RegNo: LoadFull)
5050 .addUse(RegNo: Address)
5051 .addImm(Val: Imm + (IsLittle ? 3 : 0))
5052 .addUse(RegNo: LoadHalf);
5053 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::FILL_W)).addDef(RegNo: Dest).addUse(RegNo: LoadFull);
5054 }
5055
5056 MI.eraseFromParent();
5057 return BB;
5058}
5059
5060MachineBasicBlock *MipsTargetLowering::emitLDR_D(MachineInstr &MI,
5061 MachineBasicBlock *BB) const {
5062 MachineFunction *MF = BB->getParent();
5063 MachineRegisterInfo &MRI = MF->getRegInfo();
5064 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
5065 const bool IsLittle = Subtarget.isLittle();
5066 DebugLoc DL = MI.getDebugLoc();
5067
5068 Register Dest = MI.getOperand(i: 0).getReg();
5069 Register Address = MI.getOperand(i: 1).getReg();
5070 unsigned Imm = MI.getOperand(i: 2).getImm();
5071
5072 MachineBasicBlock::iterator I(MI);
5073
5074 if (Subtarget.hasMips32r6() || Subtarget.hasMips64r6()) {
5075 // Mips release 6 can load from adress that is not naturally-aligned.
5076 if (Subtarget.isGP64bit()) {
5077 Register Temp = MRI.createVirtualRegister(RegClass: &Mips::GPR64RegClass);
5078 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::LD))
5079 .addDef(RegNo: Temp)
5080 .addUse(RegNo: Address)
5081 .addImm(Val: Imm);
5082 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::FILL_D)).addDef(RegNo: Dest).addUse(RegNo: Temp);
5083 } else {
5084 Register Wtemp = MRI.createVirtualRegister(RegClass: &Mips::MSA128WRegClass);
5085 Register Lo = MRI.createVirtualRegister(RegClass: &Mips::GPR32RegClass);
5086 Register Hi = MRI.createVirtualRegister(RegClass: &Mips::GPR32RegClass);
5087 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::LW))
5088 .addDef(RegNo: Lo)
5089 .addUse(RegNo: Address)
5090 .addImm(Val: Imm + (IsLittle ? 0 : 4));
5091 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::LW))
5092 .addDef(RegNo: Hi)
5093 .addUse(RegNo: Address)
5094 .addImm(Val: Imm + (IsLittle ? 4 : 0));
5095 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::FILL_W)).addDef(RegNo: Wtemp).addUse(RegNo: Lo);
5096 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::INSERT_W), DestReg: Dest)
5097 .addUse(RegNo: Wtemp)
5098 .addUse(RegNo: Hi)
5099 .addImm(Val: 1);
5100 }
5101 } else {
5102 // Mips release 5 needs to use instructions that can load from an unaligned
5103 // memory address.
5104 Register LoHalf = MRI.createVirtualRegister(RegClass: &Mips::GPR32RegClass);
5105 Register LoFull = MRI.createVirtualRegister(RegClass: &Mips::GPR32RegClass);
5106 Register LoUndef = MRI.createVirtualRegister(RegClass: &Mips::GPR32RegClass);
5107 Register HiHalf = MRI.createVirtualRegister(RegClass: &Mips::GPR32RegClass);
5108 Register HiFull = MRI.createVirtualRegister(RegClass: &Mips::GPR32RegClass);
5109 Register HiUndef = MRI.createVirtualRegister(RegClass: &Mips::GPR32RegClass);
5110 Register Wtemp = MRI.createVirtualRegister(RegClass: &Mips::MSA128WRegClass);
5111 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::IMPLICIT_DEF)).addDef(RegNo: LoUndef);
5112 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::LWR))
5113 .addDef(RegNo: LoHalf)
5114 .addUse(RegNo: Address)
5115 .addImm(Val: Imm + (IsLittle ? 0 : 7))
5116 .addUse(RegNo: LoUndef);
5117 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::LWL))
5118 .addDef(RegNo: LoFull)
5119 .addUse(RegNo: Address)
5120 .addImm(Val: Imm + (IsLittle ? 3 : 4))
5121 .addUse(RegNo: LoHalf);
5122 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::IMPLICIT_DEF)).addDef(RegNo: HiUndef);
5123 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::LWR))
5124 .addDef(RegNo: HiHalf)
5125 .addUse(RegNo: Address)
5126 .addImm(Val: Imm + (IsLittle ? 4 : 3))
5127 .addUse(RegNo: HiUndef);
5128 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::LWL))
5129 .addDef(RegNo: HiFull)
5130 .addUse(RegNo: Address)
5131 .addImm(Val: Imm + (IsLittle ? 7 : 0))
5132 .addUse(RegNo: HiHalf);
5133 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::FILL_W)).addDef(RegNo: Wtemp).addUse(RegNo: LoFull);
5134 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::INSERT_W), DestReg: Dest)
5135 .addUse(RegNo: Wtemp)
5136 .addUse(RegNo: HiFull)
5137 .addImm(Val: 1);
5138 }
5139
5140 MI.eraseFromParent();
5141 return BB;
5142}
5143
5144MachineBasicBlock *MipsTargetLowering::emitSTR_W(MachineInstr &MI,
5145 MachineBasicBlock *BB) const {
5146 MachineFunction *MF = BB->getParent();
5147 MachineRegisterInfo &MRI = MF->getRegInfo();
5148 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
5149 const bool IsLittle = Subtarget.isLittle();
5150 DebugLoc DL = MI.getDebugLoc();
5151
5152 Register StoreVal = MI.getOperand(i: 0).getReg();
5153 Register Address = MI.getOperand(i: 1).getReg();
5154 unsigned Imm = MI.getOperand(i: 2).getImm();
5155
5156 MachineBasicBlock::iterator I(MI);
5157
5158 if (Subtarget.hasMips32r6() || Subtarget.hasMips64r6()) {
5159 // Mips release 6 can store to adress that is not naturally-aligned.
5160 Register BitcastW = MRI.createVirtualRegister(RegClass: &Mips::MSA128WRegClass);
5161 Register Tmp = MRI.createVirtualRegister(RegClass: &Mips::GPR32RegClass);
5162 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::COPY)).addDef(RegNo: BitcastW).addUse(RegNo: StoreVal);
5163 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::COPY_S_W))
5164 .addDef(RegNo: Tmp)
5165 .addUse(RegNo: BitcastW)
5166 .addImm(Val: 0);
5167 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::SW))
5168 .addUse(RegNo: Tmp)
5169 .addUse(RegNo: Address)
5170 .addImm(Val: Imm);
5171 } else {
5172 // Mips release 5 needs to use instructions that can store to an unaligned
5173 // memory address.
5174 Register Tmp = MRI.createVirtualRegister(RegClass: &Mips::GPR32RegClass);
5175 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::COPY_S_W))
5176 .addDef(RegNo: Tmp)
5177 .addUse(RegNo: StoreVal)
5178 .addImm(Val: 0);
5179 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::SWR))
5180 .addUse(RegNo: Tmp)
5181 .addUse(RegNo: Address)
5182 .addImm(Val: Imm + (IsLittle ? 0 : 3));
5183 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::SWL))
5184 .addUse(RegNo: Tmp)
5185 .addUse(RegNo: Address)
5186 .addImm(Val: Imm + (IsLittle ? 3 : 0));
5187 }
5188
5189 MI.eraseFromParent();
5190
5191 return BB;
5192}
5193
5194MachineBasicBlock *MipsTargetLowering::emitSTR_D(MachineInstr &MI,
5195 MachineBasicBlock *BB) const {
5196 MachineFunction *MF = BB->getParent();
5197 MachineRegisterInfo &MRI = MF->getRegInfo();
5198 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
5199 const bool IsLittle = Subtarget.isLittle();
5200 DebugLoc DL = MI.getDebugLoc();
5201
5202 Register StoreVal = MI.getOperand(i: 0).getReg();
5203 Register Address = MI.getOperand(i: 1).getReg();
5204 unsigned Imm = MI.getOperand(i: 2).getImm();
5205
5206 MachineBasicBlock::iterator I(MI);
5207
5208 if (Subtarget.hasMips32r6() || Subtarget.hasMips64r6()) {
5209 // Mips release 6 can store to adress that is not naturally-aligned.
5210 if (Subtarget.isGP64bit()) {
5211 Register BitcastD = MRI.createVirtualRegister(RegClass: &Mips::MSA128DRegClass);
5212 Register Lo = MRI.createVirtualRegister(RegClass: &Mips::GPR64RegClass);
5213 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::COPY))
5214 .addDef(RegNo: BitcastD)
5215 .addUse(RegNo: StoreVal);
5216 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::COPY_S_D))
5217 .addDef(RegNo: Lo)
5218 .addUse(RegNo: BitcastD)
5219 .addImm(Val: 0);
5220 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::SD))
5221 .addUse(RegNo: Lo)
5222 .addUse(RegNo: Address)
5223 .addImm(Val: Imm);
5224 } else {
5225 Register BitcastW = MRI.createVirtualRegister(RegClass: &Mips::MSA128WRegClass);
5226 Register Lo = MRI.createVirtualRegister(RegClass: &Mips::GPR32RegClass);
5227 Register Hi = MRI.createVirtualRegister(RegClass: &Mips::GPR32RegClass);
5228 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::COPY))
5229 .addDef(RegNo: BitcastW)
5230 .addUse(RegNo: StoreVal);
5231 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::COPY_S_W))
5232 .addDef(RegNo: Lo)
5233 .addUse(RegNo: BitcastW)
5234 .addImm(Val: 0);
5235 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::COPY_S_W))
5236 .addDef(RegNo: Hi)
5237 .addUse(RegNo: BitcastW)
5238 .addImm(Val: 1);
5239 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::SW))
5240 .addUse(RegNo: Lo)
5241 .addUse(RegNo: Address)
5242 .addImm(Val: Imm + (IsLittle ? 0 : 4));
5243 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::SW))
5244 .addUse(RegNo: Hi)
5245 .addUse(RegNo: Address)
5246 .addImm(Val: Imm + (IsLittle ? 4 : 0));
5247 }
5248 } else {
5249 // Mips release 5 needs to use instructions that can store to an unaligned
5250 // memory address.
5251 Register Bitcast = MRI.createVirtualRegister(RegClass: &Mips::MSA128WRegClass);
5252 Register Lo = MRI.createVirtualRegister(RegClass: &Mips::GPR32RegClass);
5253 Register Hi = MRI.createVirtualRegister(RegClass: &Mips::GPR32RegClass);
5254 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::COPY)).addDef(RegNo: Bitcast).addUse(RegNo: StoreVal);
5255 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::COPY_S_W))
5256 .addDef(RegNo: Lo)
5257 .addUse(RegNo: Bitcast)
5258 .addImm(Val: 0);
5259 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::COPY_S_W))
5260 .addDef(RegNo: Hi)
5261 .addUse(RegNo: Bitcast)
5262 .addImm(Val: 1);
5263 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::SWR))
5264 .addUse(RegNo: Lo)
5265 .addUse(RegNo: Address)
5266 .addImm(Val: Imm + (IsLittle ? 0 : 3));
5267 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::SWL))
5268 .addUse(RegNo: Lo)
5269 .addUse(RegNo: Address)
5270 .addImm(Val: Imm + (IsLittle ? 3 : 0));
5271 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::SWR))
5272 .addUse(RegNo: Hi)
5273 .addUse(RegNo: Address)
5274 .addImm(Val: Imm + (IsLittle ? 4 : 7));
5275 BuildMI(BB&: *BB, I, MIMD: DL, MCID: TII->get(Opcode: Mips::SWL))
5276 .addUse(RegNo: Hi)
5277 .addUse(RegNo: Address)
5278 .addImm(Val: Imm + (IsLittle ? 7 : 4));
5279 }
5280
5281 MI.eraseFromParent();
5282 return BB;
5283}
5284