Movatterモバイル変換


[0]ホーム

URL:


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

Generated on Thu Jul 17 2025 15:09:38 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp