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