1//===- MipsSEISelLowering.cpp - MipsSE DAG Lowering Interface -------------===//
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// Subclass of MipsTargetLowering specialized for mips32/64.
10//
11//===----------------------------------------------------------------------===//
12
13#include "MipsSEISelLowering.h"
14#include "MipsMachineFunction.h"
15#include "MipsRegisterInfo.h"
16#include "MipsSubtarget.h"
17#include "llvm/ADT/APInt.h"
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/CodeGen/CallingConvLower.h"
20#include "llvm/CodeGen/ISDOpcodes.h"
21#include "llvm/CodeGen/MachineBasicBlock.h"
22#include "llvm/CodeGen/MachineFunction.h"
23#include "llvm/CodeGen/MachineInstr.h"
24#include "llvm/CodeGen/MachineInstrBuilder.h"
25#include "llvm/CodeGen/MachineMemOperand.h"
26#include "llvm/CodeGen/MachineRegisterInfo.h"
27#include "llvm/CodeGen/SelectionDAG.h"
28#include "llvm/CodeGen/SelectionDAGNodes.h"
29#include "llvm/CodeGen/TargetInstrInfo.h"
30#include "llvm/CodeGen/TargetLowering.h"
31#include "llvm/CodeGen/TargetSubtargetInfo.h"
32#include "llvm/CodeGen/ValueTypes.h"
33#include "llvm/CodeGenTypes/MachineValueType.h"
34#include "llvm/IR/DebugLoc.h"
35#include "llvm/IR/Intrinsics.h"
36#include "llvm/IR/IntrinsicsMips.h"
37#include "llvm/Support/Casting.h"
38#include "llvm/Support/CommandLine.h"
39#include "llvm/Support/Debug.h"
40#include "llvm/Support/ErrorHandling.h"
41#include "llvm/Support/raw_ostream.h"
42#include "llvm/TargetParser/Triple.h"
43#include <algorithm>
44#include <cassert>
45#include <cstddef>
46#include <cstdint>
47#include <iterator>
48#include <utility>
49
50using namespace llvm;
51
52#define DEBUG_TYPE "mips-isel"
53
54static cl::opt<bool> NoDPLoadStore("mno-ldc1-sdc1", cl::init(Val: false),
55 cl::desc("Expand double precision loads and "
56 "stores to their single precision "
57 "counterparts"));
58
59// Widen the v2 vectors to the register width, i.e. v2i16 -> v8i16,
60// v2i32 -> v4i32, etc, to ensure the correct rail size is used, i.e.
61// INST.h for v16, INST.w for v32, INST.d for v64.
62TargetLoweringBase::LegalizeTypeAction
63MipsSETargetLowering::getPreferredVectorAction(MVT VT) const {
64 if (this->Subtarget.hasMSA()) {
65 switch (VT.SimpleTy) {
66 // Leave v2i1 vectors to be promoted to larger ones.
67 // Other i1 types will be promoted by default.
68 case MVT::v2i1:
69 return TypePromoteInteger;
70 break;
71 // 16-bit vector types (v2 and longer)
72 case MVT::v2i8:
73 // 32-bit vector types (v2 and longer)
74 case MVT::v2i16:
75 case MVT::v4i8:
76 // 64-bit vector types (v2 and longer)
77 case MVT::v2i32:
78 case MVT::v4i16:
79 case MVT::v8i8:
80 return TypeWidenVector;
81 break;
82 // Only word (.w) and doubleword (.d) are available for floating point
83 // vectors. That means floating point vectors should be either v2f64
84 // or v4f32.
85 // Here we only explicitly widen the f32 types - f16 will be promoted
86 // by default.
87 case MVT::v2f32:
88 case MVT::v3f32:
89 return TypeWidenVector;
90 // v2i64 is already 128-bit wide.
91 default:
92 break;
93 }
94 }
95 return TargetLoweringBase::getPreferredVectorAction(VT);
96}
97
98MipsSETargetLowering::MipsSETargetLowering(const MipsTargetMachine &TM,
99 const MipsSubtarget &STI)
100 : MipsTargetLowering(TM, STI) {
101 // Set up the register classes
102 addRegisterClass(VT: MVT::i32, RC: &Mips::GPR32RegClass);
103
104 if (Subtarget.isGP64bit())
105 addRegisterClass(VT: MVT::i64, RC: &Mips::GPR64RegClass);
106
107 if (Subtarget.hasDSP() || Subtarget.hasMSA()) {
108 // Expand all truncating stores and extending loads.
109 for (MVT VT0 : MVT::fixedlen_vector_valuetypes()) {
110 for (MVT VT1 : MVT::fixedlen_vector_valuetypes()) {
111 setTruncStoreAction(ValVT: VT0, MemVT: VT1, Action: Expand);
112 setLoadExtAction(ExtType: ISD::SEXTLOAD, ValVT: VT0, MemVT: VT1, Action: Expand);
113 setLoadExtAction(ExtType: ISD::ZEXTLOAD, ValVT: VT0, MemVT: VT1, Action: Expand);
114 setLoadExtAction(ExtType: ISD::EXTLOAD, ValVT: VT0, MemVT: VT1, Action: Expand);
115 }
116 }
117 }
118
119 if (Subtarget.hasDSP()) {
120 MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8};
121
122 for (const auto &VecTy : VecTys) {
123 addRegisterClass(VT: VecTy, RC: &Mips::DSPRRegClass);
124
125 // Expand all builtin opcodes.
126 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
127 setOperationAction(Op: Opc, VT: VecTy, Action: Expand);
128
129 setOperationAction(Op: ISD::ADD, VT: VecTy, Action: Legal);
130 setOperationAction(Op: ISD::SUB, VT: VecTy, Action: Legal);
131 setOperationAction(Op: ISD::LOAD, VT: VecTy, Action: Legal);
132 setOperationAction(Op: ISD::STORE, VT: VecTy, Action: Legal);
133 setOperationAction(Op: ISD::BITCAST, VT: VecTy, Action: Legal);
134 }
135
136 setTargetDAGCombine(
137 {ISD::SHL, ISD::SRA, ISD::SRL, ISD::SETCC, ISD::VSELECT});
138
139 if (Subtarget.hasMips32r2()) {
140 setOperationAction(Op: ISD::ADDC, VT: MVT::i32, Action: Legal);
141 setOperationAction(Op: ISD::ADDE, VT: MVT::i32, Action: Legal);
142 }
143 }
144
145 if (Subtarget.hasDSPR2())
146 setOperationAction(Op: ISD::MUL, VT: MVT::v2i16, Action: Legal);
147
148 if (Subtarget.hasMSA()) {
149 addMSAIntType(Ty: MVT::v16i8, RC: &Mips::MSA128BRegClass);
150 addMSAIntType(Ty: MVT::v8i16, RC: &Mips::MSA128HRegClass);
151 addMSAIntType(Ty: MVT::v4i32, RC: &Mips::MSA128WRegClass);
152 addMSAIntType(Ty: MVT::v2i64, RC: &Mips::MSA128DRegClass);
153 addMSAFloatType(Ty: MVT::v8f16, RC: &Mips::MSA128HRegClass);
154 addMSAFloatType(Ty: MVT::v4f32, RC: &Mips::MSA128WRegClass);
155 addMSAFloatType(Ty: MVT::v2f64, RC: &Mips::MSA128DRegClass);
156
157 // We're using soft promotion for f16, but msa has some instructions for
158 // conversion to/from f16. Mark those conversions as custom so we can take
159 // advantage of these instructions.
160 for (MVT VT : {MVT::f32, MVT::f64}) {
161 setOperationAction(Op: ISD::FP16_TO_FP, VT, Action: Custom);
162 setOperationAction(Op: ISD::FP_TO_FP16, VT, Action: Custom);
163 }
164
165 setTargetDAGCombine(
166 {ISD::AND, ISD::OR, ISD::SRA, ISD::VSELECT, ISD::XOR, ISD::FP_TO_UINT});
167 }
168
169 if (!Subtarget.useSoftFloat()) {
170 addRegisterClass(VT: MVT::f32, RC: &Mips::FGR32RegClass);
171
172 // When dealing with single precision only, use libcalls
173 if (!Subtarget.isSingleFloat()) {
174 if (Subtarget.isFP64bit())
175 addRegisterClass(VT: MVT::f64, RC: &Mips::FGR64RegClass);
176 else
177 addRegisterClass(VT: MVT::f64, RC: &Mips::AFGR64RegClass);
178 }
179
180 for (auto Op : {ISD::STRICT_FADD, ISD::STRICT_FSUB, ISD::STRICT_FMUL,
181 ISD::STRICT_FDIV, ISD::STRICT_FSQRT}) {
182 setOperationAction(Op, VT: MVT::f32, Action: Legal);
183 setOperationAction(Op, VT: MVT::f64, Action: Legal);
184 }
185 }
186
187 // Targets with 64bits integer registers, but no 64bit floating point register
188 // do not support conversion between them
189 if (Subtarget.isGP64bit() && Subtarget.isSingleFloat() &&
190 !Subtarget.useSoftFloat()) {
191 setOperationAction(Op: ISD::FP_TO_SINT, VT: MVT::i64, Action: Expand);
192 setOperationAction(Op: ISD::FP_TO_UINT, VT: MVT::i64, Action: Expand);
193 setOperationAction(Op: ISD::SINT_TO_FP, VT: MVT::i64, Action: Expand);
194 setOperationAction(Op: ISD::UINT_TO_FP, VT: MVT::i64, Action: Expand);
195 }
196
197 setOperationAction(Op: ISD::SMUL_LOHI, VT: MVT::i32, Action: Custom);
198 setOperationAction(Op: ISD::UMUL_LOHI, VT: MVT::i32, Action: Custom);
199 setOperationAction(Op: ISD::MULHS, VT: MVT::i32, Action: Custom);
200 setOperationAction(Op: ISD::MULHU, VT: MVT::i32, Action: Custom);
201
202 if (Subtarget.hasCnMips())
203 setOperationAction(Op: ISD::MUL, VT: MVT::i64, Action: Legal);
204 else if (Subtarget.isR5900()) {
205 // R5900 doesn't have DMULT/DMULTU/DDIV/DDIVU - expand to 32-bit ops
206 setOperationAction(Op: ISD::MUL, VT: MVT::i64, Action: Expand);
207 setOperationAction(Op: ISD::SMUL_LOHI, VT: MVT::i64, Action: Expand);
208 setOperationAction(Op: ISD::UMUL_LOHI, VT: MVT::i64, Action: Expand);
209 setOperationAction(Op: ISD::MULHS, VT: MVT::i64, Action: Expand);
210 setOperationAction(Op: ISD::MULHU, VT: MVT::i64, Action: Expand);
211 setOperationAction(Op: ISD::SDIVREM, VT: MVT::i64, Action: Expand);
212 setOperationAction(Op: ISD::UDIVREM, VT: MVT::i64, Action: Expand);
213 } else if (Subtarget.isGP64bit())
214 setOperationAction(Op: ISD::MUL, VT: MVT::i64, Action: Custom);
215
216 if (Subtarget.isGP64bit() && !Subtarget.isR5900()) {
217 setOperationAction(Op: ISD::SMUL_LOHI, VT: MVT::i64, Action: Custom);
218 setOperationAction(Op: ISD::UMUL_LOHI, VT: MVT::i64, Action: Custom);
219 setOperationAction(Op: ISD::MULHS, VT: MVT::i64, Action: Custom);
220 setOperationAction(Op: ISD::MULHU, VT: MVT::i64, Action: Custom);
221 setOperationAction(Op: ISD::SDIVREM, VT: MVT::i64, Action: Custom);
222 setOperationAction(Op: ISD::UDIVREM, VT: MVT::i64, Action: Custom);
223 }
224
225 setOperationAction(Op: ISD::INTRINSIC_WO_CHAIN, VT: MVT::i64, Action: Custom);
226 setOperationAction(Op: ISD::INTRINSIC_W_CHAIN, VT: MVT::i64, Action: Custom);
227
228 setOperationAction(Op: ISD::SDIVREM, VT: MVT::i32, Action: Custom);
229 setOperationAction(Op: ISD::UDIVREM, VT: MVT::i32, Action: Custom);
230 setOperationAction(Op: ISD::ATOMIC_FENCE, VT: MVT::Other, Action: Custom);
231 if (Subtarget.hasMips32r6()) {
232 setOperationAction(Op: ISD::LOAD, VT: MVT::i32, Action: Legal);
233 setOperationAction(Op: ISD::STORE, VT: MVT::i32, Action: Legal);
234 } else {
235 setOperationAction(Op: ISD::LOAD, VT: MVT::i32, Action: Custom);
236 setOperationAction(Op: ISD::STORE, VT: MVT::i32, Action: Custom);
237 }
238
239 setTargetDAGCombine(ISD::MUL);
240
241 setOperationAction(Op: ISD::INTRINSIC_WO_CHAIN, VT: MVT::Other, Action: Custom);
242 setOperationAction(Op: ISD::INTRINSIC_W_CHAIN, VT: MVT::Other, Action: Custom);
243 setOperationAction(Op: ISD::INTRINSIC_VOID, VT: MVT::Other, Action: Custom);
244
245 if (Subtarget.hasMips32r2() && !Subtarget.useSoftFloat() &&
246 !Subtarget.hasMips64()) {
247 setOperationAction(Op: ISD::BITCAST, VT: MVT::i64, Action: Custom);
248 }
249
250 if (NoDPLoadStore || (Subtarget.hasMips1() && !Subtarget.hasMips2())) {
251 setOperationAction(Op: ISD::LOAD, VT: MVT::f64, Action: Custom);
252 setOperationAction(Op: ISD::STORE, VT: MVT::f64, Action: Custom);
253 }
254
255 if (Subtarget.hasMips32r6()) {
256 // MIPS32r6 replaces the accumulator-based multiplies with a three register
257 // instruction
258 setOperationAction(Op: ISD::SMUL_LOHI, VT: MVT::i32, Action: Expand);
259 setOperationAction(Op: ISD::UMUL_LOHI, VT: MVT::i32, Action: Expand);
260 setOperationAction(Op: ISD::MUL, VT: MVT::i32, Action: Legal);
261 setOperationAction(Op: ISD::MULHS, VT: MVT::i32, Action: Legal);
262 setOperationAction(Op: ISD::MULHU, VT: MVT::i32, Action: Legal);
263
264 // MIPS32r6 replaces the accumulator-based division/remainder with separate
265 // three register division and remainder instructions.
266 setOperationAction(Op: ISD::SDIVREM, VT: MVT::i32, Action: Expand);
267 setOperationAction(Op: ISD::UDIVREM, VT: MVT::i32, Action: Expand);
268 setOperationAction(Op: ISD::SDIV, VT: MVT::i32, Action: Legal);
269 setOperationAction(Op: ISD::UDIV, VT: MVT::i32, Action: Legal);
270 setOperationAction(Op: ISD::SREM, VT: MVT::i32, Action: Legal);
271 setOperationAction(Op: ISD::UREM, VT: MVT::i32, Action: Legal);
272
273 // MIPS32r6 replaces conditional moves with an equivalent that removes the
274 // need for three GPR read ports.
275 setOperationAction(Op: ISD::SETCC, VT: MVT::i32, Action: Legal);
276 setOperationAction(Op: ISD::SELECT, VT: MVT::i32, Action: Legal);
277 setOperationAction(Op: ISD::SELECT_CC, VT: MVT::i32, Action: Expand);
278
279 setOperationAction(Op: ISD::SETCC, VT: MVT::f32, Action: Legal);
280 setOperationAction(Op: ISD::SELECT, VT: MVT::f32, Action: Legal);
281 setOperationAction(Op: ISD::SELECT_CC, VT: MVT::f32, Action: Expand);
282
283 assert(Subtarget.isFP64bit() && "FR=1 is required for MIPS32r6");
284 setOperationAction(Op: ISD::SETCC, VT: MVT::f64, Action: Legal);
285 setOperationAction(Op: ISD::SELECT, VT: MVT::f64, Action: Legal);
286 setOperationAction(Op: ISD::SELECT_CC, VT: MVT::f64, Action: Expand);
287
288 setOperationAction(Op: ISD::BRCOND, VT: MVT::Other, Action: Legal);
289
290 // Floating point > and >= are supported via < and <=
291 setCondCodeAction(CCs: ISD::SETOGE, VT: MVT::f32, Action: Expand);
292 setCondCodeAction(CCs: ISD::SETOGT, VT: MVT::f32, Action: Expand);
293 setCondCodeAction(CCs: ISD::SETUGE, VT: MVT::f32, Action: Expand);
294 setCondCodeAction(CCs: ISD::SETUGT, VT: MVT::f32, Action: Expand);
295 setCondCodeAction(CCs: ISD::SETONE, VT: MVT::f32, Action: Expand);
296 setCondCodeAction(CCs: ISD::SETO, VT: MVT::f32, Action: Expand);
297 setCondCodeAction(CCs: ISD::SETUNE, VT: MVT::f32, Action: Expand);
298 setCondCodeAction(CCs: ISD::SETNE, VT: MVT::f32, Action: Expand);
299
300 setCondCodeAction(CCs: ISD::SETOGE, VT: MVT::f64, Action: Expand);
301 setCondCodeAction(CCs: ISD::SETOGT, VT: MVT::f64, Action: Expand);
302 setCondCodeAction(CCs: ISD::SETUGE, VT: MVT::f64, Action: Expand);
303 setCondCodeAction(CCs: ISD::SETUGT, VT: MVT::f64, Action: Expand);
304 setCondCodeAction(CCs: ISD::SETONE, VT: MVT::f64, Action: Expand);
305 setCondCodeAction(CCs: ISD::SETO, VT: MVT::f64, Action: Expand);
306 setCondCodeAction(CCs: ISD::SETUNE, VT: MVT::f64, Action: Expand);
307 setCondCodeAction(CCs: ISD::SETNE, VT: MVT::f64, Action: Expand);
308 }
309
310 if (Subtarget.hasMips64r6()) {
311 // MIPS64r6 replaces the accumulator-based multiplies with a three register
312 // instruction
313 setOperationAction(Op: ISD::SMUL_LOHI, VT: MVT::i64, Action: Expand);
314 setOperationAction(Op: ISD::UMUL_LOHI, VT: MVT::i64, Action: Expand);
315 setOperationAction(Op: ISD::MUL, VT: MVT::i64, Action: Legal);
316 setOperationAction(Op: ISD::MULHS, VT: MVT::i64, Action: Legal);
317 setOperationAction(Op: ISD::MULHU, VT: MVT::i64, Action: Legal);
318
319 // MIPS32r6 replaces the accumulator-based division/remainder with separate
320 // three register division and remainder instructions.
321 setOperationAction(Op: ISD::SDIVREM, VT: MVT::i64, Action: Expand);
322 setOperationAction(Op: ISD::UDIVREM, VT: MVT::i64, Action: Expand);
323 setOperationAction(Op: ISD::SDIV, VT: MVT::i64, Action: Legal);
324 setOperationAction(Op: ISD::UDIV, VT: MVT::i64, Action: Legal);
325 setOperationAction(Op: ISD::SREM, VT: MVT::i64, Action: Legal);
326 setOperationAction(Op: ISD::UREM, VT: MVT::i64, Action: Legal);
327
328 // MIPS64r6 replaces conditional moves with an equivalent that removes the
329 // need for three GPR read ports.
330 setOperationAction(Op: ISD::SETCC, VT: MVT::i64, Action: Legal);
331 setOperationAction(Op: ISD::SELECT, VT: MVT::i64, Action: Legal);
332 setOperationAction(Op: ISD::SELECT_CC, VT: MVT::i64, Action: Expand);
333 }
334
335 if (Subtarget.isR5900()) {
336 // R5900 FPU only supports 4 compare conditions: C.F, C.EQ, C.OLT, C.OLE
337 // (and their inversions via bc1t/bc1f). Expand all conditions that would
338 // require C.UN, C.UEQ, C.ULT, or C.ULE instructions (not available on
339 // R5900). The legalizer resolves these via operand swapping, condition
340 // inversion, and decomposition into supported conditions.
341 setCondCodeAction(CCs: ISD::SETOGT, VT: MVT::f32, Action: Expand);
342 setCondCodeAction(CCs: ISD::SETOGE, VT: MVT::f32, Action: Expand);
343 setCondCodeAction(CCs: ISD::SETGT, VT: MVT::f32, Action: Expand);
344 setCondCodeAction(CCs: ISD::SETGE, VT: MVT::f32, Action: Expand);
345 setCondCodeAction(CCs: ISD::SETULT, VT: MVT::f32, Action: Expand);
346 setCondCodeAction(CCs: ISD::SETULE, VT: MVT::f32, Action: Expand);
347 setCondCodeAction(CCs: ISD::SETUO, VT: MVT::f32, Action: Expand);
348 setCondCodeAction(CCs: ISD::SETO, VT: MVT::f32, Action: Expand);
349 setCondCodeAction(CCs: ISD::SETONE, VT: MVT::f32, Action: Expand);
350 setCondCodeAction(CCs: ISD::SETUEQ, VT: MVT::f32, Action: Expand);
351 setCondCodeAction(CCs: ISD::SETNE, VT: MVT::f32, Action: Expand);
352
353 // R5900 FPU does not support IEEE 754 special values (NaN, infinity). Use
354 // custom lowering to decide per-instruction: hardware when nnan+ninf flags
355 // guarantee no NaN or infinity, software libcall otherwise.
356 setOperationAction(Op: ISD::FADD, VT: MVT::f32, Action: Custom);
357 setOperationAction(Op: ISD::FSUB, VT: MVT::f32, Action: Custom);
358 setOperationAction(Op: ISD::FMUL, VT: MVT::f32, Action: Custom);
359 setOperationAction(Op: ISD::FDIV, VT: MVT::f32, Action: Custom);
360 setOperationAction(Op: ISD::FSQRT, VT: MVT::f32, Action: Custom);
361 }
362
363 computeRegisterProperties(TRI: Subtarget.getRegisterInfo());
364}
365
366const MipsTargetLowering *
367llvm::createMipsSETargetLowering(const MipsTargetMachine &TM,
368 const MipsSubtarget &STI) {
369 return new MipsSETargetLowering(TM, STI);
370}
371
372const TargetRegisterClass *
373MipsSETargetLowering::getRepRegClassFor(MVT VT) const {
374 if (VT == MVT::Untyped)
375 return Subtarget.hasDSP() ? &Mips::ACC64DSPRegClass : &Mips::ACC64RegClass;
376
377 return TargetLowering::getRepRegClassFor(VT);
378}
379
380// Enable MSA support for the given integer type and Register class.
381void MipsSETargetLowering::
382addMSAIntType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) {
383 addRegisterClass(VT: Ty, RC);
384
385 // Expand all builtin opcodes.
386 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
387 setOperationAction(Op: Opc, VT: Ty, Action: Expand);
388
389 setOperationAction(Op: ISD::BITCAST, VT: Ty, Action: Legal);
390 setOperationAction(Op: ISD::LOAD, VT: Ty, Action: Legal);
391 setOperationAction(Op: ISD::STORE, VT: Ty, Action: Legal);
392 setOperationAction(Op: ISD::EXTRACT_VECTOR_ELT, VT: Ty, Action: Custom);
393 setOperationAction(Op: ISD::INSERT_VECTOR_ELT, VT: Ty, Action: Legal);
394 setOperationAction(Op: ISD::BUILD_VECTOR, VT: Ty, Action: Custom);
395 setOperationAction(Ops: {ISD::UNDEF, ISD::POISON}, VT: Ty, Action: Legal);
396
397 setOperationAction(Op: ISD::ADD, VT: Ty, Action: Legal);
398 setOperationAction(Op: ISD::AND, VT: Ty, Action: Legal);
399 setOperationAction(Op: ISD::CTLZ, VT: Ty, Action: Legal);
400 setOperationAction(Op: ISD::CTPOP, VT: Ty, Action: Legal);
401 setOperationAction(Op: ISD::MUL, VT: Ty, Action: Legal);
402 setOperationAction(Op: ISD::OR, VT: Ty, Action: Legal);
403 setOperationAction(Op: ISD::SDIV, VT: Ty, Action: Legal);
404 setOperationAction(Op: ISD::SREM, VT: Ty, Action: Legal);
405 setOperationAction(Op: ISD::SHL, VT: Ty, Action: Legal);
406 setOperationAction(Op: ISD::SRA, VT: Ty, Action: Legal);
407 setOperationAction(Op: ISD::SRL, VT: Ty, Action: Legal);
408 setOperationAction(Op: ISD::SUB, VT: Ty, Action: Legal);
409 setOperationAction(Op: ISD::SMAX, VT: Ty, Action: Legal);
410 setOperationAction(Op: ISD::SMIN, VT: Ty, Action: Legal);
411 setOperationAction(Op: ISD::UDIV, VT: Ty, Action: Legal);
412 setOperationAction(Op: ISD::UREM, VT: Ty, Action: Legal);
413 setOperationAction(Op: ISD::UMAX, VT: Ty, Action: Legal);
414 setOperationAction(Op: ISD::UMIN, VT: Ty, Action: Legal);
415 setOperationAction(Op: ISD::VECTOR_SHUFFLE, VT: Ty, Action: Custom);
416 setOperationAction(Op: ISD::VSELECT, VT: Ty, Action: Legal);
417 setOperationAction(Op: ISD::XOR, VT: Ty, Action: Legal);
418
419 if (Ty == MVT::v4i32 || Ty == MVT::v2i64) {
420 setOperationAction(Op: ISD::FP_TO_SINT, VT: Ty, Action: Legal);
421 setOperationAction(Op: ISD::FP_TO_UINT, VT: Ty, Action: Legal);
422 setOperationAction(Op: ISD::SINT_TO_FP, VT: Ty, Action: Legal);
423 setOperationAction(Op: ISD::UINT_TO_FP, VT: Ty, Action: Legal);
424 }
425
426 setOperationAction(Op: ISD::SETCC, VT: Ty, Action: Legal);
427 setCondCodeAction(CCs: ISD::SETNE, VT: Ty, Action: Expand);
428 setCondCodeAction(CCs: ISD::SETGE, VT: Ty, Action: Expand);
429 setCondCodeAction(CCs: ISD::SETGT, VT: Ty, Action: Expand);
430 setCondCodeAction(CCs: ISD::SETUGE, VT: Ty, Action: Expand);
431 setCondCodeAction(CCs: ISD::SETUGT, VT: Ty, Action: Expand);
432}
433
434// Enable MSA support for the given floating-point type and Register class.
435void MipsSETargetLowering::
436addMSAFloatType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) {
437 addRegisterClass(VT: Ty, RC);
438
439 // Expand all builtin opcodes.
440 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
441 setOperationAction(Op: Opc, VT: Ty, Action: Expand);
442
443 setOperationAction(Op: ISD::LOAD, VT: Ty, Action: Legal);
444 setOperationAction(Op: ISD::STORE, VT: Ty, Action: Legal);
445 setOperationAction(Op: ISD::BITCAST, VT: Ty, Action: Legal);
446 setOperationAction(Op: ISD::EXTRACT_VECTOR_ELT, VT: Ty, Action: Legal);
447 setOperationAction(Op: ISD::INSERT_VECTOR_ELT, VT: Ty, Action: Legal);
448 setOperationAction(Op: ISD::BUILD_VECTOR, VT: Ty, Action: Custom);
449 setOperationAction(Op: ISD::UNDEF, VT: Ty, Action: Legal);
450
451 if (Ty != MVT::v8f16) {
452 setOperationAction(Op: ISD::FABS, VT: Ty, Action: Legal);
453 setOperationAction(Op: ISD::FADD, VT: Ty, Action: Legal);
454 setOperationAction(Op: ISD::FDIV, VT: Ty, Action: Legal);
455 setOperationAction(Op: ISD::FEXP2, VT: Ty, Action: Legal);
456 setOperationAction(Op: ISD::FLOG2, VT: Ty, Action: Legal);
457 setOperationAction(Op: ISD::FMA, VT: Ty, Action: Legal);
458 setOperationAction(Op: ISD::FMUL, VT: Ty, Action: Legal);
459 setOperationAction(Op: ISD::FRINT, VT: Ty, Action: Legal);
460 setOperationAction(Op: ISD::FSQRT, VT: Ty, Action: Legal);
461 setOperationAction(Op: ISD::FSUB, VT: Ty, Action: Legal);
462 setOperationAction(Op: ISD::VSELECT, VT: Ty, Action: Legal);
463
464 setOperationAction(Op: ISD::SETCC, VT: Ty, Action: Legal);
465 setCondCodeAction(CCs: ISD::SETOGE, VT: Ty, Action: Expand);
466 setCondCodeAction(CCs: ISD::SETOGT, VT: Ty, Action: Expand);
467 setCondCodeAction(CCs: ISD::SETUGE, VT: Ty, Action: Expand);
468 setCondCodeAction(CCs: ISD::SETUGT, VT: Ty, Action: Expand);
469 setCondCodeAction(CCs: ISD::SETGE, VT: Ty, Action: Expand);
470 setCondCodeAction(CCs: ISD::SETGT, VT: Ty, Action: Expand);
471 }
472}
473
474SDValue MipsSETargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
475 if(!Subtarget.hasMips32r6())
476 return MipsTargetLowering::LowerOperation(Op, DAG);
477
478 EVT ResTy = Op->getValueType(ResNo: 0);
479 SDLoc DL(Op);
480
481 // Although MTC1_D64 takes an i32 and writes an f64, the upper 32 bits of the
482 // floating point register are undefined. Not really an issue as sel.d, which
483 // is produced from an FSELECT node, only looks at bit 0.
484 SDValue Tmp = DAG.getNode(Opcode: MipsISD::MTC1_D64, DL, VT: MVT::f64, Operand: Op->getOperand(Num: 0));
485 return DAG.getNode(Opcode: MipsISD::FSELECT, DL, VT: ResTy, N1: Tmp, N2: Op->getOperand(Num: 1),
486 N3: Op->getOperand(Num: 2));
487}
488
489// Lower FP16_TO_FP (the soft-promote-half representation of an f16 -> f32/f64
490// conversion).
491SDValue MipsSETargetLowering::lowerFP16_TO_FP(SDValue Op,
492 SelectionDAG &DAG) const {
493 SDLoc DL(Op);
494 EVT ResTy = Op.getValueType();
495 assert((ResTy == MVT::f32 || ResTy == MVT::f64) && "Unexpected FP16_TO_FP");
496
497 // The operand type is i32 because i16 isn't actually legal on MIPS.
498 SDValue In = Op.getOperand(i: 0);
499 assert(In.getValueType() == MVT::i32 && "Unexpected FP16_TO_FP operand type");
500
501 // Splat into a v8i16 (the 32-bit In value is truncated to the lower 16 bits).
502 SDValue Splatted = DAG.getSplatBuildVector(VT: MVT::v8i16, DL, Op: In);
503
504 // Bitcast from v8i16 to v8f16.
505 SDValue HVec = DAG.getNode(Opcode: ISD::BITCAST, DL, VT: MVT::v8f16, Operand: Splatted);
506
507 // Convert from v8f16 to v4f32.
508 SDValue F32Vec = DAG.getNode(
509 Opcode: ISD::INTRINSIC_WO_CHAIN, DL, VT: MVT::v4f32,
510 N1: DAG.getConstant(Val: Intrinsic::mips_fexupr_w, DL, VT: MVT::i32), N2: HVec);
511 SDValue Res;
512 if (ResTy == MVT::f32) {
513 // Every lane has the converted value, just read it from lane 0.
514 Res = DAG.getNode(Opcode: ISD::EXTRACT_VECTOR_ELT, DL, VT: MVT::f32, N1: F32Vec,
515 N2: DAG.getVectorIdxConstant(Val: 0, DL));
516 } else {
517 // Convert from v4f32 to v2f64.
518 SDValue F64Vec = DAG.getNode(
519 Opcode: ISD::INTRINSIC_WO_CHAIN, DL, VT: MVT::v2f64,
520 N1: DAG.getConstant(Val: Intrinsic::mips_fexupr_d, DL, VT: MVT::i32), N2: F32Vec);
521 // Every lane has the converted value, just read it from lane 0.
522 Res = DAG.getNode(Opcode: ISD::EXTRACT_VECTOR_ELT, DL, VT: MVT::f64, N1: F64Vec,
523 N2: DAG.getVectorIdxConstant(Val: 0, DL));
524 }
525
526 return Res;
527}
528
529// Lower FP_TO_FP16 (the soft-promote-half representation of an f32/f64 -> f16
530// conversion)
531SDValue MipsSETargetLowering::lowerFP_TO_FP16(SDValue Op,
532 SelectionDAG &DAG) const {
533 SDLoc DL(Op);
534 EVT ResTy = Op.getValueType();
535 SDValue In = Op.getOperand(i: 0);
536 assert((In.getValueType() == MVT::f32 || In.getValueType() == MVT::f64) &&
537 "Unexpected FP_TO_FP16");
538
539 SDValue F32Vec;
540 if (In.getValueType() == MVT::f64) {
541 // Splat f64 to v2f64, then convert to v4f32.
542 SDValue F64Vec = DAG.getSplatBuildVector(VT: MVT::v2f64, DL, Op: In);
543 F32Vec = DAG.getNode(Opcode: ISD::INTRINSIC_WO_CHAIN, DL, VT: MVT::v4f32,
544 N1: DAG.getConstant(Val: Intrinsic::mips_fexdo_w, DL, VT: MVT::i32),
545 N2: F64Vec, N3: F64Vec);
546 } else {
547 // Splat f32 to v4f32.
548 F32Vec = DAG.getSplatBuildVector(VT: MVT::v4f32, DL, Op: In);
549 }
550
551 // Then convert from v4f32 to v8f16.
552 SDValue HVec = DAG.getNode(
553 Opcode: ISD::INTRINSIC_WO_CHAIN, DL, VT: MVT::v8f16,
554 N1: DAG.getConstant(Val: Intrinsic::mips_fexdo_h, DL, VT: MVT::i32), N2: F32Vec, N3: F32Vec);
555
556 // Finally cast to v8i16 (f16 is soft-promoted).
557 SDValue IVec = DAG.getNode(Opcode: ISD::BITCAST, DL, VT: MVT::v8i16, Operand: HVec);
558 SDValue Res = DAG.getNode(Opcode: ISD::EXTRACT_VECTOR_ELT, DL, VT: ResTy, N1: IVec,
559 N2: DAG.getVectorIdxConstant(Val: 0, DL));
560
561 return Res;
562}
563
564bool MipsSETargetLowering::allowsMisalignedMemoryAccesses(
565 EVT VT, unsigned, Align, MachineMemOperand::Flags, unsigned *Fast) const {
566 MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
567
568 if (Subtarget.systemSupportsUnalignedAccess()) {
569 // MIPS32r6/MIPS64r6 is required to support unaligned access. It's
570 // implementation defined whether this is handled by hardware, software, or
571 // a hybrid of the two but it's expected that most implementations will
572 // handle the majority of cases in hardware.
573 if (Fast)
574 *Fast = 1;
575 return true;
576 } else if (Subtarget.hasMips32r6()) {
577 return false;
578 }
579
580 switch (SVT) {
581 case MVT::i64:
582 case MVT::i32:
583 if (Fast)
584 *Fast = 1;
585 return true;
586 default:
587 return false;
588 }
589}
590
591SDValue MipsSETargetLowering::LowerOperation(SDValue Op,
592 SelectionDAG &DAG) const {
593 switch(Op.getOpcode()) {
594 case ISD::LOAD: return lowerLOAD(Op, DAG);
595 case ISD::STORE: return lowerSTORE(Op, DAG);
596 case ISD::SMUL_LOHI: return lowerMulDiv(Op, NewOpc: MipsISD::Mult, HasLo: true, HasHi: true, DAG);
597 case ISD::UMUL_LOHI: return lowerMulDiv(Op, NewOpc: MipsISD::Multu, HasLo: true, HasHi: true, DAG);
598 case ISD::MULHS: return lowerMulDiv(Op, NewOpc: MipsISD::Mult, HasLo: false, HasHi: true, DAG);
599 case ISD::MULHU: return lowerMulDiv(Op, NewOpc: MipsISD::Multu, HasLo: false, HasHi: true, DAG);
600 case ISD::MUL: return lowerMulDiv(Op, NewOpc: MipsISD::Mult, HasLo: true, HasHi: false, DAG);
601 case ISD::SDIVREM: return lowerMulDiv(Op, NewOpc: MipsISD::DivRem, HasLo: true, HasHi: true, DAG);
602 case ISD::UDIVREM: return lowerMulDiv(Op, NewOpc: MipsISD::DivRemU, HasLo: true, HasHi: true,
603 DAG);
604 case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG);
605 case ISD::INTRINSIC_W_CHAIN: return lowerINTRINSIC_W_CHAIN(Op, DAG);
606 case ISD::INTRINSIC_VOID: return lowerINTRINSIC_VOID(Op, DAG);
607 case ISD::EXTRACT_VECTOR_ELT: return lowerEXTRACT_VECTOR_ELT(Op, DAG);
608 case ISD::BUILD_VECTOR: return lowerBUILD_VECTOR(Op, DAG);
609 case ISD::VECTOR_SHUFFLE: return lowerVECTOR_SHUFFLE(Op, DAG);
610 case ISD::SELECT:
611 return lowerSELECT(Op, DAG);
612 case ISD::FP16_TO_FP:
613 case ISD::STRICT_FP16_TO_FP:
614 return lowerFP16_TO_FP(Op, DAG);
615 case ISD::FP_TO_FP16:
616 case ISD::STRICT_FP_TO_FP16:
617 return lowerFP_TO_FP16(Op, DAG);
618 case ISD::BITCAST: return lowerBITCAST(Op, DAG);
619 case ISD::FADD:
620 return lowerR5900FPOp(Op, DAG, LC: RTLIB::ADD_F32);
621 case ISD::FSUB:
622 return lowerR5900FPOp(Op, DAG, LC: RTLIB::SUB_F32);
623 case ISD::FMUL:
624 return lowerR5900FPOp(Op, DAG, LC: RTLIB::MUL_F32);
625 case ISD::FDIV:
626 return lowerR5900FPOp(Op, DAG, LC: RTLIB::DIV_F32);
627 case ISD::FSQRT:
628 return lowerR5900FPOp(Op, DAG, LC: RTLIB::SQRT_F32);
629 }
630
631 return MipsTargetLowering::LowerOperation(Op, DAG);
632}
633
634SDValue MipsSETargetLowering::lowerR5900FPOp(SDValue Op, SelectionDAG &DAG,
635 RTLIB::Libcall LC) const {
636 assert(Subtarget.isR5900());
637 SDNodeFlags Flags = Op->getFlags();
638
639 if (Flags.hasNoNaNs() && Flags.hasNoInfs()) {
640 // Use the hardware FPU instruction if the operation is guaranteed to have
641 // no NaN or infinity inputs/outputs (nnan+ninf flags).
642 return Op;
643 }
644
645 // Fall back to a software libcall for IEEE correctness.
646 SDLoc DL(Op);
647 MVT VT = Op.getSimpleValueType();
648 SmallVector<SDValue, 2> Ops(Op->op_begin(), Op->op_end());
649 TargetLowering::MakeLibCallOptions CallOptions;
650 auto [Result, Chain] = makeLibCall(DAG, LC, RetVT: VT, Ops, CallOptions, dl: DL);
651 return Result;
652}
653
654// Fold zero extensions into MipsISD::VEXTRACT_[SZ]EXT_ELT
655//
656// Performs the following transformations:
657// - Changes MipsISD::VEXTRACT_[SZ]EXT_ELT to zero extension if its
658// sign/zero-extension is completely overwritten by the new one performed by
659// the ISD::AND.
660// - Removes redundant zero extensions performed by an ISD::AND.
661static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG,
662 TargetLowering::DAGCombinerInfo &DCI,
663 const MipsSubtarget &Subtarget) {
664 if (!Subtarget.hasMSA())
665 return SDValue();
666
667 SDValue Op0 = N->getOperand(Num: 0);
668 SDValue Op1 = N->getOperand(Num: 1);
669 unsigned Op0Opcode = Op0->getOpcode();
670
671 // (and (MipsVExtract[SZ]Ext $a, $b, $c), imm:$d)
672 // where $d + 1 == 2^n and n == 32
673 // or $d + 1 == 2^n and n <= 32 and ZExt
674 // -> (MipsVExtractZExt $a, $b, $c)
675 if (Op0Opcode == MipsISD::VEXTRACT_SEXT_ELT ||
676 Op0Opcode == MipsISD::VEXTRACT_ZEXT_ELT) {
677 ConstantSDNode *Mask = dyn_cast<ConstantSDNode>(Val&: Op1);
678
679 if (!Mask)
680 return SDValue();
681
682 int32_t Log2IfPositive = (Mask->getAPIntValue() + 1).exactLogBase2();
683
684 if (Log2IfPositive <= 0)
685 return SDValue(); // Mask+1 is not a power of 2
686
687 SDValue Op0Op2 = Op0->getOperand(Num: 2);
688 EVT ExtendTy = cast<VTSDNode>(Val&: Op0Op2)->getVT();
689 unsigned ExtendTySize = ExtendTy.getSizeInBits();
690 unsigned Log2 = Log2IfPositive;
691
692 if ((Op0Opcode == MipsISD::VEXTRACT_ZEXT_ELT && Log2 >= ExtendTySize) ||
693 Log2 == ExtendTySize) {
694 SDValue Ops[] = { Op0->getOperand(Num: 0), Op0->getOperand(Num: 1), Op0Op2 };
695 return DAG.getNode(Opcode: MipsISD::VEXTRACT_ZEXT_ELT, DL: SDLoc(Op0),
696 VTList: Op0->getVTList(),
697 Ops: ArrayRef(Ops, Op0->getNumOperands()));
698 }
699 }
700
701 return SDValue();
702}
703
704// Determine if the specified node is a constant vector splat.
705//
706// Returns true and sets Imm if:
707// * N is a ISD::BUILD_VECTOR representing a constant splat
708//
709// This function is quite similar to MipsSEDAGToDAGISel::selectVSplat. The
710// differences are that it assumes the MSA has already been checked and the
711// arbitrary requirement for a maximum of 32-bit integers isn't applied (and
712// must not be in order for binsri.d to be selectable).
713static bool isVSplat(SDValue N, APInt &Imm, bool IsLittleEndian) {
714 BuildVectorSDNode *Node = dyn_cast<BuildVectorSDNode>(Val: N.getNode());
715
716 if (!Node)
717 return false;
718
719 APInt SplatValue, SplatUndef;
720 unsigned SplatBitSize;
721 bool HasAnyUndefs;
722
723 if (!Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
724 MinSplatBits: 8, isBigEndian: !IsLittleEndian))
725 return false;
726
727 Imm = SplatValue;
728
729 return true;
730}
731
732// Test whether the given node is an all-ones build_vector.
733static bool isVectorAllOnes(SDValue N) {
734 // Look through bitcasts. Endianness doesn't matter because we are looking
735 // for an all-ones value.
736 if (N->getOpcode() == ISD::BITCAST)
737 N = N->getOperand(Num: 0);
738
739 BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(Val&: N);
740
741 if (!BVN)
742 return false;
743
744 APInt SplatValue, SplatUndef;
745 unsigned SplatBitSize;
746 bool HasAnyUndefs;
747
748 // Endianness doesn't matter in this context because we are looking for
749 // an all-ones value.
750 if (BVN->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs))
751 return SplatValue.isAllOnes();
752
753 return false;
754}
755
756// Test whether N is the bitwise inverse of OfNode.
757static bool isBitwiseInverse(SDValue N, SDValue OfNode) {
758 if (N->getOpcode() != ISD::XOR)
759 return false;
760
761 if (isVectorAllOnes(N: N->getOperand(Num: 0)))
762 return N->getOperand(Num: 1) == OfNode;
763
764 if (isVectorAllOnes(N: N->getOperand(Num: 1)))
765 return N->getOperand(Num: 0) == OfNode;
766
767 return false;
768}
769
770// Perform combines where ISD::OR is the root node.
771//
772// Performs the following transformations:
773// - (or (and $a, $mask), (and $b, $inv_mask)) => (vselect $mask, $a, $b)
774// where $inv_mask is the bitwise inverse of $mask and the 'or' has a 128-bit
775// vector type.
776static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
777 TargetLowering::DAGCombinerInfo &DCI,
778 const MipsSubtarget &Subtarget) {
779 if (!Subtarget.hasMSA())
780 return SDValue();
781
782 EVT Ty = N->getValueType(ResNo: 0);
783
784 if (!Ty.is128BitVector())
785 return SDValue();
786
787 SDValue Op0 = N->getOperand(Num: 0);
788 SDValue Op1 = N->getOperand(Num: 1);
789
790 if (Op0->getOpcode() == ISD::AND && Op1->getOpcode() == ISD::AND) {
791 SDValue Op0Op0 = Op0->getOperand(Num: 0);
792 SDValue Op0Op1 = Op0->getOperand(Num: 1);
793 SDValue Op1Op0 = Op1->getOperand(Num: 0);
794 SDValue Op1Op1 = Op1->getOperand(Num: 1);
795 bool IsLittleEndian = !Subtarget.isLittle();
796
797 SDValue IfSet, IfClr, Cond;
798 bool IsConstantMask = false;
799 APInt Mask, InvMask;
800
801 // If Op0Op0 is an appropriate mask, try to find it's inverse in either
802 // Op1Op0, or Op1Op1. Keep track of the Cond, IfSet, and IfClr nodes, while
803 // looking.
804 // IfClr will be set if we find a valid match.
805 if (isVSplat(N: Op0Op0, Imm&: Mask, IsLittleEndian)) {
806 Cond = Op0Op0;
807 IfSet = Op0Op1;
808
809 if (isVSplat(N: Op1Op0, Imm&: InvMask, IsLittleEndian) &&
810 Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
811 IfClr = Op1Op1;
812 else if (isVSplat(N: Op1Op1, Imm&: InvMask, IsLittleEndian) &&
813 Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
814 IfClr = Op1Op0;
815
816 IsConstantMask = true;
817 }
818
819 // If IfClr is not yet set, and Op0Op1 is an appropriate mask, try the same
820 // thing again using this mask.
821 // IfClr will be set if we find a valid match.
822 if (!IfClr.getNode() && isVSplat(N: Op0Op1, Imm&: Mask, IsLittleEndian)) {
823 Cond = Op0Op1;
824 IfSet = Op0Op0;
825
826 if (isVSplat(N: Op1Op0, Imm&: InvMask, IsLittleEndian) &&
827 Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
828 IfClr = Op1Op1;
829 else if (isVSplat(N: Op1Op1, Imm&: InvMask, IsLittleEndian) &&
830 Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
831 IfClr = Op1Op0;
832
833 IsConstantMask = true;
834 }
835
836 // If IfClr is not yet set, try looking for a non-constant match.
837 // IfClr will be set if we find a valid match amongst the eight
838 // possibilities.
839 if (!IfClr.getNode()) {
840 if (isBitwiseInverse(N: Op0Op0, OfNode: Op1Op0)) {
841 Cond = Op1Op0;
842 IfSet = Op1Op1;
843 IfClr = Op0Op1;
844 } else if (isBitwiseInverse(N: Op0Op1, OfNode: Op1Op0)) {
845 Cond = Op1Op0;
846 IfSet = Op1Op1;
847 IfClr = Op0Op0;
848 } else if (isBitwiseInverse(N: Op0Op0, OfNode: Op1Op1)) {
849 Cond = Op1Op1;
850 IfSet = Op1Op0;
851 IfClr = Op0Op1;
852 } else if (isBitwiseInverse(N: Op0Op1, OfNode: Op1Op1)) {
853 Cond = Op1Op1;
854 IfSet = Op1Op0;
855 IfClr = Op0Op0;
856 } else if (isBitwiseInverse(N: Op1Op0, OfNode: Op0Op0)) {
857 Cond = Op0Op0;
858 IfSet = Op0Op1;
859 IfClr = Op1Op1;
860 } else if (isBitwiseInverse(N: Op1Op1, OfNode: Op0Op0)) {
861 Cond = Op0Op0;
862 IfSet = Op0Op1;
863 IfClr = Op1Op0;
864 } else if (isBitwiseInverse(N: Op1Op0, OfNode: Op0Op1)) {
865 Cond = Op0Op1;
866 IfSet = Op0Op0;
867 IfClr = Op1Op1;
868 } else if (isBitwiseInverse(N: Op1Op1, OfNode: Op0Op1)) {
869 Cond = Op0Op1;
870 IfSet = Op0Op0;
871 IfClr = Op1Op0;
872 }
873 }
874
875 // At this point, IfClr will be set if we have a valid match.
876 if (!IfClr.getNode())
877 return SDValue();
878
879 assert(Cond.getNode() && IfSet.getNode());
880
881 // Fold degenerate cases.
882 if (IsConstantMask) {
883 if (Mask.isAllOnes())
884 return IfSet;
885 else if (Mask == 0)
886 return IfClr;
887 }
888
889 // Transform the DAG into an equivalent VSELECT.
890 return DAG.getNode(Opcode: ISD::VSELECT, DL: SDLoc(N), VT: Ty, N1: Cond, N2: IfSet, N3: IfClr);
891 }
892
893 return SDValue();
894}
895
896static bool shouldTransformMulToShiftsAddsSubs(APInt C, EVT VT,
897 SelectionDAG &DAG,
898 const MipsSubtarget &Subtarget) {
899 // Estimate the number of operations the below transform will turn a
900 // constant multiply into. The number is approximately equal to the minimal
901 // number of powers of two that constant can be broken down to by adding
902 // or subtracting them.
903 //
904 // If we have taken more than 12[1] / 8[2] steps to attempt the
905 // optimization for a native sized value, it is more than likely that this
906 // optimization will make things worse.
907 //
908 // [1] MIPS64 requires 6 instructions at most to materialize any constant,
909 // multiplication requires at least 4 cycles, but another cycle (or two)
910 // to retrieve the result from the HI/LO registers.
911 //
912 // [2] For MIPS32, more than 8 steps is expensive as the constant could be
913 // materialized in 2 instructions, multiplication requires at least 4
914 // cycles, but another cycle (or two) to retrieve the result from the
915 // HI/LO registers.
916 //
917 // TODO:
918 // - MaxSteps needs to consider the `VT` of the constant for the current
919 // target.
920 // - Consider to perform this optimization after type legalization.
921 // That allows to remove a workaround for types not supported natively.
922 // - Take in account `-Os, -Oz` flags because this optimization
923 // increases code size.
924 unsigned MaxSteps = Subtarget.isABI_O32() ? 8 : 12;
925
926 SmallVector<APInt, 16> WorkStack(1, C);
927 unsigned Steps = 0;
928 unsigned BitWidth = C.getBitWidth();
929
930 while (!WorkStack.empty()) {
931 APInt Val = WorkStack.pop_back_val();
932
933 if (Val == 0 || Val == 1)
934 continue;
935
936 if (Steps >= MaxSteps)
937 return false;
938
939 if (Val.isPowerOf2()) {
940 ++Steps;
941 continue;
942 }
943
944 APInt Floor = APInt(BitWidth, 1) << Val.logBase2();
945 APInt Ceil = Val.isNegative() ? APInt(BitWidth, 0)
946 : APInt(BitWidth, 1) << C.ceilLogBase2();
947 if ((Val - Floor).ule(RHS: Ceil - Val)) {
948 WorkStack.push_back(Elt: Floor);
949 WorkStack.push_back(Elt: Val - Floor);
950 } else {
951 WorkStack.push_back(Elt: Ceil);
952 WorkStack.push_back(Elt: Ceil - Val);
953 }
954
955 ++Steps;
956 }
957
958 // If the value being multiplied is not supported natively, we have to pay
959 // an additional legalization cost, conservatively assume an increase in the
960 // cost of 3 instructions per step. This values for this heuristic were
961 // determined experimentally.
962 unsigned RegisterSize = DAG.getTargetLoweringInfo()
963 .getRegisterType(Context&: *DAG.getContext(), VT)
964 .getSizeInBits();
965 Steps *= (VT.getSizeInBits() != RegisterSize) * 3;
966 if (Steps > 27)
967 return false;
968
969 return true;
970}
971
972static SDValue genConstMult(SDValue X, APInt C, const SDLoc &DL, EVT VT,
973 EVT ShiftTy, SelectionDAG &DAG) {
974 // Return 0.
975 if (C == 0)
976 return DAG.getConstant(Val: 0, DL, VT);
977
978 // Return x.
979 if (C == 1)
980 return X;
981
982 // If c is power of 2, return (shl x, log2(c)).
983 if (C.isPowerOf2())
984 return DAG.getNode(Opcode: ISD::SHL, DL, VT, N1: X,
985 N2: DAG.getConstant(Val: C.logBase2(), DL, VT: ShiftTy));
986
987 unsigned BitWidth = C.getBitWidth();
988 APInt Floor = APInt(BitWidth, 1) << C.logBase2();
989 APInt Ceil = C.isNegative() ? APInt(BitWidth, 0) :
990 APInt(BitWidth, 1) << C.ceilLogBase2();
991
992 // If |c - floor_c| <= |c - ceil_c|,
993 // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))),
994 // return (add constMult(x, floor_c), constMult(x, c - floor_c)).
995 if ((C - Floor).ule(RHS: Ceil - C)) {
996 SDValue Op0 = genConstMult(X, C: Floor, DL, VT, ShiftTy, DAG);
997 SDValue Op1 = genConstMult(X, C: C - Floor, DL, VT, ShiftTy, DAG);
998 return DAG.getNode(Opcode: ISD::ADD, DL, VT, N1: Op0, N2: Op1);
999 }
1000
1001 // If |c - floor_c| > |c - ceil_c|,
1002 // return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)).
1003 SDValue Op0 = genConstMult(X, C: Ceil, DL, VT, ShiftTy, DAG);
1004 SDValue Op1 = genConstMult(X, C: Ceil - C, DL, VT, ShiftTy, DAG);
1005 return DAG.getNode(Opcode: ISD::SUB, DL, VT, N1: Op0, N2: Op1);
1006}
1007
1008static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG,
1009 const TargetLowering::DAGCombinerInfo &DCI,
1010 const MipsSETargetLowering *TL,
1011 const MipsSubtarget &Subtarget) {
1012 EVT VT = N->getValueType(ResNo: 0);
1013
1014 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val: N->getOperand(Num: 1)))
1015 if (!VT.isVector() && shouldTransformMulToShiftsAddsSubs(
1016 C: C->getAPIntValue(), VT, DAG, Subtarget))
1017 return genConstMult(X: N->getOperand(Num: 0), C: C->getAPIntValue(), DL: SDLoc(N), VT,
1018 ShiftTy: TL->getScalarShiftAmountTy(DAG.getDataLayout(), VT),
1019 DAG);
1020
1021 return SDValue(N, 0);
1022}
1023
1024static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty,
1025 SelectionDAG &DAG,
1026 const MipsSubtarget &Subtarget) {
1027 // See if this is a vector splat immediate node.
1028 APInt SplatValue, SplatUndef;
1029 unsigned SplatBitSize;
1030 bool HasAnyUndefs;
1031 unsigned EltSize = Ty.getScalarSizeInBits();
1032 BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(Val: N->getOperand(Num: 1));
1033
1034 if (!Subtarget.hasDSP())
1035 return SDValue();
1036
1037 if (!BV ||
1038 !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
1039 MinSplatBits: EltSize, isBigEndian: !Subtarget.isLittle()) ||
1040 (SplatBitSize != EltSize) ||
1041 (SplatValue.getZExtValue() >= EltSize))
1042 return SDValue();
1043
1044 SDLoc DL(N);
1045 return DAG.getNode(Opcode: Opc, DL, VT: Ty, N1: N->getOperand(Num: 0),
1046 N2: DAG.getConstant(Val: SplatValue.getZExtValue(), DL, VT: MVT::i32));
1047}
1048
1049static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
1050 TargetLowering::DAGCombinerInfo &DCI,
1051 const MipsSubtarget &Subtarget) {
1052 EVT Ty = N->getValueType(ResNo: 0);
1053
1054 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
1055 return SDValue();
1056
1057 return performDSPShiftCombine(Opc: MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget);
1058}
1059
1060// Fold sign-extensions into MipsISD::VEXTRACT_[SZ]EXT_ELT for MSA and fold
1061// constant splats into MipsISD::SHRA_DSP for DSPr2.
1062//
1063// Performs the following transformations:
1064// - Changes MipsISD::VEXTRACT_[SZ]EXT_ELT to sign extension if its
1065// sign/zero-extension is completely overwritten by the new one performed by
1066// the ISD::SRA and ISD::SHL nodes.
1067// - Removes redundant sign extensions performed by an ISD::SRA and ISD::SHL
1068// sequence.
1069//
1070// See performDSPShiftCombine for more information about the transformation
1071// used for DSPr2.
1072static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
1073 TargetLowering::DAGCombinerInfo &DCI,
1074 const MipsSubtarget &Subtarget) {
1075 EVT Ty = N->getValueType(ResNo: 0);
1076
1077 if (Subtarget.hasMSA()) {
1078 SDValue Op0 = N->getOperand(Num: 0);
1079 SDValue Op1 = N->getOperand(Num: 1);
1080
1081 // (sra (shl (MipsVExtract[SZ]Ext $a, $b, $c), imm:$d), imm:$d)
1082 // where $d + sizeof($c) == 32
1083 // or $d + sizeof($c) <= 32 and SExt
1084 // -> (MipsVExtractSExt $a, $b, $c)
1085 if (Op0->getOpcode() == ISD::SHL && Op1 == Op0->getOperand(Num: 1)) {
1086 SDValue Op0Op0 = Op0->getOperand(Num: 0);
1087 ConstantSDNode *ShAmount = dyn_cast<ConstantSDNode>(Val&: Op1);
1088
1089 if (!ShAmount)
1090 return SDValue();
1091
1092 if (Op0Op0->getOpcode() != MipsISD::VEXTRACT_SEXT_ELT &&
1093 Op0Op0->getOpcode() != MipsISD::VEXTRACT_ZEXT_ELT)
1094 return SDValue();
1095
1096 EVT ExtendTy = cast<VTSDNode>(Val: Op0Op0->getOperand(Num: 2))->getVT();
1097 unsigned TotalBits = ShAmount->getZExtValue() + ExtendTy.getSizeInBits();
1098
1099 if (TotalBits == 32 ||
1100 (Op0Op0->getOpcode() == MipsISD::VEXTRACT_SEXT_ELT &&
1101 TotalBits <= 32)) {
1102 SDValue Ops[] = { Op0Op0->getOperand(Num: 0), Op0Op0->getOperand(Num: 1),
1103 Op0Op0->getOperand(Num: 2) };
1104 return DAG.getNode(Opcode: MipsISD::VEXTRACT_SEXT_ELT, DL: SDLoc(Op0Op0),
1105 VTList: Op0Op0->getVTList(),
1106 Ops: ArrayRef(Ops, Op0Op0->getNumOperands()));
1107 }
1108 }
1109 }
1110
1111 if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget.hasDSPR2()))
1112 return SDValue();
1113
1114 return performDSPShiftCombine(Opc: MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget);
1115}
1116
1117
1118static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG,
1119 TargetLowering::DAGCombinerInfo &DCI,
1120 const MipsSubtarget &Subtarget) {
1121 EVT Ty = N->getValueType(ResNo: 0);
1122
1123 if (((Ty != MVT::v2i16) || !Subtarget.hasDSPR2()) && (Ty != MVT::v4i8))
1124 return SDValue();
1125
1126 return performDSPShiftCombine(Opc: MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget);
1127}
1128
1129static bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC) {
1130 bool IsV216 = (Ty == MVT::v2i16);
1131
1132 switch (CC) {
1133 case ISD::SETEQ:
1134 case ISD::SETNE: return true;
1135 case ISD::SETLT:
1136 case ISD::SETLE:
1137 case ISD::SETGT:
1138 case ISD::SETGE: return IsV216;
1139 case ISD::SETULT:
1140 case ISD::SETULE:
1141 case ISD::SETUGT:
1142 case ISD::SETUGE: return !IsV216;
1143 default: return false;
1144 }
1145}
1146
1147static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) {
1148 EVT Ty = N->getValueType(ResNo: 0);
1149
1150 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
1151 return SDValue();
1152
1153 if (!isLegalDSPCondCode(Ty, CC: cast<CondCodeSDNode>(Val: N->getOperand(Num: 2))->get()))
1154 return SDValue();
1155
1156 return DAG.getNode(Opcode: MipsISD::SETCC_DSP, DL: SDLoc(N), VT: Ty, N1: N->getOperand(Num: 0),
1157 N2: N->getOperand(Num: 1), N3: N->getOperand(Num: 2));
1158}
1159
1160static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) {
1161 EVT Ty = N->getValueType(ResNo: 0);
1162
1163 if (Ty == MVT::v2i16 || Ty == MVT::v4i8) {
1164 SDValue SetCC = N->getOperand(Num: 0);
1165
1166 if (SetCC.getOpcode() != MipsISD::SETCC_DSP)
1167 return SDValue();
1168
1169 return DAG.getNode(Opcode: MipsISD::SELECT_CC_DSP, DL: SDLoc(N), VT: Ty,
1170 N1: SetCC.getOperand(i: 0), N2: SetCC.getOperand(i: 1),
1171 N3: N->getOperand(Num: 1), N4: N->getOperand(Num: 2), N5: SetCC.getOperand(i: 2));
1172 }
1173
1174 return SDValue();
1175}
1176
1177static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG,
1178 const MipsSubtarget &Subtarget) {
1179 EVT Ty = N->getValueType(ResNo: 0);
1180
1181 if (Subtarget.hasMSA() && Ty.is128BitVector() && Ty.isInteger()) {
1182 // Try the following combines:
1183 // (xor (or $a, $b), (build_vector allones))
1184 // (xor (or $a, $b), (bitcast (build_vector allones)))
1185 SDValue Op0 = N->getOperand(Num: 0);
1186 SDValue Op1 = N->getOperand(Num: 1);
1187 SDValue NotOp;
1188
1189 if (ISD::isBuildVectorAllOnes(N: Op0.getNode()))
1190 NotOp = Op1;
1191 else if (ISD::isBuildVectorAllOnes(N: Op1.getNode()))
1192 NotOp = Op0;
1193 else
1194 return SDValue();
1195
1196 if (NotOp->getOpcode() == ISD::OR)
1197 return DAG.getNode(Opcode: MipsISD::VNOR, DL: SDLoc(N), VT: Ty, N1: NotOp->getOperand(Num: 0),
1198 N2: NotOp->getOperand(Num: 1));
1199 }
1200
1201 return SDValue();
1202}
1203
1204// Convert (fp_to_uint (fp16_to_fp x)) into (fp_to_sint (fp16_to_fp x)).
1205static SDValue performFP_TO_UINTCombine(SDNode *N, SelectionDAG &DAG) {
1206 SDValue Src = N->getOperand(Num: 0);
1207 EVT VT = N->getValueType(ResNo: 0);
1208
1209 // Use a trick from TargetLowering::expandFP_TO_UINT: we know that every
1210 // integer value that can be represented by f16 is <= 65504, i.e. a signed
1211 // integer of 17 bits or more can represent all values and fptoui and fptosi
1212 // are equivalent.
1213 //
1214 // NOTE: the result of fptoui is poison when the value does not fit in the
1215 // destination type (e.g. because it is negative).
1216 if (Src.getOpcode() != ISD::FP16_TO_FP || VT.getScalarSizeInBits() < 17)
1217 return SDValue();
1218 return DAG.getNode(Opcode: ISD::FP_TO_SINT, DL: SDLoc(N), VT, Operand: Src);
1219}
1220
1221SDValue
1222MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
1223 SelectionDAG &DAG = DCI.DAG;
1224 SDValue Val;
1225
1226 switch (N->getOpcode()) {
1227 case ISD::AND:
1228 Val = performANDCombine(N, DAG, DCI, Subtarget);
1229 break;
1230 case ISD::OR:
1231 Val = performORCombine(N, DAG, DCI, Subtarget);
1232 break;
1233 case ISD::MUL:
1234 return performMULCombine(N, DAG, DCI, TL: this, Subtarget);
1235 case ISD::SHL:
1236 Val = performSHLCombine(N, DAG, DCI, Subtarget);
1237 break;
1238 case ISD::SRA:
1239 return performSRACombine(N, DAG, DCI, Subtarget);
1240 case ISD::SRL:
1241 return performSRLCombine(N, DAG, DCI, Subtarget);
1242 case ISD::VSELECT:
1243 return performVSELECTCombine(N, DAG);
1244 case ISD::XOR:
1245 Val = performXORCombine(N, DAG, Subtarget);
1246 break;
1247 case ISD::SETCC:
1248 Val = performSETCCCombine(N, DAG);
1249 break;
1250 case ISD::FP_TO_UINT:
1251 Val = performFP_TO_UINTCombine(N, DAG);
1252 break;
1253 }
1254
1255 if (Val.getNode()) {
1256 LLVM_DEBUG(dbgs() << "\nMipsSE DAG Combine:\n";
1257 N->printrWithDepth(dbgs(), &DAG); dbgs() << "\n=> \n";
1258 Val.getNode()->printrWithDepth(dbgs(), &DAG); dbgs() << "\n");
1259 return Val;
1260 }
1261
1262 return MipsTargetLowering::PerformDAGCombine(N, DCI);
1263}
1264
1265MachineBasicBlock *
1266MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
1267 MachineBasicBlock *BB) const {
1268 switch (MI.getOpcode()) {
1269 default:
1270 return MipsTargetLowering::EmitInstrWithCustomInserter(MI, MBB: BB);
1271 case Mips::BPOSGE32_PSEUDO:
1272 return emitBPOSGE32(MI, BB);
1273 case Mips::SNZ_B_PSEUDO:
1274 return emitMSACBranchPseudo(MI, BB, BranchOp: Mips::BNZ_B);
1275 case Mips::SNZ_H_PSEUDO:
1276 return emitMSACBranchPseudo(MI, BB, BranchOp: Mips::BNZ_H);
1277 case Mips::SNZ_W_PSEUDO:
1278 return emitMSACBranchPseudo(MI, BB, BranchOp: Mips::BNZ_W);
1279 case Mips::SNZ_D_PSEUDO:
1280 return emitMSACBranchPseudo(MI, BB, BranchOp: Mips::BNZ_D);
1281 case Mips::SNZ_V_PSEUDO:
1282 return emitMSACBranchPseudo(MI, BB, BranchOp: Mips::BNZ_V);
1283 case Mips::SZ_B_PSEUDO:
1284 return emitMSACBranchPseudo(MI, BB, BranchOp: Mips::BZ_B);
1285 case Mips::SZ_H_PSEUDO:
1286 return emitMSACBranchPseudo(MI, BB, BranchOp: Mips::BZ_H);
1287 case Mips::SZ_W_PSEUDO:
1288 return emitMSACBranchPseudo(MI, BB, BranchOp: Mips::BZ_W);
1289 case Mips::SZ_D_PSEUDO:
1290 return emitMSACBranchPseudo(MI, BB, BranchOp: Mips::BZ_D);
1291 case Mips::SZ_V_PSEUDO:
1292 return emitMSACBranchPseudo(MI, BB, BranchOp: Mips::BZ_V);
1293 case Mips::COPY_FW_PSEUDO:
1294 return emitCOPY_FW(MI, BB);
1295 case Mips::COPY_FD_PSEUDO:
1296 return emitCOPY_FD(MI, BB);
1297 case Mips::INSERT_FW_PSEUDO:
1298 return emitINSERT_FW(MI, BB);
1299 case Mips::INSERT_FD_PSEUDO:
1300 return emitINSERT_FD(MI, BB);
1301 case Mips::INSERT_B_VIDX_PSEUDO:
1302 case Mips::INSERT_B_VIDX64_PSEUDO:
1303 return emitINSERT_DF_VIDX(MI, BB, EltSizeInBytes: 1, IsFP: false);
1304 case Mips::INSERT_H_VIDX_PSEUDO:
1305 case Mips::INSERT_H_VIDX64_PSEUDO:
1306 return emitINSERT_DF_VIDX(MI, BB, EltSizeInBytes: 2, IsFP: false);
1307 case Mips::INSERT_W_VIDX_PSEUDO:
1308 case Mips::INSERT_W_VIDX64_PSEUDO:
1309 return emitINSERT_DF_VIDX(MI, BB, EltSizeInBytes: 4, IsFP: false);
1310 case Mips::INSERT_D_VIDX_PSEUDO:
1311 case Mips::INSERT_D_VIDX64_PSEUDO:
1312 return emitINSERT_DF_VIDX(MI, BB, EltSizeInBytes: 8, IsFP: false);
1313 case Mips::INSERT_FW_VIDX_PSEUDO:
1314 case Mips::INSERT_FW_VIDX64_PSEUDO:
1315 return emitINSERT_DF_VIDX(MI, BB, EltSizeInBytes: 4, IsFP: true);
1316 case Mips::INSERT_FD_VIDX_PSEUDO:
1317 case Mips::INSERT_FD_VIDX64_PSEUDO:
1318 return emitINSERT_DF_VIDX(MI, BB, EltSizeInBytes: 8, IsFP: true);
1319 case Mips::FILL_FW_PSEUDO:
1320 return emitFILL_FW(MI, BB);
1321 case Mips::FILL_FD_PSEUDO:
1322 return emitFILL_FD(MI, BB);
1323 case Mips::FEXP2_W_1_PSEUDO:
1324 return emitFEXP2_W_1(MI, BB);
1325 case Mips::FEXP2_D_1_PSEUDO:
1326 return emitFEXP2_D_1(MI, BB);
1327 }
1328}
1329
1330bool MipsSETargetLowering::isEligibleForTailCallOptimization(
1331 const CCState &CCInfo, unsigned NextStackOffset,
1332 const MipsFunctionInfo &FI) const {
1333 // Exception has to be cleared with eret.
1334 if (FI.isISR())
1335 return false;
1336
1337 // Return false if either the callee or caller has a byval argument.
1338 if (CCInfo.getInRegsParamsCount() > 0 || FI.hasByvalArg())
1339 return false;
1340
1341 // Return true if the callee's argument area is no larger than the caller's.
1342 return NextStackOffset <= FI.getIncomingArgSize();
1343}
1344
1345void MipsSETargetLowering::
1346getOpndList(SmallVectorImpl<SDValue> &Ops,
1347 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
1348 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
1349 bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
1350 SDValue Chain) const {
1351 Ops.push_back(Elt: Callee);
1352 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
1353 InternalLinkage, IsCallReloc, CLI, Callee,
1354 Chain);
1355}
1356
1357SDValue MipsSETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {
1358 LoadSDNode &Nd = *cast<LoadSDNode>(Val&: Op);
1359
1360 if (Nd.getMemoryVT() != MVT::f64 || (!NoDPLoadStore && Subtarget.hasMips2()))
1361 return MipsTargetLowering::lowerLOAD(Op, DAG);
1362
1363 // Replace a double precision load with two i32 loads and a buildpair64.
1364 SDLoc DL(Op);
1365 SDValue Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
1366 EVT PtrVT = Ptr.getValueType();
1367 EVT VT = Subtarget.hasMips2() ? MVT::i32 : MVT::f32;
1368
1369 // i32 load from lower address.
1370 SDValue Lo = DAG.getLoad(VT, dl: DL, Chain, Ptr, PtrInfo: MachinePointerInfo(),
1371 Alignment: Nd.getAlign(), MMOFlags: Nd.getMemOperand()->getFlags());
1372
1373 // i32 load from higher address.
1374 Ptr = DAG.getNode(Opcode: ISD::ADD, DL, VT: PtrVT, N1: Ptr, N2: DAG.getConstant(Val: 4, DL, VT: PtrVT));
1375 SDValue Hi = DAG.getLoad(VT, dl: DL, Chain: Lo.getValue(R: 1), Ptr, PtrInfo: MachinePointerInfo(),
1376 Alignment: commonAlignment(A: Nd.getAlign(), Offset: 4),
1377 MMOFlags: Nd.getMemOperand()->getFlags());
1378
1379 if (!Subtarget.isLittle())
1380 std::swap(a&: Lo, b&: Hi);
1381
1382 SDValue BP;
1383 if (Subtarget.hasMips2())
1384 BP = DAG.getNode(Opcode: MipsISD::BuildPairF64, DL, VT: MVT::f64, N1: Lo, N2: Hi);
1385 else
1386 BP = DAG.getNode(Opcode: MipsISD::BuildPairF64_FPR, DL, VT: MVT::f64, N1: Hi, N2: Lo);
1387
1388 SDValue Ops[2] = {BP, Hi.getValue(R: 1)};
1389 return DAG.getMergeValues(Ops, dl: DL);
1390}
1391
1392SDValue MipsSETargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {
1393 StoreSDNode &Nd = *cast<StoreSDNode>(Val&: Op);
1394
1395 if (Nd.getMemoryVT() != MVT::f64 || (!NoDPLoadStore && Subtarget.hasMips2()))
1396 return MipsTargetLowering::lowerSTORE(Op, DAG);
1397
1398 // Replace a double precision store with two extractelement64s and i32 stores.
1399 SDLoc DL(Op);
1400 SDValue Val = Nd.getValue(), Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
1401 EVT PtrVT = Ptr.getValueType();
1402 EVT VT = Subtarget.hasMips2() ? MVT::i32 : MVT::f32;
1403
1404 unsigned ExtractOp = Subtarget.hasMips2() ? MipsISD::ExtractElementF64
1405 : MipsISD::ExtractElementF64_FPR;
1406 SDValue Lo =
1407 DAG.getNode(Opcode: ExtractOp, DL, VT, N1: Val, N2: DAG.getConstant(Val: 0, DL, VT: MVT::i32));
1408 SDValue Hi =
1409 DAG.getNode(Opcode: ExtractOp, DL, VT, N1: Val, N2: DAG.getConstant(Val: 1, DL, VT: MVT::i32));
1410
1411 if (!Subtarget.isLittle())
1412 std::swap(a&: Lo, b&: Hi);
1413
1414 // i32 store to lower address.
1415 Chain = DAG.getStore(Chain, dl: DL, Val: Lo, Ptr, PtrInfo: MachinePointerInfo(), Alignment: Nd.getAlign(),
1416 MMOFlags: Nd.getMemOperand()->getFlags(), Metadata: Nd.getAAInfo());
1417
1418 // i32 store to higher address.
1419 Ptr = DAG.getNode(Opcode: ISD::ADD, DL, VT: PtrVT, N1: Ptr, N2: DAG.getConstant(Val: 4, DL, VT: PtrVT));
1420 return DAG.getStore(Chain, dl: DL, Val: Hi, Ptr, PtrInfo: MachinePointerInfo(),
1421 Alignment: commonAlignment(A: Nd.getAlign(), Offset: 4),
1422 MMOFlags: Nd.getMemOperand()->getFlags(), Metadata: Nd.getAAInfo());
1423}
1424
1425SDValue MipsSETargetLowering::lowerBITCAST(SDValue Op,
1426 SelectionDAG &DAG) const {
1427 SDLoc DL(Op);
1428 MVT Src = Op.getOperand(i: 0).getValueType().getSimpleVT();
1429 MVT Dest = Op.getValueType().getSimpleVT();
1430
1431 // Bitcast i64 to double.
1432 if (Src == MVT::i64 && Dest == MVT::f64) {
1433 SDValue Lo, Hi;
1434 std::tie(args&: Lo, args&: Hi) =
1435 DAG.SplitScalar(N: Op.getOperand(i: 0), DL, LoVT: MVT::i32, HiVT: MVT::i32);
1436 return DAG.getNode(Opcode: MipsISD::BuildPairF64, DL, VT: MVT::f64, N1: Lo, N2: Hi);
1437 }
1438
1439 // Bitcast double to i64.
1440 if (Src == MVT::f64 && Dest == MVT::i64) {
1441 // Skip lower bitcast when operand0 has converted float results to integer
1442 // which was done by function SoftenFloatResult.
1443 if (getTypeAction(Context&: *DAG.getContext(), VT: Op.getOperand(i: 0).getValueType()) ==
1444 TargetLowering::TypeSoftenFloat)
1445 return SDValue();
1446 SDValue Lo =
1447 DAG.getNode(Opcode: MipsISD::ExtractElementF64, DL, VT: MVT::i32, N1: Op.getOperand(i: 0),
1448 N2: DAG.getConstant(Val: 0, DL, VT: MVT::i32));
1449 SDValue Hi =
1450 DAG.getNode(Opcode: MipsISD::ExtractElementF64, DL, VT: MVT::i32, N1: Op.getOperand(i: 0),
1451 N2: DAG.getConstant(Val: 1, DL, VT: MVT::i32));
1452 return DAG.getNode(Opcode: ISD::BUILD_PAIR, DL, VT: MVT::i64, N1: Lo, N2: Hi);
1453 }
1454
1455 // Skip other cases of bitcast and use default lowering.
1456 return SDValue();
1457}
1458
1459SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
1460 bool HasLo, bool HasHi,
1461 SelectionDAG &DAG) const {
1462 // MIPS32r6/MIPS64r6 removed accumulator based multiplies.
1463 assert(!Subtarget.hasMips32r6());
1464
1465 EVT Ty = Op.getOperand(i: 0).getValueType();
1466 SDLoc DL(Op);
1467 SDValue Mult = DAG.getNode(Opcode: NewOpc, DL, VT: MVT::Untyped,
1468 N1: Op.getOperand(i: 0), N2: Op.getOperand(i: 1));
1469 SDValue Lo, Hi;
1470
1471 if (HasLo)
1472 Lo = DAG.getNode(Opcode: MipsISD::MFLO, DL, VT: Ty, Operand: Mult);
1473 if (HasHi)
1474 Hi = DAG.getNode(Opcode: MipsISD::MFHI, DL, VT: Ty, Operand: Mult);
1475
1476 if (!HasLo || !HasHi)
1477 return HasLo ? Lo : Hi;
1478
1479 SDValue Vals[] = { Lo, Hi };
1480 return DAG.getMergeValues(Ops: Vals, dl: DL);
1481}
1482
1483static SDValue initAccumulator(SDValue In, const SDLoc &DL, SelectionDAG &DAG) {
1484 SDValue InLo, InHi;
1485 std::tie(args&: InLo, args&: InHi) = DAG.SplitScalar(N: In, DL, LoVT: MVT::i32, HiVT: MVT::i32);
1486 return DAG.getNode(Opcode: MipsISD::MTLOHI, DL, VT: MVT::Untyped, N1: InLo, N2: InHi);
1487}
1488
1489static SDValue extractLOHI(SDValue Op, const SDLoc &DL, SelectionDAG &DAG) {
1490 SDValue Lo = DAG.getNode(Opcode: MipsISD::MFLO, DL, VT: MVT::i32, Operand: Op);
1491 SDValue Hi = DAG.getNode(Opcode: MipsISD::MFHI, DL, VT: MVT::i32, Operand: Op);
1492 return DAG.getNode(Opcode: ISD::BUILD_PAIR, DL, VT: MVT::i64, N1: Lo, N2: Hi);
1493}
1494
1495// This function expands mips intrinsic nodes which have 64-bit input operands
1496// or output values.
1497//
1498// out64 = intrinsic-node in64
1499// =>
1500// lo = copy (extract-element (in64, 0))
1501// hi = copy (extract-element (in64, 1))
1502// mips-specific-node
1503// v0 = copy lo
1504// v1 = copy hi
1505// out64 = merge-values (v0, v1)
1506//
1507static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
1508 SDLoc DL(Op);
1509 bool HasChainIn = Op->getOperand(Num: 0).getValueType() == MVT::Other;
1510 SmallVector<SDValue, 3> Ops;
1511 unsigned OpNo = 0;
1512
1513 // See if Op has a chain input.
1514 if (HasChainIn)
1515 Ops.push_back(Elt: Op->getOperand(Num: OpNo++));
1516
1517 // The next operand is the intrinsic opcode.
1518 assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant);
1519
1520 // See if the next operand has type i64.
1521 SDValue Opnd = Op->getOperand(Num: ++OpNo), In64;
1522
1523 if (Opnd.getValueType() == MVT::i64)
1524 In64 = initAccumulator(In: Opnd, DL, DAG);
1525 else
1526 Ops.push_back(Elt: Opnd);
1527
1528 // Push the remaining operands.
1529 for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo)
1530 Ops.push_back(Elt: Op->getOperand(Num: OpNo));
1531
1532 // Add In64 to the end of the list.
1533 if (In64.getNode())
1534 Ops.push_back(Elt: In64);
1535
1536 // Scan output.
1537 SmallVector<EVT, 2> ResTys;
1538
1539 for (EVT Ty : Op->values())
1540 ResTys.push_back(Elt: (Ty == MVT::i64) ? MVT::Untyped : Ty);
1541
1542 // Create node.
1543 SDValue Val = DAG.getNode(Opcode: Opc, DL, ResultTys: ResTys, Ops);
1544 SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Op: Val, DL, DAG) : Val;
1545
1546 if (!HasChainIn)
1547 return Out;
1548
1549 assert(Val->getValueType(1) == MVT::Other);
1550 SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) };
1551 return DAG.getMergeValues(Ops: Vals, dl: DL);
1552}
1553
1554// Lower an MSA copy intrinsic into the specified SelectionDAG node
1555static SDValue lowerMSACopyIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
1556 SDLoc DL(Op);
1557 SDValue Vec = Op->getOperand(Num: 1);
1558 SDValue Idx = Op->getOperand(Num: 2);
1559 EVT ResTy = Op->getValueType(ResNo: 0);
1560 EVT EltTy = Vec->getValueType(ResNo: 0).getVectorElementType();
1561
1562 SDValue Result = DAG.getNode(Opcode: Opc, DL, VT: ResTy, N1: Vec, N2: Idx,
1563 N3: DAG.getValueType(EltTy));
1564
1565 return Result;
1566}
1567
1568static SDValue lowerMSASplatZExt(SDValue Op, unsigned OpNr, SelectionDAG &DAG) {
1569 EVT ResVecTy = Op->getValueType(ResNo: 0);
1570 EVT ViaVecTy = ResVecTy;
1571 bool BigEndian = !DAG.getSubtarget().getTargetTriple().isLittleEndian();
1572 SDLoc DL(Op);
1573
1574 // When ResVecTy == MVT::v2i64, LaneA is the upper 32 bits of the lane and
1575 // LaneB is the lower 32-bits. Otherwise LaneA and LaneB are alternating
1576 // lanes.
1577 SDValue LaneA = Op->getOperand(Num: OpNr);
1578 SDValue LaneB;
1579
1580 if (ResVecTy == MVT::v2i64) {
1581 // In case of the index being passed as an immediate value, set the upper
1582 // lane to 0 so that the splati.d instruction can be matched.
1583 if (isa<ConstantSDNode>(Val: LaneA))
1584 LaneB = DAG.getConstant(Val: 0, DL, VT: MVT::i32);
1585 // Having the index passed in a register, set the upper lane to the same
1586 // value as the lower - this results in the BUILD_VECTOR node not being
1587 // expanded through stack. This way we are able to pattern match the set of
1588 // nodes created here to splat.d.
1589 else
1590 LaneB = LaneA;
1591 ViaVecTy = MVT::v4i32;
1592 if(BigEndian)
1593 std::swap(a&: LaneA, b&: LaneB);
1594 } else
1595 LaneB = LaneA;
1596
1597 SDValue Ops[16] = { LaneA, LaneB, LaneA, LaneB, LaneA, LaneB, LaneA, LaneB,
1598 LaneA, LaneB, LaneA, LaneB, LaneA, LaneB, LaneA, LaneB };
1599
1600 SDValue Result = DAG.getBuildVector(
1601 VT: ViaVecTy, DL, Ops: ArrayRef(Ops, ViaVecTy.getVectorNumElements()));
1602
1603 if (ViaVecTy != ResVecTy) {
1604 SDValue One = DAG.getConstant(Val: 1, DL, VT: ViaVecTy);
1605 Result = DAG.getNode(Opcode: ISD::BITCAST, DL, VT: ResVecTy,
1606 Operand: DAG.getNode(Opcode: ISD::AND, DL, VT: ViaVecTy, N1: Result, N2: One));
1607 }
1608
1609 return Result;
1610}
1611
1612static SDValue lowerMSASplatImm(SDValue Op, unsigned ImmOp, SelectionDAG &DAG,
1613 bool IsSigned = false) {
1614 auto *CImm = cast<ConstantSDNode>(Val: Op->getOperand(Num: ImmOp));
1615 return DAG.getConstant(
1616 Val: APInt(Op->getValueType(ResNo: 0).getScalarType().getSizeInBits(),
1617 IsSigned ? CImm->getSExtValue() : CImm->getZExtValue(), IsSigned),
1618 DL: SDLoc(Op), VT: Op->getValueType(ResNo: 0));
1619}
1620
1621static SDValue getBuildVectorSplat(EVT VecTy, SDValue SplatValue,
1622 bool BigEndian, SelectionDAG &DAG) {
1623 EVT ViaVecTy = VecTy;
1624 SDValue SplatValueA = SplatValue;
1625 SDValue SplatValueB = SplatValue;
1626 SDLoc DL(SplatValue);
1627
1628 if (VecTy == MVT::v2i64) {
1629 // v2i64 BUILD_VECTOR must be performed via v4i32 so split into i32's.
1630 ViaVecTy = MVT::v4i32;
1631
1632 SplatValueA = DAG.getNode(Opcode: ISD::TRUNCATE, DL, VT: MVT::i32, Operand: SplatValue);
1633 SplatValueB = DAG.getNode(Opcode: ISD::SRL, DL, VT: MVT::i64, N1: SplatValue,
1634 N2: DAG.getConstant(Val: 32, DL, VT: MVT::i32));
1635 SplatValueB = DAG.getNode(Opcode: ISD::TRUNCATE, DL, VT: MVT::i32, Operand: SplatValueB);
1636 }
1637
1638 // We currently hold the parts in little endian order. Swap them if
1639 // necessary.
1640 if (BigEndian)
1641 std::swap(a&: SplatValueA, b&: SplatValueB);
1642
1643 SDValue Ops[16] = { SplatValueA, SplatValueB, SplatValueA, SplatValueB,
1644 SplatValueA, SplatValueB, SplatValueA, SplatValueB,
1645 SplatValueA, SplatValueB, SplatValueA, SplatValueB,
1646 SplatValueA, SplatValueB, SplatValueA, SplatValueB };
1647
1648 SDValue Result = DAG.getBuildVector(
1649 VT: ViaVecTy, DL, Ops: ArrayRef(Ops, ViaVecTy.getVectorNumElements()));
1650
1651 if (VecTy != ViaVecTy)
1652 Result = DAG.getNode(Opcode: ISD::BITCAST, DL, VT: VecTy, Operand: Result);
1653
1654 return Result;
1655}
1656
1657static SDValue lowerMSABinaryBitImmIntr(SDValue Op, SelectionDAG &DAG,
1658 unsigned Opc, SDValue Imm,
1659 bool BigEndian) {
1660 EVT VecTy = Op->getValueType(ResNo: 0);
1661 SDValue Exp2Imm;
1662 SDLoc DL(Op);
1663
1664 // The DAG Combiner can't constant fold bitcasted vectors yet so we must do it
1665 // here for now.
1666 if (VecTy == MVT::v2i64) {
1667 if (ConstantSDNode *CImm = dyn_cast<ConstantSDNode>(Val&: Imm)) {
1668 APInt BitImm = APInt(64, 1) << CImm->getAPIntValue();
1669
1670 SDValue BitImmHiOp = DAG.getConstant(Val: BitImm.lshr(shiftAmt: 32).trunc(width: 32), DL,
1671 VT: MVT::i32);
1672 SDValue BitImmLoOp = DAG.getConstant(Val: BitImm.trunc(width: 32), DL, VT: MVT::i32);
1673
1674 if (BigEndian)
1675 std::swap(a&: BitImmLoOp, b&: BitImmHiOp);
1676
1677 Exp2Imm = DAG.getNode(
1678 Opcode: ISD::BITCAST, DL, VT: MVT::v2i64,
1679 Operand: DAG.getBuildVector(VT: MVT::v4i32, DL,
1680 Ops: {BitImmLoOp, BitImmHiOp, BitImmLoOp, BitImmHiOp}));
1681 }
1682 }
1683
1684 if (!Exp2Imm.getNode()) {
1685 // We couldnt constant fold, do a vector shift instead
1686
1687 // Extend i32 to i64 if necessary. Sign or zero extend doesn't matter since
1688 // only values 0-63 are valid.
1689 if (VecTy == MVT::v2i64)
1690 Imm = DAG.getNode(Opcode: ISD::ZERO_EXTEND, DL, VT: MVT::i64, Operand: Imm);
1691
1692 Exp2Imm = getBuildVectorSplat(VecTy, SplatValue: Imm, BigEndian, DAG);
1693
1694 Exp2Imm = DAG.getNode(Opcode: ISD::SHL, DL, VT: VecTy, N1: DAG.getConstant(Val: 1, DL, VT: VecTy),
1695 N2: Exp2Imm);
1696 }
1697
1698 return DAG.getNode(Opcode: Opc, DL, VT: VecTy, N1: Op->getOperand(Num: 1), N2: Exp2Imm);
1699}
1700
1701static SDValue truncateVecElts(SDValue Op, SelectionDAG &DAG) {
1702 SDLoc DL(Op);
1703 EVT ResTy = Op->getValueType(ResNo: 0);
1704 SDValue Vec = Op->getOperand(Num: 2);
1705 bool BigEndian = !DAG.getSubtarget().getTargetTriple().isLittleEndian();
1706 MVT ResEltTy = ResTy == MVT::v2i64 ? MVT::i64 : MVT::i32;
1707 SDValue ConstValue = DAG.getConstant(Val: Vec.getScalarValueSizeInBits() - 1,
1708 DL, VT: ResEltTy);
1709 SDValue SplatVec = getBuildVectorSplat(VecTy: ResTy, SplatValue: ConstValue, BigEndian, DAG);
1710
1711 return DAG.getNode(Opcode: ISD::AND, DL, VT: ResTy, N1: Vec, N2: SplatVec);
1712}
1713
1714static SDValue lowerMSABitClear(SDValue Op, SelectionDAG &DAG) {
1715 EVT ResTy = Op->getValueType(ResNo: 0);
1716 SDLoc DL(Op);
1717 SDValue One = DAG.getConstant(Val: 1, DL, VT: ResTy);
1718 SDValue Bit = DAG.getNode(Opcode: ISD::SHL, DL, VT: ResTy, N1: One, N2: truncateVecElts(Op, DAG));
1719
1720 return DAG.getNode(Opcode: ISD::AND, DL, VT: ResTy, N1: Op->getOperand(Num: 1),
1721 N2: DAG.getNOT(DL, Val: Bit, VT: ResTy));
1722}
1723
1724static SDValue lowerMSABitClearImm(SDValue Op, SelectionDAG &DAG) {
1725 SDLoc DL(Op);
1726 EVT ResTy = Op->getValueType(ResNo: 0);
1727 APInt BitImm = APInt(ResTy.getScalarSizeInBits(), 1)
1728 << Op->getConstantOperandAPInt(Num: 2);
1729 SDValue BitMask = DAG.getConstant(Val: ~BitImm, DL, VT: ResTy);
1730
1731 return DAG.getNode(Opcode: ISD::AND, DL, VT: ResTy, N1: Op->getOperand(Num: 1), N2: BitMask);
1732}
1733
1734SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
1735 SelectionDAG &DAG) const {
1736 SDLoc DL(Op);
1737 unsigned Intrinsic = Op->getConstantOperandVal(Num: 0);
1738 switch (Intrinsic) {
1739 default:
1740 return SDValue();
1741 case Intrinsic::mips_shilo:
1742 return lowerDSPIntr(Op, DAG, Opc: MipsISD::SHILO);
1743 case Intrinsic::mips_dpau_h_qbl:
1744 return lowerDSPIntr(Op, DAG, Opc: MipsISD::DPAU_H_QBL);
1745 case Intrinsic::mips_dpau_h_qbr:
1746 return lowerDSPIntr(Op, DAG, Opc: MipsISD::DPAU_H_QBR);
1747 case Intrinsic::mips_dpsu_h_qbl:
1748 return lowerDSPIntr(Op, DAG, Opc: MipsISD::DPSU_H_QBL);
1749 case Intrinsic::mips_dpsu_h_qbr:
1750 return lowerDSPIntr(Op, DAG, Opc: MipsISD::DPSU_H_QBR);
1751 case Intrinsic::mips_dpa_w_ph:
1752 return lowerDSPIntr(Op, DAG, Opc: MipsISD::DPA_W_PH);
1753 case Intrinsic::mips_dps_w_ph:
1754 return lowerDSPIntr(Op, DAG, Opc: MipsISD::DPS_W_PH);
1755 case Intrinsic::mips_dpax_w_ph:
1756 return lowerDSPIntr(Op, DAG, Opc: MipsISD::DPAX_W_PH);
1757 case Intrinsic::mips_dpsx_w_ph:
1758 return lowerDSPIntr(Op, DAG, Opc: MipsISD::DPSX_W_PH);
1759 case Intrinsic::mips_mulsa_w_ph:
1760 return lowerDSPIntr(Op, DAG, Opc: MipsISD::MULSA_W_PH);
1761 case Intrinsic::mips_mult:
1762 return lowerDSPIntr(Op, DAG, Opc: MipsISD::Mult);
1763 case Intrinsic::mips_multu:
1764 return lowerDSPIntr(Op, DAG, Opc: MipsISD::Multu);
1765 case Intrinsic::mips_madd:
1766 return lowerDSPIntr(Op, DAG, Opc: MipsISD::MAdd);
1767 case Intrinsic::mips_maddu:
1768 return lowerDSPIntr(Op, DAG, Opc: MipsISD::MAddu);
1769 case Intrinsic::mips_msub:
1770 return lowerDSPIntr(Op, DAG, Opc: MipsISD::MSub);
1771 case Intrinsic::mips_msubu:
1772 return lowerDSPIntr(Op, DAG, Opc: MipsISD::MSubu);
1773 case Intrinsic::mips_addv_b:
1774 case Intrinsic::mips_addv_h:
1775 case Intrinsic::mips_addv_w:
1776 case Intrinsic::mips_addv_d:
1777 return DAG.getNode(Opcode: ISD::ADD, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
1778 N2: Op->getOperand(Num: 2));
1779 case Intrinsic::mips_addvi_b:
1780 case Intrinsic::mips_addvi_h:
1781 case Intrinsic::mips_addvi_w:
1782 case Intrinsic::mips_addvi_d:
1783 return DAG.getNode(Opcode: ISD::ADD, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
1784 N2: lowerMSASplatImm(Op, ImmOp: 2, DAG));
1785 case Intrinsic::mips_and_v:
1786 return DAG.getNode(Opcode: ISD::AND, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
1787 N2: Op->getOperand(Num: 2));
1788 case Intrinsic::mips_andi_b:
1789 return DAG.getNode(Opcode: ISD::AND, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
1790 N2: lowerMSASplatImm(Op, ImmOp: 2, DAG));
1791 case Intrinsic::mips_bclr_b:
1792 case Intrinsic::mips_bclr_h:
1793 case Intrinsic::mips_bclr_w:
1794 case Intrinsic::mips_bclr_d:
1795 return lowerMSABitClear(Op, DAG);
1796 case Intrinsic::mips_bclri_b:
1797 case Intrinsic::mips_bclri_h:
1798 case Intrinsic::mips_bclri_w:
1799 case Intrinsic::mips_bclri_d:
1800 return lowerMSABitClearImm(Op, DAG);
1801 case Intrinsic::mips_binsli_b:
1802 case Intrinsic::mips_binsli_h:
1803 case Intrinsic::mips_binsli_w:
1804 case Intrinsic::mips_binsli_d: {
1805 // binsli_x(IfClear, IfSet, nbits) -> (vselect LBitsMask, IfSet, IfClear)
1806 EVT VecTy = Op->getValueType(ResNo: 0);
1807 EVT EltTy = VecTy.getVectorElementType();
1808 if (Op->getConstantOperandVal(Num: 3) >= EltTy.getSizeInBits())
1809 report_fatal_error(reason: "Immediate out of range");
1810 APInt Mask = APInt::getHighBitsSet(numBits: EltTy.getSizeInBits(),
1811 hiBitsSet: Op->getConstantOperandVal(Num: 3) + 1);
1812 return DAG.getNode(Opcode: ISD::VSELECT, DL, VT: VecTy,
1813 N1: DAG.getConstant(Val: Mask, DL, VT: VecTy, isTarget: true),
1814 N2: Op->getOperand(Num: 2), N3: Op->getOperand(Num: 1));
1815 }
1816 case Intrinsic::mips_binsri_b:
1817 case Intrinsic::mips_binsri_h:
1818 case Intrinsic::mips_binsri_w:
1819 case Intrinsic::mips_binsri_d: {
1820 // binsri_x(IfClear, IfSet, nbits) -> (vselect RBitsMask, IfSet, IfClear)
1821 EVT VecTy = Op->getValueType(ResNo: 0);
1822 EVT EltTy = VecTy.getVectorElementType();
1823 if (Op->getConstantOperandVal(Num: 3) >= EltTy.getSizeInBits())
1824 report_fatal_error(reason: "Immediate out of range");
1825 APInt Mask = APInt::getLowBitsSet(numBits: EltTy.getSizeInBits(),
1826 loBitsSet: Op->getConstantOperandVal(Num: 3) + 1);
1827 return DAG.getNode(Opcode: ISD::VSELECT, DL, VT: VecTy,
1828 N1: DAG.getConstant(Val: Mask, DL, VT: VecTy, isTarget: true),
1829 N2: Op->getOperand(Num: 2), N3: Op->getOperand(Num: 1));
1830 }
1831 case Intrinsic::mips_bmnz_v:
1832 return DAG.getNode(Opcode: ISD::VSELECT, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 3),
1833 N2: Op->getOperand(Num: 2), N3: Op->getOperand(Num: 1));
1834 case Intrinsic::mips_bmnzi_b:
1835 return DAG.getNode(Opcode: ISD::VSELECT, DL, VT: Op->getValueType(ResNo: 0),
1836 N1: lowerMSASplatImm(Op, ImmOp: 3, DAG), N2: Op->getOperand(Num: 2),
1837 N3: Op->getOperand(Num: 1));
1838 case Intrinsic::mips_bmz_v:
1839 return DAG.getNode(Opcode: ISD::VSELECT, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 3),
1840 N2: Op->getOperand(Num: 1), N3: Op->getOperand(Num: 2));
1841 case Intrinsic::mips_bmzi_b:
1842 return DAG.getNode(Opcode: ISD::VSELECT, DL, VT: Op->getValueType(ResNo: 0),
1843 N1: lowerMSASplatImm(Op, ImmOp: 3, DAG), N2: Op->getOperand(Num: 1),
1844 N3: Op->getOperand(Num: 2));
1845 case Intrinsic::mips_bneg_b:
1846 case Intrinsic::mips_bneg_h:
1847 case Intrinsic::mips_bneg_w:
1848 case Intrinsic::mips_bneg_d: {
1849 EVT VecTy = Op->getValueType(ResNo: 0);
1850 SDValue One = DAG.getConstant(Val: 1, DL, VT: VecTy);
1851
1852 return DAG.getNode(Opcode: ISD::XOR, DL, VT: VecTy, N1: Op->getOperand(Num: 1),
1853 N2: DAG.getNode(Opcode: ISD::SHL, DL, VT: VecTy, N1: One,
1854 N2: truncateVecElts(Op, DAG)));
1855 }
1856 case Intrinsic::mips_bnegi_b:
1857 case Intrinsic::mips_bnegi_h:
1858 case Intrinsic::mips_bnegi_w:
1859 case Intrinsic::mips_bnegi_d:
1860 return lowerMSABinaryBitImmIntr(Op, DAG, Opc: ISD::XOR, Imm: Op->getOperand(Num: 2),
1861 BigEndian: !Subtarget.isLittle());
1862 case Intrinsic::mips_bnz_b:
1863 case Intrinsic::mips_bnz_h:
1864 case Intrinsic::mips_bnz_w:
1865 case Intrinsic::mips_bnz_d:
1866 return DAG.getNode(Opcode: MipsISD::VALL_NONZERO, DL, VT: Op->getValueType(ResNo: 0),
1867 Operand: Op->getOperand(Num: 1));
1868 case Intrinsic::mips_bnz_v:
1869 return DAG.getNode(Opcode: MipsISD::VANY_NONZERO, DL, VT: Op->getValueType(ResNo: 0),
1870 Operand: Op->getOperand(Num: 1));
1871 case Intrinsic::mips_bsel_v:
1872 // bsel_v(Mask, IfClear, IfSet) -> (vselect Mask, IfSet, IfClear)
1873 return DAG.getNode(Opcode: ISD::VSELECT, DL, VT: Op->getValueType(ResNo: 0),
1874 N1: Op->getOperand(Num: 1), N2: Op->getOperand(Num: 3),
1875 N3: Op->getOperand(Num: 2));
1876 case Intrinsic::mips_bseli_b:
1877 // bseli_v(Mask, IfClear, IfSet) -> (vselect Mask, IfSet, IfClear)
1878 return DAG.getNode(Opcode: ISD::VSELECT, DL, VT: Op->getValueType(ResNo: 0),
1879 N1: Op->getOperand(Num: 1), N2: lowerMSASplatImm(Op, ImmOp: 3, DAG),
1880 N3: Op->getOperand(Num: 2));
1881 case Intrinsic::mips_bset_b:
1882 case Intrinsic::mips_bset_h:
1883 case Intrinsic::mips_bset_w:
1884 case Intrinsic::mips_bset_d: {
1885 EVT VecTy = Op->getValueType(ResNo: 0);
1886 SDValue One = DAG.getConstant(Val: 1, DL, VT: VecTy);
1887
1888 return DAG.getNode(Opcode: ISD::OR, DL, VT: VecTy, N1: Op->getOperand(Num: 1),
1889 N2: DAG.getNode(Opcode: ISD::SHL, DL, VT: VecTy, N1: One,
1890 N2: truncateVecElts(Op, DAG)));
1891 }
1892 case Intrinsic::mips_bseti_b:
1893 case Intrinsic::mips_bseti_h:
1894 case Intrinsic::mips_bseti_w:
1895 case Intrinsic::mips_bseti_d:
1896 return lowerMSABinaryBitImmIntr(Op, DAG, Opc: ISD::OR, Imm: Op->getOperand(Num: 2),
1897 BigEndian: !Subtarget.isLittle());
1898 case Intrinsic::mips_bz_b:
1899 case Intrinsic::mips_bz_h:
1900 case Intrinsic::mips_bz_w:
1901 case Intrinsic::mips_bz_d:
1902 return DAG.getNode(Opcode: MipsISD::VALL_ZERO, DL, VT: Op->getValueType(ResNo: 0),
1903 Operand: Op->getOperand(Num: 1));
1904 case Intrinsic::mips_bz_v:
1905 return DAG.getNode(Opcode: MipsISD::VANY_ZERO, DL, VT: Op->getValueType(ResNo: 0),
1906 Operand: Op->getOperand(Num: 1));
1907 case Intrinsic::mips_ceq_b:
1908 case Intrinsic::mips_ceq_h:
1909 case Intrinsic::mips_ceq_w:
1910 case Intrinsic::mips_ceq_d:
1911 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
1912 RHS: Op->getOperand(Num: 2), Cond: ISD::SETEQ);
1913 case Intrinsic::mips_ceqi_b:
1914 case Intrinsic::mips_ceqi_h:
1915 case Intrinsic::mips_ceqi_w:
1916 case Intrinsic::mips_ceqi_d:
1917 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
1918 RHS: lowerMSASplatImm(Op, ImmOp: 2, DAG, IsSigned: true), Cond: ISD::SETEQ);
1919 case Intrinsic::mips_cle_s_b:
1920 case Intrinsic::mips_cle_s_h:
1921 case Intrinsic::mips_cle_s_w:
1922 case Intrinsic::mips_cle_s_d:
1923 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
1924 RHS: Op->getOperand(Num: 2), Cond: ISD::SETLE);
1925 case Intrinsic::mips_clei_s_b:
1926 case Intrinsic::mips_clei_s_h:
1927 case Intrinsic::mips_clei_s_w:
1928 case Intrinsic::mips_clei_s_d:
1929 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
1930 RHS: lowerMSASplatImm(Op, ImmOp: 2, DAG, IsSigned: true), Cond: ISD::SETLE);
1931 case Intrinsic::mips_cle_u_b:
1932 case Intrinsic::mips_cle_u_h:
1933 case Intrinsic::mips_cle_u_w:
1934 case Intrinsic::mips_cle_u_d:
1935 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
1936 RHS: Op->getOperand(Num: 2), Cond: ISD::SETULE);
1937 case Intrinsic::mips_clei_u_b:
1938 case Intrinsic::mips_clei_u_h:
1939 case Intrinsic::mips_clei_u_w:
1940 case Intrinsic::mips_clei_u_d:
1941 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
1942 RHS: lowerMSASplatImm(Op, ImmOp: 2, DAG), Cond: ISD::SETULE);
1943 case Intrinsic::mips_clt_s_b:
1944 case Intrinsic::mips_clt_s_h:
1945 case Intrinsic::mips_clt_s_w:
1946 case Intrinsic::mips_clt_s_d:
1947 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
1948 RHS: Op->getOperand(Num: 2), Cond: ISD::SETLT);
1949 case Intrinsic::mips_clti_s_b:
1950 case Intrinsic::mips_clti_s_h:
1951 case Intrinsic::mips_clti_s_w:
1952 case Intrinsic::mips_clti_s_d:
1953 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
1954 RHS: lowerMSASplatImm(Op, ImmOp: 2, DAG, IsSigned: true), Cond: ISD::SETLT);
1955 case Intrinsic::mips_clt_u_b:
1956 case Intrinsic::mips_clt_u_h:
1957 case Intrinsic::mips_clt_u_w:
1958 case Intrinsic::mips_clt_u_d:
1959 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
1960 RHS: Op->getOperand(Num: 2), Cond: ISD::SETULT);
1961 case Intrinsic::mips_clti_u_b:
1962 case Intrinsic::mips_clti_u_h:
1963 case Intrinsic::mips_clti_u_w:
1964 case Intrinsic::mips_clti_u_d:
1965 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
1966 RHS: lowerMSASplatImm(Op, ImmOp: 2, DAG), Cond: ISD::SETULT);
1967 case Intrinsic::mips_copy_s_b:
1968 case Intrinsic::mips_copy_s_h:
1969 case Intrinsic::mips_copy_s_w:
1970 return lowerMSACopyIntr(Op, DAG, Opc: MipsISD::VEXTRACT_SEXT_ELT);
1971 case Intrinsic::mips_copy_s_d:
1972 if (Subtarget.hasMips64())
1973 // Lower directly into VEXTRACT_SEXT_ELT since i64 is legal on Mips64.
1974 return lowerMSACopyIntr(Op, DAG, Opc: MipsISD::VEXTRACT_SEXT_ELT);
1975 else {
1976 // Lower into the generic EXTRACT_VECTOR_ELT node and let the type
1977 // legalizer and EXTRACT_VECTOR_ELT lowering sort it out.
1978 return DAG.getNode(Opcode: ISD::EXTRACT_VECTOR_ELT, DL: SDLoc(Op),
1979 VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
1980 N2: Op->getOperand(Num: 2));
1981 }
1982 case Intrinsic::mips_copy_u_b:
1983 case Intrinsic::mips_copy_u_h:
1984 case Intrinsic::mips_copy_u_w:
1985 return lowerMSACopyIntr(Op, DAG, Opc: MipsISD::VEXTRACT_ZEXT_ELT);
1986 case Intrinsic::mips_copy_u_d:
1987 if (Subtarget.hasMips64())
1988 // Lower directly into VEXTRACT_ZEXT_ELT since i64 is legal on Mips64.
1989 return lowerMSACopyIntr(Op, DAG, Opc: MipsISD::VEXTRACT_ZEXT_ELT);
1990 else {
1991 // Lower into the generic EXTRACT_VECTOR_ELT node and let the type
1992 // legalizer and EXTRACT_VECTOR_ELT lowering sort it out.
1993 // Note: When i64 is illegal, this results in copy_s.w instructions
1994 // instead of copy_u.w instructions. This makes no difference to the
1995 // behaviour since i64 is only illegal when the register file is 32-bit.
1996 return DAG.getNode(Opcode: ISD::EXTRACT_VECTOR_ELT, DL: SDLoc(Op),
1997 VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
1998 N2: Op->getOperand(Num: 2));
1999 }
2000 case Intrinsic::mips_div_s_b:
2001 case Intrinsic::mips_div_s_h:
2002 case Intrinsic::mips_div_s_w:
2003 case Intrinsic::mips_div_s_d:
2004 return DAG.getNode(Opcode: ISD::SDIV, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
2005 N2: Op->getOperand(Num: 2));
2006 case Intrinsic::mips_div_u_b:
2007 case Intrinsic::mips_div_u_h:
2008 case Intrinsic::mips_div_u_w:
2009 case Intrinsic::mips_div_u_d:
2010 return DAG.getNode(Opcode: ISD::UDIV, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
2011 N2: Op->getOperand(Num: 2));
2012 case Intrinsic::mips_fadd_w:
2013 case Intrinsic::mips_fadd_d:
2014 return DAG.getNode(Opcode: ISD::FADD, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
2015 N2: Op->getOperand(Num: 2), Flags: Op->getFlags());
2016 // Don't lower mips_fcaf_[wd] since LLVM folds SETFALSE condcodes away
2017 case Intrinsic::mips_fceq_w:
2018 case Intrinsic::mips_fceq_d:
2019 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
2020 RHS: Op->getOperand(Num: 2), Cond: ISD::SETOEQ);
2021 case Intrinsic::mips_fcle_w:
2022 case Intrinsic::mips_fcle_d:
2023 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
2024 RHS: Op->getOperand(Num: 2), Cond: ISD::SETOLE);
2025 case Intrinsic::mips_fclt_w:
2026 case Intrinsic::mips_fclt_d:
2027 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
2028 RHS: Op->getOperand(Num: 2), Cond: ISD::SETOLT);
2029 case Intrinsic::mips_fcne_w:
2030 case Intrinsic::mips_fcne_d:
2031 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
2032 RHS: Op->getOperand(Num: 2), Cond: ISD::SETONE);
2033 case Intrinsic::mips_fcor_w:
2034 case Intrinsic::mips_fcor_d:
2035 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
2036 RHS: Op->getOperand(Num: 2), Cond: ISD::SETO);
2037 case Intrinsic::mips_fcueq_w:
2038 case Intrinsic::mips_fcueq_d:
2039 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
2040 RHS: Op->getOperand(Num: 2), Cond: ISD::SETUEQ);
2041 case Intrinsic::mips_fcule_w:
2042 case Intrinsic::mips_fcule_d:
2043 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
2044 RHS: Op->getOperand(Num: 2), Cond: ISD::SETULE);
2045 case Intrinsic::mips_fcult_w:
2046 case Intrinsic::mips_fcult_d:
2047 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
2048 RHS: Op->getOperand(Num: 2), Cond: ISD::SETULT);
2049 case Intrinsic::mips_fcun_w:
2050 case Intrinsic::mips_fcun_d:
2051 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
2052 RHS: Op->getOperand(Num: 2), Cond: ISD::SETUO);
2053 case Intrinsic::mips_fcune_w:
2054 case Intrinsic::mips_fcune_d:
2055 return DAG.getSetCC(DL, VT: Op->getValueType(ResNo: 0), LHS: Op->getOperand(Num: 1),
2056 RHS: Op->getOperand(Num: 2), Cond: ISD::SETUNE);
2057 case Intrinsic::mips_fdiv_w:
2058 case Intrinsic::mips_fdiv_d:
2059 // TODO: If intrinsics have fast-math-flags, propagate them.
2060 return DAG.getNode(Opcode: ISD::FDIV, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
2061 N2: Op->getOperand(Num: 2));
2062 case Intrinsic::mips_ffint_u_w:
2063 case Intrinsic::mips_ffint_u_d:
2064 return DAG.getNode(Opcode: ISD::UINT_TO_FP, DL, VT: Op->getValueType(ResNo: 0),
2065 Operand: Op->getOperand(Num: 1));
2066 case Intrinsic::mips_ffint_s_w:
2067 case Intrinsic::mips_ffint_s_d:
2068 return DAG.getNode(Opcode: ISD::SINT_TO_FP, DL, VT: Op->getValueType(ResNo: 0),
2069 Operand: Op->getOperand(Num: 1));
2070 case Intrinsic::mips_fill_b:
2071 case Intrinsic::mips_fill_h:
2072 case Intrinsic::mips_fill_w:
2073 case Intrinsic::mips_fill_d: {
2074 EVT ResTy = Op->getValueType(ResNo: 0);
2075 SmallVector<SDValue, 16> Ops(ResTy.getVectorNumElements(),
2076 Op->getOperand(Num: 1));
2077
2078 // If ResTy is v2i64 then the type legalizer will break this node down into
2079 // an equivalent v4i32.
2080 return DAG.getBuildVector(VT: ResTy, DL, Ops);
2081 }
2082 case Intrinsic::mips_fexp2_w:
2083 case Intrinsic::mips_fexp2_d: {
2084 // TODO: If intrinsics have fast-math-flags, propagate them.
2085 EVT ResTy = Op->getValueType(ResNo: 0);
2086 return DAG.getNode(
2087 Opcode: ISD::FMUL, DL: SDLoc(Op), VT: ResTy, N1: Op->getOperand(Num: 1),
2088 N2: DAG.getNode(Opcode: ISD::FEXP2, DL: SDLoc(Op), VT: ResTy, Operand: Op->getOperand(Num: 2)));
2089 }
2090 case Intrinsic::mips_flog2_w:
2091 case Intrinsic::mips_flog2_d:
2092 return DAG.getNode(Opcode: ISD::FLOG2, DL, VT: Op->getValueType(ResNo: 0), Operand: Op->getOperand(Num: 1));
2093 case Intrinsic::mips_fmadd_w:
2094 case Intrinsic::mips_fmadd_d:
2095 return DAG.getNode(Opcode: ISD::FMA, DL: SDLoc(Op), VT: Op->getValueType(ResNo: 0),
2096 N1: Op->getOperand(Num: 1), N2: Op->getOperand(Num: 2), N3: Op->getOperand(Num: 3));
2097 case Intrinsic::mips_fmul_w:
2098 case Intrinsic::mips_fmul_d:
2099 return DAG.getNode(Opcode: ISD::FMUL, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
2100 N2: Op->getOperand(Num: 2), Flags: Op->getFlags());
2101 case Intrinsic::mips_fmsub_w:
2102 case Intrinsic::mips_fmsub_d: {
2103 // TODO: If intrinsics have fast-math-flags, propagate them.
2104 return DAG.getNode(Opcode: MipsISD::FMS, DL: SDLoc(Op), VT: Op->getValueType(ResNo: 0),
2105 N1: Op->getOperand(Num: 1), N2: Op->getOperand(Num: 2), N3: Op->getOperand(Num: 3));
2106 }
2107 case Intrinsic::mips_frint_w:
2108 case Intrinsic::mips_frint_d:
2109 return DAG.getNode(Opcode: ISD::FRINT, DL, VT: Op->getValueType(ResNo: 0), Operand: Op->getOperand(Num: 1));
2110 case Intrinsic::mips_fsqrt_w:
2111 case Intrinsic::mips_fsqrt_d:
2112 return DAG.getNode(Opcode: ISD::FSQRT, DL, VT: Op->getValueType(ResNo: 0), Operand: Op->getOperand(Num: 1));
2113 case Intrinsic::mips_fsub_w:
2114 case Intrinsic::mips_fsub_d:
2115 return DAG.getNode(Opcode: ISD::FSUB, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
2116 N2: Op->getOperand(Num: 2), Flags: Op->getFlags());
2117 case Intrinsic::mips_ftrunc_u_w:
2118 case Intrinsic::mips_ftrunc_u_d:
2119 return DAG.getNode(Opcode: ISD::FP_TO_UINT, DL, VT: Op->getValueType(ResNo: 0),
2120 Operand: Op->getOperand(Num: 1));
2121 case Intrinsic::mips_ftrunc_s_w:
2122 case Intrinsic::mips_ftrunc_s_d:
2123 return DAG.getNode(Opcode: ISD::FP_TO_SINT, DL, VT: Op->getValueType(ResNo: 0),
2124 Operand: Op->getOperand(Num: 1));
2125 case Intrinsic::mips_ilvev_b:
2126 case Intrinsic::mips_ilvev_h:
2127 case Intrinsic::mips_ilvev_w:
2128 case Intrinsic::mips_ilvev_d:
2129 return DAG.getNode(Opcode: MipsISD::ILVEV, DL, VT: Op->getValueType(ResNo: 0),
2130 N1: Op->getOperand(Num: 1), N2: Op->getOperand(Num: 2));
2131 case Intrinsic::mips_ilvl_b:
2132 case Intrinsic::mips_ilvl_h:
2133 case Intrinsic::mips_ilvl_w:
2134 case Intrinsic::mips_ilvl_d:
2135 return DAG.getNode(Opcode: MipsISD::ILVL, DL, VT: Op->getValueType(ResNo: 0),
2136 N1: Op->getOperand(Num: 1), N2: Op->getOperand(Num: 2));
2137 case Intrinsic::mips_ilvod_b:
2138 case Intrinsic::mips_ilvod_h:
2139 case Intrinsic::mips_ilvod_w:
2140 case Intrinsic::mips_ilvod_d:
2141 return DAG.getNode(Opcode: MipsISD::ILVOD, DL, VT: Op->getValueType(ResNo: 0),
2142 N1: Op->getOperand(Num: 1), N2: Op->getOperand(Num: 2));
2143 case Intrinsic::mips_ilvr_b:
2144 case Intrinsic::mips_ilvr_h:
2145 case Intrinsic::mips_ilvr_w:
2146 case Intrinsic::mips_ilvr_d:
2147 return DAG.getNode(Opcode: MipsISD::ILVR, DL, VT: Op->getValueType(ResNo: 0),
2148 N1: Op->getOperand(Num: 1), N2: Op->getOperand(Num: 2));
2149 case Intrinsic::mips_insert_b:
2150 case Intrinsic::mips_insert_h:
2151 case Intrinsic::mips_insert_w:
2152 case Intrinsic::mips_insert_d:
2153 return DAG.getNode(Opcode: ISD::INSERT_VECTOR_ELT, DL: SDLoc(Op), VT: Op->getValueType(ResNo: 0),
2154 N1: Op->getOperand(Num: 1), N2: Op->getOperand(Num: 3), N3: Op->getOperand(Num: 2));
2155 case Intrinsic::mips_insve_b:
2156 case Intrinsic::mips_insve_h:
2157 case Intrinsic::mips_insve_w:
2158 case Intrinsic::mips_insve_d: {
2159 // Report an error for out of range values.
2160 int64_t Max;
2161 switch (Intrinsic) {
2162 case Intrinsic::mips_insve_b: Max = 15; break;
2163 case Intrinsic::mips_insve_h: Max = 7; break;
2164 case Intrinsic::mips_insve_w: Max = 3; break;
2165 case Intrinsic::mips_insve_d: Max = 1; break;
2166 default: llvm_unreachable("Unmatched intrinsic");
2167 }
2168 int64_t Value = cast<ConstantSDNode>(Val: Op->getOperand(Num: 2))->getSExtValue();
2169 if (Value < 0 || Value > Max)
2170 report_fatal_error(reason: "Immediate out of range");
2171 return DAG.getNode(Opcode: MipsISD::INSVE, DL, VT: Op->getValueType(ResNo: 0),
2172 N1: Op->getOperand(Num: 1), N2: Op->getOperand(Num: 2), N3: Op->getOperand(Num: 3),
2173 N4: DAG.getConstant(Val: 0, DL, VT: MVT::i32));
2174 }
2175 case Intrinsic::mips_ldi_b:
2176 case Intrinsic::mips_ldi_h:
2177 case Intrinsic::mips_ldi_w:
2178 case Intrinsic::mips_ldi_d:
2179 return lowerMSASplatImm(Op, ImmOp: 1, DAG, IsSigned: true);
2180 case Intrinsic::mips_lsa:
2181 case Intrinsic::mips_dlsa: {
2182 EVT ResTy = Op->getValueType(ResNo: 0);
2183 return DAG.getNode(Opcode: ISD::ADD, DL: SDLoc(Op), VT: ResTy, N1: Op->getOperand(Num: 1),
2184 N2: DAG.getNode(Opcode: ISD::SHL, DL: SDLoc(Op), VT: ResTy,
2185 N1: Op->getOperand(Num: 2), N2: Op->getOperand(Num: 3)));
2186 }
2187 case Intrinsic::mips_maddv_b:
2188 case Intrinsic::mips_maddv_h:
2189 case Intrinsic::mips_maddv_w:
2190 case Intrinsic::mips_maddv_d: {
2191 EVT ResTy = Op->getValueType(ResNo: 0);
2192 return DAG.getNode(Opcode: ISD::ADD, DL: SDLoc(Op), VT: ResTy, N1: Op->getOperand(Num: 1),
2193 N2: DAG.getNode(Opcode: ISD::MUL, DL: SDLoc(Op), VT: ResTy,
2194 N1: Op->getOperand(Num: 2), N2: Op->getOperand(Num: 3)));
2195 }
2196 case Intrinsic::mips_max_s_b:
2197 case Intrinsic::mips_max_s_h:
2198 case Intrinsic::mips_max_s_w:
2199 case Intrinsic::mips_max_s_d:
2200 return DAG.getNode(Opcode: ISD::SMAX, DL, VT: Op->getValueType(ResNo: 0),
2201 N1: Op->getOperand(Num: 1), N2: Op->getOperand(Num: 2));
2202 case Intrinsic::mips_max_u_b:
2203 case Intrinsic::mips_max_u_h:
2204 case Intrinsic::mips_max_u_w:
2205 case Intrinsic::mips_max_u_d:
2206 return DAG.getNode(Opcode: ISD::UMAX, DL, VT: Op->getValueType(ResNo: 0),
2207 N1: Op->getOperand(Num: 1), N2: Op->getOperand(Num: 2));
2208 case Intrinsic::mips_maxi_s_b:
2209 case Intrinsic::mips_maxi_s_h:
2210 case Intrinsic::mips_maxi_s_w:
2211 case Intrinsic::mips_maxi_s_d:
2212 return DAG.getNode(Opcode: ISD::SMAX, DL, VT: Op->getValueType(ResNo: 0),
2213 N1: Op->getOperand(Num: 1), N2: lowerMSASplatImm(Op, ImmOp: 2, DAG, IsSigned: true));
2214 case Intrinsic::mips_maxi_u_b:
2215 case Intrinsic::mips_maxi_u_h:
2216 case Intrinsic::mips_maxi_u_w:
2217 case Intrinsic::mips_maxi_u_d:
2218 return DAG.getNode(Opcode: ISD::UMAX, DL, VT: Op->getValueType(ResNo: 0),
2219 N1: Op->getOperand(Num: 1), N2: lowerMSASplatImm(Op, ImmOp: 2, DAG));
2220 case Intrinsic::mips_min_s_b:
2221 case Intrinsic::mips_min_s_h:
2222 case Intrinsic::mips_min_s_w:
2223 case Intrinsic::mips_min_s_d:
2224 return DAG.getNode(Opcode: ISD::SMIN, DL, VT: Op->getValueType(ResNo: 0),
2225 N1: Op->getOperand(Num: 1), N2: Op->getOperand(Num: 2));
2226 case Intrinsic::mips_min_u_b:
2227 case Intrinsic::mips_min_u_h:
2228 case Intrinsic::mips_min_u_w:
2229 case Intrinsic::mips_min_u_d:
2230 return DAG.getNode(Opcode: ISD::UMIN, DL, VT: Op->getValueType(ResNo: 0),
2231 N1: Op->getOperand(Num: 1), N2: Op->getOperand(Num: 2));
2232 case Intrinsic::mips_mini_s_b:
2233 case Intrinsic::mips_mini_s_h:
2234 case Intrinsic::mips_mini_s_w:
2235 case Intrinsic::mips_mini_s_d:
2236 return DAG.getNode(Opcode: ISD::SMIN, DL, VT: Op->getValueType(ResNo: 0),
2237 N1: Op->getOperand(Num: 1), N2: lowerMSASplatImm(Op, ImmOp: 2, DAG, IsSigned: true));
2238 case Intrinsic::mips_mini_u_b:
2239 case Intrinsic::mips_mini_u_h:
2240 case Intrinsic::mips_mini_u_w:
2241 case Intrinsic::mips_mini_u_d:
2242 return DAG.getNode(Opcode: ISD::UMIN, DL, VT: Op->getValueType(ResNo: 0),
2243 N1: Op->getOperand(Num: 1), N2: lowerMSASplatImm(Op, ImmOp: 2, DAG));
2244 case Intrinsic::mips_mod_s_b:
2245 case Intrinsic::mips_mod_s_h:
2246 case Intrinsic::mips_mod_s_w:
2247 case Intrinsic::mips_mod_s_d:
2248 return DAG.getNode(Opcode: ISD::SREM, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
2249 N2: Op->getOperand(Num: 2));
2250 case Intrinsic::mips_mod_u_b:
2251 case Intrinsic::mips_mod_u_h:
2252 case Intrinsic::mips_mod_u_w:
2253 case Intrinsic::mips_mod_u_d:
2254 return DAG.getNode(Opcode: ISD::UREM, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
2255 N2: Op->getOperand(Num: 2));
2256 case Intrinsic::mips_mulv_b:
2257 case Intrinsic::mips_mulv_h:
2258 case Intrinsic::mips_mulv_w:
2259 case Intrinsic::mips_mulv_d:
2260 return DAG.getNode(Opcode: ISD::MUL, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
2261 N2: Op->getOperand(Num: 2));
2262 case Intrinsic::mips_msubv_b:
2263 case Intrinsic::mips_msubv_h:
2264 case Intrinsic::mips_msubv_w:
2265 case Intrinsic::mips_msubv_d: {
2266 EVT ResTy = Op->getValueType(ResNo: 0);
2267 return DAG.getNode(Opcode: ISD::SUB, DL: SDLoc(Op), VT: ResTy, N1: Op->getOperand(Num: 1),
2268 N2: DAG.getNode(Opcode: ISD::MUL, DL: SDLoc(Op), VT: ResTy,
2269 N1: Op->getOperand(Num: 2), N2: Op->getOperand(Num: 3)));
2270 }
2271 case Intrinsic::mips_nlzc_b:
2272 case Intrinsic::mips_nlzc_h:
2273 case Intrinsic::mips_nlzc_w:
2274 case Intrinsic::mips_nlzc_d:
2275 return DAG.getNode(Opcode: ISD::CTLZ, DL, VT: Op->getValueType(ResNo: 0), Operand: Op->getOperand(Num: 1));
2276 case Intrinsic::mips_nor_v: {
2277 SDValue Res = DAG.getNode(Opcode: ISD::OR, DL, VT: Op->getValueType(ResNo: 0),
2278 N1: Op->getOperand(Num: 1), N2: Op->getOperand(Num: 2));
2279 return DAG.getNOT(DL, Val: Res, VT: Res->getValueType(ResNo: 0));
2280 }
2281 case Intrinsic::mips_nori_b: {
2282 SDValue Res = DAG.getNode(Opcode: ISD::OR, DL, VT: Op->getValueType(ResNo: 0),
2283 N1: Op->getOperand(Num: 1),
2284 N2: lowerMSASplatImm(Op, ImmOp: 2, DAG));
2285 return DAG.getNOT(DL, Val: Res, VT: Res->getValueType(ResNo: 0));
2286 }
2287 case Intrinsic::mips_or_v:
2288 return DAG.getNode(Opcode: ISD::OR, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
2289 N2: Op->getOperand(Num: 2));
2290 case Intrinsic::mips_ori_b:
2291 return DAG.getNode(Opcode: ISD::OR, DL, VT: Op->getValueType(ResNo: 0),
2292 N1: Op->getOperand(Num: 1), N2: lowerMSASplatImm(Op, ImmOp: 2, DAG));
2293 case Intrinsic::mips_pckev_b:
2294 case Intrinsic::mips_pckev_h:
2295 case Intrinsic::mips_pckev_w:
2296 case Intrinsic::mips_pckev_d:
2297 return DAG.getNode(Opcode: MipsISD::PCKEV, DL, VT: Op->getValueType(ResNo: 0),
2298 N1: Op->getOperand(Num: 1), N2: Op->getOperand(Num: 2));
2299 case Intrinsic::mips_pckod_b:
2300 case Intrinsic::mips_pckod_h:
2301 case Intrinsic::mips_pckod_w:
2302 case Intrinsic::mips_pckod_d:
2303 return DAG.getNode(Opcode: MipsISD::PCKOD, DL, VT: Op->getValueType(ResNo: 0),
2304 N1: Op->getOperand(Num: 1), N2: Op->getOperand(Num: 2));
2305 case Intrinsic::mips_pcnt_b:
2306 case Intrinsic::mips_pcnt_h:
2307 case Intrinsic::mips_pcnt_w:
2308 case Intrinsic::mips_pcnt_d:
2309 return DAG.getNode(Opcode: ISD::CTPOP, DL, VT: Op->getValueType(ResNo: 0), Operand: Op->getOperand(Num: 1));
2310 case Intrinsic::mips_sat_s_b:
2311 case Intrinsic::mips_sat_s_h:
2312 case Intrinsic::mips_sat_s_w:
2313 case Intrinsic::mips_sat_s_d:
2314 case Intrinsic::mips_sat_u_b:
2315 case Intrinsic::mips_sat_u_h:
2316 case Intrinsic::mips_sat_u_w:
2317 case Intrinsic::mips_sat_u_d: {
2318 // Report an error for out of range values.
2319 int64_t Max;
2320 switch (Intrinsic) {
2321 case Intrinsic::mips_sat_s_b:
2322 case Intrinsic::mips_sat_u_b: Max = 7; break;
2323 case Intrinsic::mips_sat_s_h:
2324 case Intrinsic::mips_sat_u_h: Max = 15; break;
2325 case Intrinsic::mips_sat_s_w:
2326 case Intrinsic::mips_sat_u_w: Max = 31; break;
2327 case Intrinsic::mips_sat_s_d:
2328 case Intrinsic::mips_sat_u_d: Max = 63; break;
2329 default: llvm_unreachable("Unmatched intrinsic");
2330 }
2331 int64_t Value = cast<ConstantSDNode>(Val: Op->getOperand(Num: 2))->getSExtValue();
2332 if (Value < 0 || Value > Max)
2333 report_fatal_error(reason: "Immediate out of range");
2334 return SDValue();
2335 }
2336 case Intrinsic::mips_shf_b:
2337 case Intrinsic::mips_shf_h:
2338 case Intrinsic::mips_shf_w: {
2339 int64_t Value = cast<ConstantSDNode>(Val: Op->getOperand(Num: 2))->getSExtValue();
2340 if (Value < 0 || Value > 255)
2341 report_fatal_error(reason: "Immediate out of range");
2342 return DAG.getNode(Opcode: MipsISD::SHF, DL, VT: Op->getValueType(ResNo: 0),
2343 N1: Op->getOperand(Num: 2), N2: Op->getOperand(Num: 1));
2344 }
2345 case Intrinsic::mips_sldi_b:
2346 case Intrinsic::mips_sldi_h:
2347 case Intrinsic::mips_sldi_w:
2348 case Intrinsic::mips_sldi_d: {
2349 // Report an error for out of range values.
2350 int64_t Max;
2351 switch (Intrinsic) {
2352 case Intrinsic::mips_sldi_b: Max = 15; break;
2353 case Intrinsic::mips_sldi_h: Max = 7; break;
2354 case Intrinsic::mips_sldi_w: Max = 3; break;
2355 case Intrinsic::mips_sldi_d: Max = 1; break;
2356 default: llvm_unreachable("Unmatched intrinsic");
2357 }
2358 int64_t Value = cast<ConstantSDNode>(Val: Op->getOperand(Num: 3))->getSExtValue();
2359 if (Value < 0 || Value > Max)
2360 report_fatal_error(reason: "Immediate out of range");
2361 return SDValue();
2362 }
2363 case Intrinsic::mips_sll_b:
2364 case Intrinsic::mips_sll_h:
2365 case Intrinsic::mips_sll_w:
2366 case Intrinsic::mips_sll_d:
2367 return DAG.getNode(Opcode: ISD::SHL, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
2368 N2: truncateVecElts(Op, DAG));
2369 case Intrinsic::mips_slli_b:
2370 case Intrinsic::mips_slli_h:
2371 case Intrinsic::mips_slli_w:
2372 case Intrinsic::mips_slli_d:
2373 return DAG.getNode(Opcode: ISD::SHL, DL, VT: Op->getValueType(ResNo: 0),
2374 N1: Op->getOperand(Num: 1), N2: lowerMSASplatImm(Op, ImmOp: 2, DAG));
2375 case Intrinsic::mips_splat_b:
2376 case Intrinsic::mips_splat_h:
2377 case Intrinsic::mips_splat_w:
2378 case Intrinsic::mips_splat_d:
2379 // We can't lower via VECTOR_SHUFFLE because it requires constant shuffle
2380 // masks, nor can we lower via BUILD_VECTOR & EXTRACT_VECTOR_ELT because
2381 // EXTRACT_VECTOR_ELT can't extract i64's on MIPS32.
2382 // Instead we lower to MipsISD::VSHF and match from there.
2383 return DAG.getNode(Opcode: MipsISD::VSHF, DL, VT: Op->getValueType(ResNo: 0),
2384 N1: lowerMSASplatZExt(Op, OpNr: 2, DAG), N2: Op->getOperand(Num: 1),
2385 N3: Op->getOperand(Num: 1));
2386 case Intrinsic::mips_splati_b:
2387 case Intrinsic::mips_splati_h:
2388 case Intrinsic::mips_splati_w:
2389 case Intrinsic::mips_splati_d:
2390 return DAG.getNode(Opcode: MipsISD::VSHF, DL, VT: Op->getValueType(ResNo: 0),
2391 N1: lowerMSASplatImm(Op, ImmOp: 2, DAG), N2: Op->getOperand(Num: 1),
2392 N3: Op->getOperand(Num: 1));
2393 case Intrinsic::mips_sra_b:
2394 case Intrinsic::mips_sra_h:
2395 case Intrinsic::mips_sra_w:
2396 case Intrinsic::mips_sra_d:
2397 return DAG.getNode(Opcode: ISD::SRA, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
2398 N2: truncateVecElts(Op, DAG));
2399 case Intrinsic::mips_srai_b:
2400 case Intrinsic::mips_srai_h:
2401 case Intrinsic::mips_srai_w:
2402 case Intrinsic::mips_srai_d:
2403 return DAG.getNode(Opcode: ISD::SRA, DL, VT: Op->getValueType(ResNo: 0),
2404 N1: Op->getOperand(Num: 1), N2: lowerMSASplatImm(Op, ImmOp: 2, DAG));
2405 case Intrinsic::mips_srari_b:
2406 case Intrinsic::mips_srari_h:
2407 case Intrinsic::mips_srari_w:
2408 case Intrinsic::mips_srari_d: {
2409 // Report an error for out of range values.
2410 int64_t Max;
2411 switch (Intrinsic) {
2412 case Intrinsic::mips_srari_b: Max = 7; break;
2413 case Intrinsic::mips_srari_h: Max = 15; break;
2414 case Intrinsic::mips_srari_w: Max = 31; break;
2415 case Intrinsic::mips_srari_d: Max = 63; break;
2416 default: llvm_unreachable("Unmatched intrinsic");
2417 }
2418 int64_t Value = cast<ConstantSDNode>(Val: Op->getOperand(Num: 2))->getSExtValue();
2419 if (Value < 0 || Value > Max)
2420 report_fatal_error(reason: "Immediate out of range");
2421 return SDValue();
2422 }
2423 case Intrinsic::mips_srl_b:
2424 case Intrinsic::mips_srl_h:
2425 case Intrinsic::mips_srl_w:
2426 case Intrinsic::mips_srl_d:
2427 return DAG.getNode(Opcode: ISD::SRL, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
2428 N2: truncateVecElts(Op, DAG));
2429 case Intrinsic::mips_srli_b:
2430 case Intrinsic::mips_srli_h:
2431 case Intrinsic::mips_srli_w:
2432 case Intrinsic::mips_srli_d:
2433 return DAG.getNode(Opcode: ISD::SRL, DL, VT: Op->getValueType(ResNo: 0),
2434 N1: Op->getOperand(Num: 1), N2: lowerMSASplatImm(Op, ImmOp: 2, DAG));
2435 case Intrinsic::mips_srlri_b:
2436 case Intrinsic::mips_srlri_h:
2437 case Intrinsic::mips_srlri_w:
2438 case Intrinsic::mips_srlri_d: {
2439 // Report an error for out of range values.
2440 int64_t Max;
2441 switch (Intrinsic) {
2442 case Intrinsic::mips_srlri_b: Max = 7; break;
2443 case Intrinsic::mips_srlri_h: Max = 15; break;
2444 case Intrinsic::mips_srlri_w: Max = 31; break;
2445 case Intrinsic::mips_srlri_d: Max = 63; break;
2446 default: llvm_unreachable("Unmatched intrinsic");
2447 }
2448 int64_t Value = cast<ConstantSDNode>(Val: Op->getOperand(Num: 2))->getSExtValue();
2449 if (Value < 0 || Value > Max)
2450 report_fatal_error(reason: "Immediate out of range");
2451 return SDValue();
2452 }
2453 case Intrinsic::mips_subv_b:
2454 case Intrinsic::mips_subv_h:
2455 case Intrinsic::mips_subv_w:
2456 case Intrinsic::mips_subv_d:
2457 return DAG.getNode(Opcode: ISD::SUB, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
2458 N2: Op->getOperand(Num: 2));
2459 case Intrinsic::mips_subvi_b:
2460 case Intrinsic::mips_subvi_h:
2461 case Intrinsic::mips_subvi_w:
2462 case Intrinsic::mips_subvi_d:
2463 return DAG.getNode(Opcode: ISD::SUB, DL, VT: Op->getValueType(ResNo: 0),
2464 N1: Op->getOperand(Num: 1), N2: lowerMSASplatImm(Op, ImmOp: 2, DAG));
2465 case Intrinsic::mips_vshf_b:
2466 case Intrinsic::mips_vshf_h:
2467 case Intrinsic::mips_vshf_w:
2468 case Intrinsic::mips_vshf_d:
2469 return DAG.getNode(Opcode: MipsISD::VSHF, DL, VT: Op->getValueType(ResNo: 0),
2470 N1: Op->getOperand(Num: 1), N2: Op->getOperand(Num: 2), N3: Op->getOperand(Num: 3));
2471 case Intrinsic::mips_xor_v:
2472 return DAG.getNode(Opcode: ISD::XOR, DL, VT: Op->getValueType(ResNo: 0), N1: Op->getOperand(Num: 1),
2473 N2: Op->getOperand(Num: 2));
2474 case Intrinsic::mips_xori_b:
2475 return DAG.getNode(Opcode: ISD::XOR, DL, VT: Op->getValueType(ResNo: 0),
2476 N1: Op->getOperand(Num: 1), N2: lowerMSASplatImm(Op, ImmOp: 2, DAG));
2477 case Intrinsic::thread_pointer: {
2478 EVT PtrVT = getPointerTy(DL: DAG.getDataLayout());
2479 return DAG.getNode(Opcode: MipsISD::ThreadPointer, DL, VT: PtrVT);
2480 }
2481 }
2482}
2483
2484static SDValue lowerMSALoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr,
2485 const MipsSubtarget &Subtarget) {
2486 SDLoc DL(Op);
2487 SDValue ChainIn = Op->getOperand(Num: 0);
2488 SDValue Address = Op->getOperand(Num: 2);
2489 SDValue Offset = Op->getOperand(Num: 3);
2490 EVT ResTy = Op->getValueType(ResNo: 0);
2491 EVT PtrTy = Address->getValueType(ResNo: 0);
2492
2493 // For N64 addresses have the underlying type MVT::i64. This intrinsic
2494 // however takes an i32 signed constant offset. The actual type of the
2495 // intrinsic is a scaled signed i10.
2496 if (Subtarget.isABI_N64())
2497 Offset = DAG.getNode(Opcode: ISD::SIGN_EXTEND, DL, VT: PtrTy, Operand: Offset);
2498
2499 Address = DAG.getNode(Opcode: ISD::ADD, DL, VT: PtrTy, N1: Address, N2: Offset);
2500 return DAG.getLoad(VT: ResTy, dl: DL, Chain: ChainIn, Ptr: Address, PtrInfo: MachinePointerInfo(),
2501 Alignment: Align(16));
2502}
2503
2504SDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
2505 SelectionDAG &DAG) const {
2506 unsigned Intr = Op->getConstantOperandVal(Num: 1);
2507 switch (Intr) {
2508 default:
2509 return SDValue();
2510 case Intrinsic::mips_extp:
2511 return lowerDSPIntr(Op, DAG, Opc: MipsISD::EXTP);
2512 case Intrinsic::mips_extpdp:
2513 return lowerDSPIntr(Op, DAG, Opc: MipsISD::EXTPDP);
2514 case Intrinsic::mips_extr_w:
2515 return lowerDSPIntr(Op, DAG, Opc: MipsISD::EXTR_W);
2516 case Intrinsic::mips_extr_r_w:
2517 return lowerDSPIntr(Op, DAG, Opc: MipsISD::EXTR_R_W);
2518 case Intrinsic::mips_extr_rs_w:
2519 return lowerDSPIntr(Op, DAG, Opc: MipsISD::EXTR_RS_W);
2520 case Intrinsic::mips_extr_s_h:
2521 return lowerDSPIntr(Op, DAG, Opc: MipsISD::EXTR_S_H);
2522 case Intrinsic::mips_mthlip:
2523 return lowerDSPIntr(Op, DAG, Opc: MipsISD::MTHLIP);
2524 case Intrinsic::mips_mulsaq_s_w_ph:
2525 return lowerDSPIntr(Op, DAG, Opc: MipsISD::MULSAQ_S_W_PH);
2526 case Intrinsic::mips_maq_s_w_phl:
2527 return lowerDSPIntr(Op, DAG, Opc: MipsISD::MAQ_S_W_PHL);
2528 case Intrinsic::mips_maq_s_w_phr:
2529 return lowerDSPIntr(Op, DAG, Opc: MipsISD::MAQ_S_W_PHR);
2530 case Intrinsic::mips_maq_sa_w_phl:
2531 return lowerDSPIntr(Op, DAG, Opc: MipsISD::MAQ_SA_W_PHL);
2532 case Intrinsic::mips_maq_sa_w_phr:
2533 return lowerDSPIntr(Op, DAG, Opc: MipsISD::MAQ_SA_W_PHR);
2534 case Intrinsic::mips_dpaq_s_w_ph:
2535 return lowerDSPIntr(Op, DAG, Opc: MipsISD::DPAQ_S_W_PH);
2536 case Intrinsic::mips_dpsq_s_w_ph:
2537 return lowerDSPIntr(Op, DAG, Opc: MipsISD::DPSQ_S_W_PH);
2538 case Intrinsic::mips_dpaq_sa_l_w:
2539 return lowerDSPIntr(Op, DAG, Opc: MipsISD::DPAQ_SA_L_W);
2540 case Intrinsic::mips_dpsq_sa_l_w:
2541 return lowerDSPIntr(Op, DAG, Opc: MipsISD::DPSQ_SA_L_W);
2542 case Intrinsic::mips_dpaqx_s_w_ph:
2543 return lowerDSPIntr(Op, DAG, Opc: MipsISD::DPAQX_S_W_PH);
2544 case Intrinsic::mips_dpaqx_sa_w_ph:
2545 return lowerDSPIntr(Op, DAG, Opc: MipsISD::DPAQX_SA_W_PH);
2546 case Intrinsic::mips_dpsqx_s_w_ph:
2547 return lowerDSPIntr(Op, DAG, Opc: MipsISD::DPSQX_S_W_PH);
2548 case Intrinsic::mips_dpsqx_sa_w_ph:
2549 return lowerDSPIntr(Op, DAG, Opc: MipsISD::DPSQX_SA_W_PH);
2550 case Intrinsic::mips_ld_b:
2551 case Intrinsic::mips_ld_h:
2552 case Intrinsic::mips_ld_w:
2553 case Intrinsic::mips_ld_d:
2554 return lowerMSALoadIntr(Op, DAG, Intr, Subtarget);
2555 }
2556}
2557
2558static SDValue lowerMSAStoreIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr,
2559 const MipsSubtarget &Subtarget) {
2560 SDLoc DL(Op);
2561 SDValue ChainIn = Op->getOperand(Num: 0);
2562 SDValue Value = Op->getOperand(Num: 2);
2563 SDValue Address = Op->getOperand(Num: 3);
2564 SDValue Offset = Op->getOperand(Num: 4);
2565 EVT PtrTy = Address->getValueType(ResNo: 0);
2566
2567 // For N64 addresses have the underlying type MVT::i64. This intrinsic
2568 // however takes an i32 signed constant offset. The actual type of the
2569 // intrinsic is a scaled signed i10.
2570 if (Subtarget.isABI_N64())
2571 Offset = DAG.getNode(Opcode: ISD::SIGN_EXTEND, DL, VT: PtrTy, Operand: Offset);
2572
2573 Address = DAG.getNode(Opcode: ISD::ADD, DL, VT: PtrTy, N1: Address, N2: Offset);
2574
2575 return DAG.getStore(Chain: ChainIn, dl: DL, Val: Value, Ptr: Address, PtrInfo: MachinePointerInfo(),
2576 Alignment: Align(16));
2577}
2578
2579SDValue MipsSETargetLowering::lowerINTRINSIC_VOID(SDValue Op,
2580 SelectionDAG &DAG) const {
2581 unsigned Intr = Op->getConstantOperandVal(Num: 1);
2582 switch (Intr) {
2583 default:
2584 return SDValue();
2585 case Intrinsic::mips_st_b:
2586 case Intrinsic::mips_st_h:
2587 case Intrinsic::mips_st_w:
2588 case Intrinsic::mips_st_d:
2589 return lowerMSAStoreIntr(Op, DAG, Intr, Subtarget);
2590 }
2591}
2592
2593// Lower ISD::EXTRACT_VECTOR_ELT into MipsISD::VEXTRACT_SEXT_ELT.
2594//
2595// The non-value bits resulting from ISD::EXTRACT_VECTOR_ELT are undefined. We
2596// choose to sign-extend but we could have equally chosen zero-extend. The
2597// DAGCombiner will fold any sign/zero extension of the ISD::EXTRACT_VECTOR_ELT
2598// result into this node later (possibly changing it to a zero-extend in the
2599// process).
2600SDValue MipsSETargetLowering::
2601lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const {
2602 SDLoc DL(Op);
2603 EVT ResTy = Op->getValueType(ResNo: 0);
2604 SDValue Op0 = Op->getOperand(Num: 0);
2605 EVT VecTy = Op0->getValueType(ResNo: 0);
2606
2607 if (!VecTy.is128BitVector())
2608 return SDValue();
2609
2610 if (ResTy.isInteger()) {
2611 SDValue Op1 = Op->getOperand(Num: 1);
2612 EVT EltTy = VecTy.getVectorElementType();
2613 return DAG.getNode(Opcode: MipsISD::VEXTRACT_SEXT_ELT, DL, VT: ResTy, N1: Op0, N2: Op1,
2614 N3: DAG.getValueType(EltTy));
2615 }
2616
2617 return Op;
2618}
2619
2620static bool isConstantOrUndef(const SDValue Op) {
2621 if (Op->isUndef())
2622 return true;
2623 if (isa<ConstantSDNode>(Val: Op))
2624 return true;
2625 if (isa<ConstantFPSDNode>(Val: Op))
2626 return true;
2627 return false;
2628}
2629
2630static bool isConstantOrUndefBUILD_VECTOR(const BuildVectorSDNode *Op) {
2631 for (unsigned i = 0; i < Op->getNumOperands(); ++i)
2632 if (isConstantOrUndef(Op: Op->getOperand(Num: i)))
2633 return true;
2634 return false;
2635}
2636
2637// Lowers ISD::BUILD_VECTOR into appropriate SelectionDAG nodes for the
2638// backend.
2639//
2640// Lowers according to the following rules:
2641// - Constant splats are legal as-is as long as the SplatBitSize is a power of
2642// 2 less than or equal to 64 and the value fits into a signed 10-bit
2643// immediate
2644// - Constant splats are lowered to bitconverted BUILD_VECTORs if SplatBitSize
2645// is a power of 2 less than or equal to 64 and the value does not fit into a
2646// signed 10-bit immediate
2647// - Non-constant splats are legal as-is.
2648// - Non-constant non-splats are lowered to sequences of INSERT_VECTOR_ELT.
2649// - All others are illegal and must be expanded.
2650SDValue MipsSETargetLowering::lowerBUILD_VECTOR(SDValue Op,
2651 SelectionDAG &DAG) const {
2652 BuildVectorSDNode *Node = cast<BuildVectorSDNode>(Val&: Op);
2653 EVT ResTy = Op->getValueType(ResNo: 0);
2654 SDLoc DL(Op);
2655 APInt SplatValue, SplatUndef;
2656 unsigned SplatBitSize;
2657 bool HasAnyUndefs;
2658
2659 if (!Subtarget.hasMSA() || !ResTy.is128BitVector())
2660 return SDValue();
2661
2662 if (Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
2663 HasAnyUndefs, MinSplatBits: 8,
2664 isBigEndian: !Subtarget.isLittle()) && SplatBitSize <= 64) {
2665 // We can only cope with 8, 16, 32, or 64-bit elements
2666 if (SplatBitSize != 8 && SplatBitSize != 16 && SplatBitSize != 32 &&
2667 SplatBitSize != 64)
2668 return SDValue();
2669
2670 // If the value isn't an integer type we will have to bitcast
2671 // from an integer type first. Also, if there are any undefs, we must
2672 // lower them to defined values first.
2673 if (ResTy.isInteger() && !HasAnyUndefs)
2674 return Op;
2675
2676 EVT ViaVecTy;
2677
2678 switch (SplatBitSize) {
2679 default:
2680 return SDValue();
2681 case 8:
2682 ViaVecTy = MVT::v16i8;
2683 break;
2684 case 16:
2685 ViaVecTy = MVT::v8i16;
2686 break;
2687 case 32:
2688 ViaVecTy = MVT::v4i32;
2689 break;
2690 case 64:
2691 // There's no fill.d to fall back on for 64-bit values
2692 return SDValue();
2693 }
2694
2695 // SelectionDAG::getConstant will promote SplatValue appropriately.
2696 SDValue Result = DAG.getConstant(Val: SplatValue, DL, VT: ViaVecTy);
2697
2698 // Bitcast to the type we originally wanted
2699 if (ViaVecTy != ResTy)
2700 Result = DAG.getNode(Opcode: ISD::BITCAST, DL: SDLoc(Node), VT: ResTy, Operand: Result);
2701
2702 return Result;
2703 } else if (DAG.isSplatValue(V: Op, /* AllowUndefs */ false))
2704 return Op;
2705 else if (!isConstantOrUndefBUILD_VECTOR(Op: Node)) {
2706 // Use INSERT_VECTOR_ELT operations rather than expand to stores.
2707 // The resulting code is the same length as the expansion, but it doesn't
2708 // use memory operations
2709 EVT ResTy = Node->getValueType(ResNo: 0);
2710
2711 assert(ResTy.isVector());
2712
2713 unsigned NumElts = ResTy.getVectorNumElements();
2714 SDValue Vector = DAG.getUNDEF(VT: ResTy);
2715 for (unsigned i = 0; i < NumElts; ++i) {
2716 Vector = DAG.getNode(Opcode: ISD::INSERT_VECTOR_ELT, DL, VT: ResTy, N1: Vector,
2717 N2: Node->getOperand(Num: i),
2718 N3: DAG.getConstant(Val: i, DL, VT: MVT::i32));
2719 }
2720 return Vector;
2721 }
2722
2723 return SDValue();
2724}
2725
2726// Lower VECTOR_SHUFFLE into SHF (if possible).
2727//
2728// SHF splits the vector into blocks of four elements, then shuffles these
2729// elements according to a <4 x i2> constant (encoded as an integer immediate).
2730//
2731// It is therefore possible to lower into SHF when the mask takes the form:
2732// <a, b, c, d, a+4, b+4, c+4, d+4, a+8, b+8, c+8, d+8, ...>
2733// When undef's appear they are treated as if they were whatever value is
2734// necessary in order to fit the above forms.
2735//
2736// For example:
2737// %2 = shufflevector <8 x i16> %0, <8 x i16> undef,
2738// <8 x i32> <i32 3, i32 2, i32 1, i32 0,
2739// i32 7, i32 6, i32 5, i32 4>
2740// is lowered to:
2741// (SHF_H $w0, $w1, 27)
2742// where the 27 comes from:
2743// 3 + (2 << 2) + (1 << 4) + (0 << 6)
2744static SDValue lowerVECTOR_SHUFFLE_SHF(SDValue Op, EVT ResTy,
2745 SmallVector<int, 16> Indices,
2746 SelectionDAG &DAG) {
2747 int SHFIndices[4] = { -1, -1, -1, -1 };
2748
2749 if (Indices.size() < 4)
2750 return SDValue();
2751
2752 for (unsigned i = 0; i < 4; ++i) {
2753 for (unsigned j = i; j < Indices.size(); j += 4) {
2754 int Idx = Indices[j];
2755
2756 // Convert from vector index to 4-element subvector index
2757 // If an index refers to an element outside of the subvector then give up
2758 if (Idx != -1) {
2759 Idx -= 4 * (j / 4);
2760 if (Idx < 0 || Idx >= 4)
2761 return SDValue();
2762 }
2763
2764 // If the mask has an undef, replace it with the current index.
2765 // Note that it might still be undef if the current index is also undef
2766 if (SHFIndices[i] == -1)
2767 SHFIndices[i] = Idx;
2768
2769 // Check that non-undef values are the same as in the mask. If they
2770 // aren't then give up
2771 if (!(Idx == -1 || Idx == SHFIndices[i]))
2772 return SDValue();
2773 }
2774 }
2775
2776 // Calculate the immediate. Replace any remaining undefs with zero
2777 APInt Imm(32, 0);
2778 for (int i = 3; i >= 0; --i) {
2779 int Idx = SHFIndices[i];
2780
2781 if (Idx == -1)
2782 Idx = 0;
2783
2784 Imm <<= 2;
2785 Imm |= Idx & 0x3;
2786 }
2787
2788 SDLoc DL(Op);
2789 return DAG.getNode(Opcode: MipsISD::SHF, DL, VT: ResTy,
2790 N1: DAG.getTargetConstant(Val: Imm, DL, VT: MVT::i32),
2791 N2: Op->getOperand(Num: 0));
2792}
2793
2794/// Determine whether a range fits a regular pattern of values.
2795/// This function accounts for the possibility of jumping over the End iterator.
2796template <typename ValType>
2797static bool
2798fitsRegularPattern(typename SmallVectorImpl<ValType>::const_iterator Begin,
2799 unsigned CheckStride,
2800 typename SmallVectorImpl<ValType>::const_iterator End,
2801 ValType ExpectedIndex, unsigned ExpectedIndexStride) {
2802 auto &I = Begin;
2803
2804 while (I != End) {
2805 if (*I != -1 && *I != ExpectedIndex)
2806 return false;
2807 ExpectedIndex += ExpectedIndexStride;
2808
2809 // Incrementing past End is undefined behaviour so we must increment one
2810 // step at a time and check for End at each step.
2811 for (unsigned n = 0; n < CheckStride && I != End; ++n, ++I)
2812 ; // Empty loop body.
2813 }
2814 return true;
2815}
2816
2817// Determine whether VECTOR_SHUFFLE is a SPLATI.
2818//
2819// It is a SPLATI when the mask is:
2820// <x, x, x, ...>
2821// where x is any valid index.
2822//
2823// When undef's appear in the mask they are treated as if they were whatever
2824// value is necessary in order to fit the above form.
2825static bool isVECTOR_SHUFFLE_SPLATI(SDValue Op, EVT ResTy,
2826 SmallVector<int, 16> Indices,
2827 SelectionDAG &DAG) {
2828 assert((Indices.size() % 2) == 0);
2829
2830 int SplatIndex = -1;
2831 for (const auto &V : Indices) {
2832 if (V != -1) {
2833 SplatIndex = V;
2834 break;
2835 }
2836 }
2837
2838 return fitsRegularPattern<int>(Begin: Indices.begin(), CheckStride: 1, End: Indices.end(), ExpectedIndex: SplatIndex,
2839 ExpectedIndexStride: 0);
2840}
2841
2842// Lower VECTOR_SHUFFLE into ILVEV (if possible).
2843//
2844// ILVEV interleaves the even elements from each vector.
2845//
2846// It is possible to lower into ILVEV when the mask consists of two of the
2847// following forms interleaved:
2848// <0, 2, 4, ...>
2849// <n, n+2, n+4, ...>
2850// where n is the number of elements in the vector.
2851// For example:
2852// <0, 0, 2, 2, 4, 4, ...>
2853// <0, n, 2, n+2, 4, n+4, ...>
2854//
2855// When undef's appear in the mask they are treated as if they were whatever
2856// value is necessary in order to fit the above forms.
2857static SDValue lowerVECTOR_SHUFFLE_ILVEV(SDValue Op, EVT ResTy,
2858 SmallVector<int, 16> Indices,
2859 SelectionDAG &DAG) {
2860 assert((Indices.size() % 2) == 0);
2861
2862 SDValue Wt;
2863 SDValue Ws;
2864 const auto &Begin = Indices.begin();
2865 const auto &End = Indices.end();
2866
2867 // Check even elements are taken from the even elements of one half or the
2868 // other and pick an operand accordingly.
2869 if (fitsRegularPattern<int>(Begin, CheckStride: 2, End, ExpectedIndex: 0, ExpectedIndexStride: 2))
2870 Wt = Op->getOperand(Num: 0);
2871 else if (fitsRegularPattern<int>(Begin, CheckStride: 2, End, ExpectedIndex: Indices.size(), ExpectedIndexStride: 2))
2872 Wt = Op->getOperand(Num: 1);
2873 else
2874 return SDValue();
2875
2876 // Check odd elements are taken from the even elements of one half or the
2877 // other and pick an operand accordingly.
2878 if (fitsRegularPattern<int>(Begin: Begin + 1, CheckStride: 2, End, ExpectedIndex: 0, ExpectedIndexStride: 2))
2879 Ws = Op->getOperand(Num: 0);
2880 else if (fitsRegularPattern<int>(Begin: Begin + 1, CheckStride: 2, End, ExpectedIndex: Indices.size(), ExpectedIndexStride: 2))
2881 Ws = Op->getOperand(Num: 1);
2882 else
2883 return SDValue();
2884
2885 return DAG.getNode(Opcode: MipsISD::ILVEV, DL: SDLoc(Op), VT: ResTy, N1: Ws, N2: Wt);
2886}
2887
2888// Lower VECTOR_SHUFFLE into ILVOD (if possible).
2889//
2890// ILVOD interleaves the odd elements from each vector.
2891//
2892// It is possible to lower into ILVOD when the mask consists of two of the
2893// following forms interleaved:
2894// <1, 3, 5, ...>
2895// <n+1, n+3, n+5, ...>
2896// where n is the number of elements in the vector.
2897// For example:
2898// <1, 1, 3, 3, 5, 5, ...>
2899// <1, n+1, 3, n+3, 5, n+5, ...>
2900//
2901// When undef's appear in the mask they are treated as if they were whatever
2902// value is necessary in order to fit the above forms.
2903static SDValue lowerVECTOR_SHUFFLE_ILVOD(SDValue Op, EVT ResTy,
2904 SmallVector<int, 16> Indices,
2905 SelectionDAG &DAG) {
2906 assert((Indices.size() % 2) == 0);
2907
2908 SDValue Wt;
2909 SDValue Ws;
2910 const auto &Begin = Indices.begin();
2911 const auto &End = Indices.end();
2912
2913 // Check even elements are taken from the odd elements of one half or the
2914 // other and pick an operand accordingly.
2915 if (fitsRegularPattern<int>(Begin, CheckStride: 2, End, ExpectedIndex: 1, ExpectedIndexStride: 2))
2916 Wt = Op->getOperand(Num: 0);
2917 else if (fitsRegularPattern<int>(Begin, CheckStride: 2, End, ExpectedIndex: Indices.size() + 1, ExpectedIndexStride: 2))
2918 Wt = Op->getOperand(Num: 1);
2919 else
2920 return SDValue();
2921
2922 // Check odd elements are taken from the odd elements of one half or the
2923 // other and pick an operand accordingly.
2924 if (fitsRegularPattern<int>(Begin: Begin + 1, CheckStride: 2, End, ExpectedIndex: 1, ExpectedIndexStride: 2))
2925 Ws = Op->getOperand(Num: 0);
2926 else if (fitsRegularPattern<int>(Begin: Begin + 1, CheckStride: 2, End, ExpectedIndex: Indices.size() + 1, ExpectedIndexStride: 2))
2927 Ws = Op->getOperand(Num: 1);
2928 else
2929 return SDValue();
2930
2931 return DAG.getNode(Opcode: MipsISD::ILVOD, DL: SDLoc(Op), VT: ResTy, N1: Ws, N2: Wt);
2932}
2933
2934// Lower VECTOR_SHUFFLE into ILVR (if possible).
2935//
2936// ILVR interleaves consecutive elements from the right (lowest-indexed) half of
2937// each vector.
2938//
2939// It is possible to lower into ILVR when the mask consists of two of the
2940// following forms interleaved:
2941// <0, 1, 2, ...>
2942// <n, n+1, n+2, ...>
2943// where n is the number of elements in the vector.
2944// For example:
2945// <0, 0, 1, 1, 2, 2, ...>
2946// <0, n, 1, n+1, 2, n+2, ...>
2947//
2948// When undef's appear in the mask they are treated as if they were whatever
2949// value is necessary in order to fit the above forms.
2950static SDValue lowerVECTOR_SHUFFLE_ILVR(SDValue Op, EVT ResTy,
2951 SmallVector<int, 16> Indices,
2952 SelectionDAG &DAG) {
2953 assert((Indices.size() % 2) == 0);
2954
2955 SDValue Wt;
2956 SDValue Ws;
2957 const auto &Begin = Indices.begin();
2958 const auto &End = Indices.end();
2959
2960 // Check even elements are taken from the right (lowest-indexed) elements of
2961 // one half or the other and pick an operand accordingly.
2962 if (fitsRegularPattern<int>(Begin, CheckStride: 2, End, ExpectedIndex: 0, ExpectedIndexStride: 1))
2963 Wt = Op->getOperand(Num: 0);
2964 else if (fitsRegularPattern<int>(Begin, CheckStride: 2, End, ExpectedIndex: Indices.size(), ExpectedIndexStride: 1))
2965 Wt = Op->getOperand(Num: 1);
2966 else
2967 return SDValue();
2968
2969 // Check odd elements are taken from the right (lowest-indexed) elements of
2970 // one half or the other and pick an operand accordingly.
2971 if (fitsRegularPattern<int>(Begin: Begin + 1, CheckStride: 2, End, ExpectedIndex: 0, ExpectedIndexStride: 1))
2972 Ws = Op->getOperand(Num: 0);
2973 else if (fitsRegularPattern<int>(Begin: Begin + 1, CheckStride: 2, End, ExpectedIndex: Indices.size(), ExpectedIndexStride: 1))
2974 Ws = Op->getOperand(Num: 1);
2975 else
2976 return SDValue();
2977
2978 return DAG.getNode(Opcode: MipsISD::ILVR, DL: SDLoc(Op), VT: ResTy, N1: Ws, N2: Wt);
2979}
2980
2981// Lower VECTOR_SHUFFLE into ILVL (if possible).
2982//
2983// ILVL interleaves consecutive elements from the left (highest-indexed) half
2984// of each vector.
2985//
2986// It is possible to lower into ILVL when the mask consists of two of the
2987// following forms interleaved:
2988// <x, x+1, x+2, ...>
2989// <n+x, n+x+1, n+x+2, ...>
2990// where n is the number of elements in the vector and x is half n.
2991// For example:
2992// <x, x, x+1, x+1, x+2, x+2, ...>
2993// <x, n+x, x+1, n+x+1, x+2, n+x+2, ...>
2994//
2995// When undef's appear in the mask they are treated as if they were whatever
2996// value is necessary in order to fit the above forms.
2997static SDValue lowerVECTOR_SHUFFLE_ILVL(SDValue Op, EVT ResTy,
2998 SmallVector<int, 16> Indices,
2999 SelectionDAG &DAG) {
3000 assert((Indices.size() % 2) == 0);
3001
3002 unsigned HalfSize = Indices.size() / 2;
3003 SDValue Wt;
3004 SDValue Ws;
3005 const auto &Begin = Indices.begin();
3006 const auto &End = Indices.end();
3007
3008 // Check even elements are taken from the left (highest-indexed) elements of
3009 // one half or the other and pick an operand accordingly.
3010 if (fitsRegularPattern<int>(Begin, CheckStride: 2, End, ExpectedIndex: HalfSize, ExpectedIndexStride: 1))
3011 Wt = Op->getOperand(Num: 0);
3012 else if (fitsRegularPattern<int>(Begin, CheckStride: 2, End, ExpectedIndex: Indices.size() + HalfSize, ExpectedIndexStride: 1))
3013 Wt = Op->getOperand(Num: 1);
3014 else
3015 return SDValue();
3016
3017 // Check odd elements are taken from the left (highest-indexed) elements of
3018 // one half or the other and pick an operand accordingly.
3019 if (fitsRegularPattern<int>(Begin: Begin + 1, CheckStride: 2, End, ExpectedIndex: HalfSize, ExpectedIndexStride: 1))
3020 Ws = Op->getOperand(Num: 0);
3021 else if (fitsRegularPattern<int>(Begin: Begin + 1, CheckStride: 2, End, ExpectedIndex: Indices.size() + HalfSize,
3022 ExpectedIndexStride: 1))
3023 Ws = Op->getOperand(Num: 1);
3024 else
3025 return SDValue();
3026
3027 return DAG.getNode(Opcode: MipsISD::ILVL, DL: SDLoc(Op), VT: ResTy, N1: Ws, N2: Wt);
3028}
3029
3030// Lower VECTOR_SHUFFLE into PCKEV (if possible).
3031//
3032// PCKEV copies the even elements of each vector into the result vector.
3033//
3034// It is possible to lower into PCKEV when the mask consists of two of the
3035// following forms concatenated:
3036// <0, 2, 4, ...>
3037// <n, n+2, n+4, ...>
3038// where n is the number of elements in the vector.
3039// For example:
3040// <0, 2, 4, ..., 0, 2, 4, ...>
3041// <0, 2, 4, ..., n, n+2, n+4, ...>
3042//
3043// When undef's appear in the mask they are treated as if they were whatever
3044// value is necessary in order to fit the above forms.
3045static SDValue lowerVECTOR_SHUFFLE_PCKEV(SDValue Op, EVT ResTy,
3046 SmallVector<int, 16> Indices,
3047 SelectionDAG &DAG) {
3048 assert((Indices.size() % 2) == 0);
3049
3050 SDValue Wt;
3051 SDValue Ws;
3052 const auto &Begin = Indices.begin();
3053 const auto &Mid = Indices.begin() + Indices.size() / 2;
3054 const auto &End = Indices.end();
3055
3056 if (fitsRegularPattern<int>(Begin, CheckStride: 1, End: Mid, ExpectedIndex: 0, ExpectedIndexStride: 2))
3057 Wt = Op->getOperand(Num: 0);
3058 else if (fitsRegularPattern<int>(Begin, CheckStride: 1, End: Mid, ExpectedIndex: Indices.size(), ExpectedIndexStride: 2))
3059 Wt = Op->getOperand(Num: 1);
3060 else
3061 return SDValue();
3062
3063 if (fitsRegularPattern<int>(Begin: Mid, CheckStride: 1, End, ExpectedIndex: 0, ExpectedIndexStride: 2))
3064 Ws = Op->getOperand(Num: 0);
3065 else if (fitsRegularPattern<int>(Begin: Mid, CheckStride: 1, End, ExpectedIndex: Indices.size(), ExpectedIndexStride: 2))
3066 Ws = Op->getOperand(Num: 1);
3067 else
3068 return SDValue();
3069
3070 return DAG.getNode(Opcode: MipsISD::PCKEV, DL: SDLoc(Op), VT: ResTy, N1: Ws, N2: Wt);
3071}
3072
3073// Lower VECTOR_SHUFFLE into PCKOD (if possible).
3074//
3075// PCKOD copies the odd elements of each vector into the result vector.
3076//
3077// It is possible to lower into PCKOD when the mask consists of two of the
3078// following forms concatenated:
3079// <1, 3, 5, ...>
3080// <n+1, n+3, n+5, ...>
3081// where n is the number of elements in the vector.
3082// For example:
3083// <1, 3, 5, ..., 1, 3, 5, ...>
3084// <1, 3, 5, ..., n+1, n+3, n+5, ...>
3085//
3086// When undef's appear in the mask they are treated as if they were whatever
3087// value is necessary in order to fit the above forms.
3088static SDValue lowerVECTOR_SHUFFLE_PCKOD(SDValue Op, EVT ResTy,
3089 SmallVector<int, 16> Indices,
3090 SelectionDAG &DAG) {
3091 assert((Indices.size() % 2) == 0);
3092
3093 SDValue Wt;
3094 SDValue Ws;
3095 const auto &Begin = Indices.begin();
3096 const auto &Mid = Indices.begin() + Indices.size() / 2;
3097 const auto &End = Indices.end();
3098
3099 if (fitsRegularPattern<int>(Begin, CheckStride: 1, End: Mid, ExpectedIndex: 1, ExpectedIndexStride: 2))
3100 Wt = Op->getOperand(Num: 0);
3101 else if (fitsRegularPattern<int>(Begin, CheckStride: 1, End: Mid, ExpectedIndex: Indices.size() + 1, ExpectedIndexStride: 2))
3102 Wt = Op->getOperand(Num: 1);
3103 else
3104 return SDValue();
3105
3106 if (fitsRegularPattern<int>(Begin: Mid, CheckStride: 1, End, ExpectedIndex: 1, ExpectedIndexStride: 2))
3107 Ws = Op->getOperand(Num: 0);
3108 else if (fitsRegularPattern<int>(Begin: Mid, CheckStride: 1, End, ExpectedIndex: Indices.size() + 1, ExpectedIndexStride: 2))
3109 Ws = Op->getOperand(Num: 1);
3110 else
3111 return SDValue();
3112
3113 return DAG.getNode(Opcode: MipsISD::PCKOD, DL: SDLoc(Op), VT: ResTy, N1: Ws, N2: Wt);
3114}
3115
3116// Lower VECTOR_SHUFFLE into VSHF.
3117//
3118// This mostly consists of converting the shuffle indices in Indices into a
3119// BUILD_VECTOR and adding it as an operand to the resulting VSHF. There is
3120// also code to eliminate unused operands of the VECTOR_SHUFFLE. For example,
3121// if the type is v8i16 and all the indices are less than 8 then the second
3122// operand is unused and can be replaced with anything. We choose to replace it
3123// with the used operand since this reduces the number of instructions overall.
3124//
3125// NOTE: SPLATI shuffle masks may contain UNDEFs, since isSPLATI() treats
3126// UNDEFs as same as SPLATI index.
3127// For other instances we use the last valid index if UNDEF is
3128// encountered.
3129static SDValue lowerVECTOR_SHUFFLE_VSHF(SDValue Op, EVT ResTy,
3130 const SmallVector<int, 16> &Indices,
3131 const bool isSPLATI,
3132 SelectionDAG &DAG) {
3133 SmallVector<SDValue, 16> Ops;
3134 SDValue Op0;
3135 SDValue Op1;
3136 EVT MaskVecTy = ResTy.changeVectorElementTypeToInteger();
3137 EVT MaskEltTy = MaskVecTy.getVectorElementType();
3138 bool Using1stVec = false;
3139 bool Using2ndVec = false;
3140 SDLoc DL(Op);
3141 int ResTyNumElts = ResTy.getVectorNumElements();
3142
3143 for (int i = 0; i < ResTyNumElts; ++i) {
3144 // Idx == -1 means UNDEF/poison
3145 int Idx = Indices[i];
3146
3147 if (0 <= Idx && Idx < ResTyNumElts)
3148 Using1stVec = true;
3149 if (ResTyNumElts <= Idx && Idx < ResTyNumElts * 2)
3150 Using2ndVec = true;
3151 }
3152
3153 // Find the first non-undef index. This index is used as a default when there
3154 // is a leading UNDEF/poison.
3155 int SplatIndex = 0;
3156 for (int Idx : Indices)
3157 if (Idx >= 0) {
3158 SplatIndex = Idx;
3159 break;
3160 }
3161
3162 int LastValidIndex = SplatIndex;
3163 for (size_t i = 0; i < Indices.size(); i++) {
3164 int Idx = Indices[i];
3165 if (Idx < 0) {
3166 // Continue using splati index or use the last valid index.
3167 Idx = isSPLATI ? SplatIndex : LastValidIndex;
3168 } else {
3169 LastValidIndex = Idx;
3170 }
3171 Ops.push_back(Elt: DAG.getTargetConstant(Val: Idx, DL, VT: MaskEltTy));
3172 }
3173
3174 SDValue MaskVec = DAG.getBuildVector(VT: MaskVecTy, DL, Ops);
3175
3176 if (Using1stVec && Using2ndVec) {
3177 Op0 = Op->getOperand(Num: 0);
3178 Op1 = Op->getOperand(Num: 1);
3179 } else if (Using1stVec)
3180 Op0 = Op1 = Op->getOperand(Num: 0);
3181 else if (Using2ndVec)
3182 Op0 = Op1 = Op->getOperand(Num: 1);
3183 else
3184 llvm_unreachable("shuffle vector mask references neither vector operand?");
3185
3186 // VECTOR_SHUFFLE concatenates the vectors in an vectorwise fashion.
3187 // <0b00, 0b01> + <0b10, 0b11> -> <0b00, 0b01, 0b10, 0b11>
3188 // VSHF concatenates the vectors in a bitwise fashion:
3189 // <0b00, 0b01> + <0b10, 0b11> ->
3190 // 0b0100 + 0b1110 -> 0b01001110
3191 // <0b10, 0b11, 0b00, 0b01>
3192 // We must therefore swap the operands to get the correct result.
3193 return DAG.getNode(Opcode: MipsISD::VSHF, DL, VT: ResTy, N1: MaskVec, N2: Op1, N3: Op0);
3194}
3195
3196// Lower VECTOR_SHUFFLE into one of a number of instructions depending on the
3197// indices in the shuffle.
3198SDValue MipsSETargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
3199 SelectionDAG &DAG) const {
3200 ShuffleVectorSDNode *Node = cast<ShuffleVectorSDNode>(Val&: Op);
3201 EVT ResTy = Op->getValueType(ResNo: 0);
3202
3203 if (!ResTy.is128BitVector())
3204 return SDValue();
3205
3206 int ResTyNumElts = ResTy.getVectorNumElements();
3207 SmallVector<int, 16> Indices;
3208
3209 for (int i = 0; i < ResTyNumElts; ++i)
3210 Indices.push_back(Elt: Node->getMaskElt(Idx: i));
3211
3212 // splati.[bhwd] is preferable to the others but is matched from
3213 // MipsISD::VSHF.
3214 if (isVECTOR_SHUFFLE_SPLATI(Op, ResTy, Indices, DAG))
3215 return lowerVECTOR_SHUFFLE_VSHF(Op, ResTy, Indices, isSPLATI: true, DAG);
3216 SDValue Result;
3217 if ((Result = lowerVECTOR_SHUFFLE_ILVEV(Op, ResTy, Indices, DAG)))
3218 return Result;
3219 if ((Result = lowerVECTOR_SHUFFLE_ILVOD(Op, ResTy, Indices, DAG)))
3220 return Result;
3221 if ((Result = lowerVECTOR_SHUFFLE_ILVL(Op, ResTy, Indices, DAG)))
3222 return Result;
3223 if ((Result = lowerVECTOR_SHUFFLE_ILVR(Op, ResTy, Indices, DAG)))
3224 return Result;
3225 if ((Result = lowerVECTOR_SHUFFLE_PCKEV(Op, ResTy, Indices, DAG)))
3226 return Result;
3227 if ((Result = lowerVECTOR_SHUFFLE_PCKOD(Op, ResTy, Indices, DAG)))
3228 return Result;
3229 if ((Result = lowerVECTOR_SHUFFLE_SHF(Op, ResTy, Indices, DAG)))
3230 return Result;
3231 return lowerVECTOR_SHUFFLE_VSHF(Op, ResTy, Indices, isSPLATI: false, DAG);
3232}
3233
3234MachineBasicBlock *
3235MipsSETargetLowering::emitBPOSGE32(MachineInstr &MI,
3236 MachineBasicBlock *BB) const {
3237 // $bb:
3238 // bposge32_pseudo $vr0
3239 // =>
3240 // $bb:
3241 // bposge32 $tbb
3242 // $fbb:
3243 // li $vr2, 0
3244 // b $sink
3245 // $tbb:
3246 // li $vr1, 1
3247 // $sink:
3248 // $vr0 = phi($vr2, $fbb, $vr1, $tbb)
3249
3250 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3251 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3252 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
3253 DebugLoc DL = MI.getDebugLoc();
3254 const BasicBlock *LLVM_BB = BB->getBasicBlock();
3255 MachineFunction::iterator It = std::next(x: MachineFunction::iterator(BB));
3256 MachineFunction *F = BB->getParent();
3257 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(BB: LLVM_BB);
3258 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(BB: LLVM_BB);
3259 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(BB: LLVM_BB);
3260 F->insert(MBBI: It, MBB: FBB);
3261 F->insert(MBBI: It, MBB: TBB);
3262 F->insert(MBBI: It, MBB: Sink);
3263
3264 // Transfer the remainder of BB and its successor edges to Sink.
3265 Sink->splice(Where: Sink->begin(), Other: BB, From: std::next(x: MachineBasicBlock::iterator(MI)),
3266 To: BB->end());
3267 Sink->transferSuccessorsAndUpdatePHIs(FromMBB: BB);
3268
3269 // Add successors.
3270 BB->addSuccessor(Succ: FBB);
3271 BB->addSuccessor(Succ: TBB);
3272 FBB->addSuccessor(Succ: Sink);
3273 TBB->addSuccessor(Succ: Sink);
3274
3275 // Insert the real bposge32 instruction to $BB.
3276 BuildMI(BB, MIMD: DL, MCID: TII->get(Opcode: Mips::BPOSGE32)).addMBB(MBB: TBB);
3277 // Insert the real bposge32c instruction to $BB.
3278 BuildMI(BB, MIMD: DL, MCID: TII->get(Opcode: Mips::BPOSGE32C_MMR3)).addMBB(MBB: TBB);
3279
3280 // Fill $FBB.
3281 Register VR2 = RegInfo.createVirtualRegister(RegClass: RC);
3282 BuildMI(BB&: *FBB, I: FBB->end(), MIMD: DL, MCID: TII->get(Opcode: Mips::ADDiu), DestReg: VR2)
3283 .addReg(RegNo: Mips::ZERO).addImm(Val: 0);
3284 BuildMI(BB&: *FBB, I: FBB->end(), MIMD: DL, MCID: TII->get(Opcode: Mips::B)).addMBB(MBB: Sink);
3285
3286 // Fill $TBB.
3287 Register VR1 = RegInfo.createVirtualRegister(RegClass: RC);
3288 BuildMI(BB&: *TBB, I: TBB->end(), MIMD: DL, MCID: TII->get(Opcode: Mips::ADDiu), DestReg: VR1)
3289 .addReg(RegNo: Mips::ZERO).addImm(Val: 1);
3290
3291 // Insert phi function to $Sink.
3292 BuildMI(BB&: *Sink, I: Sink->begin(), MIMD: DL, MCID: TII->get(Opcode: Mips::PHI),
3293 DestReg: MI.getOperand(i: 0).getReg())
3294 .addReg(RegNo: VR2)
3295 .addMBB(MBB: FBB)
3296 .addReg(RegNo: VR1)
3297 .addMBB(MBB: TBB);
3298
3299 MI.eraseFromParent(); // The pseudo instruction is gone now.
3300 return Sink;
3301}
3302
3303MachineBasicBlock *MipsSETargetLowering::emitMSACBranchPseudo(
3304 MachineInstr &MI, MachineBasicBlock *BB, unsigned BranchOp) const {
3305 // $bb:
3306 // vany_nonzero $rd, $ws
3307 // =>
3308 // $bb:
3309 // bnz.b $ws, $tbb
3310 // b $fbb
3311 // $fbb:
3312 // li $rd1, 0
3313 // b $sink
3314 // $tbb:
3315 // li $rd2, 1
3316 // $sink:
3317 // $rd = phi($rd1, $fbb, $rd2, $tbb)
3318
3319 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3320 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3321 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
3322 DebugLoc DL = MI.getDebugLoc();
3323 const BasicBlock *LLVM_BB = BB->getBasicBlock();
3324 MachineFunction::iterator It = std::next(x: MachineFunction::iterator(BB));
3325 MachineFunction *F = BB->getParent();
3326 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(BB: LLVM_BB);
3327 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(BB: LLVM_BB);
3328 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(BB: LLVM_BB);
3329 F->insert(MBBI: It, MBB: FBB);
3330 F->insert(MBBI: It, MBB: TBB);
3331 F->insert(MBBI: It, MBB: Sink);
3332
3333 // Transfer the remainder of BB and its successor edges to Sink.
3334 Sink->splice(Where: Sink->begin(), Other: BB, From: std::next(x: MachineBasicBlock::iterator(MI)),
3335 To: BB->end());
3336 Sink->transferSuccessorsAndUpdatePHIs(FromMBB: BB);
3337
3338 // Add successors.
3339 BB->addSuccessor(Succ: FBB);
3340 BB->addSuccessor(Succ: TBB);
3341 FBB->addSuccessor(Succ: Sink);
3342 TBB->addSuccessor(Succ: Sink);
3343
3344 // Insert the real bnz.b instruction to $BB.
3345 BuildMI(BB, MIMD: DL, MCID: TII->get(Opcode: BranchOp))
3346 .addReg(RegNo: MI.getOperand(i: 1).getReg())
3347 .addMBB(MBB: TBB);
3348
3349 // Fill $FBB.
3350 Register RD1 = RegInfo.createVirtualRegister(RegClass: RC);
3351 BuildMI(BB&: *FBB, I: FBB->end(), MIMD: DL, MCID: TII->get(Opcode: Mips::ADDiu), DestReg: RD1)
3352 .addReg(RegNo: Mips::ZERO).addImm(Val: 0);
3353 BuildMI(BB&: *FBB, I: FBB->end(), MIMD: DL, MCID: TII->get(Opcode: Mips::B)).addMBB(MBB: Sink);
3354
3355 // Fill $TBB.
3356 Register RD2 = RegInfo.createVirtualRegister(RegClass: RC);
3357 BuildMI(BB&: *TBB, I: TBB->end(), MIMD: DL, MCID: TII->get(Opcode: Mips::ADDiu), DestReg: RD2)
3358 .addReg(RegNo: Mips::ZERO).addImm(Val: 1);
3359
3360 // Insert phi function to $Sink.
3361 BuildMI(BB&: *Sink, I: Sink->begin(), MIMD: DL, MCID: TII->get(Opcode: Mips::PHI),
3362 DestReg: MI.getOperand(i: 0).getReg())
3363 .addReg(RegNo: RD1)
3364 .addMBB(MBB: FBB)
3365 .addReg(RegNo: RD2)
3366 .addMBB(MBB: TBB);
3367
3368 MI.eraseFromParent(); // The pseudo instruction is gone now.
3369 return Sink;
3370}
3371
3372// Emit the COPY_FW pseudo instruction.
3373//
3374// copy_fw_pseudo $fd, $ws, n
3375// =>
3376// copy_u_w $rt, $ws, $n
3377// mtc1 $rt, $fd
3378//
3379// When n is zero, the equivalent operation can be performed with (potentially)
3380// zero instructions due to register overlaps. This optimization is never valid
3381// for lane 1 because it would require FR=0 mode which isn't supported by MSA.
3382MachineBasicBlock *
3383MipsSETargetLowering::emitCOPY_FW(MachineInstr &MI,
3384 MachineBasicBlock *BB) const {
3385 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3386 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3387 DebugLoc DL = MI.getDebugLoc();
3388 Register Fd = MI.getOperand(i: 0).getReg();
3389 Register Ws = MI.getOperand(i: 1).getReg();
3390 unsigned Lane = MI.getOperand(i: 2).getImm();
3391
3392 if (Lane == 0) {
3393 unsigned Wt = Ws;
3394 if (!Subtarget.useOddSPReg()) {
3395 // We must copy to an even-numbered MSA register so that the
3396 // single-precision sub-register is also guaranteed to be even-numbered.
3397 Wt = RegInfo.createVirtualRegister(RegClass: &Mips::MSA128WEvensRegClass);
3398
3399 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::COPY), DestReg: Wt).addReg(RegNo: Ws);
3400 }
3401
3402 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::COPY), DestReg: Fd).addReg(RegNo: Wt, Flags: {}, SubReg: Mips::sub_lo);
3403 } else {
3404 Register Wt = RegInfo.createVirtualRegister(
3405 RegClass: Subtarget.useOddSPReg() ? &Mips::MSA128WRegClass
3406 : &Mips::MSA128WEvensRegClass);
3407
3408 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::SPLATI_W), DestReg: Wt).addReg(RegNo: Ws).addImm(Val: Lane);
3409 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::COPY), DestReg: Fd).addReg(RegNo: Wt, Flags: {}, SubReg: Mips::sub_lo);
3410 }
3411
3412 MI.eraseFromParent(); // The pseudo instruction is gone now.
3413 return BB;
3414}
3415
3416// Emit the COPY_FD pseudo instruction.
3417//
3418// copy_fd_pseudo $fd, $ws, n
3419// =>
3420// splati.d $wt, $ws, $n
3421// copy $fd, $wt:sub_64
3422//
3423// When n is zero, the equivalent operation can be performed with (potentially)
3424// zero instructions due to register overlaps. This optimization is always
3425// valid because FR=1 mode which is the only supported mode in MSA.
3426MachineBasicBlock *
3427MipsSETargetLowering::emitCOPY_FD(MachineInstr &MI,
3428 MachineBasicBlock *BB) const {
3429 assert(Subtarget.isFP64bit());
3430
3431 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3432 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3433 Register Fd = MI.getOperand(i: 0).getReg();
3434 Register Ws = MI.getOperand(i: 1).getReg();
3435 unsigned Lane = MI.getOperand(i: 2).getImm() * 2;
3436 DebugLoc DL = MI.getDebugLoc();
3437
3438 if (Lane == 0)
3439 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::COPY), DestReg: Fd).addReg(RegNo: Ws, Flags: {}, SubReg: Mips::sub_64);
3440 else {
3441 Register Wt = RegInfo.createVirtualRegister(RegClass: &Mips::MSA128DRegClass);
3442
3443 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::SPLATI_D), DestReg: Wt).addReg(RegNo: Ws).addImm(Val: 1);
3444 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::COPY), DestReg: Fd).addReg(RegNo: Wt, Flags: {}, SubReg: Mips::sub_64);
3445 }
3446
3447 MI.eraseFromParent(); // The pseudo instruction is gone now.
3448 return BB;
3449}
3450
3451// Emit the INSERT_FW pseudo instruction.
3452//
3453// insert_fw_pseudo $wd, $wd_in, $n, $fs
3454// =>
3455// subreg_to_reg $wt:sub_lo, $fs
3456// insve_w $wd[$n], $wd_in, $wt[0]
3457MachineBasicBlock *
3458MipsSETargetLowering::emitINSERT_FW(MachineInstr &MI,
3459 MachineBasicBlock *BB) const {
3460 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3461 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3462 DebugLoc DL = MI.getDebugLoc();
3463 Register Wd = MI.getOperand(i: 0).getReg();
3464 Register Wd_in = MI.getOperand(i: 1).getReg();
3465 unsigned Lane = MI.getOperand(i: 2).getImm();
3466 Register Fs = MI.getOperand(i: 3).getReg();
3467 Register Wt = RegInfo.createVirtualRegister(
3468 RegClass: Subtarget.useOddSPReg() ? &Mips::MSA128WRegClass
3469 : &Mips::MSA128WEvensRegClass);
3470
3471 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::SUBREG_TO_REG), DestReg: Wt)
3472 .addReg(RegNo: Fs)
3473 .addImm(Val: Mips::sub_lo);
3474 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::INSVE_W), DestReg: Wd)
3475 .addReg(RegNo: Wd_in)
3476 .addImm(Val: Lane)
3477 .addReg(RegNo: Wt)
3478 .addImm(Val: 0);
3479
3480 MI.eraseFromParent(); // The pseudo instruction is gone now.
3481 return BB;
3482}
3483
3484// Emit the INSERT_FD pseudo instruction.
3485//
3486// insert_fd_pseudo $wd, $fs, n
3487// =>
3488// subreg_to_reg $wt:sub_64, $fs
3489// insve_d $wd[$n], $wd_in, $wt[0]
3490MachineBasicBlock *
3491MipsSETargetLowering::emitINSERT_FD(MachineInstr &MI,
3492 MachineBasicBlock *BB) const {
3493 assert(Subtarget.isFP64bit());
3494
3495 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3496 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3497 DebugLoc DL = MI.getDebugLoc();
3498 Register Wd = MI.getOperand(i: 0).getReg();
3499 Register Wd_in = MI.getOperand(i: 1).getReg();
3500 unsigned Lane = MI.getOperand(i: 2).getImm();
3501 Register Fs = MI.getOperand(i: 3).getReg();
3502 Register Wt = RegInfo.createVirtualRegister(RegClass: &Mips::MSA128DRegClass);
3503
3504 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::SUBREG_TO_REG), DestReg: Wt)
3505 .addReg(RegNo: Fs)
3506 .addImm(Val: Mips::sub_64);
3507 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::INSVE_D), DestReg: Wd)
3508 .addReg(RegNo: Wd_in)
3509 .addImm(Val: Lane)
3510 .addReg(RegNo: Wt)
3511 .addImm(Val: 0);
3512
3513 MI.eraseFromParent(); // The pseudo instruction is gone now.
3514 return BB;
3515}
3516
3517// Emit the INSERT_([BHWD]|F[WD])_VIDX pseudo instruction.
3518//
3519// For integer:
3520// (INSERT_([BHWD]|F[WD])_PSEUDO $wd, $wd_in, $n, $rs)
3521// =>
3522// (SLL $lanetmp1, $lane, <log2size)
3523// (SLD_B $wdtmp1, $wd_in, $wd_in, $lanetmp1)
3524// (INSERT_[BHWD], $wdtmp2, $wdtmp1, 0, $rs)
3525// (NEG $lanetmp2, $lanetmp1)
3526// (SLD_B $wd, $wdtmp2, $wdtmp2, $lanetmp2)
3527//
3528// For floating point:
3529// (INSERT_([BHWD]|F[WD])_PSEUDO $wd, $wd_in, $n, $fs)
3530// =>
3531// (SUBREG_TO_REG $wt, $fs, <subreg>)
3532// (SLL $lanetmp1, $lane, <log2size)
3533// (SLD_B $wdtmp1, $wd_in, $wd_in, $lanetmp1)
3534// (INSVE_[WD], $wdtmp2, 0, $wdtmp1, 0)
3535// (NEG $lanetmp2, $lanetmp1)
3536// (SLD_B $wd, $wdtmp2, $wdtmp2, $lanetmp2)
3537MachineBasicBlock *MipsSETargetLowering::emitINSERT_DF_VIDX(
3538 MachineInstr &MI, MachineBasicBlock *BB, unsigned EltSizeInBytes,
3539 bool IsFP) const {
3540 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3541 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3542 DebugLoc DL = MI.getDebugLoc();
3543 Register Wd = MI.getOperand(i: 0).getReg();
3544 Register SrcVecReg = MI.getOperand(i: 1).getReg();
3545 Register LaneReg = MI.getOperand(i: 2).getReg();
3546 Register SrcValReg = MI.getOperand(i: 3).getReg();
3547
3548 const TargetRegisterClass *VecRC = nullptr;
3549 // FIXME: This should be true for N32 too.
3550 const TargetRegisterClass *GPRRC =
3551 Subtarget.isABI_N64() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
3552 unsigned SubRegIdx = Subtarget.isABI_N64() ? Mips::sub_32 : 0;
3553 unsigned ShiftOp = Subtarget.isABI_N64() ? Mips::DSLL : Mips::SLL;
3554 unsigned EltLog2Size;
3555 unsigned InsertOp = 0;
3556 unsigned InsveOp = 0;
3557 switch (EltSizeInBytes) {
3558 default:
3559 llvm_unreachable("Unexpected size");
3560 case 1:
3561 EltLog2Size = 0;
3562 InsertOp = Mips::INSERT_B;
3563 InsveOp = Mips::INSVE_B;
3564 VecRC = &Mips::MSA128BRegClass;
3565 break;
3566 case 2:
3567 EltLog2Size = 1;
3568 InsertOp = Mips::INSERT_H;
3569 InsveOp = Mips::INSVE_H;
3570 VecRC = &Mips::MSA128HRegClass;
3571 break;
3572 case 4:
3573 EltLog2Size = 2;
3574 InsertOp = Mips::INSERT_W;
3575 InsveOp = Mips::INSVE_W;
3576 VecRC = &Mips::MSA128WRegClass;
3577 break;
3578 case 8:
3579 EltLog2Size = 3;
3580 InsertOp = Mips::INSERT_D;
3581 InsveOp = Mips::INSVE_D;
3582 VecRC = &Mips::MSA128DRegClass;
3583 break;
3584 }
3585
3586 if (IsFP) {
3587 Register Wt = RegInfo.createVirtualRegister(RegClass: VecRC);
3588 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::SUBREG_TO_REG), DestReg: Wt)
3589 .addReg(RegNo: SrcValReg)
3590 .addImm(Val: EltSizeInBytes == 8 ? Mips::sub_64 : Mips::sub_lo);
3591 SrcValReg = Wt;
3592 }
3593
3594 // Convert the lane index into a byte index
3595 if (EltSizeInBytes != 1) {
3596 Register LaneTmp1 = RegInfo.createVirtualRegister(RegClass: GPRRC);
3597 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: ShiftOp), DestReg: LaneTmp1)
3598 .addReg(RegNo: LaneReg)
3599 .addImm(Val: EltLog2Size);
3600 LaneReg = LaneTmp1;
3601 }
3602
3603 // Rotate bytes around so that the desired lane is element zero
3604 Register WdTmp1 = RegInfo.createVirtualRegister(RegClass: VecRC);
3605 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::SLD_B), DestReg: WdTmp1)
3606 .addReg(RegNo: SrcVecReg)
3607 .addReg(RegNo: SrcVecReg)
3608 .addReg(RegNo: LaneReg, Flags: {}, SubReg: SubRegIdx);
3609
3610 Register WdTmp2 = RegInfo.createVirtualRegister(RegClass: VecRC);
3611 if (IsFP) {
3612 // Use insve.df to insert to element zero
3613 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: InsveOp), DestReg: WdTmp2)
3614 .addReg(RegNo: WdTmp1)
3615 .addImm(Val: 0)
3616 .addReg(RegNo: SrcValReg)
3617 .addImm(Val: 0);
3618 } else {
3619 // Use insert.df to insert to element zero
3620 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: InsertOp), DestReg: WdTmp2)
3621 .addReg(RegNo: WdTmp1)
3622 .addReg(RegNo: SrcValReg)
3623 .addImm(Val: 0);
3624 }
3625
3626 // Rotate elements the rest of the way for a full rotation.
3627 // sld.df inteprets $rt modulo the number of columns so we only need to negate
3628 // the lane index to do this.
3629 Register LaneTmp2 = RegInfo.createVirtualRegister(RegClass: GPRRC);
3630 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Subtarget.isABI_N64() ? Mips::DSUB : Mips::SUB),
3631 DestReg: LaneTmp2)
3632 .addReg(RegNo: Subtarget.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO)
3633 .addReg(RegNo: LaneReg);
3634 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::SLD_B), DestReg: Wd)
3635 .addReg(RegNo: WdTmp2)
3636 .addReg(RegNo: WdTmp2)
3637 .addReg(RegNo: LaneTmp2, Flags: {}, SubReg: SubRegIdx);
3638
3639 MI.eraseFromParent(); // The pseudo instruction is gone now.
3640 return BB;
3641}
3642
3643// Emit the FILL_FW pseudo instruction.
3644//
3645// fill_fw_pseudo $wd, $fs
3646// =>
3647// implicit_def $wt1
3648// insert_subreg $wt2:subreg_lo, $wt1, $fs
3649// splati.w $wd, $wt2[0]
3650MachineBasicBlock *
3651MipsSETargetLowering::emitFILL_FW(MachineInstr &MI,
3652 MachineBasicBlock *BB) const {
3653 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3654 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3655 DebugLoc DL = MI.getDebugLoc();
3656 Register Wd = MI.getOperand(i: 0).getReg();
3657 Register Fs = MI.getOperand(i: 1).getReg();
3658 Register Wt1 = RegInfo.createVirtualRegister(
3659 RegClass: Subtarget.useOddSPReg() ? &Mips::MSA128WRegClass
3660 : &Mips::MSA128WEvensRegClass);
3661 Register Wt2 = RegInfo.createVirtualRegister(
3662 RegClass: Subtarget.useOddSPReg() ? &Mips::MSA128WRegClass
3663 : &Mips::MSA128WEvensRegClass);
3664
3665 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::IMPLICIT_DEF), DestReg: Wt1);
3666 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::INSERT_SUBREG), DestReg: Wt2)
3667 .addReg(RegNo: Wt1)
3668 .addReg(RegNo: Fs)
3669 .addImm(Val: Mips::sub_lo);
3670 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::SPLATI_W), DestReg: Wd).addReg(RegNo: Wt2).addImm(Val: 0);
3671
3672 MI.eraseFromParent(); // The pseudo instruction is gone now.
3673 return BB;
3674}
3675
3676// Emit the FILL_FD pseudo instruction.
3677//
3678// fill_fd_pseudo $wd, $fs
3679// =>
3680// implicit_def $wt1
3681// insert_subreg $wt2:subreg_64, $wt1, $fs
3682// splati.d $wd, $wt2[0]
3683MachineBasicBlock *
3684MipsSETargetLowering::emitFILL_FD(MachineInstr &MI,
3685 MachineBasicBlock *BB) const {
3686 assert(Subtarget.isFP64bit());
3687
3688 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3689 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3690 DebugLoc DL = MI.getDebugLoc();
3691 Register Wd = MI.getOperand(i: 0).getReg();
3692 Register Fs = MI.getOperand(i: 1).getReg();
3693 Register Wt1 = RegInfo.createVirtualRegister(RegClass: &Mips::MSA128DRegClass);
3694 Register Wt2 = RegInfo.createVirtualRegister(RegClass: &Mips::MSA128DRegClass);
3695
3696 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::IMPLICIT_DEF), DestReg: Wt1);
3697 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::INSERT_SUBREG), DestReg: Wt2)
3698 .addReg(RegNo: Wt1)
3699 .addReg(RegNo: Fs)
3700 .addImm(Val: Mips::sub_64);
3701 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::SPLATI_D), DestReg: Wd).addReg(RegNo: Wt2).addImm(Val: 0);
3702
3703 MI.eraseFromParent(); // The pseudo instruction is gone now.
3704 return BB;
3705}
3706
3707// Emit the FEXP2_W_1 pseudo instructions.
3708//
3709// fexp2_w_1_pseudo $wd, $wt
3710// =>
3711// ldi.w $ws, 1
3712// fexp2.w $wd, $ws, $wt
3713MachineBasicBlock *
3714MipsSETargetLowering::emitFEXP2_W_1(MachineInstr &MI,
3715 MachineBasicBlock *BB) const {
3716 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3717 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3718 const TargetRegisterClass *RC = &Mips::MSA128WRegClass;
3719 Register Ws1 = RegInfo.createVirtualRegister(RegClass: RC);
3720 Register Ws2 = RegInfo.createVirtualRegister(RegClass: RC);
3721 DebugLoc DL = MI.getDebugLoc();
3722
3723 // Splat 1.0 into a vector
3724 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::LDI_W), DestReg: Ws1).addImm(Val: 1);
3725 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::FFINT_U_W), DestReg: Ws2).addReg(RegNo: Ws1);
3726
3727 // Emit 1.0 * fexp2(Wt)
3728 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::FEXP2_W), DestReg: MI.getOperand(i: 0).getReg())
3729 .addReg(RegNo: Ws2)
3730 .addReg(RegNo: MI.getOperand(i: 1).getReg());
3731
3732 MI.eraseFromParent(); // The pseudo instruction is gone now.
3733 return BB;
3734}
3735
3736// Emit the FEXP2_D_1 pseudo instructions.
3737//
3738// fexp2_d_1_pseudo $wd, $wt
3739// =>
3740// ldi.d $ws, 1
3741// fexp2.d $wd, $ws, $wt
3742MachineBasicBlock *
3743MipsSETargetLowering::emitFEXP2_D_1(MachineInstr &MI,
3744 MachineBasicBlock *BB) const {
3745 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3746 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3747 const TargetRegisterClass *RC = &Mips::MSA128DRegClass;
3748 Register Ws1 = RegInfo.createVirtualRegister(RegClass: RC);
3749 Register Ws2 = RegInfo.createVirtualRegister(RegClass: RC);
3750 DebugLoc DL = MI.getDebugLoc();
3751
3752 // Splat 1.0 into a vector
3753 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::LDI_D), DestReg: Ws1).addImm(Val: 1);
3754 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::FFINT_U_D), DestReg: Ws2).addReg(RegNo: Ws1);
3755
3756 // Emit 1.0 * fexp2(Wt)
3757 BuildMI(BB&: *BB, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Mips::FEXP2_D), DestReg: MI.getOperand(i: 0).getReg())
3758 .addReg(RegNo: Ws2)
3759 .addReg(RegNo: MI.getOperand(i: 1).getReg());
3760
3761 MI.eraseFromParent(); // The pseudo instruction is gone now.
3762 return BB;
3763}
3764