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