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