xref: /aosp_15_r20/external/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- SystemZISelLowering.cpp - SystemZ DAG lowering implementation -----===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements the SystemZTargetLowering class.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #include "SystemZISelLowering.h"
15*9880d681SAndroid Build Coastguard Worker #include "SystemZCallingConv.h"
16*9880d681SAndroid Build Coastguard Worker #include "SystemZConstantPoolValue.h"
17*9880d681SAndroid Build Coastguard Worker #include "SystemZMachineFunctionInfo.h"
18*9880d681SAndroid Build Coastguard Worker #include "SystemZTargetMachine.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/CallingConvLower.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Intrinsics.h"
24*9880d681SAndroid Build Coastguard Worker #include <cctype>
25*9880d681SAndroid Build Coastguard Worker 
26*9880d681SAndroid Build Coastguard Worker using namespace llvm;
27*9880d681SAndroid Build Coastguard Worker 
28*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "systemz-lower"
29*9880d681SAndroid Build Coastguard Worker 
30*9880d681SAndroid Build Coastguard Worker namespace {
31*9880d681SAndroid Build Coastguard Worker // Represents a sequence for extracting a 0/1 value from an IPM result:
32*9880d681SAndroid Build Coastguard Worker // (((X ^ XORValue) + AddValue) >> Bit)
33*9880d681SAndroid Build Coastguard Worker struct IPMConversion {
IPMConversion__anon8c72947f0111::IPMConversion34*9880d681SAndroid Build Coastguard Worker   IPMConversion(unsigned xorValue, int64_t addValue, unsigned bit)
35*9880d681SAndroid Build Coastguard Worker     : XORValue(xorValue), AddValue(addValue), Bit(bit) {}
36*9880d681SAndroid Build Coastguard Worker 
37*9880d681SAndroid Build Coastguard Worker   int64_t XORValue;
38*9880d681SAndroid Build Coastguard Worker   int64_t AddValue;
39*9880d681SAndroid Build Coastguard Worker   unsigned Bit;
40*9880d681SAndroid Build Coastguard Worker };
41*9880d681SAndroid Build Coastguard Worker 
42*9880d681SAndroid Build Coastguard Worker // Represents information about a comparison.
43*9880d681SAndroid Build Coastguard Worker struct Comparison {
Comparison__anon8c72947f0111::Comparison44*9880d681SAndroid Build Coastguard Worker   Comparison(SDValue Op0In, SDValue Op1In)
45*9880d681SAndroid Build Coastguard Worker     : Op0(Op0In), Op1(Op1In), Opcode(0), ICmpType(0), CCValid(0), CCMask(0) {}
46*9880d681SAndroid Build Coastguard Worker 
47*9880d681SAndroid Build Coastguard Worker   // The operands to the comparison.
48*9880d681SAndroid Build Coastguard Worker   SDValue Op0, Op1;
49*9880d681SAndroid Build Coastguard Worker 
50*9880d681SAndroid Build Coastguard Worker   // The opcode that should be used to compare Op0 and Op1.
51*9880d681SAndroid Build Coastguard Worker   unsigned Opcode;
52*9880d681SAndroid Build Coastguard Worker 
53*9880d681SAndroid Build Coastguard Worker   // A SystemZICMP value.  Only used for integer comparisons.
54*9880d681SAndroid Build Coastguard Worker   unsigned ICmpType;
55*9880d681SAndroid Build Coastguard Worker 
56*9880d681SAndroid Build Coastguard Worker   // The mask of CC values that Opcode can produce.
57*9880d681SAndroid Build Coastguard Worker   unsigned CCValid;
58*9880d681SAndroid Build Coastguard Worker 
59*9880d681SAndroid Build Coastguard Worker   // The mask of CC values for which the original condition is true.
60*9880d681SAndroid Build Coastguard Worker   unsigned CCMask;
61*9880d681SAndroid Build Coastguard Worker };
62*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
63*9880d681SAndroid Build Coastguard Worker 
64*9880d681SAndroid Build Coastguard Worker // Classify VT as either 32 or 64 bit.
is32Bit(EVT VT)65*9880d681SAndroid Build Coastguard Worker static bool is32Bit(EVT VT) {
66*9880d681SAndroid Build Coastguard Worker   switch (VT.getSimpleVT().SimpleTy) {
67*9880d681SAndroid Build Coastguard Worker   case MVT::i32:
68*9880d681SAndroid Build Coastguard Worker     return true;
69*9880d681SAndroid Build Coastguard Worker   case MVT::i64:
70*9880d681SAndroid Build Coastguard Worker     return false;
71*9880d681SAndroid Build Coastguard Worker   default:
72*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Unsupported type");
73*9880d681SAndroid Build Coastguard Worker   }
74*9880d681SAndroid Build Coastguard Worker }
75*9880d681SAndroid Build Coastguard Worker 
76*9880d681SAndroid Build Coastguard Worker // Return a version of MachineOperand that can be safely used before the
77*9880d681SAndroid Build Coastguard Worker // final use.
earlyUseOperand(MachineOperand Op)78*9880d681SAndroid Build Coastguard Worker static MachineOperand earlyUseOperand(MachineOperand Op) {
79*9880d681SAndroid Build Coastguard Worker   if (Op.isReg())
80*9880d681SAndroid Build Coastguard Worker     Op.setIsKill(false);
81*9880d681SAndroid Build Coastguard Worker   return Op;
82*9880d681SAndroid Build Coastguard Worker }
83*9880d681SAndroid Build Coastguard Worker 
SystemZTargetLowering(const TargetMachine & TM,const SystemZSubtarget & STI)84*9880d681SAndroid Build Coastguard Worker SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
85*9880d681SAndroid Build Coastguard Worker                                              const SystemZSubtarget &STI)
86*9880d681SAndroid Build Coastguard Worker     : TargetLowering(TM), Subtarget(STI) {
87*9880d681SAndroid Build Coastguard Worker   MVT PtrVT = MVT::getIntegerVT(8 * TM.getPointerSize());
88*9880d681SAndroid Build Coastguard Worker 
89*9880d681SAndroid Build Coastguard Worker   // Set up the register classes.
90*9880d681SAndroid Build Coastguard Worker   if (Subtarget.hasHighWord())
91*9880d681SAndroid Build Coastguard Worker     addRegisterClass(MVT::i32, &SystemZ::GRX32BitRegClass);
92*9880d681SAndroid Build Coastguard Worker   else
93*9880d681SAndroid Build Coastguard Worker     addRegisterClass(MVT::i32, &SystemZ::GR32BitRegClass);
94*9880d681SAndroid Build Coastguard Worker   addRegisterClass(MVT::i64, &SystemZ::GR64BitRegClass);
95*9880d681SAndroid Build Coastguard Worker   if (Subtarget.hasVector()) {
96*9880d681SAndroid Build Coastguard Worker     addRegisterClass(MVT::f32, &SystemZ::VR32BitRegClass);
97*9880d681SAndroid Build Coastguard Worker     addRegisterClass(MVT::f64, &SystemZ::VR64BitRegClass);
98*9880d681SAndroid Build Coastguard Worker   } else {
99*9880d681SAndroid Build Coastguard Worker     addRegisterClass(MVT::f32, &SystemZ::FP32BitRegClass);
100*9880d681SAndroid Build Coastguard Worker     addRegisterClass(MVT::f64, &SystemZ::FP64BitRegClass);
101*9880d681SAndroid Build Coastguard Worker   }
102*9880d681SAndroid Build Coastguard Worker   addRegisterClass(MVT::f128, &SystemZ::FP128BitRegClass);
103*9880d681SAndroid Build Coastguard Worker 
104*9880d681SAndroid Build Coastguard Worker   if (Subtarget.hasVector()) {
105*9880d681SAndroid Build Coastguard Worker     addRegisterClass(MVT::v16i8, &SystemZ::VR128BitRegClass);
106*9880d681SAndroid Build Coastguard Worker     addRegisterClass(MVT::v8i16, &SystemZ::VR128BitRegClass);
107*9880d681SAndroid Build Coastguard Worker     addRegisterClass(MVT::v4i32, &SystemZ::VR128BitRegClass);
108*9880d681SAndroid Build Coastguard Worker     addRegisterClass(MVT::v2i64, &SystemZ::VR128BitRegClass);
109*9880d681SAndroid Build Coastguard Worker     addRegisterClass(MVT::v4f32, &SystemZ::VR128BitRegClass);
110*9880d681SAndroid Build Coastguard Worker     addRegisterClass(MVT::v2f64, &SystemZ::VR128BitRegClass);
111*9880d681SAndroid Build Coastguard Worker   }
112*9880d681SAndroid Build Coastguard Worker 
113*9880d681SAndroid Build Coastguard Worker   // Compute derived properties from the register classes
114*9880d681SAndroid Build Coastguard Worker   computeRegisterProperties(Subtarget.getRegisterInfo());
115*9880d681SAndroid Build Coastguard Worker 
116*9880d681SAndroid Build Coastguard Worker   // Set up special registers.
117*9880d681SAndroid Build Coastguard Worker   setStackPointerRegisterToSaveRestore(SystemZ::R15D);
118*9880d681SAndroid Build Coastguard Worker 
119*9880d681SAndroid Build Coastguard Worker   // TODO: It may be better to default to latency-oriented scheduling, however
120*9880d681SAndroid Build Coastguard Worker   // LLVM's current latency-oriented scheduler can't handle physreg definitions
121*9880d681SAndroid Build Coastguard Worker   // such as SystemZ has with CC, so set this to the register-pressure
122*9880d681SAndroid Build Coastguard Worker   // scheduler, because it can.
123*9880d681SAndroid Build Coastguard Worker   setSchedulingPreference(Sched::RegPressure);
124*9880d681SAndroid Build Coastguard Worker 
125*9880d681SAndroid Build Coastguard Worker   setBooleanContents(ZeroOrOneBooleanContent);
126*9880d681SAndroid Build Coastguard Worker   setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
127*9880d681SAndroid Build Coastguard Worker 
128*9880d681SAndroid Build Coastguard Worker   // Instructions are strings of 2-byte aligned 2-byte values.
129*9880d681SAndroid Build Coastguard Worker   setMinFunctionAlignment(2);
130*9880d681SAndroid Build Coastguard Worker 
131*9880d681SAndroid Build Coastguard Worker   // Handle operations that are handled in a similar way for all types.
132*9880d681SAndroid Build Coastguard Worker   for (unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
133*9880d681SAndroid Build Coastguard Worker        I <= MVT::LAST_FP_VALUETYPE;
134*9880d681SAndroid Build Coastguard Worker        ++I) {
135*9880d681SAndroid Build Coastguard Worker     MVT VT = MVT::SimpleValueType(I);
136*9880d681SAndroid Build Coastguard Worker     if (isTypeLegal(VT)) {
137*9880d681SAndroid Build Coastguard Worker       // Lower SET_CC into an IPM-based sequence.
138*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::SETCC, VT, Custom);
139*9880d681SAndroid Build Coastguard Worker 
140*9880d681SAndroid Build Coastguard Worker       // Expand SELECT(C, A, B) into SELECT_CC(X, 0, A, B, NE).
141*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::SELECT, VT, Expand);
142*9880d681SAndroid Build Coastguard Worker 
143*9880d681SAndroid Build Coastguard Worker       // Lower SELECT_CC and BR_CC into separate comparisons and branches.
144*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::SELECT_CC, VT, Custom);
145*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::BR_CC,     VT, Custom);
146*9880d681SAndroid Build Coastguard Worker     }
147*9880d681SAndroid Build Coastguard Worker   }
148*9880d681SAndroid Build Coastguard Worker 
149*9880d681SAndroid Build Coastguard Worker   // Expand jump table branches as address arithmetic followed by an
150*9880d681SAndroid Build Coastguard Worker   // indirect jump.
151*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::BR_JT, MVT::Other, Expand);
152*9880d681SAndroid Build Coastguard Worker 
153*9880d681SAndroid Build Coastguard Worker   // Expand BRCOND into a BR_CC (see above).
154*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::BRCOND, MVT::Other, Expand);
155*9880d681SAndroid Build Coastguard Worker 
156*9880d681SAndroid Build Coastguard Worker   // Handle integer types.
157*9880d681SAndroid Build Coastguard Worker   for (unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
158*9880d681SAndroid Build Coastguard Worker        I <= MVT::LAST_INTEGER_VALUETYPE;
159*9880d681SAndroid Build Coastguard Worker        ++I) {
160*9880d681SAndroid Build Coastguard Worker     MVT VT = MVT::SimpleValueType(I);
161*9880d681SAndroid Build Coastguard Worker     if (isTypeLegal(VT)) {
162*9880d681SAndroid Build Coastguard Worker       // Expand individual DIV and REMs into DIVREMs.
163*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::SDIV, VT, Expand);
164*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::UDIV, VT, Expand);
165*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::SREM, VT, Expand);
166*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::UREM, VT, Expand);
167*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::SDIVREM, VT, Custom);
168*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::UDIVREM, VT, Custom);
169*9880d681SAndroid Build Coastguard Worker 
170*9880d681SAndroid Build Coastguard Worker       // Lower ATOMIC_LOAD and ATOMIC_STORE into normal volatile loads and
171*9880d681SAndroid Build Coastguard Worker       // stores, putting a serialization instruction after the stores.
172*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::ATOMIC_LOAD,  VT, Custom);
173*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::ATOMIC_STORE, VT, Custom);
174*9880d681SAndroid Build Coastguard Worker 
175*9880d681SAndroid Build Coastguard Worker       // Lower ATOMIC_LOAD_SUB into ATOMIC_LOAD_ADD if LAA and LAAG are
176*9880d681SAndroid Build Coastguard Worker       // available, or if the operand is constant.
177*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::ATOMIC_LOAD_SUB, VT, Custom);
178*9880d681SAndroid Build Coastguard Worker 
179*9880d681SAndroid Build Coastguard Worker       // Use POPCNT on z196 and above.
180*9880d681SAndroid Build Coastguard Worker       if (Subtarget.hasPopulationCount())
181*9880d681SAndroid Build Coastguard Worker         setOperationAction(ISD::CTPOP, VT, Custom);
182*9880d681SAndroid Build Coastguard Worker       else
183*9880d681SAndroid Build Coastguard Worker         setOperationAction(ISD::CTPOP, VT, Expand);
184*9880d681SAndroid Build Coastguard Worker 
185*9880d681SAndroid Build Coastguard Worker       // No special instructions for these.
186*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::CTTZ,            VT, Expand);
187*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::ROTR,            VT, Expand);
188*9880d681SAndroid Build Coastguard Worker 
189*9880d681SAndroid Build Coastguard Worker       // Use *MUL_LOHI where possible instead of MULH*.
190*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::MULHS, VT, Expand);
191*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::MULHU, VT, Expand);
192*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::SMUL_LOHI, VT, Custom);
193*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::UMUL_LOHI, VT, Custom);
194*9880d681SAndroid Build Coastguard Worker 
195*9880d681SAndroid Build Coastguard Worker       // Only z196 and above have native support for conversions to unsigned.
196*9880d681SAndroid Build Coastguard Worker       if (!Subtarget.hasFPExtension())
197*9880d681SAndroid Build Coastguard Worker         setOperationAction(ISD::FP_TO_UINT, VT, Expand);
198*9880d681SAndroid Build Coastguard Worker     }
199*9880d681SAndroid Build Coastguard Worker   }
200*9880d681SAndroid Build Coastguard Worker 
201*9880d681SAndroid Build Coastguard Worker   // Type legalization will convert 8- and 16-bit atomic operations into
202*9880d681SAndroid Build Coastguard Worker   // forms that operate on i32s (but still keeping the original memory VT).
203*9880d681SAndroid Build Coastguard Worker   // Lower them into full i32 operations.
204*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::ATOMIC_SWAP,      MVT::i32, Custom);
205*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::ATOMIC_LOAD_ADD,  MVT::i32, Custom);
206*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::ATOMIC_LOAD_SUB,  MVT::i32, Custom);
207*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::ATOMIC_LOAD_AND,  MVT::i32, Custom);
208*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::ATOMIC_LOAD_OR,   MVT::i32, Custom);
209*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::ATOMIC_LOAD_XOR,  MVT::i32, Custom);
210*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::ATOMIC_LOAD_NAND, MVT::i32, Custom);
211*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::ATOMIC_LOAD_MIN,  MVT::i32, Custom);
212*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::ATOMIC_LOAD_MAX,  MVT::i32, Custom);
213*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::ATOMIC_LOAD_UMIN, MVT::i32, Custom);
214*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::ATOMIC_LOAD_UMAX, MVT::i32, Custom);
215*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::ATOMIC_CMP_SWAP,  MVT::i32, Custom);
216*9880d681SAndroid Build Coastguard Worker 
217*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
218*9880d681SAndroid Build Coastguard Worker 
219*9880d681SAndroid Build Coastguard Worker   // Traps are legal, as we will convert them to "j .+2".
220*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::TRAP, MVT::Other, Legal);
221*9880d681SAndroid Build Coastguard Worker 
222*9880d681SAndroid Build Coastguard Worker   // z10 has instructions for signed but not unsigned FP conversion.
223*9880d681SAndroid Build Coastguard Worker   // Handle unsigned 32-bit types as signed 64-bit types.
224*9880d681SAndroid Build Coastguard Worker   if (!Subtarget.hasFPExtension()) {
225*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::UINT_TO_FP, MVT::i32, Promote);
226*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand);
227*9880d681SAndroid Build Coastguard Worker   }
228*9880d681SAndroid Build Coastguard Worker 
229*9880d681SAndroid Build Coastguard Worker   // We have native support for a 64-bit CTLZ, via FLOGR.
230*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::CTLZ, MVT::i32, Promote);
231*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::CTLZ, MVT::i64, Legal);
232*9880d681SAndroid Build Coastguard Worker 
233*9880d681SAndroid Build Coastguard Worker   // Give LowerOperation the chance to replace 64-bit ORs with subregs.
234*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::OR, MVT::i64, Custom);
235*9880d681SAndroid Build Coastguard Worker 
236*9880d681SAndroid Build Coastguard Worker   // FIXME: Can we support these natively?
237*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::SRL_PARTS, MVT::i64, Expand);
238*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::SHL_PARTS, MVT::i64, Expand);
239*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::SRA_PARTS, MVT::i64, Expand);
240*9880d681SAndroid Build Coastguard Worker 
241*9880d681SAndroid Build Coastguard Worker   // We have native instructions for i8, i16 and i32 extensions, but not i1.
242*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
243*9880d681SAndroid Build Coastguard Worker   for (MVT VT : MVT::integer_valuetypes()) {
244*9880d681SAndroid Build Coastguard Worker     setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote);
245*9880d681SAndroid Build Coastguard Worker     setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i1, Promote);
246*9880d681SAndroid Build Coastguard Worker     setLoadExtAction(ISD::EXTLOAD,  VT, MVT::i1, Promote);
247*9880d681SAndroid Build Coastguard Worker   }
248*9880d681SAndroid Build Coastguard Worker 
249*9880d681SAndroid Build Coastguard Worker   // Handle the various types of symbolic address.
250*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::ConstantPool,     PtrVT, Custom);
251*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::GlobalAddress,    PtrVT, Custom);
252*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::GlobalTLSAddress, PtrVT, Custom);
253*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::BlockAddress,     PtrVT, Custom);
254*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::JumpTable,        PtrVT, Custom);
255*9880d681SAndroid Build Coastguard Worker 
256*9880d681SAndroid Build Coastguard Worker   // We need to handle dynamic allocations specially because of the
257*9880d681SAndroid Build Coastguard Worker   // 160-byte area at the bottom of the stack.
258*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::DYNAMIC_STACKALLOC, PtrVT, Custom);
259*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::GET_DYNAMIC_AREA_OFFSET, PtrVT, Custom);
260*9880d681SAndroid Build Coastguard Worker 
261*9880d681SAndroid Build Coastguard Worker   // Use custom expanders so that we can force the function to use
262*9880d681SAndroid Build Coastguard Worker   // a frame pointer.
263*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::STACKSAVE,    MVT::Other, Custom);
264*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::STACKRESTORE, MVT::Other, Custom);
265*9880d681SAndroid Build Coastguard Worker 
266*9880d681SAndroid Build Coastguard Worker   // Handle prefetches with PFD or PFDRL.
267*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::PREFETCH, MVT::Other, Custom);
268*9880d681SAndroid Build Coastguard Worker 
269*9880d681SAndroid Build Coastguard Worker   for (MVT VT : MVT::vector_valuetypes()) {
270*9880d681SAndroid Build Coastguard Worker     // Assume by default that all vector operations need to be expanded.
271*9880d681SAndroid Build Coastguard Worker     for (unsigned Opcode = 0; Opcode < ISD::BUILTIN_OP_END; ++Opcode)
272*9880d681SAndroid Build Coastguard Worker       if (getOperationAction(Opcode, VT) == Legal)
273*9880d681SAndroid Build Coastguard Worker         setOperationAction(Opcode, VT, Expand);
274*9880d681SAndroid Build Coastguard Worker 
275*9880d681SAndroid Build Coastguard Worker     // Likewise all truncating stores and extending loads.
276*9880d681SAndroid Build Coastguard Worker     for (MVT InnerVT : MVT::vector_valuetypes()) {
277*9880d681SAndroid Build Coastguard Worker       setTruncStoreAction(VT, InnerVT, Expand);
278*9880d681SAndroid Build Coastguard Worker       setLoadExtAction(ISD::SEXTLOAD, VT, InnerVT, Expand);
279*9880d681SAndroid Build Coastguard Worker       setLoadExtAction(ISD::ZEXTLOAD, VT, InnerVT, Expand);
280*9880d681SAndroid Build Coastguard Worker       setLoadExtAction(ISD::EXTLOAD, VT, InnerVT, Expand);
281*9880d681SAndroid Build Coastguard Worker     }
282*9880d681SAndroid Build Coastguard Worker 
283*9880d681SAndroid Build Coastguard Worker     if (isTypeLegal(VT)) {
284*9880d681SAndroid Build Coastguard Worker       // These operations are legal for anything that can be stored in a
285*9880d681SAndroid Build Coastguard Worker       // vector register, even if there is no native support for the format
286*9880d681SAndroid Build Coastguard Worker       // as such.  In particular, we can do these for v4f32 even though there
287*9880d681SAndroid Build Coastguard Worker       // are no specific instructions for that format.
288*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::LOAD, VT, Legal);
289*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::STORE, VT, Legal);
290*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::VSELECT, VT, Legal);
291*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::BITCAST, VT, Legal);
292*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::UNDEF, VT, Legal);
293*9880d681SAndroid Build Coastguard Worker 
294*9880d681SAndroid Build Coastguard Worker       // Likewise, except that we need to replace the nodes with something
295*9880d681SAndroid Build Coastguard Worker       // more specific.
296*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::BUILD_VECTOR, VT, Custom);
297*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::VECTOR_SHUFFLE, VT, Custom);
298*9880d681SAndroid Build Coastguard Worker     }
299*9880d681SAndroid Build Coastguard Worker   }
300*9880d681SAndroid Build Coastguard Worker 
301*9880d681SAndroid Build Coastguard Worker   // Handle integer vector types.
302*9880d681SAndroid Build Coastguard Worker   for (MVT VT : MVT::integer_vector_valuetypes()) {
303*9880d681SAndroid Build Coastguard Worker     if (isTypeLegal(VT)) {
304*9880d681SAndroid Build Coastguard Worker       // These operations have direct equivalents.
305*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Legal);
306*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::INSERT_VECTOR_ELT, VT, Legal);
307*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::ADD, VT, Legal);
308*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::SUB, VT, Legal);
309*9880d681SAndroid Build Coastguard Worker       if (VT != MVT::v2i64)
310*9880d681SAndroid Build Coastguard Worker         setOperationAction(ISD::MUL, VT, Legal);
311*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::AND, VT, Legal);
312*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::OR, VT, Legal);
313*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::XOR, VT, Legal);
314*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::CTPOP, VT, Custom);
315*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::CTTZ, VT, Legal);
316*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::CTLZ, VT, Legal);
317*9880d681SAndroid Build Coastguard Worker 
318*9880d681SAndroid Build Coastguard Worker       // Convert a GPR scalar to a vector by inserting it into element 0.
319*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::SCALAR_TO_VECTOR, VT, Custom);
320*9880d681SAndroid Build Coastguard Worker 
321*9880d681SAndroid Build Coastguard Worker       // Use a series of unpacks for extensions.
322*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, VT, Custom);
323*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::ZERO_EXTEND_VECTOR_INREG, VT, Custom);
324*9880d681SAndroid Build Coastguard Worker 
325*9880d681SAndroid Build Coastguard Worker       // Detect shifts by a scalar amount and convert them into
326*9880d681SAndroid Build Coastguard Worker       // V*_BY_SCALAR.
327*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::SHL, VT, Custom);
328*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::SRA, VT, Custom);
329*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::SRL, VT, Custom);
330*9880d681SAndroid Build Coastguard Worker 
331*9880d681SAndroid Build Coastguard Worker       // At present ROTL isn't matched by DAGCombiner.  ROTR should be
332*9880d681SAndroid Build Coastguard Worker       // converted into ROTL.
333*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::ROTL, VT, Expand);
334*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::ROTR, VT, Expand);
335*9880d681SAndroid Build Coastguard Worker 
336*9880d681SAndroid Build Coastguard Worker       // Map SETCCs onto one of VCE, VCH or VCHL, swapping the operands
337*9880d681SAndroid Build Coastguard Worker       // and inverting the result as necessary.
338*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::SETCC, VT, Custom);
339*9880d681SAndroid Build Coastguard Worker     }
340*9880d681SAndroid Build Coastguard Worker   }
341*9880d681SAndroid Build Coastguard Worker 
342*9880d681SAndroid Build Coastguard Worker   if (Subtarget.hasVector()) {
343*9880d681SAndroid Build Coastguard Worker     // There should be no need to check for float types other than v2f64
344*9880d681SAndroid Build Coastguard Worker     // since <2 x f32> isn't a legal type.
345*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::FP_TO_SINT, MVT::v2i64, Legal);
346*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::FP_TO_UINT, MVT::v2i64, Legal);
347*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::SINT_TO_FP, MVT::v2i64, Legal);
348*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::UINT_TO_FP, MVT::v2i64, Legal);
349*9880d681SAndroid Build Coastguard Worker   }
350*9880d681SAndroid Build Coastguard Worker 
351*9880d681SAndroid Build Coastguard Worker   // Handle floating-point types.
352*9880d681SAndroid Build Coastguard Worker   for (unsigned I = MVT::FIRST_FP_VALUETYPE;
353*9880d681SAndroid Build Coastguard Worker        I <= MVT::LAST_FP_VALUETYPE;
354*9880d681SAndroid Build Coastguard Worker        ++I) {
355*9880d681SAndroid Build Coastguard Worker     MVT VT = MVT::SimpleValueType(I);
356*9880d681SAndroid Build Coastguard Worker     if (isTypeLegal(VT)) {
357*9880d681SAndroid Build Coastguard Worker       // We can use FI for FRINT.
358*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::FRINT, VT, Legal);
359*9880d681SAndroid Build Coastguard Worker 
360*9880d681SAndroid Build Coastguard Worker       // We can use the extended form of FI for other rounding operations.
361*9880d681SAndroid Build Coastguard Worker       if (Subtarget.hasFPExtension()) {
362*9880d681SAndroid Build Coastguard Worker         setOperationAction(ISD::FNEARBYINT, VT, Legal);
363*9880d681SAndroid Build Coastguard Worker         setOperationAction(ISD::FFLOOR, VT, Legal);
364*9880d681SAndroid Build Coastguard Worker         setOperationAction(ISD::FCEIL, VT, Legal);
365*9880d681SAndroid Build Coastguard Worker         setOperationAction(ISD::FTRUNC, VT, Legal);
366*9880d681SAndroid Build Coastguard Worker         setOperationAction(ISD::FROUND, VT, Legal);
367*9880d681SAndroid Build Coastguard Worker       }
368*9880d681SAndroid Build Coastguard Worker 
369*9880d681SAndroid Build Coastguard Worker       // No special instructions for these.
370*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::FSIN, VT, Expand);
371*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::FCOS, VT, Expand);
372*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::FSINCOS, VT, Expand);
373*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::FREM, VT, Expand);
374*9880d681SAndroid Build Coastguard Worker       setOperationAction(ISD::FPOW, VT, Expand);
375*9880d681SAndroid Build Coastguard Worker     }
376*9880d681SAndroid Build Coastguard Worker   }
377*9880d681SAndroid Build Coastguard Worker 
378*9880d681SAndroid Build Coastguard Worker   // Handle floating-point vector types.
379*9880d681SAndroid Build Coastguard Worker   if (Subtarget.hasVector()) {
380*9880d681SAndroid Build Coastguard Worker     // Scalar-to-vector conversion is just a subreg.
381*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Legal);
382*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v2f64, Legal);
383*9880d681SAndroid Build Coastguard Worker 
384*9880d681SAndroid Build Coastguard Worker     // Some insertions and extractions can be done directly but others
385*9880d681SAndroid Build Coastguard Worker     // need to go via integers.
386*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Custom);
387*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v2f64, Custom);
388*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Custom);
389*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v2f64, Custom);
390*9880d681SAndroid Build Coastguard Worker 
391*9880d681SAndroid Build Coastguard Worker     // These operations have direct equivalents.
392*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::FADD, MVT::v2f64, Legal);
393*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::FNEG, MVT::v2f64, Legal);
394*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::FSUB, MVT::v2f64, Legal);
395*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::FMUL, MVT::v2f64, Legal);
396*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::FMA, MVT::v2f64, Legal);
397*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::FDIV, MVT::v2f64, Legal);
398*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::FABS, MVT::v2f64, Legal);
399*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::FSQRT, MVT::v2f64, Legal);
400*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::FRINT, MVT::v2f64, Legal);
401*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::FNEARBYINT, MVT::v2f64, Legal);
402*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::FFLOOR, MVT::v2f64, Legal);
403*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::FCEIL, MVT::v2f64, Legal);
404*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::FTRUNC, MVT::v2f64, Legal);
405*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::FROUND, MVT::v2f64, Legal);
406*9880d681SAndroid Build Coastguard Worker   }
407*9880d681SAndroid Build Coastguard Worker 
408*9880d681SAndroid Build Coastguard Worker   // We have fused multiply-addition for f32 and f64 but not f128.
409*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::FMA, MVT::f32,  Legal);
410*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::FMA, MVT::f64,  Legal);
411*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::FMA, MVT::f128, Expand);
412*9880d681SAndroid Build Coastguard Worker 
413*9880d681SAndroid Build Coastguard Worker   // Needed so that we don't try to implement f128 constant loads using
414*9880d681SAndroid Build Coastguard Worker   // a load-and-extend of a f80 constant (in cases where the constant
415*9880d681SAndroid Build Coastguard Worker   // would fit in an f80).
416*9880d681SAndroid Build Coastguard Worker   for (MVT VT : MVT::fp_valuetypes())
417*9880d681SAndroid Build Coastguard Worker     setLoadExtAction(ISD::EXTLOAD, VT, MVT::f80, Expand);
418*9880d681SAndroid Build Coastguard Worker 
419*9880d681SAndroid Build Coastguard Worker   // Floating-point truncation and stores need to be done separately.
420*9880d681SAndroid Build Coastguard Worker   setTruncStoreAction(MVT::f64,  MVT::f32, Expand);
421*9880d681SAndroid Build Coastguard Worker   setTruncStoreAction(MVT::f128, MVT::f32, Expand);
422*9880d681SAndroid Build Coastguard Worker   setTruncStoreAction(MVT::f128, MVT::f64, Expand);
423*9880d681SAndroid Build Coastguard Worker 
424*9880d681SAndroid Build Coastguard Worker   // We have 64-bit FPR<->GPR moves, but need special handling for
425*9880d681SAndroid Build Coastguard Worker   // 32-bit forms.
426*9880d681SAndroid Build Coastguard Worker   if (!Subtarget.hasVector()) {
427*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::BITCAST, MVT::i32, Custom);
428*9880d681SAndroid Build Coastguard Worker     setOperationAction(ISD::BITCAST, MVT::f32, Custom);
429*9880d681SAndroid Build Coastguard Worker   }
430*9880d681SAndroid Build Coastguard Worker 
431*9880d681SAndroid Build Coastguard Worker   // VASTART and VACOPY need to deal with the SystemZ-specific varargs
432*9880d681SAndroid Build Coastguard Worker   // structure, but VAEND is a no-op.
433*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::VASTART, MVT::Other, Custom);
434*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::VACOPY,  MVT::Other, Custom);
435*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::VAEND,   MVT::Other, Expand);
436*9880d681SAndroid Build Coastguard Worker 
437*9880d681SAndroid Build Coastguard Worker   // Codes for which we want to perform some z-specific combinations.
438*9880d681SAndroid Build Coastguard Worker   setTargetDAGCombine(ISD::SIGN_EXTEND);
439*9880d681SAndroid Build Coastguard Worker   setTargetDAGCombine(ISD::STORE);
440*9880d681SAndroid Build Coastguard Worker   setTargetDAGCombine(ISD::EXTRACT_VECTOR_ELT);
441*9880d681SAndroid Build Coastguard Worker   setTargetDAGCombine(ISD::FP_ROUND);
442*9880d681SAndroid Build Coastguard Worker   setTargetDAGCombine(ISD::BSWAP);
443*9880d681SAndroid Build Coastguard Worker   setTargetDAGCombine(ISD::SHL);
444*9880d681SAndroid Build Coastguard Worker   setTargetDAGCombine(ISD::SRA);
445*9880d681SAndroid Build Coastguard Worker   setTargetDAGCombine(ISD::SRL);
446*9880d681SAndroid Build Coastguard Worker   setTargetDAGCombine(ISD::ROTL);
447*9880d681SAndroid Build Coastguard Worker 
448*9880d681SAndroid Build Coastguard Worker   // Handle intrinsics.
449*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
450*9880d681SAndroid Build Coastguard Worker   setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
451*9880d681SAndroid Build Coastguard Worker 
452*9880d681SAndroid Build Coastguard Worker   // We want to use MVC in preference to even a single load/store pair.
453*9880d681SAndroid Build Coastguard Worker   MaxStoresPerMemcpy = 0;
454*9880d681SAndroid Build Coastguard Worker   MaxStoresPerMemcpyOptSize = 0;
455*9880d681SAndroid Build Coastguard Worker 
456*9880d681SAndroid Build Coastguard Worker   // The main memset sequence is a byte store followed by an MVC.
457*9880d681SAndroid Build Coastguard Worker   // Two STC or MV..I stores win over that, but the kind of fused stores
458*9880d681SAndroid Build Coastguard Worker   // generated by target-independent code don't when the byte value is
459*9880d681SAndroid Build Coastguard Worker   // variable.  E.g.  "STC <reg>;MHI <reg>,257;STH <reg>" is not better
460*9880d681SAndroid Build Coastguard Worker   // than "STC;MVC".  Handle the choice in target-specific code instead.
461*9880d681SAndroid Build Coastguard Worker   MaxStoresPerMemset = 0;
462*9880d681SAndroid Build Coastguard Worker   MaxStoresPerMemsetOptSize = 0;
463*9880d681SAndroid Build Coastguard Worker }
464*9880d681SAndroid Build Coastguard Worker 
getSetCCResultType(const DataLayout & DL,LLVMContext &,EVT VT) const465*9880d681SAndroid Build Coastguard Worker EVT SystemZTargetLowering::getSetCCResultType(const DataLayout &DL,
466*9880d681SAndroid Build Coastguard Worker                                               LLVMContext &, EVT VT) const {
467*9880d681SAndroid Build Coastguard Worker   if (!VT.isVector())
468*9880d681SAndroid Build Coastguard Worker     return MVT::i32;
469*9880d681SAndroid Build Coastguard Worker   return VT.changeVectorElementTypeToInteger();
470*9880d681SAndroid Build Coastguard Worker }
471*9880d681SAndroid Build Coastguard Worker 
isFMAFasterThanFMulAndFAdd(EVT VT) const472*9880d681SAndroid Build Coastguard Worker bool SystemZTargetLowering::isFMAFasterThanFMulAndFAdd(EVT VT) const {
473*9880d681SAndroid Build Coastguard Worker   VT = VT.getScalarType();
474*9880d681SAndroid Build Coastguard Worker 
475*9880d681SAndroid Build Coastguard Worker   if (!VT.isSimple())
476*9880d681SAndroid Build Coastguard Worker     return false;
477*9880d681SAndroid Build Coastguard Worker 
478*9880d681SAndroid Build Coastguard Worker   switch (VT.getSimpleVT().SimpleTy) {
479*9880d681SAndroid Build Coastguard Worker   case MVT::f32:
480*9880d681SAndroid Build Coastguard Worker   case MVT::f64:
481*9880d681SAndroid Build Coastguard Worker     return true;
482*9880d681SAndroid Build Coastguard Worker   case MVT::f128:
483*9880d681SAndroid Build Coastguard Worker     return false;
484*9880d681SAndroid Build Coastguard Worker   default:
485*9880d681SAndroid Build Coastguard Worker     break;
486*9880d681SAndroid Build Coastguard Worker   }
487*9880d681SAndroid Build Coastguard Worker 
488*9880d681SAndroid Build Coastguard Worker   return false;
489*9880d681SAndroid Build Coastguard Worker }
490*9880d681SAndroid Build Coastguard Worker 
isFPImmLegal(const APFloat & Imm,EVT VT) const491*9880d681SAndroid Build Coastguard Worker bool SystemZTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
492*9880d681SAndroid Build Coastguard Worker   // We can load zero using LZ?R and negative zero using LZ?R;LC?BR.
493*9880d681SAndroid Build Coastguard Worker   return Imm.isZero() || Imm.isNegZero();
494*9880d681SAndroid Build Coastguard Worker }
495*9880d681SAndroid Build Coastguard Worker 
isLegalICmpImmediate(int64_t Imm) const496*9880d681SAndroid Build Coastguard Worker bool SystemZTargetLowering::isLegalICmpImmediate(int64_t Imm) const {
497*9880d681SAndroid Build Coastguard Worker   // We can use CGFI or CLGFI.
498*9880d681SAndroid Build Coastguard Worker   return isInt<32>(Imm) || isUInt<32>(Imm);
499*9880d681SAndroid Build Coastguard Worker }
500*9880d681SAndroid Build Coastguard Worker 
isLegalAddImmediate(int64_t Imm) const501*9880d681SAndroid Build Coastguard Worker bool SystemZTargetLowering::isLegalAddImmediate(int64_t Imm) const {
502*9880d681SAndroid Build Coastguard Worker   // We can use ALGFI or SLGFI.
503*9880d681SAndroid Build Coastguard Worker   return isUInt<32>(Imm) || isUInt<32>(-Imm);
504*9880d681SAndroid Build Coastguard Worker }
505*9880d681SAndroid Build Coastguard Worker 
allowsMisalignedMemoryAccesses(EVT VT,unsigned,unsigned,bool * Fast) const506*9880d681SAndroid Build Coastguard Worker bool SystemZTargetLowering::allowsMisalignedMemoryAccesses(EVT VT,
507*9880d681SAndroid Build Coastguard Worker                                                            unsigned,
508*9880d681SAndroid Build Coastguard Worker                                                            unsigned,
509*9880d681SAndroid Build Coastguard Worker                                                            bool *Fast) const {
510*9880d681SAndroid Build Coastguard Worker   // Unaligned accesses should never be slower than the expanded version.
511*9880d681SAndroid Build Coastguard Worker   // We check specifically for aligned accesses in the few cases where
512*9880d681SAndroid Build Coastguard Worker   // they are required.
513*9880d681SAndroid Build Coastguard Worker   if (Fast)
514*9880d681SAndroid Build Coastguard Worker     *Fast = true;
515*9880d681SAndroid Build Coastguard Worker   return true;
516*9880d681SAndroid Build Coastguard Worker }
517*9880d681SAndroid Build Coastguard Worker 
isLegalAddressingMode(const DataLayout & DL,const AddrMode & AM,Type * Ty,unsigned AS) const518*9880d681SAndroid Build Coastguard Worker bool SystemZTargetLowering::isLegalAddressingMode(const DataLayout &DL,
519*9880d681SAndroid Build Coastguard Worker                                                   const AddrMode &AM, Type *Ty,
520*9880d681SAndroid Build Coastguard Worker                                                   unsigned AS) const {
521*9880d681SAndroid Build Coastguard Worker   // Punt on globals for now, although they can be used in limited
522*9880d681SAndroid Build Coastguard Worker   // RELATIVE LONG cases.
523*9880d681SAndroid Build Coastguard Worker   if (AM.BaseGV)
524*9880d681SAndroid Build Coastguard Worker     return false;
525*9880d681SAndroid Build Coastguard Worker 
526*9880d681SAndroid Build Coastguard Worker   // Require a 20-bit signed offset.
527*9880d681SAndroid Build Coastguard Worker   if (!isInt<20>(AM.BaseOffs))
528*9880d681SAndroid Build Coastguard Worker     return false;
529*9880d681SAndroid Build Coastguard Worker 
530*9880d681SAndroid Build Coastguard Worker   // Indexing is OK but no scale factor can be applied.
531*9880d681SAndroid Build Coastguard Worker   return AM.Scale == 0 || AM.Scale == 1;
532*9880d681SAndroid Build Coastguard Worker }
533*9880d681SAndroid Build Coastguard Worker 
isTruncateFree(Type * FromType,Type * ToType) const534*9880d681SAndroid Build Coastguard Worker bool SystemZTargetLowering::isTruncateFree(Type *FromType, Type *ToType) const {
535*9880d681SAndroid Build Coastguard Worker   if (!FromType->isIntegerTy() || !ToType->isIntegerTy())
536*9880d681SAndroid Build Coastguard Worker     return false;
537*9880d681SAndroid Build Coastguard Worker   unsigned FromBits = FromType->getPrimitiveSizeInBits();
538*9880d681SAndroid Build Coastguard Worker   unsigned ToBits = ToType->getPrimitiveSizeInBits();
539*9880d681SAndroid Build Coastguard Worker   return FromBits > ToBits;
540*9880d681SAndroid Build Coastguard Worker }
541*9880d681SAndroid Build Coastguard Worker 
isTruncateFree(EVT FromVT,EVT ToVT) const542*9880d681SAndroid Build Coastguard Worker bool SystemZTargetLowering::isTruncateFree(EVT FromVT, EVT ToVT) const {
543*9880d681SAndroid Build Coastguard Worker   if (!FromVT.isInteger() || !ToVT.isInteger())
544*9880d681SAndroid Build Coastguard Worker     return false;
545*9880d681SAndroid Build Coastguard Worker   unsigned FromBits = FromVT.getSizeInBits();
546*9880d681SAndroid Build Coastguard Worker   unsigned ToBits = ToVT.getSizeInBits();
547*9880d681SAndroid Build Coastguard Worker   return FromBits > ToBits;
548*9880d681SAndroid Build Coastguard Worker }
549*9880d681SAndroid Build Coastguard Worker 
550*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
551*9880d681SAndroid Build Coastguard Worker // Inline asm support
552*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
553*9880d681SAndroid Build Coastguard Worker 
554*9880d681SAndroid Build Coastguard Worker TargetLowering::ConstraintType
getConstraintType(StringRef Constraint) const555*9880d681SAndroid Build Coastguard Worker SystemZTargetLowering::getConstraintType(StringRef Constraint) const {
556*9880d681SAndroid Build Coastguard Worker   if (Constraint.size() == 1) {
557*9880d681SAndroid Build Coastguard Worker     switch (Constraint[0]) {
558*9880d681SAndroid Build Coastguard Worker     case 'a': // Address register
559*9880d681SAndroid Build Coastguard Worker     case 'd': // Data register (equivalent to 'r')
560*9880d681SAndroid Build Coastguard Worker     case 'f': // Floating-point register
561*9880d681SAndroid Build Coastguard Worker     case 'h': // High-part register
562*9880d681SAndroid Build Coastguard Worker     case 'r': // General-purpose register
563*9880d681SAndroid Build Coastguard Worker       return C_RegisterClass;
564*9880d681SAndroid Build Coastguard Worker 
565*9880d681SAndroid Build Coastguard Worker     case 'Q': // Memory with base and unsigned 12-bit displacement
566*9880d681SAndroid Build Coastguard Worker     case 'R': // Likewise, plus an index
567*9880d681SAndroid Build Coastguard Worker     case 'S': // Memory with base and signed 20-bit displacement
568*9880d681SAndroid Build Coastguard Worker     case 'T': // Likewise, plus an index
569*9880d681SAndroid Build Coastguard Worker     case 'm': // Equivalent to 'T'.
570*9880d681SAndroid Build Coastguard Worker       return C_Memory;
571*9880d681SAndroid Build Coastguard Worker 
572*9880d681SAndroid Build Coastguard Worker     case 'I': // Unsigned 8-bit constant
573*9880d681SAndroid Build Coastguard Worker     case 'J': // Unsigned 12-bit constant
574*9880d681SAndroid Build Coastguard Worker     case 'K': // Signed 16-bit constant
575*9880d681SAndroid Build Coastguard Worker     case 'L': // Signed 20-bit displacement (on all targets we support)
576*9880d681SAndroid Build Coastguard Worker     case 'M': // 0x7fffffff
577*9880d681SAndroid Build Coastguard Worker       return C_Other;
578*9880d681SAndroid Build Coastguard Worker 
579*9880d681SAndroid Build Coastguard Worker     default:
580*9880d681SAndroid Build Coastguard Worker       break;
581*9880d681SAndroid Build Coastguard Worker     }
582*9880d681SAndroid Build Coastguard Worker   }
583*9880d681SAndroid Build Coastguard Worker   return TargetLowering::getConstraintType(Constraint);
584*9880d681SAndroid Build Coastguard Worker }
585*9880d681SAndroid Build Coastguard Worker 
586*9880d681SAndroid Build Coastguard Worker TargetLowering::ConstraintWeight SystemZTargetLowering::
getSingleConstraintMatchWeight(AsmOperandInfo & info,const char * constraint) const587*9880d681SAndroid Build Coastguard Worker getSingleConstraintMatchWeight(AsmOperandInfo &info,
588*9880d681SAndroid Build Coastguard Worker                                const char *constraint) const {
589*9880d681SAndroid Build Coastguard Worker   ConstraintWeight weight = CW_Invalid;
590*9880d681SAndroid Build Coastguard Worker   Value *CallOperandVal = info.CallOperandVal;
591*9880d681SAndroid Build Coastguard Worker   // If we don't have a value, we can't do a match,
592*9880d681SAndroid Build Coastguard Worker   // but allow it at the lowest weight.
593*9880d681SAndroid Build Coastguard Worker   if (!CallOperandVal)
594*9880d681SAndroid Build Coastguard Worker     return CW_Default;
595*9880d681SAndroid Build Coastguard Worker   Type *type = CallOperandVal->getType();
596*9880d681SAndroid Build Coastguard Worker   // Look at the constraint type.
597*9880d681SAndroid Build Coastguard Worker   switch (*constraint) {
598*9880d681SAndroid Build Coastguard Worker   default:
599*9880d681SAndroid Build Coastguard Worker     weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);
600*9880d681SAndroid Build Coastguard Worker     break;
601*9880d681SAndroid Build Coastguard Worker 
602*9880d681SAndroid Build Coastguard Worker   case 'a': // Address register
603*9880d681SAndroid Build Coastguard Worker   case 'd': // Data register (equivalent to 'r')
604*9880d681SAndroid Build Coastguard Worker   case 'h': // High-part register
605*9880d681SAndroid Build Coastguard Worker   case 'r': // General-purpose register
606*9880d681SAndroid Build Coastguard Worker     if (CallOperandVal->getType()->isIntegerTy())
607*9880d681SAndroid Build Coastguard Worker       weight = CW_Register;
608*9880d681SAndroid Build Coastguard Worker     break;
609*9880d681SAndroid Build Coastguard Worker 
610*9880d681SAndroid Build Coastguard Worker   case 'f': // Floating-point register
611*9880d681SAndroid Build Coastguard Worker     if (type->isFloatingPointTy())
612*9880d681SAndroid Build Coastguard Worker       weight = CW_Register;
613*9880d681SAndroid Build Coastguard Worker     break;
614*9880d681SAndroid Build Coastguard Worker 
615*9880d681SAndroid Build Coastguard Worker   case 'I': // Unsigned 8-bit constant
616*9880d681SAndroid Build Coastguard Worker     if (auto *C = dyn_cast<ConstantInt>(CallOperandVal))
617*9880d681SAndroid Build Coastguard Worker       if (isUInt<8>(C->getZExtValue()))
618*9880d681SAndroid Build Coastguard Worker         weight = CW_Constant;
619*9880d681SAndroid Build Coastguard Worker     break;
620*9880d681SAndroid Build Coastguard Worker 
621*9880d681SAndroid Build Coastguard Worker   case 'J': // Unsigned 12-bit constant
622*9880d681SAndroid Build Coastguard Worker     if (auto *C = dyn_cast<ConstantInt>(CallOperandVal))
623*9880d681SAndroid Build Coastguard Worker       if (isUInt<12>(C->getZExtValue()))
624*9880d681SAndroid Build Coastguard Worker         weight = CW_Constant;
625*9880d681SAndroid Build Coastguard Worker     break;
626*9880d681SAndroid Build Coastguard Worker 
627*9880d681SAndroid Build Coastguard Worker   case 'K': // Signed 16-bit constant
628*9880d681SAndroid Build Coastguard Worker     if (auto *C = dyn_cast<ConstantInt>(CallOperandVal))
629*9880d681SAndroid Build Coastguard Worker       if (isInt<16>(C->getSExtValue()))
630*9880d681SAndroid Build Coastguard Worker         weight = CW_Constant;
631*9880d681SAndroid Build Coastguard Worker     break;
632*9880d681SAndroid Build Coastguard Worker 
633*9880d681SAndroid Build Coastguard Worker   case 'L': // Signed 20-bit displacement (on all targets we support)
634*9880d681SAndroid Build Coastguard Worker     if (auto *C = dyn_cast<ConstantInt>(CallOperandVal))
635*9880d681SAndroid Build Coastguard Worker       if (isInt<20>(C->getSExtValue()))
636*9880d681SAndroid Build Coastguard Worker         weight = CW_Constant;
637*9880d681SAndroid Build Coastguard Worker     break;
638*9880d681SAndroid Build Coastguard Worker 
639*9880d681SAndroid Build Coastguard Worker   case 'M': // 0x7fffffff
640*9880d681SAndroid Build Coastguard Worker     if (auto *C = dyn_cast<ConstantInt>(CallOperandVal))
641*9880d681SAndroid Build Coastguard Worker       if (C->getZExtValue() == 0x7fffffff)
642*9880d681SAndroid Build Coastguard Worker         weight = CW_Constant;
643*9880d681SAndroid Build Coastguard Worker     break;
644*9880d681SAndroid Build Coastguard Worker   }
645*9880d681SAndroid Build Coastguard Worker   return weight;
646*9880d681SAndroid Build Coastguard Worker }
647*9880d681SAndroid Build Coastguard Worker 
648*9880d681SAndroid Build Coastguard Worker // Parse a "{tNNN}" register constraint for which the register type "t"
649*9880d681SAndroid Build Coastguard Worker // has already been verified.  MC is the class associated with "t" and
650*9880d681SAndroid Build Coastguard Worker // Map maps 0-based register numbers to LLVM register numbers.
651*9880d681SAndroid Build Coastguard Worker static std::pair<unsigned, const TargetRegisterClass *>
parseRegisterNumber(StringRef Constraint,const TargetRegisterClass * RC,const unsigned * Map)652*9880d681SAndroid Build Coastguard Worker parseRegisterNumber(StringRef Constraint, const TargetRegisterClass *RC,
653*9880d681SAndroid Build Coastguard Worker                     const unsigned *Map) {
654*9880d681SAndroid Build Coastguard Worker   assert(*(Constraint.end()-1) == '}' && "Missing '}'");
655*9880d681SAndroid Build Coastguard Worker   if (isdigit(Constraint[2])) {
656*9880d681SAndroid Build Coastguard Worker     unsigned Index;
657*9880d681SAndroid Build Coastguard Worker     bool Failed =
658*9880d681SAndroid Build Coastguard Worker         Constraint.slice(2, Constraint.size() - 1).getAsInteger(10, Index);
659*9880d681SAndroid Build Coastguard Worker     if (!Failed && Index < 16 && Map[Index])
660*9880d681SAndroid Build Coastguard Worker       return std::make_pair(Map[Index], RC);
661*9880d681SAndroid Build Coastguard Worker   }
662*9880d681SAndroid Build Coastguard Worker   return std::make_pair(0U, nullptr);
663*9880d681SAndroid Build Coastguard Worker }
664*9880d681SAndroid Build Coastguard Worker 
665*9880d681SAndroid Build Coastguard Worker std::pair<unsigned, const TargetRegisterClass *>
getRegForInlineAsmConstraint(const TargetRegisterInfo * TRI,StringRef Constraint,MVT VT) const666*9880d681SAndroid Build Coastguard Worker SystemZTargetLowering::getRegForInlineAsmConstraint(
667*9880d681SAndroid Build Coastguard Worker     const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
668*9880d681SAndroid Build Coastguard Worker   if (Constraint.size() == 1) {
669*9880d681SAndroid Build Coastguard Worker     // GCC Constraint Letters
670*9880d681SAndroid Build Coastguard Worker     switch (Constraint[0]) {
671*9880d681SAndroid Build Coastguard Worker     default: break;
672*9880d681SAndroid Build Coastguard Worker     case 'd': // Data register (equivalent to 'r')
673*9880d681SAndroid Build Coastguard Worker     case 'r': // General-purpose register
674*9880d681SAndroid Build Coastguard Worker       if (VT == MVT::i64)
675*9880d681SAndroid Build Coastguard Worker         return std::make_pair(0U, &SystemZ::GR64BitRegClass);
676*9880d681SAndroid Build Coastguard Worker       else if (VT == MVT::i128)
677*9880d681SAndroid Build Coastguard Worker         return std::make_pair(0U, &SystemZ::GR128BitRegClass);
678*9880d681SAndroid Build Coastguard Worker       return std::make_pair(0U, &SystemZ::GR32BitRegClass);
679*9880d681SAndroid Build Coastguard Worker 
680*9880d681SAndroid Build Coastguard Worker     case 'a': // Address register
681*9880d681SAndroid Build Coastguard Worker       if (VT == MVT::i64)
682*9880d681SAndroid Build Coastguard Worker         return std::make_pair(0U, &SystemZ::ADDR64BitRegClass);
683*9880d681SAndroid Build Coastguard Worker       else if (VT == MVT::i128)
684*9880d681SAndroid Build Coastguard Worker         return std::make_pair(0U, &SystemZ::ADDR128BitRegClass);
685*9880d681SAndroid Build Coastguard Worker       return std::make_pair(0U, &SystemZ::ADDR32BitRegClass);
686*9880d681SAndroid Build Coastguard Worker 
687*9880d681SAndroid Build Coastguard Worker     case 'h': // High-part register (an LLVM extension)
688*9880d681SAndroid Build Coastguard Worker       return std::make_pair(0U, &SystemZ::GRH32BitRegClass);
689*9880d681SAndroid Build Coastguard Worker 
690*9880d681SAndroid Build Coastguard Worker     case 'f': // Floating-point register
691*9880d681SAndroid Build Coastguard Worker       if (VT == MVT::f64)
692*9880d681SAndroid Build Coastguard Worker         return std::make_pair(0U, &SystemZ::FP64BitRegClass);
693*9880d681SAndroid Build Coastguard Worker       else if (VT == MVT::f128)
694*9880d681SAndroid Build Coastguard Worker         return std::make_pair(0U, &SystemZ::FP128BitRegClass);
695*9880d681SAndroid Build Coastguard Worker       return std::make_pair(0U, &SystemZ::FP32BitRegClass);
696*9880d681SAndroid Build Coastguard Worker     }
697*9880d681SAndroid Build Coastguard Worker   }
698*9880d681SAndroid Build Coastguard Worker   if (Constraint.size() > 0 && Constraint[0] == '{') {
699*9880d681SAndroid Build Coastguard Worker     // We need to override the default register parsing for GPRs and FPRs
700*9880d681SAndroid Build Coastguard Worker     // because the interpretation depends on VT.  The internal names of
701*9880d681SAndroid Build Coastguard Worker     // the registers are also different from the external names
702*9880d681SAndroid Build Coastguard Worker     // (F0D and F0S instead of F0, etc.).
703*9880d681SAndroid Build Coastguard Worker     if (Constraint[1] == 'r') {
704*9880d681SAndroid Build Coastguard Worker       if (VT == MVT::i32)
705*9880d681SAndroid Build Coastguard Worker         return parseRegisterNumber(Constraint, &SystemZ::GR32BitRegClass,
706*9880d681SAndroid Build Coastguard Worker                                    SystemZMC::GR32Regs);
707*9880d681SAndroid Build Coastguard Worker       if (VT == MVT::i128)
708*9880d681SAndroid Build Coastguard Worker         return parseRegisterNumber(Constraint, &SystemZ::GR128BitRegClass,
709*9880d681SAndroid Build Coastguard Worker                                    SystemZMC::GR128Regs);
710*9880d681SAndroid Build Coastguard Worker       return parseRegisterNumber(Constraint, &SystemZ::GR64BitRegClass,
711*9880d681SAndroid Build Coastguard Worker                                  SystemZMC::GR64Regs);
712*9880d681SAndroid Build Coastguard Worker     }
713*9880d681SAndroid Build Coastguard Worker     if (Constraint[1] == 'f') {
714*9880d681SAndroid Build Coastguard Worker       if (VT == MVT::f32)
715*9880d681SAndroid Build Coastguard Worker         return parseRegisterNumber(Constraint, &SystemZ::FP32BitRegClass,
716*9880d681SAndroid Build Coastguard Worker                                    SystemZMC::FP32Regs);
717*9880d681SAndroid Build Coastguard Worker       if (VT == MVT::f128)
718*9880d681SAndroid Build Coastguard Worker         return parseRegisterNumber(Constraint, &SystemZ::FP128BitRegClass,
719*9880d681SAndroid Build Coastguard Worker                                    SystemZMC::FP128Regs);
720*9880d681SAndroid Build Coastguard Worker       return parseRegisterNumber(Constraint, &SystemZ::FP64BitRegClass,
721*9880d681SAndroid Build Coastguard Worker                                  SystemZMC::FP64Regs);
722*9880d681SAndroid Build Coastguard Worker     }
723*9880d681SAndroid Build Coastguard Worker   }
724*9880d681SAndroid Build Coastguard Worker   return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
725*9880d681SAndroid Build Coastguard Worker }
726*9880d681SAndroid Build Coastguard Worker 
727*9880d681SAndroid Build Coastguard Worker void SystemZTargetLowering::
LowerAsmOperandForConstraint(SDValue Op,std::string & Constraint,std::vector<SDValue> & Ops,SelectionDAG & DAG) const728*9880d681SAndroid Build Coastguard Worker LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint,
729*9880d681SAndroid Build Coastguard Worker                              std::vector<SDValue> &Ops,
730*9880d681SAndroid Build Coastguard Worker                              SelectionDAG &DAG) const {
731*9880d681SAndroid Build Coastguard Worker   // Only support length 1 constraints for now.
732*9880d681SAndroid Build Coastguard Worker   if (Constraint.length() == 1) {
733*9880d681SAndroid Build Coastguard Worker     switch (Constraint[0]) {
734*9880d681SAndroid Build Coastguard Worker     case 'I': // Unsigned 8-bit constant
735*9880d681SAndroid Build Coastguard Worker       if (auto *C = dyn_cast<ConstantSDNode>(Op))
736*9880d681SAndroid Build Coastguard Worker         if (isUInt<8>(C->getZExtValue()))
737*9880d681SAndroid Build Coastguard Worker           Ops.push_back(DAG.getTargetConstant(C->getZExtValue(), SDLoc(Op),
738*9880d681SAndroid Build Coastguard Worker                                               Op.getValueType()));
739*9880d681SAndroid Build Coastguard Worker       return;
740*9880d681SAndroid Build Coastguard Worker 
741*9880d681SAndroid Build Coastguard Worker     case 'J': // Unsigned 12-bit constant
742*9880d681SAndroid Build Coastguard Worker       if (auto *C = dyn_cast<ConstantSDNode>(Op))
743*9880d681SAndroid Build Coastguard Worker         if (isUInt<12>(C->getZExtValue()))
744*9880d681SAndroid Build Coastguard Worker           Ops.push_back(DAG.getTargetConstant(C->getZExtValue(), SDLoc(Op),
745*9880d681SAndroid Build Coastguard Worker                                               Op.getValueType()));
746*9880d681SAndroid Build Coastguard Worker       return;
747*9880d681SAndroid Build Coastguard Worker 
748*9880d681SAndroid Build Coastguard Worker     case 'K': // Signed 16-bit constant
749*9880d681SAndroid Build Coastguard Worker       if (auto *C = dyn_cast<ConstantSDNode>(Op))
750*9880d681SAndroid Build Coastguard Worker         if (isInt<16>(C->getSExtValue()))
751*9880d681SAndroid Build Coastguard Worker           Ops.push_back(DAG.getTargetConstant(C->getSExtValue(), SDLoc(Op),
752*9880d681SAndroid Build Coastguard Worker                                               Op.getValueType()));
753*9880d681SAndroid Build Coastguard Worker       return;
754*9880d681SAndroid Build Coastguard Worker 
755*9880d681SAndroid Build Coastguard Worker     case 'L': // Signed 20-bit displacement (on all targets we support)
756*9880d681SAndroid Build Coastguard Worker       if (auto *C = dyn_cast<ConstantSDNode>(Op))
757*9880d681SAndroid Build Coastguard Worker         if (isInt<20>(C->getSExtValue()))
758*9880d681SAndroid Build Coastguard Worker           Ops.push_back(DAG.getTargetConstant(C->getSExtValue(), SDLoc(Op),
759*9880d681SAndroid Build Coastguard Worker                                               Op.getValueType()));
760*9880d681SAndroid Build Coastguard Worker       return;
761*9880d681SAndroid Build Coastguard Worker 
762*9880d681SAndroid Build Coastguard Worker     case 'M': // 0x7fffffff
763*9880d681SAndroid Build Coastguard Worker       if (auto *C = dyn_cast<ConstantSDNode>(Op))
764*9880d681SAndroid Build Coastguard Worker         if (C->getZExtValue() == 0x7fffffff)
765*9880d681SAndroid Build Coastguard Worker           Ops.push_back(DAG.getTargetConstant(C->getZExtValue(), SDLoc(Op),
766*9880d681SAndroid Build Coastguard Worker                                               Op.getValueType()));
767*9880d681SAndroid Build Coastguard Worker       return;
768*9880d681SAndroid Build Coastguard Worker     }
769*9880d681SAndroid Build Coastguard Worker   }
770*9880d681SAndroid Build Coastguard Worker   TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
771*9880d681SAndroid Build Coastguard Worker }
772*9880d681SAndroid Build Coastguard Worker 
773*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
774*9880d681SAndroid Build Coastguard Worker // Calling conventions
775*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
776*9880d681SAndroid Build Coastguard Worker 
777*9880d681SAndroid Build Coastguard Worker #include "SystemZGenCallingConv.inc"
778*9880d681SAndroid Build Coastguard Worker 
allowTruncateForTailCall(Type * FromType,Type * ToType) const779*9880d681SAndroid Build Coastguard Worker bool SystemZTargetLowering::allowTruncateForTailCall(Type *FromType,
780*9880d681SAndroid Build Coastguard Worker                                                      Type *ToType) const {
781*9880d681SAndroid Build Coastguard Worker   return isTruncateFree(FromType, ToType);
782*9880d681SAndroid Build Coastguard Worker }
783*9880d681SAndroid Build Coastguard Worker 
mayBeEmittedAsTailCall(CallInst * CI) const784*9880d681SAndroid Build Coastguard Worker bool SystemZTargetLowering::mayBeEmittedAsTailCall(CallInst *CI) const {
785*9880d681SAndroid Build Coastguard Worker   return CI->isTailCall();
786*9880d681SAndroid Build Coastguard Worker }
787*9880d681SAndroid Build Coastguard Worker 
788*9880d681SAndroid Build Coastguard Worker // We do not yet support 128-bit single-element vector types.  If the user
789*9880d681SAndroid Build Coastguard Worker // attempts to use such types as function argument or return type, prefer
790*9880d681SAndroid Build Coastguard Worker // to error out instead of emitting code violating the ABI.
VerifyVectorType(MVT VT,EVT ArgVT)791*9880d681SAndroid Build Coastguard Worker static void VerifyVectorType(MVT VT, EVT ArgVT) {
792*9880d681SAndroid Build Coastguard Worker   if (ArgVT.isVector() && !VT.isVector())
793*9880d681SAndroid Build Coastguard Worker     report_fatal_error("Unsupported vector argument or return type");
794*9880d681SAndroid Build Coastguard Worker }
795*9880d681SAndroid Build Coastguard Worker 
VerifyVectorTypes(const SmallVectorImpl<ISD::InputArg> & Ins)796*9880d681SAndroid Build Coastguard Worker static void VerifyVectorTypes(const SmallVectorImpl<ISD::InputArg> &Ins) {
797*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0; i < Ins.size(); ++i)
798*9880d681SAndroid Build Coastguard Worker     VerifyVectorType(Ins[i].VT, Ins[i].ArgVT);
799*9880d681SAndroid Build Coastguard Worker }
800*9880d681SAndroid Build Coastguard Worker 
VerifyVectorTypes(const SmallVectorImpl<ISD::OutputArg> & Outs)801*9880d681SAndroid Build Coastguard Worker static void VerifyVectorTypes(const SmallVectorImpl<ISD::OutputArg> &Outs) {
802*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0; i < Outs.size(); ++i)
803*9880d681SAndroid Build Coastguard Worker     VerifyVectorType(Outs[i].VT, Outs[i].ArgVT);
804*9880d681SAndroid Build Coastguard Worker }
805*9880d681SAndroid Build Coastguard Worker 
806*9880d681SAndroid Build Coastguard Worker // Value is a value that has been passed to us in the location described by VA
807*9880d681SAndroid Build Coastguard Worker // (and so has type VA.getLocVT()).  Convert Value to VA.getValVT(), chaining
808*9880d681SAndroid Build Coastguard Worker // any loads onto Chain.
convertLocVTToValVT(SelectionDAG & DAG,const SDLoc & DL,CCValAssign & VA,SDValue Chain,SDValue Value)809*9880d681SAndroid Build Coastguard Worker static SDValue convertLocVTToValVT(SelectionDAG &DAG, const SDLoc &DL,
810*9880d681SAndroid Build Coastguard Worker                                    CCValAssign &VA, SDValue Chain,
811*9880d681SAndroid Build Coastguard Worker                                    SDValue Value) {
812*9880d681SAndroid Build Coastguard Worker   // If the argument has been promoted from a smaller type, insert an
813*9880d681SAndroid Build Coastguard Worker   // assertion to capture this.
814*9880d681SAndroid Build Coastguard Worker   if (VA.getLocInfo() == CCValAssign::SExt)
815*9880d681SAndroid Build Coastguard Worker     Value = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Value,
816*9880d681SAndroid Build Coastguard Worker                         DAG.getValueType(VA.getValVT()));
817*9880d681SAndroid Build Coastguard Worker   else if (VA.getLocInfo() == CCValAssign::ZExt)
818*9880d681SAndroid Build Coastguard Worker     Value = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Value,
819*9880d681SAndroid Build Coastguard Worker                         DAG.getValueType(VA.getValVT()));
820*9880d681SAndroid Build Coastguard Worker 
821*9880d681SAndroid Build Coastguard Worker   if (VA.isExtInLoc())
822*9880d681SAndroid Build Coastguard Worker     Value = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Value);
823*9880d681SAndroid Build Coastguard Worker   else if (VA.getLocInfo() == CCValAssign::BCvt) {
824*9880d681SAndroid Build Coastguard Worker     // If this is a short vector argument loaded from the stack,
825*9880d681SAndroid Build Coastguard Worker     // extend from i64 to full vector size and then bitcast.
826*9880d681SAndroid Build Coastguard Worker     assert(VA.getLocVT() == MVT::i64);
827*9880d681SAndroid Build Coastguard Worker     assert(VA.getValVT().isVector());
828*9880d681SAndroid Build Coastguard Worker     Value = DAG.getBuildVector(MVT::v2i64, DL, {Value, DAG.getUNDEF(MVT::i64)});
829*9880d681SAndroid Build Coastguard Worker     Value = DAG.getNode(ISD::BITCAST, DL, VA.getValVT(), Value);
830*9880d681SAndroid Build Coastguard Worker   } else
831*9880d681SAndroid Build Coastguard Worker     assert(VA.getLocInfo() == CCValAssign::Full && "Unsupported getLocInfo");
832*9880d681SAndroid Build Coastguard Worker   return Value;
833*9880d681SAndroid Build Coastguard Worker }
834*9880d681SAndroid Build Coastguard Worker 
835*9880d681SAndroid Build Coastguard Worker // Value is a value of type VA.getValVT() that we need to copy into
836*9880d681SAndroid Build Coastguard Worker // the location described by VA.  Return a copy of Value converted to
837*9880d681SAndroid Build Coastguard Worker // VA.getValVT().  The caller is responsible for handling indirect values.
convertValVTToLocVT(SelectionDAG & DAG,const SDLoc & DL,CCValAssign & VA,SDValue Value)838*9880d681SAndroid Build Coastguard Worker static SDValue convertValVTToLocVT(SelectionDAG &DAG, const SDLoc &DL,
839*9880d681SAndroid Build Coastguard Worker                                    CCValAssign &VA, SDValue Value) {
840*9880d681SAndroid Build Coastguard Worker   switch (VA.getLocInfo()) {
841*9880d681SAndroid Build Coastguard Worker   case CCValAssign::SExt:
842*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Value);
843*9880d681SAndroid Build Coastguard Worker   case CCValAssign::ZExt:
844*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Value);
845*9880d681SAndroid Build Coastguard Worker   case CCValAssign::AExt:
846*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Value);
847*9880d681SAndroid Build Coastguard Worker   case CCValAssign::BCvt:
848*9880d681SAndroid Build Coastguard Worker     // If this is a short vector argument to be stored to the stack,
849*9880d681SAndroid Build Coastguard Worker     // bitcast to v2i64 and then extract first element.
850*9880d681SAndroid Build Coastguard Worker     assert(VA.getLocVT() == MVT::i64);
851*9880d681SAndroid Build Coastguard Worker     assert(VA.getValVT().isVector());
852*9880d681SAndroid Build Coastguard Worker     Value = DAG.getNode(ISD::BITCAST, DL, MVT::v2i64, Value);
853*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VA.getLocVT(), Value,
854*9880d681SAndroid Build Coastguard Worker                        DAG.getConstant(0, DL, MVT::i32));
855*9880d681SAndroid Build Coastguard Worker   case CCValAssign::Full:
856*9880d681SAndroid Build Coastguard Worker     return Value;
857*9880d681SAndroid Build Coastguard Worker   default:
858*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Unhandled getLocInfo()");
859*9880d681SAndroid Build Coastguard Worker   }
860*9880d681SAndroid Build Coastguard Worker }
861*9880d681SAndroid Build Coastguard Worker 
LowerFormalArguments(SDValue Chain,CallingConv::ID CallConv,bool IsVarArg,const SmallVectorImpl<ISD::InputArg> & Ins,const SDLoc & DL,SelectionDAG & DAG,SmallVectorImpl<SDValue> & InVals) const862*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::LowerFormalArguments(
863*9880d681SAndroid Build Coastguard Worker     SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
864*9880d681SAndroid Build Coastguard Worker     const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
865*9880d681SAndroid Build Coastguard Worker     SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
866*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = DAG.getMachineFunction();
867*9880d681SAndroid Build Coastguard Worker   MachineFrameInfo *MFI = MF.getFrameInfo();
868*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo &MRI = MF.getRegInfo();
869*9880d681SAndroid Build Coastguard Worker   SystemZMachineFunctionInfo *FuncInfo =
870*9880d681SAndroid Build Coastguard Worker       MF.getInfo<SystemZMachineFunctionInfo>();
871*9880d681SAndroid Build Coastguard Worker   auto *TFL =
872*9880d681SAndroid Build Coastguard Worker       static_cast<const SystemZFrameLowering *>(Subtarget.getFrameLowering());
873*9880d681SAndroid Build Coastguard Worker   EVT PtrVT = getPointerTy(DAG.getDataLayout());
874*9880d681SAndroid Build Coastguard Worker 
875*9880d681SAndroid Build Coastguard Worker   // Detect unsupported vector argument types.
876*9880d681SAndroid Build Coastguard Worker   if (Subtarget.hasVector())
877*9880d681SAndroid Build Coastguard Worker     VerifyVectorTypes(Ins);
878*9880d681SAndroid Build Coastguard Worker 
879*9880d681SAndroid Build Coastguard Worker   // Assign locations to all of the incoming arguments.
880*9880d681SAndroid Build Coastguard Worker   SmallVector<CCValAssign, 16> ArgLocs;
881*9880d681SAndroid Build Coastguard Worker   SystemZCCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
882*9880d681SAndroid Build Coastguard Worker   CCInfo.AnalyzeFormalArguments(Ins, CC_SystemZ);
883*9880d681SAndroid Build Coastguard Worker 
884*9880d681SAndroid Build Coastguard Worker   unsigned NumFixedGPRs = 0;
885*9880d681SAndroid Build Coastguard Worker   unsigned NumFixedFPRs = 0;
886*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) {
887*9880d681SAndroid Build Coastguard Worker     SDValue ArgValue;
888*9880d681SAndroid Build Coastguard Worker     CCValAssign &VA = ArgLocs[I];
889*9880d681SAndroid Build Coastguard Worker     EVT LocVT = VA.getLocVT();
890*9880d681SAndroid Build Coastguard Worker     if (VA.isRegLoc()) {
891*9880d681SAndroid Build Coastguard Worker       // Arguments passed in registers
892*9880d681SAndroid Build Coastguard Worker       const TargetRegisterClass *RC;
893*9880d681SAndroid Build Coastguard Worker       switch (LocVT.getSimpleVT().SimpleTy) {
894*9880d681SAndroid Build Coastguard Worker       default:
895*9880d681SAndroid Build Coastguard Worker         // Integers smaller than i64 should be promoted to i64.
896*9880d681SAndroid Build Coastguard Worker         llvm_unreachable("Unexpected argument type");
897*9880d681SAndroid Build Coastguard Worker       case MVT::i32:
898*9880d681SAndroid Build Coastguard Worker         NumFixedGPRs += 1;
899*9880d681SAndroid Build Coastguard Worker         RC = &SystemZ::GR32BitRegClass;
900*9880d681SAndroid Build Coastguard Worker         break;
901*9880d681SAndroid Build Coastguard Worker       case MVT::i64:
902*9880d681SAndroid Build Coastguard Worker         NumFixedGPRs += 1;
903*9880d681SAndroid Build Coastguard Worker         RC = &SystemZ::GR64BitRegClass;
904*9880d681SAndroid Build Coastguard Worker         break;
905*9880d681SAndroid Build Coastguard Worker       case MVT::f32:
906*9880d681SAndroid Build Coastguard Worker         NumFixedFPRs += 1;
907*9880d681SAndroid Build Coastguard Worker         RC = &SystemZ::FP32BitRegClass;
908*9880d681SAndroid Build Coastguard Worker         break;
909*9880d681SAndroid Build Coastguard Worker       case MVT::f64:
910*9880d681SAndroid Build Coastguard Worker         NumFixedFPRs += 1;
911*9880d681SAndroid Build Coastguard Worker         RC = &SystemZ::FP64BitRegClass;
912*9880d681SAndroid Build Coastguard Worker         break;
913*9880d681SAndroid Build Coastguard Worker       case MVT::v16i8:
914*9880d681SAndroid Build Coastguard Worker       case MVT::v8i16:
915*9880d681SAndroid Build Coastguard Worker       case MVT::v4i32:
916*9880d681SAndroid Build Coastguard Worker       case MVT::v2i64:
917*9880d681SAndroid Build Coastguard Worker       case MVT::v4f32:
918*9880d681SAndroid Build Coastguard Worker       case MVT::v2f64:
919*9880d681SAndroid Build Coastguard Worker         RC = &SystemZ::VR128BitRegClass;
920*9880d681SAndroid Build Coastguard Worker         break;
921*9880d681SAndroid Build Coastguard Worker       }
922*9880d681SAndroid Build Coastguard Worker 
923*9880d681SAndroid Build Coastguard Worker       unsigned VReg = MRI.createVirtualRegister(RC);
924*9880d681SAndroid Build Coastguard Worker       MRI.addLiveIn(VA.getLocReg(), VReg);
925*9880d681SAndroid Build Coastguard Worker       ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, LocVT);
926*9880d681SAndroid Build Coastguard Worker     } else {
927*9880d681SAndroid Build Coastguard Worker       assert(VA.isMemLoc() && "Argument not register or memory");
928*9880d681SAndroid Build Coastguard Worker 
929*9880d681SAndroid Build Coastguard Worker       // Create the frame index object for this incoming parameter.
930*9880d681SAndroid Build Coastguard Worker       int FI = MFI->CreateFixedObject(LocVT.getSizeInBits() / 8,
931*9880d681SAndroid Build Coastguard Worker                                       VA.getLocMemOffset(), true);
932*9880d681SAndroid Build Coastguard Worker 
933*9880d681SAndroid Build Coastguard Worker       // Create the SelectionDAG nodes corresponding to a load
934*9880d681SAndroid Build Coastguard Worker       // from this parameter.  Unpromoted ints and floats are
935*9880d681SAndroid Build Coastguard Worker       // passed as right-justified 8-byte values.
936*9880d681SAndroid Build Coastguard Worker       SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
937*9880d681SAndroid Build Coastguard Worker       if (VA.getLocVT() == MVT::i32 || VA.getLocVT() == MVT::f32)
938*9880d681SAndroid Build Coastguard Worker         FIN = DAG.getNode(ISD::ADD, DL, PtrVT, FIN,
939*9880d681SAndroid Build Coastguard Worker                           DAG.getIntPtrConstant(4, DL));
940*9880d681SAndroid Build Coastguard Worker       ArgValue = DAG.getLoad(LocVT, DL, Chain, FIN,
941*9880d681SAndroid Build Coastguard Worker                              MachinePointerInfo::getFixedStack(MF, FI), false,
942*9880d681SAndroid Build Coastguard Worker                              false, false, 0);
943*9880d681SAndroid Build Coastguard Worker     }
944*9880d681SAndroid Build Coastguard Worker 
945*9880d681SAndroid Build Coastguard Worker     // Convert the value of the argument register into the value that's
946*9880d681SAndroid Build Coastguard Worker     // being passed.
947*9880d681SAndroid Build Coastguard Worker     if (VA.getLocInfo() == CCValAssign::Indirect) {
948*9880d681SAndroid Build Coastguard Worker       InVals.push_back(DAG.getLoad(VA.getValVT(), DL, Chain,
949*9880d681SAndroid Build Coastguard Worker                                    ArgValue, MachinePointerInfo(),
950*9880d681SAndroid Build Coastguard Worker                                    false, false, false, 0));
951*9880d681SAndroid Build Coastguard Worker       // If the original argument was split (e.g. i128), we need
952*9880d681SAndroid Build Coastguard Worker       // to load all parts of it here (using the same address).
953*9880d681SAndroid Build Coastguard Worker       unsigned ArgIndex = Ins[I].OrigArgIndex;
954*9880d681SAndroid Build Coastguard Worker       assert (Ins[I].PartOffset == 0);
955*9880d681SAndroid Build Coastguard Worker       while (I + 1 != E && Ins[I + 1].OrigArgIndex == ArgIndex) {
956*9880d681SAndroid Build Coastguard Worker         CCValAssign &PartVA = ArgLocs[I + 1];
957*9880d681SAndroid Build Coastguard Worker         unsigned PartOffset = Ins[I + 1].PartOffset;
958*9880d681SAndroid Build Coastguard Worker         SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, ArgValue,
959*9880d681SAndroid Build Coastguard Worker                                       DAG.getIntPtrConstant(PartOffset, DL));
960*9880d681SAndroid Build Coastguard Worker         InVals.push_back(DAG.getLoad(PartVA.getValVT(), DL, Chain,
961*9880d681SAndroid Build Coastguard Worker                                      Address, MachinePointerInfo(),
962*9880d681SAndroid Build Coastguard Worker                                      false, false, false, 0));
963*9880d681SAndroid Build Coastguard Worker         ++I;
964*9880d681SAndroid Build Coastguard Worker       }
965*9880d681SAndroid Build Coastguard Worker     } else
966*9880d681SAndroid Build Coastguard Worker       InVals.push_back(convertLocVTToValVT(DAG, DL, VA, Chain, ArgValue));
967*9880d681SAndroid Build Coastguard Worker   }
968*9880d681SAndroid Build Coastguard Worker 
969*9880d681SAndroid Build Coastguard Worker   if (IsVarArg) {
970*9880d681SAndroid Build Coastguard Worker     // Save the number of non-varargs registers for later use by va_start, etc.
971*9880d681SAndroid Build Coastguard Worker     FuncInfo->setVarArgsFirstGPR(NumFixedGPRs);
972*9880d681SAndroid Build Coastguard Worker     FuncInfo->setVarArgsFirstFPR(NumFixedFPRs);
973*9880d681SAndroid Build Coastguard Worker 
974*9880d681SAndroid Build Coastguard Worker     // Likewise the address (in the form of a frame index) of where the
975*9880d681SAndroid Build Coastguard Worker     // first stack vararg would be.  The 1-byte size here is arbitrary.
976*9880d681SAndroid Build Coastguard Worker     int64_t StackSize = CCInfo.getNextStackOffset();
977*9880d681SAndroid Build Coastguard Worker     FuncInfo->setVarArgsFrameIndex(MFI->CreateFixedObject(1, StackSize, true));
978*9880d681SAndroid Build Coastguard Worker 
979*9880d681SAndroid Build Coastguard Worker     // ...and a similar frame index for the caller-allocated save area
980*9880d681SAndroid Build Coastguard Worker     // that will be used to store the incoming registers.
981*9880d681SAndroid Build Coastguard Worker     int64_t RegSaveOffset = TFL->getOffsetOfLocalArea();
982*9880d681SAndroid Build Coastguard Worker     unsigned RegSaveIndex = MFI->CreateFixedObject(1, RegSaveOffset, true);
983*9880d681SAndroid Build Coastguard Worker     FuncInfo->setRegSaveFrameIndex(RegSaveIndex);
984*9880d681SAndroid Build Coastguard Worker 
985*9880d681SAndroid Build Coastguard Worker     // Store the FPR varargs in the reserved frame slots.  (We store the
986*9880d681SAndroid Build Coastguard Worker     // GPRs as part of the prologue.)
987*9880d681SAndroid Build Coastguard Worker     if (NumFixedFPRs < SystemZ::NumArgFPRs) {
988*9880d681SAndroid Build Coastguard Worker       SDValue MemOps[SystemZ::NumArgFPRs];
989*9880d681SAndroid Build Coastguard Worker       for (unsigned I = NumFixedFPRs; I < SystemZ::NumArgFPRs; ++I) {
990*9880d681SAndroid Build Coastguard Worker         unsigned Offset = TFL->getRegSpillOffset(SystemZ::ArgFPRs[I]);
991*9880d681SAndroid Build Coastguard Worker         int FI = MFI->CreateFixedObject(8, RegSaveOffset + Offset, true);
992*9880d681SAndroid Build Coastguard Worker         SDValue FIN = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
993*9880d681SAndroid Build Coastguard Worker         unsigned VReg = MF.addLiveIn(SystemZ::ArgFPRs[I],
994*9880d681SAndroid Build Coastguard Worker                                      &SystemZ::FP64BitRegClass);
995*9880d681SAndroid Build Coastguard Worker         SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, MVT::f64);
996*9880d681SAndroid Build Coastguard Worker         MemOps[I] = DAG.getStore(ArgValue.getValue(1), DL, ArgValue, FIN,
997*9880d681SAndroid Build Coastguard Worker                                  MachinePointerInfo::getFixedStack(MF, FI),
998*9880d681SAndroid Build Coastguard Worker                                  false, false, 0);
999*9880d681SAndroid Build Coastguard Worker       }
1000*9880d681SAndroid Build Coastguard Worker       // Join the stores, which are independent of one another.
1001*9880d681SAndroid Build Coastguard Worker       Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
1002*9880d681SAndroid Build Coastguard Worker                           makeArrayRef(&MemOps[NumFixedFPRs],
1003*9880d681SAndroid Build Coastguard Worker                                        SystemZ::NumArgFPRs-NumFixedFPRs));
1004*9880d681SAndroid Build Coastguard Worker     }
1005*9880d681SAndroid Build Coastguard Worker   }
1006*9880d681SAndroid Build Coastguard Worker 
1007*9880d681SAndroid Build Coastguard Worker   return Chain;
1008*9880d681SAndroid Build Coastguard Worker }
1009*9880d681SAndroid Build Coastguard Worker 
canUseSiblingCall(const CCState & ArgCCInfo,SmallVectorImpl<CCValAssign> & ArgLocs,SmallVectorImpl<ISD::OutputArg> & Outs)1010*9880d681SAndroid Build Coastguard Worker static bool canUseSiblingCall(const CCState &ArgCCInfo,
1011*9880d681SAndroid Build Coastguard Worker                               SmallVectorImpl<CCValAssign> &ArgLocs,
1012*9880d681SAndroid Build Coastguard Worker                               SmallVectorImpl<ISD::OutputArg> &Outs) {
1013*9880d681SAndroid Build Coastguard Worker   // Punt if there are any indirect or stack arguments, or if the call
1014*9880d681SAndroid Build Coastguard Worker   // needs the callee-saved argument register R6, or if the call uses
1015*9880d681SAndroid Build Coastguard Worker   // the callee-saved register arguments SwiftSelf and SwiftError.
1016*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) {
1017*9880d681SAndroid Build Coastguard Worker     CCValAssign &VA = ArgLocs[I];
1018*9880d681SAndroid Build Coastguard Worker     if (VA.getLocInfo() == CCValAssign::Indirect)
1019*9880d681SAndroid Build Coastguard Worker       return false;
1020*9880d681SAndroid Build Coastguard Worker     if (!VA.isRegLoc())
1021*9880d681SAndroid Build Coastguard Worker       return false;
1022*9880d681SAndroid Build Coastguard Worker     unsigned Reg = VA.getLocReg();
1023*9880d681SAndroid Build Coastguard Worker     if (Reg == SystemZ::R6H || Reg == SystemZ::R6L || Reg == SystemZ::R6D)
1024*9880d681SAndroid Build Coastguard Worker       return false;
1025*9880d681SAndroid Build Coastguard Worker     if (Outs[I].Flags.isSwiftSelf() || Outs[I].Flags.isSwiftError())
1026*9880d681SAndroid Build Coastguard Worker       return false;
1027*9880d681SAndroid Build Coastguard Worker   }
1028*9880d681SAndroid Build Coastguard Worker   return true;
1029*9880d681SAndroid Build Coastguard Worker }
1030*9880d681SAndroid Build Coastguard Worker 
1031*9880d681SAndroid Build Coastguard Worker SDValue
LowerCall(CallLoweringInfo & CLI,SmallVectorImpl<SDValue> & InVals) const1032*9880d681SAndroid Build Coastguard Worker SystemZTargetLowering::LowerCall(CallLoweringInfo &CLI,
1033*9880d681SAndroid Build Coastguard Worker                                  SmallVectorImpl<SDValue> &InVals) const {
1034*9880d681SAndroid Build Coastguard Worker   SelectionDAG &DAG = CLI.DAG;
1035*9880d681SAndroid Build Coastguard Worker   SDLoc &DL = CLI.DL;
1036*9880d681SAndroid Build Coastguard Worker   SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
1037*9880d681SAndroid Build Coastguard Worker   SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
1038*9880d681SAndroid Build Coastguard Worker   SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
1039*9880d681SAndroid Build Coastguard Worker   SDValue Chain = CLI.Chain;
1040*9880d681SAndroid Build Coastguard Worker   SDValue Callee = CLI.Callee;
1041*9880d681SAndroid Build Coastguard Worker   bool &IsTailCall = CLI.IsTailCall;
1042*9880d681SAndroid Build Coastguard Worker   CallingConv::ID CallConv = CLI.CallConv;
1043*9880d681SAndroid Build Coastguard Worker   bool IsVarArg = CLI.IsVarArg;
1044*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = DAG.getMachineFunction();
1045*9880d681SAndroid Build Coastguard Worker   EVT PtrVT = getPointerTy(MF.getDataLayout());
1046*9880d681SAndroid Build Coastguard Worker 
1047*9880d681SAndroid Build Coastguard Worker   // Detect unsupported vector argument and return types.
1048*9880d681SAndroid Build Coastguard Worker   if (Subtarget.hasVector()) {
1049*9880d681SAndroid Build Coastguard Worker     VerifyVectorTypes(Outs);
1050*9880d681SAndroid Build Coastguard Worker     VerifyVectorTypes(Ins);
1051*9880d681SAndroid Build Coastguard Worker   }
1052*9880d681SAndroid Build Coastguard Worker 
1053*9880d681SAndroid Build Coastguard Worker   // Analyze the operands of the call, assigning locations to each operand.
1054*9880d681SAndroid Build Coastguard Worker   SmallVector<CCValAssign, 16> ArgLocs;
1055*9880d681SAndroid Build Coastguard Worker   SystemZCCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
1056*9880d681SAndroid Build Coastguard Worker   ArgCCInfo.AnalyzeCallOperands(Outs, CC_SystemZ);
1057*9880d681SAndroid Build Coastguard Worker 
1058*9880d681SAndroid Build Coastguard Worker   // We don't support GuaranteedTailCallOpt, only automatically-detected
1059*9880d681SAndroid Build Coastguard Worker   // sibling calls.
1060*9880d681SAndroid Build Coastguard Worker   if (IsTailCall && !canUseSiblingCall(ArgCCInfo, ArgLocs, Outs))
1061*9880d681SAndroid Build Coastguard Worker     IsTailCall = false;
1062*9880d681SAndroid Build Coastguard Worker 
1063*9880d681SAndroid Build Coastguard Worker   // Get a count of how many bytes are to be pushed on the stack.
1064*9880d681SAndroid Build Coastguard Worker   unsigned NumBytes = ArgCCInfo.getNextStackOffset();
1065*9880d681SAndroid Build Coastguard Worker 
1066*9880d681SAndroid Build Coastguard Worker   // Mark the start of the call.
1067*9880d681SAndroid Build Coastguard Worker   if (!IsTailCall)
1068*9880d681SAndroid Build Coastguard Worker     Chain = DAG.getCALLSEQ_START(Chain,
1069*9880d681SAndroid Build Coastguard Worker                                  DAG.getConstant(NumBytes, DL, PtrVT, true),
1070*9880d681SAndroid Build Coastguard Worker                                  DL);
1071*9880d681SAndroid Build Coastguard Worker 
1072*9880d681SAndroid Build Coastguard Worker   // Copy argument values to their designated locations.
1073*9880d681SAndroid Build Coastguard Worker   SmallVector<std::pair<unsigned, SDValue>, 9> RegsToPass;
1074*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, 8> MemOpChains;
1075*9880d681SAndroid Build Coastguard Worker   SDValue StackPtr;
1076*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) {
1077*9880d681SAndroid Build Coastguard Worker     CCValAssign &VA = ArgLocs[I];
1078*9880d681SAndroid Build Coastguard Worker     SDValue ArgValue = OutVals[I];
1079*9880d681SAndroid Build Coastguard Worker 
1080*9880d681SAndroid Build Coastguard Worker     if (VA.getLocInfo() == CCValAssign::Indirect) {
1081*9880d681SAndroid Build Coastguard Worker       // Store the argument in a stack slot and pass its address.
1082*9880d681SAndroid Build Coastguard Worker       SDValue SpillSlot = DAG.CreateStackTemporary(Outs[I].ArgVT);
1083*9880d681SAndroid Build Coastguard Worker       int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
1084*9880d681SAndroid Build Coastguard Worker       MemOpChains.push_back(DAG.getStore(
1085*9880d681SAndroid Build Coastguard Worker           Chain, DL, ArgValue, SpillSlot,
1086*9880d681SAndroid Build Coastguard Worker           MachinePointerInfo::getFixedStack(MF, FI), false, false, 0));
1087*9880d681SAndroid Build Coastguard Worker       // If the original argument was split (e.g. i128), we need
1088*9880d681SAndroid Build Coastguard Worker       // to store all parts of it here (and pass just one address).
1089*9880d681SAndroid Build Coastguard Worker       unsigned ArgIndex = Outs[I].OrigArgIndex;
1090*9880d681SAndroid Build Coastguard Worker       assert (Outs[I].PartOffset == 0);
1091*9880d681SAndroid Build Coastguard Worker       while (I + 1 != E && Outs[I + 1].OrigArgIndex == ArgIndex) {
1092*9880d681SAndroid Build Coastguard Worker         SDValue PartValue = OutVals[I + 1];
1093*9880d681SAndroid Build Coastguard Worker         unsigned PartOffset = Outs[I + 1].PartOffset;
1094*9880d681SAndroid Build Coastguard Worker         SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, SpillSlot,
1095*9880d681SAndroid Build Coastguard Worker                                       DAG.getIntPtrConstant(PartOffset, DL));
1096*9880d681SAndroid Build Coastguard Worker         MemOpChains.push_back(DAG.getStore(
1097*9880d681SAndroid Build Coastguard Worker             Chain, DL, PartValue, Address,
1098*9880d681SAndroid Build Coastguard Worker             MachinePointerInfo::getFixedStack(MF, FI), false, false, 0));
1099*9880d681SAndroid Build Coastguard Worker         ++I;
1100*9880d681SAndroid Build Coastguard Worker       }
1101*9880d681SAndroid Build Coastguard Worker       ArgValue = SpillSlot;
1102*9880d681SAndroid Build Coastguard Worker     } else
1103*9880d681SAndroid Build Coastguard Worker       ArgValue = convertValVTToLocVT(DAG, DL, VA, ArgValue);
1104*9880d681SAndroid Build Coastguard Worker 
1105*9880d681SAndroid Build Coastguard Worker     if (VA.isRegLoc())
1106*9880d681SAndroid Build Coastguard Worker       // Queue up the argument copies and emit them at the end.
1107*9880d681SAndroid Build Coastguard Worker       RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue));
1108*9880d681SAndroid Build Coastguard Worker     else {
1109*9880d681SAndroid Build Coastguard Worker       assert(VA.isMemLoc() && "Argument not register or memory");
1110*9880d681SAndroid Build Coastguard Worker 
1111*9880d681SAndroid Build Coastguard Worker       // Work out the address of the stack slot.  Unpromoted ints and
1112*9880d681SAndroid Build Coastguard Worker       // floats are passed as right-justified 8-byte values.
1113*9880d681SAndroid Build Coastguard Worker       if (!StackPtr.getNode())
1114*9880d681SAndroid Build Coastguard Worker         StackPtr = DAG.getCopyFromReg(Chain, DL, SystemZ::R15D, PtrVT);
1115*9880d681SAndroid Build Coastguard Worker       unsigned Offset = SystemZMC::CallFrameSize + VA.getLocMemOffset();
1116*9880d681SAndroid Build Coastguard Worker       if (VA.getLocVT() == MVT::i32 || VA.getLocVT() == MVT::f32)
1117*9880d681SAndroid Build Coastguard Worker         Offset += 4;
1118*9880d681SAndroid Build Coastguard Worker       SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
1119*9880d681SAndroid Build Coastguard Worker                                     DAG.getIntPtrConstant(Offset, DL));
1120*9880d681SAndroid Build Coastguard Worker 
1121*9880d681SAndroid Build Coastguard Worker       // Emit the store.
1122*9880d681SAndroid Build Coastguard Worker       MemOpChains.push_back(DAG.getStore(Chain, DL, ArgValue, Address,
1123*9880d681SAndroid Build Coastguard Worker                                          MachinePointerInfo(),
1124*9880d681SAndroid Build Coastguard Worker                                          false, false, 0));
1125*9880d681SAndroid Build Coastguard Worker     }
1126*9880d681SAndroid Build Coastguard Worker   }
1127*9880d681SAndroid Build Coastguard Worker 
1128*9880d681SAndroid Build Coastguard Worker   // Join the stores, which are independent of one another.
1129*9880d681SAndroid Build Coastguard Worker   if (!MemOpChains.empty())
1130*9880d681SAndroid Build Coastguard Worker     Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
1131*9880d681SAndroid Build Coastguard Worker 
1132*9880d681SAndroid Build Coastguard Worker   // Accept direct calls by converting symbolic call addresses to the
1133*9880d681SAndroid Build Coastguard Worker   // associated Target* opcodes.  Force %r1 to be used for indirect
1134*9880d681SAndroid Build Coastguard Worker   // tail calls.
1135*9880d681SAndroid Build Coastguard Worker   SDValue Glue;
1136*9880d681SAndroid Build Coastguard Worker   if (auto *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
1137*9880d681SAndroid Build Coastguard Worker     Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, PtrVT);
1138*9880d681SAndroid Build Coastguard Worker     Callee = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Callee);
1139*9880d681SAndroid Build Coastguard Worker   } else if (auto *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
1140*9880d681SAndroid Build Coastguard Worker     Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT);
1141*9880d681SAndroid Build Coastguard Worker     Callee = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Callee);
1142*9880d681SAndroid Build Coastguard Worker   } else if (IsTailCall) {
1143*9880d681SAndroid Build Coastguard Worker     Chain = DAG.getCopyToReg(Chain, DL, SystemZ::R1D, Callee, Glue);
1144*9880d681SAndroid Build Coastguard Worker     Glue = Chain.getValue(1);
1145*9880d681SAndroid Build Coastguard Worker     Callee = DAG.getRegister(SystemZ::R1D, Callee.getValueType());
1146*9880d681SAndroid Build Coastguard Worker   }
1147*9880d681SAndroid Build Coastguard Worker 
1148*9880d681SAndroid Build Coastguard Worker   // Build a sequence of copy-to-reg nodes, chained and glued together.
1149*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) {
1150*9880d681SAndroid Build Coastguard Worker     Chain = DAG.getCopyToReg(Chain, DL, RegsToPass[I].first,
1151*9880d681SAndroid Build Coastguard Worker                              RegsToPass[I].second, Glue);
1152*9880d681SAndroid Build Coastguard Worker     Glue = Chain.getValue(1);
1153*9880d681SAndroid Build Coastguard Worker   }
1154*9880d681SAndroid Build Coastguard Worker 
1155*9880d681SAndroid Build Coastguard Worker   // The first call operand is the chain and the second is the target address.
1156*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, 8> Ops;
1157*9880d681SAndroid Build Coastguard Worker   Ops.push_back(Chain);
1158*9880d681SAndroid Build Coastguard Worker   Ops.push_back(Callee);
1159*9880d681SAndroid Build Coastguard Worker 
1160*9880d681SAndroid Build Coastguard Worker   // Add argument registers to the end of the list so that they are
1161*9880d681SAndroid Build Coastguard Worker   // known live into the call.
1162*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I)
1163*9880d681SAndroid Build Coastguard Worker     Ops.push_back(DAG.getRegister(RegsToPass[I].first,
1164*9880d681SAndroid Build Coastguard Worker                                   RegsToPass[I].second.getValueType()));
1165*9880d681SAndroid Build Coastguard Worker 
1166*9880d681SAndroid Build Coastguard Worker   // Add a register mask operand representing the call-preserved registers.
1167*9880d681SAndroid Build Coastguard Worker   const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
1168*9880d681SAndroid Build Coastguard Worker   const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);
1169*9880d681SAndroid Build Coastguard Worker   assert(Mask && "Missing call preserved mask for calling convention");
1170*9880d681SAndroid Build Coastguard Worker   Ops.push_back(DAG.getRegisterMask(Mask));
1171*9880d681SAndroid Build Coastguard Worker 
1172*9880d681SAndroid Build Coastguard Worker   // Glue the call to the argument copies, if any.
1173*9880d681SAndroid Build Coastguard Worker   if (Glue.getNode())
1174*9880d681SAndroid Build Coastguard Worker     Ops.push_back(Glue);
1175*9880d681SAndroid Build Coastguard Worker 
1176*9880d681SAndroid Build Coastguard Worker   // Emit the call.
1177*9880d681SAndroid Build Coastguard Worker   SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
1178*9880d681SAndroid Build Coastguard Worker   if (IsTailCall)
1179*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(SystemZISD::SIBCALL, DL, NodeTys, Ops);
1180*9880d681SAndroid Build Coastguard Worker   Chain = DAG.getNode(SystemZISD::CALL, DL, NodeTys, Ops);
1181*9880d681SAndroid Build Coastguard Worker   Glue = Chain.getValue(1);
1182*9880d681SAndroid Build Coastguard Worker 
1183*9880d681SAndroid Build Coastguard Worker   // Mark the end of the call, which is glued to the call itself.
1184*9880d681SAndroid Build Coastguard Worker   Chain = DAG.getCALLSEQ_END(Chain,
1185*9880d681SAndroid Build Coastguard Worker                              DAG.getConstant(NumBytes, DL, PtrVT, true),
1186*9880d681SAndroid Build Coastguard Worker                              DAG.getConstant(0, DL, PtrVT, true),
1187*9880d681SAndroid Build Coastguard Worker                              Glue, DL);
1188*9880d681SAndroid Build Coastguard Worker   Glue = Chain.getValue(1);
1189*9880d681SAndroid Build Coastguard Worker 
1190*9880d681SAndroid Build Coastguard Worker   // Assign locations to each value returned by this call.
1191*9880d681SAndroid Build Coastguard Worker   SmallVector<CCValAssign, 16> RetLocs;
1192*9880d681SAndroid Build Coastguard Worker   CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext());
1193*9880d681SAndroid Build Coastguard Worker   RetCCInfo.AnalyzeCallResult(Ins, RetCC_SystemZ);
1194*9880d681SAndroid Build Coastguard Worker 
1195*9880d681SAndroid Build Coastguard Worker   // Copy all of the result registers out of their specified physreg.
1196*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) {
1197*9880d681SAndroid Build Coastguard Worker     CCValAssign &VA = RetLocs[I];
1198*9880d681SAndroid Build Coastguard Worker 
1199*9880d681SAndroid Build Coastguard Worker     // Copy the value out, gluing the copy to the end of the call sequence.
1200*9880d681SAndroid Build Coastguard Worker     SDValue RetValue = DAG.getCopyFromReg(Chain, DL, VA.getLocReg(),
1201*9880d681SAndroid Build Coastguard Worker                                           VA.getLocVT(), Glue);
1202*9880d681SAndroid Build Coastguard Worker     Chain = RetValue.getValue(1);
1203*9880d681SAndroid Build Coastguard Worker     Glue = RetValue.getValue(2);
1204*9880d681SAndroid Build Coastguard Worker 
1205*9880d681SAndroid Build Coastguard Worker     // Convert the value of the return register into the value that's
1206*9880d681SAndroid Build Coastguard Worker     // being returned.
1207*9880d681SAndroid Build Coastguard Worker     InVals.push_back(convertLocVTToValVT(DAG, DL, VA, Chain, RetValue));
1208*9880d681SAndroid Build Coastguard Worker   }
1209*9880d681SAndroid Build Coastguard Worker 
1210*9880d681SAndroid Build Coastguard Worker   return Chain;
1211*9880d681SAndroid Build Coastguard Worker }
1212*9880d681SAndroid Build Coastguard Worker 
1213*9880d681SAndroid Build Coastguard Worker bool SystemZTargetLowering::
CanLowerReturn(CallingConv::ID CallConv,MachineFunction & MF,bool isVarArg,const SmallVectorImpl<ISD::OutputArg> & Outs,LLVMContext & Context) const1214*9880d681SAndroid Build Coastguard Worker CanLowerReturn(CallingConv::ID CallConv,
1215*9880d681SAndroid Build Coastguard Worker                MachineFunction &MF, bool isVarArg,
1216*9880d681SAndroid Build Coastguard Worker                const SmallVectorImpl<ISD::OutputArg> &Outs,
1217*9880d681SAndroid Build Coastguard Worker                LLVMContext &Context) const {
1218*9880d681SAndroid Build Coastguard Worker   // Detect unsupported vector return types.
1219*9880d681SAndroid Build Coastguard Worker   if (Subtarget.hasVector())
1220*9880d681SAndroid Build Coastguard Worker     VerifyVectorTypes(Outs);
1221*9880d681SAndroid Build Coastguard Worker 
1222*9880d681SAndroid Build Coastguard Worker   // Special case that we cannot easily detect in RetCC_SystemZ since
1223*9880d681SAndroid Build Coastguard Worker   // i128 is not a legal type.
1224*9880d681SAndroid Build Coastguard Worker   for (auto &Out : Outs)
1225*9880d681SAndroid Build Coastguard Worker     if (Out.ArgVT == MVT::i128)
1226*9880d681SAndroid Build Coastguard Worker       return false;
1227*9880d681SAndroid Build Coastguard Worker 
1228*9880d681SAndroid Build Coastguard Worker   SmallVector<CCValAssign, 16> RetLocs;
1229*9880d681SAndroid Build Coastguard Worker   CCState RetCCInfo(CallConv, isVarArg, MF, RetLocs, Context);
1230*9880d681SAndroid Build Coastguard Worker   return RetCCInfo.CheckReturn(Outs, RetCC_SystemZ);
1231*9880d681SAndroid Build Coastguard Worker }
1232*9880d681SAndroid Build Coastguard Worker 
1233*9880d681SAndroid Build Coastguard Worker SDValue
LowerReturn(SDValue Chain,CallingConv::ID CallConv,bool IsVarArg,const SmallVectorImpl<ISD::OutputArg> & Outs,const SmallVectorImpl<SDValue> & OutVals,const SDLoc & DL,SelectionDAG & DAG) const1234*9880d681SAndroid Build Coastguard Worker SystemZTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
1235*9880d681SAndroid Build Coastguard Worker                                    bool IsVarArg,
1236*9880d681SAndroid Build Coastguard Worker                                    const SmallVectorImpl<ISD::OutputArg> &Outs,
1237*9880d681SAndroid Build Coastguard Worker                                    const SmallVectorImpl<SDValue> &OutVals,
1238*9880d681SAndroid Build Coastguard Worker                                    const SDLoc &DL, SelectionDAG &DAG) const {
1239*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = DAG.getMachineFunction();
1240*9880d681SAndroid Build Coastguard Worker 
1241*9880d681SAndroid Build Coastguard Worker   // Detect unsupported vector return types.
1242*9880d681SAndroid Build Coastguard Worker   if (Subtarget.hasVector())
1243*9880d681SAndroid Build Coastguard Worker     VerifyVectorTypes(Outs);
1244*9880d681SAndroid Build Coastguard Worker 
1245*9880d681SAndroid Build Coastguard Worker   // Assign locations to each returned value.
1246*9880d681SAndroid Build Coastguard Worker   SmallVector<CCValAssign, 16> RetLocs;
1247*9880d681SAndroid Build Coastguard Worker   CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext());
1248*9880d681SAndroid Build Coastguard Worker   RetCCInfo.AnalyzeReturn(Outs, RetCC_SystemZ);
1249*9880d681SAndroid Build Coastguard Worker 
1250*9880d681SAndroid Build Coastguard Worker   // Quick exit for void returns
1251*9880d681SAndroid Build Coastguard Worker   if (RetLocs.empty())
1252*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(SystemZISD::RET_FLAG, DL, MVT::Other, Chain);
1253*9880d681SAndroid Build Coastguard Worker 
1254*9880d681SAndroid Build Coastguard Worker   // Copy the result values into the output registers.
1255*9880d681SAndroid Build Coastguard Worker   SDValue Glue;
1256*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, 4> RetOps;
1257*9880d681SAndroid Build Coastguard Worker   RetOps.push_back(Chain);
1258*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) {
1259*9880d681SAndroid Build Coastguard Worker     CCValAssign &VA = RetLocs[I];
1260*9880d681SAndroid Build Coastguard Worker     SDValue RetValue = OutVals[I];
1261*9880d681SAndroid Build Coastguard Worker 
1262*9880d681SAndroid Build Coastguard Worker     // Make the return register live on exit.
1263*9880d681SAndroid Build Coastguard Worker     assert(VA.isRegLoc() && "Can only return in registers!");
1264*9880d681SAndroid Build Coastguard Worker 
1265*9880d681SAndroid Build Coastguard Worker     // Promote the value as required.
1266*9880d681SAndroid Build Coastguard Worker     RetValue = convertValVTToLocVT(DAG, DL, VA, RetValue);
1267*9880d681SAndroid Build Coastguard Worker 
1268*9880d681SAndroid Build Coastguard Worker     // Chain and glue the copies together.
1269*9880d681SAndroid Build Coastguard Worker     unsigned Reg = VA.getLocReg();
1270*9880d681SAndroid Build Coastguard Worker     Chain = DAG.getCopyToReg(Chain, DL, Reg, RetValue, Glue);
1271*9880d681SAndroid Build Coastguard Worker     Glue = Chain.getValue(1);
1272*9880d681SAndroid Build Coastguard Worker     RetOps.push_back(DAG.getRegister(Reg, VA.getLocVT()));
1273*9880d681SAndroid Build Coastguard Worker   }
1274*9880d681SAndroid Build Coastguard Worker 
1275*9880d681SAndroid Build Coastguard Worker   // Update chain and glue.
1276*9880d681SAndroid Build Coastguard Worker   RetOps[0] = Chain;
1277*9880d681SAndroid Build Coastguard Worker   if (Glue.getNode())
1278*9880d681SAndroid Build Coastguard Worker     RetOps.push_back(Glue);
1279*9880d681SAndroid Build Coastguard Worker 
1280*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(SystemZISD::RET_FLAG, DL, MVT::Other, RetOps);
1281*9880d681SAndroid Build Coastguard Worker }
1282*9880d681SAndroid Build Coastguard Worker 
prepareVolatileOrAtomicLoad(SDValue Chain,const SDLoc & DL,SelectionDAG & DAG) const1283*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::prepareVolatileOrAtomicLoad(
1284*9880d681SAndroid Build Coastguard Worker     SDValue Chain, const SDLoc &DL, SelectionDAG &DAG) const {
1285*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(SystemZISD::SERIALIZE, DL, MVT::Other, Chain);
1286*9880d681SAndroid Build Coastguard Worker }
1287*9880d681SAndroid Build Coastguard Worker 
1288*9880d681SAndroid Build Coastguard Worker // Return true if Op is an intrinsic node with chain that returns the CC value
1289*9880d681SAndroid Build Coastguard Worker // as its only (other) argument.  Provide the associated SystemZISD opcode and
1290*9880d681SAndroid Build Coastguard Worker // the mask of valid CC values if so.
isIntrinsicWithCCAndChain(SDValue Op,unsigned & Opcode,unsigned & CCValid)1291*9880d681SAndroid Build Coastguard Worker static bool isIntrinsicWithCCAndChain(SDValue Op, unsigned &Opcode,
1292*9880d681SAndroid Build Coastguard Worker                                       unsigned &CCValid) {
1293*9880d681SAndroid Build Coastguard Worker   unsigned Id = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
1294*9880d681SAndroid Build Coastguard Worker   switch (Id) {
1295*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_tbegin:
1296*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::TBEGIN;
1297*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_TBEGIN;
1298*9880d681SAndroid Build Coastguard Worker     return true;
1299*9880d681SAndroid Build Coastguard Worker 
1300*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_tbegin_nofloat:
1301*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::TBEGIN_NOFLOAT;
1302*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_TBEGIN;
1303*9880d681SAndroid Build Coastguard Worker     return true;
1304*9880d681SAndroid Build Coastguard Worker 
1305*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_tend:
1306*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::TEND;
1307*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_TEND;
1308*9880d681SAndroid Build Coastguard Worker     return true;
1309*9880d681SAndroid Build Coastguard Worker 
1310*9880d681SAndroid Build Coastguard Worker   default:
1311*9880d681SAndroid Build Coastguard Worker     return false;
1312*9880d681SAndroid Build Coastguard Worker   }
1313*9880d681SAndroid Build Coastguard Worker }
1314*9880d681SAndroid Build Coastguard Worker 
1315*9880d681SAndroid Build Coastguard Worker // Return true if Op is an intrinsic node without chain that returns the
1316*9880d681SAndroid Build Coastguard Worker // CC value as its final argument.  Provide the associated SystemZISD
1317*9880d681SAndroid Build Coastguard Worker // opcode and the mask of valid CC values if so.
isIntrinsicWithCC(SDValue Op,unsigned & Opcode,unsigned & CCValid)1318*9880d681SAndroid Build Coastguard Worker static bool isIntrinsicWithCC(SDValue Op, unsigned &Opcode, unsigned &CCValid) {
1319*9880d681SAndroid Build Coastguard Worker   unsigned Id = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
1320*9880d681SAndroid Build Coastguard Worker   switch (Id) {
1321*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vpkshs:
1322*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vpksfs:
1323*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vpksgs:
1324*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::PACKS_CC;
1325*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_VCMP;
1326*9880d681SAndroid Build Coastguard Worker     return true;
1327*9880d681SAndroid Build Coastguard Worker 
1328*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vpklshs:
1329*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vpklsfs:
1330*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vpklsgs:
1331*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::PACKLS_CC;
1332*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_VCMP;
1333*9880d681SAndroid Build Coastguard Worker     return true;
1334*9880d681SAndroid Build Coastguard Worker 
1335*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vceqbs:
1336*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vceqhs:
1337*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vceqfs:
1338*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vceqgs:
1339*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::VICMPES;
1340*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_VCMP;
1341*9880d681SAndroid Build Coastguard Worker     return true;
1342*9880d681SAndroid Build Coastguard Worker 
1343*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vchbs:
1344*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vchhs:
1345*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vchfs:
1346*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vchgs:
1347*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::VICMPHS;
1348*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_VCMP;
1349*9880d681SAndroid Build Coastguard Worker     return true;
1350*9880d681SAndroid Build Coastguard Worker 
1351*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vchlbs:
1352*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vchlhs:
1353*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vchlfs:
1354*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vchlgs:
1355*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::VICMPHLS;
1356*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_VCMP;
1357*9880d681SAndroid Build Coastguard Worker     return true;
1358*9880d681SAndroid Build Coastguard Worker 
1359*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vtm:
1360*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::VTM;
1361*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_VCMP;
1362*9880d681SAndroid Build Coastguard Worker     return true;
1363*9880d681SAndroid Build Coastguard Worker 
1364*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfaebs:
1365*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfaehs:
1366*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfaefs:
1367*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::VFAE_CC;
1368*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_ANY;
1369*9880d681SAndroid Build Coastguard Worker     return true;
1370*9880d681SAndroid Build Coastguard Worker 
1371*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfaezbs:
1372*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfaezhs:
1373*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfaezfs:
1374*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::VFAEZ_CC;
1375*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_ANY;
1376*9880d681SAndroid Build Coastguard Worker     return true;
1377*9880d681SAndroid Build Coastguard Worker 
1378*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfeebs:
1379*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfeehs:
1380*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfeefs:
1381*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::VFEE_CC;
1382*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_ANY;
1383*9880d681SAndroid Build Coastguard Worker     return true;
1384*9880d681SAndroid Build Coastguard Worker 
1385*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfeezbs:
1386*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfeezhs:
1387*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfeezfs:
1388*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::VFEEZ_CC;
1389*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_ANY;
1390*9880d681SAndroid Build Coastguard Worker     return true;
1391*9880d681SAndroid Build Coastguard Worker 
1392*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfenebs:
1393*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfenehs:
1394*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfenefs:
1395*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::VFENE_CC;
1396*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_ANY;
1397*9880d681SAndroid Build Coastguard Worker     return true;
1398*9880d681SAndroid Build Coastguard Worker 
1399*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfenezbs:
1400*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfenezhs:
1401*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfenezfs:
1402*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::VFENEZ_CC;
1403*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_ANY;
1404*9880d681SAndroid Build Coastguard Worker     return true;
1405*9880d681SAndroid Build Coastguard Worker 
1406*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vistrbs:
1407*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vistrhs:
1408*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vistrfs:
1409*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::VISTR_CC;
1410*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_0 | SystemZ::CCMASK_3;
1411*9880d681SAndroid Build Coastguard Worker     return true;
1412*9880d681SAndroid Build Coastguard Worker 
1413*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vstrcbs:
1414*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vstrchs:
1415*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vstrcfs:
1416*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::VSTRC_CC;
1417*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_ANY;
1418*9880d681SAndroid Build Coastguard Worker     return true;
1419*9880d681SAndroid Build Coastguard Worker 
1420*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vstrczbs:
1421*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vstrczhs:
1422*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vstrczfs:
1423*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::VSTRCZ_CC;
1424*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_ANY;
1425*9880d681SAndroid Build Coastguard Worker     return true;
1426*9880d681SAndroid Build Coastguard Worker 
1427*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfcedbs:
1428*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::VFCMPES;
1429*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_VCMP;
1430*9880d681SAndroid Build Coastguard Worker     return true;
1431*9880d681SAndroid Build Coastguard Worker 
1432*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfchdbs:
1433*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::VFCMPHS;
1434*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_VCMP;
1435*9880d681SAndroid Build Coastguard Worker     return true;
1436*9880d681SAndroid Build Coastguard Worker 
1437*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vfchedbs:
1438*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::VFCMPHES;
1439*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_VCMP;
1440*9880d681SAndroid Build Coastguard Worker     return true;
1441*9880d681SAndroid Build Coastguard Worker 
1442*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vftcidb:
1443*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::VFTCI;
1444*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_VCMP;
1445*9880d681SAndroid Build Coastguard Worker     return true;
1446*9880d681SAndroid Build Coastguard Worker 
1447*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_tdc:
1448*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::TDC;
1449*9880d681SAndroid Build Coastguard Worker     CCValid = SystemZ::CCMASK_TDC;
1450*9880d681SAndroid Build Coastguard Worker     return true;
1451*9880d681SAndroid Build Coastguard Worker 
1452*9880d681SAndroid Build Coastguard Worker   default:
1453*9880d681SAndroid Build Coastguard Worker     return false;
1454*9880d681SAndroid Build Coastguard Worker   }
1455*9880d681SAndroid Build Coastguard Worker }
1456*9880d681SAndroid Build Coastguard Worker 
1457*9880d681SAndroid Build Coastguard Worker // Emit an intrinsic with chain with a glued value instead of its CC result.
emitIntrinsicWithChainAndGlue(SelectionDAG & DAG,SDValue Op,unsigned Opcode)1458*9880d681SAndroid Build Coastguard Worker static SDValue emitIntrinsicWithChainAndGlue(SelectionDAG &DAG, SDValue Op,
1459*9880d681SAndroid Build Coastguard Worker                                              unsigned Opcode) {
1460*9880d681SAndroid Build Coastguard Worker   // Copy all operands except the intrinsic ID.
1461*9880d681SAndroid Build Coastguard Worker   unsigned NumOps = Op.getNumOperands();
1462*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, 6> Ops;
1463*9880d681SAndroid Build Coastguard Worker   Ops.reserve(NumOps - 1);
1464*9880d681SAndroid Build Coastguard Worker   Ops.push_back(Op.getOperand(0));
1465*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 2; I < NumOps; ++I)
1466*9880d681SAndroid Build Coastguard Worker     Ops.push_back(Op.getOperand(I));
1467*9880d681SAndroid Build Coastguard Worker 
1468*9880d681SAndroid Build Coastguard Worker   assert(Op->getNumValues() == 2 && "Expected only CC result and chain");
1469*9880d681SAndroid Build Coastguard Worker   SDVTList RawVTs = DAG.getVTList(MVT::Other, MVT::Glue);
1470*9880d681SAndroid Build Coastguard Worker   SDValue Intr = DAG.getNode(Opcode, SDLoc(Op), RawVTs, Ops);
1471*9880d681SAndroid Build Coastguard Worker   SDValue OldChain = SDValue(Op.getNode(), 1);
1472*9880d681SAndroid Build Coastguard Worker   SDValue NewChain = SDValue(Intr.getNode(), 0);
1473*9880d681SAndroid Build Coastguard Worker   DAG.ReplaceAllUsesOfValueWith(OldChain, NewChain);
1474*9880d681SAndroid Build Coastguard Worker   return Intr;
1475*9880d681SAndroid Build Coastguard Worker }
1476*9880d681SAndroid Build Coastguard Worker 
1477*9880d681SAndroid Build Coastguard Worker // Emit an intrinsic with a glued value instead of its CC result.
emitIntrinsicWithGlue(SelectionDAG & DAG,SDValue Op,unsigned Opcode)1478*9880d681SAndroid Build Coastguard Worker static SDValue emitIntrinsicWithGlue(SelectionDAG &DAG, SDValue Op,
1479*9880d681SAndroid Build Coastguard Worker                                      unsigned Opcode) {
1480*9880d681SAndroid Build Coastguard Worker   // Copy all operands except the intrinsic ID.
1481*9880d681SAndroid Build Coastguard Worker   unsigned NumOps = Op.getNumOperands();
1482*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, 6> Ops;
1483*9880d681SAndroid Build Coastguard Worker   Ops.reserve(NumOps - 1);
1484*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 1; I < NumOps; ++I)
1485*9880d681SAndroid Build Coastguard Worker     Ops.push_back(Op.getOperand(I));
1486*9880d681SAndroid Build Coastguard Worker 
1487*9880d681SAndroid Build Coastguard Worker   if (Op->getNumValues() == 1)
1488*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(Opcode, SDLoc(Op), MVT::Glue, Ops);
1489*9880d681SAndroid Build Coastguard Worker   assert(Op->getNumValues() == 2 && "Expected exactly one non-CC result");
1490*9880d681SAndroid Build Coastguard Worker   SDVTList RawVTs = DAG.getVTList(Op->getValueType(0), MVT::Glue);
1491*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(Opcode, SDLoc(Op), RawVTs, Ops);
1492*9880d681SAndroid Build Coastguard Worker }
1493*9880d681SAndroid Build Coastguard Worker 
1494*9880d681SAndroid Build Coastguard Worker // CC is a comparison that will be implemented using an integer or
1495*9880d681SAndroid Build Coastguard Worker // floating-point comparison.  Return the condition code mask for
1496*9880d681SAndroid Build Coastguard Worker // a branch on true.  In the integer case, CCMASK_CMP_UO is set for
1497*9880d681SAndroid Build Coastguard Worker // unsigned comparisons and clear for signed ones.  In the floating-point
1498*9880d681SAndroid Build Coastguard Worker // case, CCMASK_CMP_UO has its normal mask meaning (unordered).
CCMaskForCondCode(ISD::CondCode CC)1499*9880d681SAndroid Build Coastguard Worker static unsigned CCMaskForCondCode(ISD::CondCode CC) {
1500*9880d681SAndroid Build Coastguard Worker #define CONV(X) \
1501*9880d681SAndroid Build Coastguard Worker   case ISD::SET##X: return SystemZ::CCMASK_CMP_##X; \
1502*9880d681SAndroid Build Coastguard Worker   case ISD::SETO##X: return SystemZ::CCMASK_CMP_##X; \
1503*9880d681SAndroid Build Coastguard Worker   case ISD::SETU##X: return SystemZ::CCMASK_CMP_UO | SystemZ::CCMASK_CMP_##X
1504*9880d681SAndroid Build Coastguard Worker 
1505*9880d681SAndroid Build Coastguard Worker   switch (CC) {
1506*9880d681SAndroid Build Coastguard Worker   default:
1507*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Invalid integer condition!");
1508*9880d681SAndroid Build Coastguard Worker 
1509*9880d681SAndroid Build Coastguard Worker   CONV(EQ);
1510*9880d681SAndroid Build Coastguard Worker   CONV(NE);
1511*9880d681SAndroid Build Coastguard Worker   CONV(GT);
1512*9880d681SAndroid Build Coastguard Worker   CONV(GE);
1513*9880d681SAndroid Build Coastguard Worker   CONV(LT);
1514*9880d681SAndroid Build Coastguard Worker   CONV(LE);
1515*9880d681SAndroid Build Coastguard Worker 
1516*9880d681SAndroid Build Coastguard Worker   case ISD::SETO:  return SystemZ::CCMASK_CMP_O;
1517*9880d681SAndroid Build Coastguard Worker   case ISD::SETUO: return SystemZ::CCMASK_CMP_UO;
1518*9880d681SAndroid Build Coastguard Worker   }
1519*9880d681SAndroid Build Coastguard Worker #undef CONV
1520*9880d681SAndroid Build Coastguard Worker }
1521*9880d681SAndroid Build Coastguard Worker 
1522*9880d681SAndroid Build Coastguard Worker // Return a sequence for getting a 1 from an IPM result when CC has a
1523*9880d681SAndroid Build Coastguard Worker // value in CCMask and a 0 when CC has a value in CCValid & ~CCMask.
1524*9880d681SAndroid Build Coastguard Worker // The handling of CC values outside CCValid doesn't matter.
getIPMConversion(unsigned CCValid,unsigned CCMask)1525*9880d681SAndroid Build Coastguard Worker static IPMConversion getIPMConversion(unsigned CCValid, unsigned CCMask) {
1526*9880d681SAndroid Build Coastguard Worker   // Deal with cases where the result can be taken directly from a bit
1527*9880d681SAndroid Build Coastguard Worker   // of the IPM result.
1528*9880d681SAndroid Build Coastguard Worker   if (CCMask == (CCValid & (SystemZ::CCMASK_1 | SystemZ::CCMASK_3)))
1529*9880d681SAndroid Build Coastguard Worker     return IPMConversion(0, 0, SystemZ::IPM_CC);
1530*9880d681SAndroid Build Coastguard Worker   if (CCMask == (CCValid & (SystemZ::CCMASK_2 | SystemZ::CCMASK_3)))
1531*9880d681SAndroid Build Coastguard Worker     return IPMConversion(0, 0, SystemZ::IPM_CC + 1);
1532*9880d681SAndroid Build Coastguard Worker 
1533*9880d681SAndroid Build Coastguard Worker   // Deal with cases where we can add a value to force the sign bit
1534*9880d681SAndroid Build Coastguard Worker   // to contain the right value.  Putting the bit in 31 means we can
1535*9880d681SAndroid Build Coastguard Worker   // use SRL rather than RISBG(L), and also makes it easier to get a
1536*9880d681SAndroid Build Coastguard Worker   // 0/-1 value, so it has priority over the other tests below.
1537*9880d681SAndroid Build Coastguard Worker   //
1538*9880d681SAndroid Build Coastguard Worker   // These sequences rely on the fact that the upper two bits of the
1539*9880d681SAndroid Build Coastguard Worker   // IPM result are zero.
1540*9880d681SAndroid Build Coastguard Worker   uint64_t TopBit = uint64_t(1) << 31;
1541*9880d681SAndroid Build Coastguard Worker   if (CCMask == (CCValid & SystemZ::CCMASK_0))
1542*9880d681SAndroid Build Coastguard Worker     return IPMConversion(0, -(1 << SystemZ::IPM_CC), 31);
1543*9880d681SAndroid Build Coastguard Worker   if (CCMask == (CCValid & (SystemZ::CCMASK_0 | SystemZ::CCMASK_1)))
1544*9880d681SAndroid Build Coastguard Worker     return IPMConversion(0, -(2 << SystemZ::IPM_CC), 31);
1545*9880d681SAndroid Build Coastguard Worker   if (CCMask == (CCValid & (SystemZ::CCMASK_0
1546*9880d681SAndroid Build Coastguard Worker                             | SystemZ::CCMASK_1
1547*9880d681SAndroid Build Coastguard Worker                             | SystemZ::CCMASK_2)))
1548*9880d681SAndroid Build Coastguard Worker     return IPMConversion(0, -(3 << SystemZ::IPM_CC), 31);
1549*9880d681SAndroid Build Coastguard Worker   if (CCMask == (CCValid & SystemZ::CCMASK_3))
1550*9880d681SAndroid Build Coastguard Worker     return IPMConversion(0, TopBit - (3 << SystemZ::IPM_CC), 31);
1551*9880d681SAndroid Build Coastguard Worker   if (CCMask == (CCValid & (SystemZ::CCMASK_1
1552*9880d681SAndroid Build Coastguard Worker                             | SystemZ::CCMASK_2
1553*9880d681SAndroid Build Coastguard Worker                             | SystemZ::CCMASK_3)))
1554*9880d681SAndroid Build Coastguard Worker     return IPMConversion(0, TopBit - (1 << SystemZ::IPM_CC), 31);
1555*9880d681SAndroid Build Coastguard Worker 
1556*9880d681SAndroid Build Coastguard Worker   // Next try inverting the value and testing a bit.  0/1 could be
1557*9880d681SAndroid Build Coastguard Worker   // handled this way too, but we dealt with that case above.
1558*9880d681SAndroid Build Coastguard Worker   if (CCMask == (CCValid & (SystemZ::CCMASK_0 | SystemZ::CCMASK_2)))
1559*9880d681SAndroid Build Coastguard Worker     return IPMConversion(-1, 0, SystemZ::IPM_CC);
1560*9880d681SAndroid Build Coastguard Worker 
1561*9880d681SAndroid Build Coastguard Worker   // Handle cases where adding a value forces a non-sign bit to contain
1562*9880d681SAndroid Build Coastguard Worker   // the right value.
1563*9880d681SAndroid Build Coastguard Worker   if (CCMask == (CCValid & (SystemZ::CCMASK_1 | SystemZ::CCMASK_2)))
1564*9880d681SAndroid Build Coastguard Worker     return IPMConversion(0, 1 << SystemZ::IPM_CC, SystemZ::IPM_CC + 1);
1565*9880d681SAndroid Build Coastguard Worker   if (CCMask == (CCValid & (SystemZ::CCMASK_0 | SystemZ::CCMASK_3)))
1566*9880d681SAndroid Build Coastguard Worker     return IPMConversion(0, -(1 << SystemZ::IPM_CC), SystemZ::IPM_CC + 1);
1567*9880d681SAndroid Build Coastguard Worker 
1568*9880d681SAndroid Build Coastguard Worker   // The remaining cases are 1, 2, 0/1/3 and 0/2/3.  All these are
1569*9880d681SAndroid Build Coastguard Worker   // can be done by inverting the low CC bit and applying one of the
1570*9880d681SAndroid Build Coastguard Worker   // sign-based extractions above.
1571*9880d681SAndroid Build Coastguard Worker   if (CCMask == (CCValid & SystemZ::CCMASK_1))
1572*9880d681SAndroid Build Coastguard Worker     return IPMConversion(1 << SystemZ::IPM_CC, -(1 << SystemZ::IPM_CC), 31);
1573*9880d681SAndroid Build Coastguard Worker   if (CCMask == (CCValid & SystemZ::CCMASK_2))
1574*9880d681SAndroid Build Coastguard Worker     return IPMConversion(1 << SystemZ::IPM_CC,
1575*9880d681SAndroid Build Coastguard Worker                          TopBit - (3 << SystemZ::IPM_CC), 31);
1576*9880d681SAndroid Build Coastguard Worker   if (CCMask == (CCValid & (SystemZ::CCMASK_0
1577*9880d681SAndroid Build Coastguard Worker                             | SystemZ::CCMASK_1
1578*9880d681SAndroid Build Coastguard Worker                             | SystemZ::CCMASK_3)))
1579*9880d681SAndroid Build Coastguard Worker     return IPMConversion(1 << SystemZ::IPM_CC, -(3 << SystemZ::IPM_CC), 31);
1580*9880d681SAndroid Build Coastguard Worker   if (CCMask == (CCValid & (SystemZ::CCMASK_0
1581*9880d681SAndroid Build Coastguard Worker                             | SystemZ::CCMASK_2
1582*9880d681SAndroid Build Coastguard Worker                             | SystemZ::CCMASK_3)))
1583*9880d681SAndroid Build Coastguard Worker     return IPMConversion(1 << SystemZ::IPM_CC,
1584*9880d681SAndroid Build Coastguard Worker                          TopBit - (1 << SystemZ::IPM_CC), 31);
1585*9880d681SAndroid Build Coastguard Worker 
1586*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Unexpected CC combination");
1587*9880d681SAndroid Build Coastguard Worker }
1588*9880d681SAndroid Build Coastguard Worker 
1589*9880d681SAndroid Build Coastguard Worker // If C can be converted to a comparison against zero, adjust the operands
1590*9880d681SAndroid Build Coastguard Worker // as necessary.
adjustZeroCmp(SelectionDAG & DAG,const SDLoc & DL,Comparison & C)1591*9880d681SAndroid Build Coastguard Worker static void adjustZeroCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C) {
1592*9880d681SAndroid Build Coastguard Worker   if (C.ICmpType == SystemZICMP::UnsignedOnly)
1593*9880d681SAndroid Build Coastguard Worker     return;
1594*9880d681SAndroid Build Coastguard Worker 
1595*9880d681SAndroid Build Coastguard Worker   auto *ConstOp1 = dyn_cast<ConstantSDNode>(C.Op1.getNode());
1596*9880d681SAndroid Build Coastguard Worker   if (!ConstOp1)
1597*9880d681SAndroid Build Coastguard Worker     return;
1598*9880d681SAndroid Build Coastguard Worker 
1599*9880d681SAndroid Build Coastguard Worker   int64_t Value = ConstOp1->getSExtValue();
1600*9880d681SAndroid Build Coastguard Worker   if ((Value == -1 && C.CCMask == SystemZ::CCMASK_CMP_GT) ||
1601*9880d681SAndroid Build Coastguard Worker       (Value == -1 && C.CCMask == SystemZ::CCMASK_CMP_LE) ||
1602*9880d681SAndroid Build Coastguard Worker       (Value == 1 && C.CCMask == SystemZ::CCMASK_CMP_LT) ||
1603*9880d681SAndroid Build Coastguard Worker       (Value == 1 && C.CCMask == SystemZ::CCMASK_CMP_GE)) {
1604*9880d681SAndroid Build Coastguard Worker     C.CCMask ^= SystemZ::CCMASK_CMP_EQ;
1605*9880d681SAndroid Build Coastguard Worker     C.Op1 = DAG.getConstant(0, DL, C.Op1.getValueType());
1606*9880d681SAndroid Build Coastguard Worker   }
1607*9880d681SAndroid Build Coastguard Worker }
1608*9880d681SAndroid Build Coastguard Worker 
1609*9880d681SAndroid Build Coastguard Worker // If a comparison described by C is suitable for CLI(Y), CHHSI or CLHHSI,
1610*9880d681SAndroid Build Coastguard Worker // adjust the operands as necessary.
adjustSubwordCmp(SelectionDAG & DAG,const SDLoc & DL,Comparison & C)1611*9880d681SAndroid Build Coastguard Worker static void adjustSubwordCmp(SelectionDAG &DAG, const SDLoc &DL,
1612*9880d681SAndroid Build Coastguard Worker                              Comparison &C) {
1613*9880d681SAndroid Build Coastguard Worker   // For us to make any changes, it must a comparison between a single-use
1614*9880d681SAndroid Build Coastguard Worker   // load and a constant.
1615*9880d681SAndroid Build Coastguard Worker   if (!C.Op0.hasOneUse() ||
1616*9880d681SAndroid Build Coastguard Worker       C.Op0.getOpcode() != ISD::LOAD ||
1617*9880d681SAndroid Build Coastguard Worker       C.Op1.getOpcode() != ISD::Constant)
1618*9880d681SAndroid Build Coastguard Worker     return;
1619*9880d681SAndroid Build Coastguard Worker 
1620*9880d681SAndroid Build Coastguard Worker   // We must have an 8- or 16-bit load.
1621*9880d681SAndroid Build Coastguard Worker   auto *Load = cast<LoadSDNode>(C.Op0);
1622*9880d681SAndroid Build Coastguard Worker   unsigned NumBits = Load->getMemoryVT().getStoreSizeInBits();
1623*9880d681SAndroid Build Coastguard Worker   if (NumBits != 8 && NumBits != 16)
1624*9880d681SAndroid Build Coastguard Worker     return;
1625*9880d681SAndroid Build Coastguard Worker 
1626*9880d681SAndroid Build Coastguard Worker   // The load must be an extending one and the constant must be within the
1627*9880d681SAndroid Build Coastguard Worker   // range of the unextended value.
1628*9880d681SAndroid Build Coastguard Worker   auto *ConstOp1 = cast<ConstantSDNode>(C.Op1);
1629*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ConstOp1->getZExtValue();
1630*9880d681SAndroid Build Coastguard Worker   uint64_t Mask = (1 << NumBits) - 1;
1631*9880d681SAndroid Build Coastguard Worker   if (Load->getExtensionType() == ISD::SEXTLOAD) {
1632*9880d681SAndroid Build Coastguard Worker     // Make sure that ConstOp1 is in range of C.Op0.
1633*9880d681SAndroid Build Coastguard Worker     int64_t SignedValue = ConstOp1->getSExtValue();
1634*9880d681SAndroid Build Coastguard Worker     if (uint64_t(SignedValue) + (uint64_t(1) << (NumBits - 1)) > Mask)
1635*9880d681SAndroid Build Coastguard Worker       return;
1636*9880d681SAndroid Build Coastguard Worker     if (C.ICmpType != SystemZICMP::SignedOnly) {
1637*9880d681SAndroid Build Coastguard Worker       // Unsigned comparison between two sign-extended values is equivalent
1638*9880d681SAndroid Build Coastguard Worker       // to unsigned comparison between two zero-extended values.
1639*9880d681SAndroid Build Coastguard Worker       Value &= Mask;
1640*9880d681SAndroid Build Coastguard Worker     } else if (NumBits == 8) {
1641*9880d681SAndroid Build Coastguard Worker       // Try to treat the comparison as unsigned, so that we can use CLI.
1642*9880d681SAndroid Build Coastguard Worker       // Adjust CCMask and Value as necessary.
1643*9880d681SAndroid Build Coastguard Worker       if (Value == 0 && C.CCMask == SystemZ::CCMASK_CMP_LT)
1644*9880d681SAndroid Build Coastguard Worker         // Test whether the high bit of the byte is set.
1645*9880d681SAndroid Build Coastguard Worker         Value = 127, C.CCMask = SystemZ::CCMASK_CMP_GT;
1646*9880d681SAndroid Build Coastguard Worker       else if (Value == 0 && C.CCMask == SystemZ::CCMASK_CMP_GE)
1647*9880d681SAndroid Build Coastguard Worker         // Test whether the high bit of the byte is clear.
1648*9880d681SAndroid Build Coastguard Worker         Value = 128, C.CCMask = SystemZ::CCMASK_CMP_LT;
1649*9880d681SAndroid Build Coastguard Worker       else
1650*9880d681SAndroid Build Coastguard Worker         // No instruction exists for this combination.
1651*9880d681SAndroid Build Coastguard Worker         return;
1652*9880d681SAndroid Build Coastguard Worker       C.ICmpType = SystemZICMP::UnsignedOnly;
1653*9880d681SAndroid Build Coastguard Worker     }
1654*9880d681SAndroid Build Coastguard Worker   } else if (Load->getExtensionType() == ISD::ZEXTLOAD) {
1655*9880d681SAndroid Build Coastguard Worker     if (Value > Mask)
1656*9880d681SAndroid Build Coastguard Worker       return;
1657*9880d681SAndroid Build Coastguard Worker     // If the constant is in range, we can use any comparison.
1658*9880d681SAndroid Build Coastguard Worker     C.ICmpType = SystemZICMP::Any;
1659*9880d681SAndroid Build Coastguard Worker   } else
1660*9880d681SAndroid Build Coastguard Worker     return;
1661*9880d681SAndroid Build Coastguard Worker 
1662*9880d681SAndroid Build Coastguard Worker   // Make sure that the first operand is an i32 of the right extension type.
1663*9880d681SAndroid Build Coastguard Worker   ISD::LoadExtType ExtType = (C.ICmpType == SystemZICMP::SignedOnly ?
1664*9880d681SAndroid Build Coastguard Worker                               ISD::SEXTLOAD :
1665*9880d681SAndroid Build Coastguard Worker                               ISD::ZEXTLOAD);
1666*9880d681SAndroid Build Coastguard Worker   if (C.Op0.getValueType() != MVT::i32 ||
1667*9880d681SAndroid Build Coastguard Worker       Load->getExtensionType() != ExtType)
1668*9880d681SAndroid Build Coastguard Worker     C.Op0 = DAG.getExtLoad(ExtType, SDLoc(Load), MVT::i32,
1669*9880d681SAndroid Build Coastguard Worker                            Load->getChain(), Load->getBasePtr(),
1670*9880d681SAndroid Build Coastguard Worker                            Load->getPointerInfo(), Load->getMemoryVT(),
1671*9880d681SAndroid Build Coastguard Worker                            Load->isVolatile(), Load->isNonTemporal(),
1672*9880d681SAndroid Build Coastguard Worker                            Load->isInvariant(), Load->getAlignment());
1673*9880d681SAndroid Build Coastguard Worker 
1674*9880d681SAndroid Build Coastguard Worker   // Make sure that the second operand is an i32 with the right value.
1675*9880d681SAndroid Build Coastguard Worker   if (C.Op1.getValueType() != MVT::i32 ||
1676*9880d681SAndroid Build Coastguard Worker       Value != ConstOp1->getZExtValue())
1677*9880d681SAndroid Build Coastguard Worker     C.Op1 = DAG.getConstant(Value, DL, MVT::i32);
1678*9880d681SAndroid Build Coastguard Worker }
1679*9880d681SAndroid Build Coastguard Worker 
1680*9880d681SAndroid Build Coastguard Worker // Return true if Op is either an unextended load, or a load suitable
1681*9880d681SAndroid Build Coastguard Worker // for integer register-memory comparisons of type ICmpType.
isNaturalMemoryOperand(SDValue Op,unsigned ICmpType)1682*9880d681SAndroid Build Coastguard Worker static bool isNaturalMemoryOperand(SDValue Op, unsigned ICmpType) {
1683*9880d681SAndroid Build Coastguard Worker   auto *Load = dyn_cast<LoadSDNode>(Op.getNode());
1684*9880d681SAndroid Build Coastguard Worker   if (Load) {
1685*9880d681SAndroid Build Coastguard Worker     // There are no instructions to compare a register with a memory byte.
1686*9880d681SAndroid Build Coastguard Worker     if (Load->getMemoryVT() == MVT::i8)
1687*9880d681SAndroid Build Coastguard Worker       return false;
1688*9880d681SAndroid Build Coastguard Worker     // Otherwise decide on extension type.
1689*9880d681SAndroid Build Coastguard Worker     switch (Load->getExtensionType()) {
1690*9880d681SAndroid Build Coastguard Worker     case ISD::NON_EXTLOAD:
1691*9880d681SAndroid Build Coastguard Worker       return true;
1692*9880d681SAndroid Build Coastguard Worker     case ISD::SEXTLOAD:
1693*9880d681SAndroid Build Coastguard Worker       return ICmpType != SystemZICMP::UnsignedOnly;
1694*9880d681SAndroid Build Coastguard Worker     case ISD::ZEXTLOAD:
1695*9880d681SAndroid Build Coastguard Worker       return ICmpType != SystemZICMP::SignedOnly;
1696*9880d681SAndroid Build Coastguard Worker     default:
1697*9880d681SAndroid Build Coastguard Worker       break;
1698*9880d681SAndroid Build Coastguard Worker     }
1699*9880d681SAndroid Build Coastguard Worker   }
1700*9880d681SAndroid Build Coastguard Worker   return false;
1701*9880d681SAndroid Build Coastguard Worker }
1702*9880d681SAndroid Build Coastguard Worker 
1703*9880d681SAndroid Build Coastguard Worker // Return true if it is better to swap the operands of C.
shouldSwapCmpOperands(const Comparison & C)1704*9880d681SAndroid Build Coastguard Worker static bool shouldSwapCmpOperands(const Comparison &C) {
1705*9880d681SAndroid Build Coastguard Worker   // Leave f128 comparisons alone, since they have no memory forms.
1706*9880d681SAndroid Build Coastguard Worker   if (C.Op0.getValueType() == MVT::f128)
1707*9880d681SAndroid Build Coastguard Worker     return false;
1708*9880d681SAndroid Build Coastguard Worker 
1709*9880d681SAndroid Build Coastguard Worker   // Always keep a floating-point constant second, since comparisons with
1710*9880d681SAndroid Build Coastguard Worker   // zero can use LOAD TEST and comparisons with other constants make a
1711*9880d681SAndroid Build Coastguard Worker   // natural memory operand.
1712*9880d681SAndroid Build Coastguard Worker   if (isa<ConstantFPSDNode>(C.Op1))
1713*9880d681SAndroid Build Coastguard Worker     return false;
1714*9880d681SAndroid Build Coastguard Worker 
1715*9880d681SAndroid Build Coastguard Worker   // Never swap comparisons with zero since there are many ways to optimize
1716*9880d681SAndroid Build Coastguard Worker   // those later.
1717*9880d681SAndroid Build Coastguard Worker   auto *ConstOp1 = dyn_cast<ConstantSDNode>(C.Op1);
1718*9880d681SAndroid Build Coastguard Worker   if (ConstOp1 && ConstOp1->getZExtValue() == 0)
1719*9880d681SAndroid Build Coastguard Worker     return false;
1720*9880d681SAndroid Build Coastguard Worker 
1721*9880d681SAndroid Build Coastguard Worker   // Also keep natural memory operands second if the loaded value is
1722*9880d681SAndroid Build Coastguard Worker   // only used here.  Several comparisons have memory forms.
1723*9880d681SAndroid Build Coastguard Worker   if (isNaturalMemoryOperand(C.Op1, C.ICmpType) && C.Op1.hasOneUse())
1724*9880d681SAndroid Build Coastguard Worker     return false;
1725*9880d681SAndroid Build Coastguard Worker 
1726*9880d681SAndroid Build Coastguard Worker   // Look for cases where Cmp0 is a single-use load and Cmp1 isn't.
1727*9880d681SAndroid Build Coastguard Worker   // In that case we generally prefer the memory to be second.
1728*9880d681SAndroid Build Coastguard Worker   if (isNaturalMemoryOperand(C.Op0, C.ICmpType) && C.Op0.hasOneUse()) {
1729*9880d681SAndroid Build Coastguard Worker     // The only exceptions are when the second operand is a constant and
1730*9880d681SAndroid Build Coastguard Worker     // we can use things like CHHSI.
1731*9880d681SAndroid Build Coastguard Worker     if (!ConstOp1)
1732*9880d681SAndroid Build Coastguard Worker       return true;
1733*9880d681SAndroid Build Coastguard Worker     // The unsigned memory-immediate instructions can handle 16-bit
1734*9880d681SAndroid Build Coastguard Worker     // unsigned integers.
1735*9880d681SAndroid Build Coastguard Worker     if (C.ICmpType != SystemZICMP::SignedOnly &&
1736*9880d681SAndroid Build Coastguard Worker         isUInt<16>(ConstOp1->getZExtValue()))
1737*9880d681SAndroid Build Coastguard Worker       return false;
1738*9880d681SAndroid Build Coastguard Worker     // The signed memory-immediate instructions can handle 16-bit
1739*9880d681SAndroid Build Coastguard Worker     // signed integers.
1740*9880d681SAndroid Build Coastguard Worker     if (C.ICmpType != SystemZICMP::UnsignedOnly &&
1741*9880d681SAndroid Build Coastguard Worker         isInt<16>(ConstOp1->getSExtValue()))
1742*9880d681SAndroid Build Coastguard Worker       return false;
1743*9880d681SAndroid Build Coastguard Worker     return true;
1744*9880d681SAndroid Build Coastguard Worker   }
1745*9880d681SAndroid Build Coastguard Worker 
1746*9880d681SAndroid Build Coastguard Worker   // Try to promote the use of CGFR and CLGFR.
1747*9880d681SAndroid Build Coastguard Worker   unsigned Opcode0 = C.Op0.getOpcode();
1748*9880d681SAndroid Build Coastguard Worker   if (C.ICmpType != SystemZICMP::UnsignedOnly && Opcode0 == ISD::SIGN_EXTEND)
1749*9880d681SAndroid Build Coastguard Worker     return true;
1750*9880d681SAndroid Build Coastguard Worker   if (C.ICmpType != SystemZICMP::SignedOnly && Opcode0 == ISD::ZERO_EXTEND)
1751*9880d681SAndroid Build Coastguard Worker     return true;
1752*9880d681SAndroid Build Coastguard Worker   if (C.ICmpType != SystemZICMP::SignedOnly &&
1753*9880d681SAndroid Build Coastguard Worker       Opcode0 == ISD::AND &&
1754*9880d681SAndroid Build Coastguard Worker       C.Op0.getOperand(1).getOpcode() == ISD::Constant &&
1755*9880d681SAndroid Build Coastguard Worker       cast<ConstantSDNode>(C.Op0.getOperand(1))->getZExtValue() == 0xffffffff)
1756*9880d681SAndroid Build Coastguard Worker     return true;
1757*9880d681SAndroid Build Coastguard Worker 
1758*9880d681SAndroid Build Coastguard Worker   return false;
1759*9880d681SAndroid Build Coastguard Worker }
1760*9880d681SAndroid Build Coastguard Worker 
1761*9880d681SAndroid Build Coastguard Worker // Return a version of comparison CC mask CCMask in which the LT and GT
1762*9880d681SAndroid Build Coastguard Worker // actions are swapped.
reverseCCMask(unsigned CCMask)1763*9880d681SAndroid Build Coastguard Worker static unsigned reverseCCMask(unsigned CCMask) {
1764*9880d681SAndroid Build Coastguard Worker   return ((CCMask & SystemZ::CCMASK_CMP_EQ) |
1765*9880d681SAndroid Build Coastguard Worker           (CCMask & SystemZ::CCMASK_CMP_GT ? SystemZ::CCMASK_CMP_LT : 0) |
1766*9880d681SAndroid Build Coastguard Worker           (CCMask & SystemZ::CCMASK_CMP_LT ? SystemZ::CCMASK_CMP_GT : 0) |
1767*9880d681SAndroid Build Coastguard Worker           (CCMask & SystemZ::CCMASK_CMP_UO));
1768*9880d681SAndroid Build Coastguard Worker }
1769*9880d681SAndroid Build Coastguard Worker 
1770*9880d681SAndroid Build Coastguard Worker // Check whether C tests for equality between X and Y and whether X - Y
1771*9880d681SAndroid Build Coastguard Worker // or Y - X is also computed.  In that case it's better to compare the
1772*9880d681SAndroid Build Coastguard Worker // result of the subtraction against zero.
adjustForSubtraction(SelectionDAG & DAG,const SDLoc & DL,Comparison & C)1773*9880d681SAndroid Build Coastguard Worker static void adjustForSubtraction(SelectionDAG &DAG, const SDLoc &DL,
1774*9880d681SAndroid Build Coastguard Worker                                  Comparison &C) {
1775*9880d681SAndroid Build Coastguard Worker   if (C.CCMask == SystemZ::CCMASK_CMP_EQ ||
1776*9880d681SAndroid Build Coastguard Worker       C.CCMask == SystemZ::CCMASK_CMP_NE) {
1777*9880d681SAndroid Build Coastguard Worker     for (auto I = C.Op0->use_begin(), E = C.Op0->use_end(); I != E; ++I) {
1778*9880d681SAndroid Build Coastguard Worker       SDNode *N = *I;
1779*9880d681SAndroid Build Coastguard Worker       if (N->getOpcode() == ISD::SUB &&
1780*9880d681SAndroid Build Coastguard Worker           ((N->getOperand(0) == C.Op0 && N->getOperand(1) == C.Op1) ||
1781*9880d681SAndroid Build Coastguard Worker            (N->getOperand(0) == C.Op1 && N->getOperand(1) == C.Op0))) {
1782*9880d681SAndroid Build Coastguard Worker         C.Op0 = SDValue(N, 0);
1783*9880d681SAndroid Build Coastguard Worker         C.Op1 = DAG.getConstant(0, DL, N->getValueType(0));
1784*9880d681SAndroid Build Coastguard Worker         return;
1785*9880d681SAndroid Build Coastguard Worker       }
1786*9880d681SAndroid Build Coastguard Worker     }
1787*9880d681SAndroid Build Coastguard Worker   }
1788*9880d681SAndroid Build Coastguard Worker }
1789*9880d681SAndroid Build Coastguard Worker 
1790*9880d681SAndroid Build Coastguard Worker // Check whether C compares a floating-point value with zero and if that
1791*9880d681SAndroid Build Coastguard Worker // floating-point value is also negated.  In this case we can use the
1792*9880d681SAndroid Build Coastguard Worker // negation to set CC, so avoiding separate LOAD AND TEST and
1793*9880d681SAndroid Build Coastguard Worker // LOAD (NEGATIVE/COMPLEMENT) instructions.
adjustForFNeg(Comparison & C)1794*9880d681SAndroid Build Coastguard Worker static void adjustForFNeg(Comparison &C) {
1795*9880d681SAndroid Build Coastguard Worker   auto *C1 = dyn_cast<ConstantFPSDNode>(C.Op1);
1796*9880d681SAndroid Build Coastguard Worker   if (C1 && C1->isZero()) {
1797*9880d681SAndroid Build Coastguard Worker     for (auto I = C.Op0->use_begin(), E = C.Op0->use_end(); I != E; ++I) {
1798*9880d681SAndroid Build Coastguard Worker       SDNode *N = *I;
1799*9880d681SAndroid Build Coastguard Worker       if (N->getOpcode() == ISD::FNEG) {
1800*9880d681SAndroid Build Coastguard Worker         C.Op0 = SDValue(N, 0);
1801*9880d681SAndroid Build Coastguard Worker         C.CCMask = reverseCCMask(C.CCMask);
1802*9880d681SAndroid Build Coastguard Worker         return;
1803*9880d681SAndroid Build Coastguard Worker       }
1804*9880d681SAndroid Build Coastguard Worker     }
1805*9880d681SAndroid Build Coastguard Worker   }
1806*9880d681SAndroid Build Coastguard Worker }
1807*9880d681SAndroid Build Coastguard Worker 
1808*9880d681SAndroid Build Coastguard Worker // Check whether C compares (shl X, 32) with 0 and whether X is
1809*9880d681SAndroid Build Coastguard Worker // also sign-extended.  In that case it is better to test the result
1810*9880d681SAndroid Build Coastguard Worker // of the sign extension using LTGFR.
1811*9880d681SAndroid Build Coastguard Worker //
1812*9880d681SAndroid Build Coastguard Worker // This case is important because InstCombine transforms a comparison
1813*9880d681SAndroid Build Coastguard Worker // with (sext (trunc X)) into a comparison with (shl X, 32).
adjustForLTGFR(Comparison & C)1814*9880d681SAndroid Build Coastguard Worker static void adjustForLTGFR(Comparison &C) {
1815*9880d681SAndroid Build Coastguard Worker   // Check for a comparison between (shl X, 32) and 0.
1816*9880d681SAndroid Build Coastguard Worker   if (C.Op0.getOpcode() == ISD::SHL &&
1817*9880d681SAndroid Build Coastguard Worker       C.Op0.getValueType() == MVT::i64 &&
1818*9880d681SAndroid Build Coastguard Worker       C.Op1.getOpcode() == ISD::Constant &&
1819*9880d681SAndroid Build Coastguard Worker       cast<ConstantSDNode>(C.Op1)->getZExtValue() == 0) {
1820*9880d681SAndroid Build Coastguard Worker     auto *C1 = dyn_cast<ConstantSDNode>(C.Op0.getOperand(1));
1821*9880d681SAndroid Build Coastguard Worker     if (C1 && C1->getZExtValue() == 32) {
1822*9880d681SAndroid Build Coastguard Worker       SDValue ShlOp0 = C.Op0.getOperand(0);
1823*9880d681SAndroid Build Coastguard Worker       // See whether X has any SIGN_EXTEND_INREG uses.
1824*9880d681SAndroid Build Coastguard Worker       for (auto I = ShlOp0->use_begin(), E = ShlOp0->use_end(); I != E; ++I) {
1825*9880d681SAndroid Build Coastguard Worker         SDNode *N = *I;
1826*9880d681SAndroid Build Coastguard Worker         if (N->getOpcode() == ISD::SIGN_EXTEND_INREG &&
1827*9880d681SAndroid Build Coastguard Worker             cast<VTSDNode>(N->getOperand(1))->getVT() == MVT::i32) {
1828*9880d681SAndroid Build Coastguard Worker           C.Op0 = SDValue(N, 0);
1829*9880d681SAndroid Build Coastguard Worker           return;
1830*9880d681SAndroid Build Coastguard Worker         }
1831*9880d681SAndroid Build Coastguard Worker       }
1832*9880d681SAndroid Build Coastguard Worker     }
1833*9880d681SAndroid Build Coastguard Worker   }
1834*9880d681SAndroid Build Coastguard Worker }
1835*9880d681SAndroid Build Coastguard Worker 
1836*9880d681SAndroid Build Coastguard Worker // If C compares the truncation of an extending load, try to compare
1837*9880d681SAndroid Build Coastguard Worker // the untruncated value instead.  This exposes more opportunities to
1838*9880d681SAndroid Build Coastguard Worker // reuse CC.
adjustICmpTruncate(SelectionDAG & DAG,const SDLoc & DL,Comparison & C)1839*9880d681SAndroid Build Coastguard Worker static void adjustICmpTruncate(SelectionDAG &DAG, const SDLoc &DL,
1840*9880d681SAndroid Build Coastguard Worker                                Comparison &C) {
1841*9880d681SAndroid Build Coastguard Worker   if (C.Op0.getOpcode() == ISD::TRUNCATE &&
1842*9880d681SAndroid Build Coastguard Worker       C.Op0.getOperand(0).getOpcode() == ISD::LOAD &&
1843*9880d681SAndroid Build Coastguard Worker       C.Op1.getOpcode() == ISD::Constant &&
1844*9880d681SAndroid Build Coastguard Worker       cast<ConstantSDNode>(C.Op1)->getZExtValue() == 0) {
1845*9880d681SAndroid Build Coastguard Worker     auto *L = cast<LoadSDNode>(C.Op0.getOperand(0));
1846*9880d681SAndroid Build Coastguard Worker     if (L->getMemoryVT().getStoreSizeInBits()
1847*9880d681SAndroid Build Coastguard Worker         <= C.Op0.getValueType().getSizeInBits()) {
1848*9880d681SAndroid Build Coastguard Worker       unsigned Type = L->getExtensionType();
1849*9880d681SAndroid Build Coastguard Worker       if ((Type == ISD::ZEXTLOAD && C.ICmpType != SystemZICMP::SignedOnly) ||
1850*9880d681SAndroid Build Coastguard Worker           (Type == ISD::SEXTLOAD && C.ICmpType != SystemZICMP::UnsignedOnly)) {
1851*9880d681SAndroid Build Coastguard Worker         C.Op0 = C.Op0.getOperand(0);
1852*9880d681SAndroid Build Coastguard Worker         C.Op1 = DAG.getConstant(0, DL, C.Op0.getValueType());
1853*9880d681SAndroid Build Coastguard Worker       }
1854*9880d681SAndroid Build Coastguard Worker     }
1855*9880d681SAndroid Build Coastguard Worker   }
1856*9880d681SAndroid Build Coastguard Worker }
1857*9880d681SAndroid Build Coastguard Worker 
1858*9880d681SAndroid Build Coastguard Worker // Return true if shift operation N has an in-range constant shift value.
1859*9880d681SAndroid Build Coastguard Worker // Store it in ShiftVal if so.
isSimpleShift(SDValue N,unsigned & ShiftVal)1860*9880d681SAndroid Build Coastguard Worker static bool isSimpleShift(SDValue N, unsigned &ShiftVal) {
1861*9880d681SAndroid Build Coastguard Worker   auto *Shift = dyn_cast<ConstantSDNode>(N.getOperand(1));
1862*9880d681SAndroid Build Coastguard Worker   if (!Shift)
1863*9880d681SAndroid Build Coastguard Worker     return false;
1864*9880d681SAndroid Build Coastguard Worker 
1865*9880d681SAndroid Build Coastguard Worker   uint64_t Amount = Shift->getZExtValue();
1866*9880d681SAndroid Build Coastguard Worker   if (Amount >= N.getValueType().getSizeInBits())
1867*9880d681SAndroid Build Coastguard Worker     return false;
1868*9880d681SAndroid Build Coastguard Worker 
1869*9880d681SAndroid Build Coastguard Worker   ShiftVal = Amount;
1870*9880d681SAndroid Build Coastguard Worker   return true;
1871*9880d681SAndroid Build Coastguard Worker }
1872*9880d681SAndroid Build Coastguard Worker 
1873*9880d681SAndroid Build Coastguard Worker // Check whether an AND with Mask is suitable for a TEST UNDER MASK
1874*9880d681SAndroid Build Coastguard Worker // instruction and whether the CC value is descriptive enough to handle
1875*9880d681SAndroid Build Coastguard Worker // a comparison of type Opcode between the AND result and CmpVal.
1876*9880d681SAndroid Build Coastguard Worker // CCMask says which comparison result is being tested and BitSize is
1877*9880d681SAndroid Build Coastguard Worker // the number of bits in the operands.  If TEST UNDER MASK can be used,
1878*9880d681SAndroid Build Coastguard Worker // return the corresponding CC mask, otherwise return 0.
getTestUnderMaskCond(unsigned BitSize,unsigned CCMask,uint64_t Mask,uint64_t CmpVal,unsigned ICmpType)1879*9880d681SAndroid Build Coastguard Worker static unsigned getTestUnderMaskCond(unsigned BitSize, unsigned CCMask,
1880*9880d681SAndroid Build Coastguard Worker                                      uint64_t Mask, uint64_t CmpVal,
1881*9880d681SAndroid Build Coastguard Worker                                      unsigned ICmpType) {
1882*9880d681SAndroid Build Coastguard Worker   assert(Mask != 0 && "ANDs with zero should have been removed by now");
1883*9880d681SAndroid Build Coastguard Worker 
1884*9880d681SAndroid Build Coastguard Worker   // Check whether the mask is suitable for TMHH, TMHL, TMLH or TMLL.
1885*9880d681SAndroid Build Coastguard Worker   if (!SystemZ::isImmLL(Mask) && !SystemZ::isImmLH(Mask) &&
1886*9880d681SAndroid Build Coastguard Worker       !SystemZ::isImmHL(Mask) && !SystemZ::isImmHH(Mask))
1887*9880d681SAndroid Build Coastguard Worker     return 0;
1888*9880d681SAndroid Build Coastguard Worker 
1889*9880d681SAndroid Build Coastguard Worker   // Work out the masks for the lowest and highest bits.
1890*9880d681SAndroid Build Coastguard Worker   unsigned HighShift = 63 - countLeadingZeros(Mask);
1891*9880d681SAndroid Build Coastguard Worker   uint64_t High = uint64_t(1) << HighShift;
1892*9880d681SAndroid Build Coastguard Worker   uint64_t Low = uint64_t(1) << countTrailingZeros(Mask);
1893*9880d681SAndroid Build Coastguard Worker 
1894*9880d681SAndroid Build Coastguard Worker   // Signed ordered comparisons are effectively unsigned if the sign
1895*9880d681SAndroid Build Coastguard Worker   // bit is dropped.
1896*9880d681SAndroid Build Coastguard Worker   bool EffectivelyUnsigned = (ICmpType != SystemZICMP::SignedOnly);
1897*9880d681SAndroid Build Coastguard Worker 
1898*9880d681SAndroid Build Coastguard Worker   // Check for equality comparisons with 0, or the equivalent.
1899*9880d681SAndroid Build Coastguard Worker   if (CmpVal == 0) {
1900*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_EQ)
1901*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_ALL_0;
1902*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_NE)
1903*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_SOME_1;
1904*9880d681SAndroid Build Coastguard Worker   }
1905*9880d681SAndroid Build Coastguard Worker   if (EffectivelyUnsigned && CmpVal > 0 && CmpVal <= Low) {
1906*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_LT)
1907*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_ALL_0;
1908*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_GE)
1909*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_SOME_1;
1910*9880d681SAndroid Build Coastguard Worker   }
1911*9880d681SAndroid Build Coastguard Worker   if (EffectivelyUnsigned && CmpVal < Low) {
1912*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_LE)
1913*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_ALL_0;
1914*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_GT)
1915*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_SOME_1;
1916*9880d681SAndroid Build Coastguard Worker   }
1917*9880d681SAndroid Build Coastguard Worker 
1918*9880d681SAndroid Build Coastguard Worker   // Check for equality comparisons with the mask, or the equivalent.
1919*9880d681SAndroid Build Coastguard Worker   if (CmpVal == Mask) {
1920*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_EQ)
1921*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_ALL_1;
1922*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_NE)
1923*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_SOME_0;
1924*9880d681SAndroid Build Coastguard Worker   }
1925*9880d681SAndroid Build Coastguard Worker   if (EffectivelyUnsigned && CmpVal >= Mask - Low && CmpVal < Mask) {
1926*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_GT)
1927*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_ALL_1;
1928*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_LE)
1929*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_SOME_0;
1930*9880d681SAndroid Build Coastguard Worker   }
1931*9880d681SAndroid Build Coastguard Worker   if (EffectivelyUnsigned && CmpVal > Mask - Low && CmpVal <= Mask) {
1932*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_GE)
1933*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_ALL_1;
1934*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_LT)
1935*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_SOME_0;
1936*9880d681SAndroid Build Coastguard Worker   }
1937*9880d681SAndroid Build Coastguard Worker 
1938*9880d681SAndroid Build Coastguard Worker   // Check for ordered comparisons with the top bit.
1939*9880d681SAndroid Build Coastguard Worker   if (EffectivelyUnsigned && CmpVal >= Mask - High && CmpVal < High) {
1940*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_LE)
1941*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_MSB_0;
1942*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_GT)
1943*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_MSB_1;
1944*9880d681SAndroid Build Coastguard Worker   }
1945*9880d681SAndroid Build Coastguard Worker   if (EffectivelyUnsigned && CmpVal > Mask - High && CmpVal <= High) {
1946*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_LT)
1947*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_MSB_0;
1948*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_GE)
1949*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_MSB_1;
1950*9880d681SAndroid Build Coastguard Worker   }
1951*9880d681SAndroid Build Coastguard Worker 
1952*9880d681SAndroid Build Coastguard Worker   // If there are just two bits, we can do equality checks for Low and High
1953*9880d681SAndroid Build Coastguard Worker   // as well.
1954*9880d681SAndroid Build Coastguard Worker   if (Mask == Low + High) {
1955*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_EQ && CmpVal == Low)
1956*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_MIXED_MSB_0;
1957*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_NE && CmpVal == Low)
1958*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_MIXED_MSB_0 ^ SystemZ::CCMASK_ANY;
1959*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_EQ && CmpVal == High)
1960*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_MIXED_MSB_1;
1961*9880d681SAndroid Build Coastguard Worker     if (CCMask == SystemZ::CCMASK_CMP_NE && CmpVal == High)
1962*9880d681SAndroid Build Coastguard Worker       return SystemZ::CCMASK_TM_MIXED_MSB_1 ^ SystemZ::CCMASK_ANY;
1963*9880d681SAndroid Build Coastguard Worker   }
1964*9880d681SAndroid Build Coastguard Worker 
1965*9880d681SAndroid Build Coastguard Worker   // Looks like we've exhausted our options.
1966*9880d681SAndroid Build Coastguard Worker   return 0;
1967*9880d681SAndroid Build Coastguard Worker }
1968*9880d681SAndroid Build Coastguard Worker 
1969*9880d681SAndroid Build Coastguard Worker // See whether C can be implemented as a TEST UNDER MASK instruction.
1970*9880d681SAndroid Build Coastguard Worker // Update the arguments with the TM version if so.
adjustForTestUnderMask(SelectionDAG & DAG,const SDLoc & DL,Comparison & C)1971*9880d681SAndroid Build Coastguard Worker static void adjustForTestUnderMask(SelectionDAG &DAG, const SDLoc &DL,
1972*9880d681SAndroid Build Coastguard Worker                                    Comparison &C) {
1973*9880d681SAndroid Build Coastguard Worker   // Check that we have a comparison with a constant.
1974*9880d681SAndroid Build Coastguard Worker   auto *ConstOp1 = dyn_cast<ConstantSDNode>(C.Op1);
1975*9880d681SAndroid Build Coastguard Worker   if (!ConstOp1)
1976*9880d681SAndroid Build Coastguard Worker     return;
1977*9880d681SAndroid Build Coastguard Worker   uint64_t CmpVal = ConstOp1->getZExtValue();
1978*9880d681SAndroid Build Coastguard Worker 
1979*9880d681SAndroid Build Coastguard Worker   // Check whether the nonconstant input is an AND with a constant mask.
1980*9880d681SAndroid Build Coastguard Worker   Comparison NewC(C);
1981*9880d681SAndroid Build Coastguard Worker   uint64_t MaskVal;
1982*9880d681SAndroid Build Coastguard Worker   ConstantSDNode *Mask = nullptr;
1983*9880d681SAndroid Build Coastguard Worker   if (C.Op0.getOpcode() == ISD::AND) {
1984*9880d681SAndroid Build Coastguard Worker     NewC.Op0 = C.Op0.getOperand(0);
1985*9880d681SAndroid Build Coastguard Worker     NewC.Op1 = C.Op0.getOperand(1);
1986*9880d681SAndroid Build Coastguard Worker     Mask = dyn_cast<ConstantSDNode>(NewC.Op1);
1987*9880d681SAndroid Build Coastguard Worker     if (!Mask)
1988*9880d681SAndroid Build Coastguard Worker       return;
1989*9880d681SAndroid Build Coastguard Worker     MaskVal = Mask->getZExtValue();
1990*9880d681SAndroid Build Coastguard Worker   } else {
1991*9880d681SAndroid Build Coastguard Worker     // There is no instruction to compare with a 64-bit immediate
1992*9880d681SAndroid Build Coastguard Worker     // so use TMHH instead if possible.  We need an unsigned ordered
1993*9880d681SAndroid Build Coastguard Worker     // comparison with an i64 immediate.
1994*9880d681SAndroid Build Coastguard Worker     if (NewC.Op0.getValueType() != MVT::i64 ||
1995*9880d681SAndroid Build Coastguard Worker         NewC.CCMask == SystemZ::CCMASK_CMP_EQ ||
1996*9880d681SAndroid Build Coastguard Worker         NewC.CCMask == SystemZ::CCMASK_CMP_NE ||
1997*9880d681SAndroid Build Coastguard Worker         NewC.ICmpType == SystemZICMP::SignedOnly)
1998*9880d681SAndroid Build Coastguard Worker       return;
1999*9880d681SAndroid Build Coastguard Worker     // Convert LE and GT comparisons into LT and GE.
2000*9880d681SAndroid Build Coastguard Worker     if (NewC.CCMask == SystemZ::CCMASK_CMP_LE ||
2001*9880d681SAndroid Build Coastguard Worker         NewC.CCMask == SystemZ::CCMASK_CMP_GT) {
2002*9880d681SAndroid Build Coastguard Worker       if (CmpVal == uint64_t(-1))
2003*9880d681SAndroid Build Coastguard Worker         return;
2004*9880d681SAndroid Build Coastguard Worker       CmpVal += 1;
2005*9880d681SAndroid Build Coastguard Worker       NewC.CCMask ^= SystemZ::CCMASK_CMP_EQ;
2006*9880d681SAndroid Build Coastguard Worker     }
2007*9880d681SAndroid Build Coastguard Worker     // If the low N bits of Op1 are zero than the low N bits of Op0 can
2008*9880d681SAndroid Build Coastguard Worker     // be masked off without changing the result.
2009*9880d681SAndroid Build Coastguard Worker     MaskVal = -(CmpVal & -CmpVal);
2010*9880d681SAndroid Build Coastguard Worker     NewC.ICmpType = SystemZICMP::UnsignedOnly;
2011*9880d681SAndroid Build Coastguard Worker   }
2012*9880d681SAndroid Build Coastguard Worker   if (!MaskVal)
2013*9880d681SAndroid Build Coastguard Worker     return;
2014*9880d681SAndroid Build Coastguard Worker 
2015*9880d681SAndroid Build Coastguard Worker   // Check whether the combination of mask, comparison value and comparison
2016*9880d681SAndroid Build Coastguard Worker   // type are suitable.
2017*9880d681SAndroid Build Coastguard Worker   unsigned BitSize = NewC.Op0.getValueType().getSizeInBits();
2018*9880d681SAndroid Build Coastguard Worker   unsigned NewCCMask, ShiftVal;
2019*9880d681SAndroid Build Coastguard Worker   if (NewC.ICmpType != SystemZICMP::SignedOnly &&
2020*9880d681SAndroid Build Coastguard Worker       NewC.Op0.getOpcode() == ISD::SHL &&
2021*9880d681SAndroid Build Coastguard Worker       isSimpleShift(NewC.Op0, ShiftVal) &&
2022*9880d681SAndroid Build Coastguard Worker       (NewCCMask = getTestUnderMaskCond(BitSize, NewC.CCMask,
2023*9880d681SAndroid Build Coastguard Worker                                         MaskVal >> ShiftVal,
2024*9880d681SAndroid Build Coastguard Worker                                         CmpVal >> ShiftVal,
2025*9880d681SAndroid Build Coastguard Worker                                         SystemZICMP::Any))) {
2026*9880d681SAndroid Build Coastguard Worker     NewC.Op0 = NewC.Op0.getOperand(0);
2027*9880d681SAndroid Build Coastguard Worker     MaskVal >>= ShiftVal;
2028*9880d681SAndroid Build Coastguard Worker   } else if (NewC.ICmpType != SystemZICMP::SignedOnly &&
2029*9880d681SAndroid Build Coastguard Worker              NewC.Op0.getOpcode() == ISD::SRL &&
2030*9880d681SAndroid Build Coastguard Worker              isSimpleShift(NewC.Op0, ShiftVal) &&
2031*9880d681SAndroid Build Coastguard Worker              (NewCCMask = getTestUnderMaskCond(BitSize, NewC.CCMask,
2032*9880d681SAndroid Build Coastguard Worker                                                MaskVal << ShiftVal,
2033*9880d681SAndroid Build Coastguard Worker                                                CmpVal << ShiftVal,
2034*9880d681SAndroid Build Coastguard Worker                                                SystemZICMP::UnsignedOnly))) {
2035*9880d681SAndroid Build Coastguard Worker     NewC.Op0 = NewC.Op0.getOperand(0);
2036*9880d681SAndroid Build Coastguard Worker     MaskVal <<= ShiftVal;
2037*9880d681SAndroid Build Coastguard Worker   } else {
2038*9880d681SAndroid Build Coastguard Worker     NewCCMask = getTestUnderMaskCond(BitSize, NewC.CCMask, MaskVal, CmpVal,
2039*9880d681SAndroid Build Coastguard Worker                                      NewC.ICmpType);
2040*9880d681SAndroid Build Coastguard Worker     if (!NewCCMask)
2041*9880d681SAndroid Build Coastguard Worker       return;
2042*9880d681SAndroid Build Coastguard Worker   }
2043*9880d681SAndroid Build Coastguard Worker 
2044*9880d681SAndroid Build Coastguard Worker   // Go ahead and make the change.
2045*9880d681SAndroid Build Coastguard Worker   C.Opcode = SystemZISD::TM;
2046*9880d681SAndroid Build Coastguard Worker   C.Op0 = NewC.Op0;
2047*9880d681SAndroid Build Coastguard Worker   if (Mask && Mask->getZExtValue() == MaskVal)
2048*9880d681SAndroid Build Coastguard Worker     C.Op1 = SDValue(Mask, 0);
2049*9880d681SAndroid Build Coastguard Worker   else
2050*9880d681SAndroid Build Coastguard Worker     C.Op1 = DAG.getConstant(MaskVal, DL, C.Op0.getValueType());
2051*9880d681SAndroid Build Coastguard Worker   C.CCValid = SystemZ::CCMASK_TM;
2052*9880d681SAndroid Build Coastguard Worker   C.CCMask = NewCCMask;
2053*9880d681SAndroid Build Coastguard Worker }
2054*9880d681SAndroid Build Coastguard Worker 
2055*9880d681SAndroid Build Coastguard Worker // Return a Comparison that tests the condition-code result of intrinsic
2056*9880d681SAndroid Build Coastguard Worker // node Call against constant integer CC using comparison code Cond.
2057*9880d681SAndroid Build Coastguard Worker // Opcode is the opcode of the SystemZISD operation for the intrinsic
2058*9880d681SAndroid Build Coastguard Worker // and CCValid is the set of possible condition-code results.
getIntrinsicCmp(SelectionDAG & DAG,unsigned Opcode,SDValue Call,unsigned CCValid,uint64_t CC,ISD::CondCode Cond)2059*9880d681SAndroid Build Coastguard Worker static Comparison getIntrinsicCmp(SelectionDAG &DAG, unsigned Opcode,
2060*9880d681SAndroid Build Coastguard Worker                                   SDValue Call, unsigned CCValid, uint64_t CC,
2061*9880d681SAndroid Build Coastguard Worker                                   ISD::CondCode Cond) {
2062*9880d681SAndroid Build Coastguard Worker   Comparison C(Call, SDValue());
2063*9880d681SAndroid Build Coastguard Worker   C.Opcode = Opcode;
2064*9880d681SAndroid Build Coastguard Worker   C.CCValid = CCValid;
2065*9880d681SAndroid Build Coastguard Worker   if (Cond == ISD::SETEQ)
2066*9880d681SAndroid Build Coastguard Worker     // bit 3 for CC==0, bit 0 for CC==3, always false for CC>3.
2067*9880d681SAndroid Build Coastguard Worker     C.CCMask = CC < 4 ? 1 << (3 - CC) : 0;
2068*9880d681SAndroid Build Coastguard Worker   else if (Cond == ISD::SETNE)
2069*9880d681SAndroid Build Coastguard Worker     // ...and the inverse of that.
2070*9880d681SAndroid Build Coastguard Worker     C.CCMask = CC < 4 ? ~(1 << (3 - CC)) : -1;
2071*9880d681SAndroid Build Coastguard Worker   else if (Cond == ISD::SETLT || Cond == ISD::SETULT)
2072*9880d681SAndroid Build Coastguard Worker     // bits above bit 3 for CC==0 (always false), bits above bit 0 for CC==3,
2073*9880d681SAndroid Build Coastguard Worker     // always true for CC>3.
2074*9880d681SAndroid Build Coastguard Worker     C.CCMask = CC < 4 ? ~0U << (4 - CC) : -1;
2075*9880d681SAndroid Build Coastguard Worker   else if (Cond == ISD::SETGE || Cond == ISD::SETUGE)
2076*9880d681SAndroid Build Coastguard Worker     // ...and the inverse of that.
2077*9880d681SAndroid Build Coastguard Worker     C.CCMask = CC < 4 ? ~(~0U << (4 - CC)) : 0;
2078*9880d681SAndroid Build Coastguard Worker   else if (Cond == ISD::SETLE || Cond == ISD::SETULE)
2079*9880d681SAndroid Build Coastguard Worker     // bit 3 and above for CC==0, bit 0 and above for CC==3 (always true),
2080*9880d681SAndroid Build Coastguard Worker     // always true for CC>3.
2081*9880d681SAndroid Build Coastguard Worker     C.CCMask = CC < 4 ? ~0U << (3 - CC) : -1;
2082*9880d681SAndroid Build Coastguard Worker   else if (Cond == ISD::SETGT || Cond == ISD::SETUGT)
2083*9880d681SAndroid Build Coastguard Worker     // ...and the inverse of that.
2084*9880d681SAndroid Build Coastguard Worker     C.CCMask = CC < 4 ? ~(~0U << (3 - CC)) : 0;
2085*9880d681SAndroid Build Coastguard Worker   else
2086*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Unexpected integer comparison type");
2087*9880d681SAndroid Build Coastguard Worker   C.CCMask &= CCValid;
2088*9880d681SAndroid Build Coastguard Worker   return C;
2089*9880d681SAndroid Build Coastguard Worker }
2090*9880d681SAndroid Build Coastguard Worker 
2091*9880d681SAndroid Build Coastguard Worker // Decide how to implement a comparison of type Cond between CmpOp0 with CmpOp1.
getCmp(SelectionDAG & DAG,SDValue CmpOp0,SDValue CmpOp1,ISD::CondCode Cond,const SDLoc & DL)2092*9880d681SAndroid Build Coastguard Worker static Comparison getCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1,
2093*9880d681SAndroid Build Coastguard Worker                          ISD::CondCode Cond, const SDLoc &DL) {
2094*9880d681SAndroid Build Coastguard Worker   if (CmpOp1.getOpcode() == ISD::Constant) {
2095*9880d681SAndroid Build Coastguard Worker     uint64_t Constant = cast<ConstantSDNode>(CmpOp1)->getZExtValue();
2096*9880d681SAndroid Build Coastguard Worker     unsigned Opcode, CCValid;
2097*9880d681SAndroid Build Coastguard Worker     if (CmpOp0.getOpcode() == ISD::INTRINSIC_W_CHAIN &&
2098*9880d681SAndroid Build Coastguard Worker         CmpOp0.getResNo() == 0 && CmpOp0->hasNUsesOfValue(1, 0) &&
2099*9880d681SAndroid Build Coastguard Worker         isIntrinsicWithCCAndChain(CmpOp0, Opcode, CCValid))
2100*9880d681SAndroid Build Coastguard Worker       return getIntrinsicCmp(DAG, Opcode, CmpOp0, CCValid, Constant, Cond);
2101*9880d681SAndroid Build Coastguard Worker     if (CmpOp0.getOpcode() == ISD::INTRINSIC_WO_CHAIN &&
2102*9880d681SAndroid Build Coastguard Worker         CmpOp0.getResNo() == CmpOp0->getNumValues() - 1 &&
2103*9880d681SAndroid Build Coastguard Worker         isIntrinsicWithCC(CmpOp0, Opcode, CCValid))
2104*9880d681SAndroid Build Coastguard Worker       return getIntrinsicCmp(DAG, Opcode, CmpOp0, CCValid, Constant, Cond);
2105*9880d681SAndroid Build Coastguard Worker   }
2106*9880d681SAndroid Build Coastguard Worker   Comparison C(CmpOp0, CmpOp1);
2107*9880d681SAndroid Build Coastguard Worker   C.CCMask = CCMaskForCondCode(Cond);
2108*9880d681SAndroid Build Coastguard Worker   if (C.Op0.getValueType().isFloatingPoint()) {
2109*9880d681SAndroid Build Coastguard Worker     C.CCValid = SystemZ::CCMASK_FCMP;
2110*9880d681SAndroid Build Coastguard Worker     C.Opcode = SystemZISD::FCMP;
2111*9880d681SAndroid Build Coastguard Worker     adjustForFNeg(C);
2112*9880d681SAndroid Build Coastguard Worker   } else {
2113*9880d681SAndroid Build Coastguard Worker     C.CCValid = SystemZ::CCMASK_ICMP;
2114*9880d681SAndroid Build Coastguard Worker     C.Opcode = SystemZISD::ICMP;
2115*9880d681SAndroid Build Coastguard Worker     // Choose the type of comparison.  Equality and inequality tests can
2116*9880d681SAndroid Build Coastguard Worker     // use either signed or unsigned comparisons.  The choice also doesn't
2117*9880d681SAndroid Build Coastguard Worker     // matter if both sign bits are known to be clear.  In those cases we
2118*9880d681SAndroid Build Coastguard Worker     // want to give the main isel code the freedom to choose whichever
2119*9880d681SAndroid Build Coastguard Worker     // form fits best.
2120*9880d681SAndroid Build Coastguard Worker     if (C.CCMask == SystemZ::CCMASK_CMP_EQ ||
2121*9880d681SAndroid Build Coastguard Worker         C.CCMask == SystemZ::CCMASK_CMP_NE ||
2122*9880d681SAndroid Build Coastguard Worker         (DAG.SignBitIsZero(C.Op0) && DAG.SignBitIsZero(C.Op1)))
2123*9880d681SAndroid Build Coastguard Worker       C.ICmpType = SystemZICMP::Any;
2124*9880d681SAndroid Build Coastguard Worker     else if (C.CCMask & SystemZ::CCMASK_CMP_UO)
2125*9880d681SAndroid Build Coastguard Worker       C.ICmpType = SystemZICMP::UnsignedOnly;
2126*9880d681SAndroid Build Coastguard Worker     else
2127*9880d681SAndroid Build Coastguard Worker       C.ICmpType = SystemZICMP::SignedOnly;
2128*9880d681SAndroid Build Coastguard Worker     C.CCMask &= ~SystemZ::CCMASK_CMP_UO;
2129*9880d681SAndroid Build Coastguard Worker     adjustZeroCmp(DAG, DL, C);
2130*9880d681SAndroid Build Coastguard Worker     adjustSubwordCmp(DAG, DL, C);
2131*9880d681SAndroid Build Coastguard Worker     adjustForSubtraction(DAG, DL, C);
2132*9880d681SAndroid Build Coastguard Worker     adjustForLTGFR(C);
2133*9880d681SAndroid Build Coastguard Worker     adjustICmpTruncate(DAG, DL, C);
2134*9880d681SAndroid Build Coastguard Worker   }
2135*9880d681SAndroid Build Coastguard Worker 
2136*9880d681SAndroid Build Coastguard Worker   if (shouldSwapCmpOperands(C)) {
2137*9880d681SAndroid Build Coastguard Worker     std::swap(C.Op0, C.Op1);
2138*9880d681SAndroid Build Coastguard Worker     C.CCMask = reverseCCMask(C.CCMask);
2139*9880d681SAndroid Build Coastguard Worker   }
2140*9880d681SAndroid Build Coastguard Worker 
2141*9880d681SAndroid Build Coastguard Worker   adjustForTestUnderMask(DAG, DL, C);
2142*9880d681SAndroid Build Coastguard Worker   return C;
2143*9880d681SAndroid Build Coastguard Worker }
2144*9880d681SAndroid Build Coastguard Worker 
2145*9880d681SAndroid Build Coastguard Worker // Emit the comparison instruction described by C.
emitCmp(SelectionDAG & DAG,const SDLoc & DL,Comparison & C)2146*9880d681SAndroid Build Coastguard Worker static SDValue emitCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C) {
2147*9880d681SAndroid Build Coastguard Worker   if (!C.Op1.getNode()) {
2148*9880d681SAndroid Build Coastguard Worker     SDValue Op;
2149*9880d681SAndroid Build Coastguard Worker     switch (C.Op0.getOpcode()) {
2150*9880d681SAndroid Build Coastguard Worker     case ISD::INTRINSIC_W_CHAIN:
2151*9880d681SAndroid Build Coastguard Worker       Op = emitIntrinsicWithChainAndGlue(DAG, C.Op0, C.Opcode);
2152*9880d681SAndroid Build Coastguard Worker       break;
2153*9880d681SAndroid Build Coastguard Worker     case ISD::INTRINSIC_WO_CHAIN:
2154*9880d681SAndroid Build Coastguard Worker       Op = emitIntrinsicWithGlue(DAG, C.Op0, C.Opcode);
2155*9880d681SAndroid Build Coastguard Worker       break;
2156*9880d681SAndroid Build Coastguard Worker     default:
2157*9880d681SAndroid Build Coastguard Worker       llvm_unreachable("Invalid comparison operands");
2158*9880d681SAndroid Build Coastguard Worker     }
2159*9880d681SAndroid Build Coastguard Worker     return SDValue(Op.getNode(), Op->getNumValues() - 1);
2160*9880d681SAndroid Build Coastguard Worker   }
2161*9880d681SAndroid Build Coastguard Worker   if (C.Opcode == SystemZISD::ICMP)
2162*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(SystemZISD::ICMP, DL, MVT::Glue, C.Op0, C.Op1,
2163*9880d681SAndroid Build Coastguard Worker                        DAG.getConstant(C.ICmpType, DL, MVT::i32));
2164*9880d681SAndroid Build Coastguard Worker   if (C.Opcode == SystemZISD::TM) {
2165*9880d681SAndroid Build Coastguard Worker     bool RegisterOnly = (bool(C.CCMask & SystemZ::CCMASK_TM_MIXED_MSB_0) !=
2166*9880d681SAndroid Build Coastguard Worker                          bool(C.CCMask & SystemZ::CCMASK_TM_MIXED_MSB_1));
2167*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(SystemZISD::TM, DL, MVT::Glue, C.Op0, C.Op1,
2168*9880d681SAndroid Build Coastguard Worker                        DAG.getConstant(RegisterOnly, DL, MVT::i32));
2169*9880d681SAndroid Build Coastguard Worker   }
2170*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(C.Opcode, DL, MVT::Glue, C.Op0, C.Op1);
2171*9880d681SAndroid Build Coastguard Worker }
2172*9880d681SAndroid Build Coastguard Worker 
2173*9880d681SAndroid Build Coastguard Worker // Implement a 32-bit *MUL_LOHI operation by extending both operands to
2174*9880d681SAndroid Build Coastguard Worker // 64 bits.  Extend is the extension type to use.  Store the high part
2175*9880d681SAndroid Build Coastguard Worker // in Hi and the low part in Lo.
lowerMUL_LOHI32(SelectionDAG & DAG,const SDLoc & DL,unsigned Extend,SDValue Op0,SDValue Op1,SDValue & Hi,SDValue & Lo)2176*9880d681SAndroid Build Coastguard Worker static void lowerMUL_LOHI32(SelectionDAG &DAG, const SDLoc &DL, unsigned Extend,
2177*9880d681SAndroid Build Coastguard Worker                             SDValue Op0, SDValue Op1, SDValue &Hi,
2178*9880d681SAndroid Build Coastguard Worker                             SDValue &Lo) {
2179*9880d681SAndroid Build Coastguard Worker   Op0 = DAG.getNode(Extend, DL, MVT::i64, Op0);
2180*9880d681SAndroid Build Coastguard Worker   Op1 = DAG.getNode(Extend, DL, MVT::i64, Op1);
2181*9880d681SAndroid Build Coastguard Worker   SDValue Mul = DAG.getNode(ISD::MUL, DL, MVT::i64, Op0, Op1);
2182*9880d681SAndroid Build Coastguard Worker   Hi = DAG.getNode(ISD::SRL, DL, MVT::i64, Mul,
2183*9880d681SAndroid Build Coastguard Worker                    DAG.getConstant(32, DL, MVT::i64));
2184*9880d681SAndroid Build Coastguard Worker   Hi = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Hi);
2185*9880d681SAndroid Build Coastguard Worker   Lo = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Mul);
2186*9880d681SAndroid Build Coastguard Worker }
2187*9880d681SAndroid Build Coastguard Worker 
2188*9880d681SAndroid Build Coastguard Worker // Lower a binary operation that produces two VT results, one in each
2189*9880d681SAndroid Build Coastguard Worker // half of a GR128 pair.  Op0 and Op1 are the VT operands to the operation,
2190*9880d681SAndroid Build Coastguard Worker // Extend extends Op0 to a GR128, and Opcode performs the GR128 operation
2191*9880d681SAndroid Build Coastguard Worker // on the extended Op0 and (unextended) Op1.  Store the even register result
2192*9880d681SAndroid Build Coastguard Worker // in Even and the odd register result in Odd.
lowerGR128Binary(SelectionDAG & DAG,const SDLoc & DL,EVT VT,unsigned Extend,unsigned Opcode,SDValue Op0,SDValue Op1,SDValue & Even,SDValue & Odd)2193*9880d681SAndroid Build Coastguard Worker static void lowerGR128Binary(SelectionDAG &DAG, const SDLoc &DL, EVT VT,
2194*9880d681SAndroid Build Coastguard Worker                              unsigned Extend, unsigned Opcode, SDValue Op0,
2195*9880d681SAndroid Build Coastguard Worker                              SDValue Op1, SDValue &Even, SDValue &Odd) {
2196*9880d681SAndroid Build Coastguard Worker   SDNode *In128 = DAG.getMachineNode(Extend, DL, MVT::Untyped, Op0);
2197*9880d681SAndroid Build Coastguard Worker   SDValue Result = DAG.getNode(Opcode, DL, MVT::Untyped,
2198*9880d681SAndroid Build Coastguard Worker                                SDValue(In128, 0), Op1);
2199*9880d681SAndroid Build Coastguard Worker   bool Is32Bit = is32Bit(VT);
2200*9880d681SAndroid Build Coastguard Worker   Even = DAG.getTargetExtractSubreg(SystemZ::even128(Is32Bit), DL, VT, Result);
2201*9880d681SAndroid Build Coastguard Worker   Odd = DAG.getTargetExtractSubreg(SystemZ::odd128(Is32Bit), DL, VT, Result);
2202*9880d681SAndroid Build Coastguard Worker }
2203*9880d681SAndroid Build Coastguard Worker 
2204*9880d681SAndroid Build Coastguard Worker // Return an i32 value that is 1 if the CC value produced by Glue is
2205*9880d681SAndroid Build Coastguard Worker // in the mask CCMask and 0 otherwise.  CC is known to have a value
2206*9880d681SAndroid Build Coastguard Worker // in CCValid, so other values can be ignored.
emitSETCC(SelectionDAG & DAG,const SDLoc & DL,SDValue Glue,unsigned CCValid,unsigned CCMask)2207*9880d681SAndroid Build Coastguard Worker static SDValue emitSETCC(SelectionDAG &DAG, const SDLoc &DL, SDValue Glue,
2208*9880d681SAndroid Build Coastguard Worker                          unsigned CCValid, unsigned CCMask) {
2209*9880d681SAndroid Build Coastguard Worker   IPMConversion Conversion = getIPMConversion(CCValid, CCMask);
2210*9880d681SAndroid Build Coastguard Worker   SDValue Result = DAG.getNode(SystemZISD::IPM, DL, MVT::i32, Glue);
2211*9880d681SAndroid Build Coastguard Worker 
2212*9880d681SAndroid Build Coastguard Worker   if (Conversion.XORValue)
2213*9880d681SAndroid Build Coastguard Worker     Result = DAG.getNode(ISD::XOR, DL, MVT::i32, Result,
2214*9880d681SAndroid Build Coastguard Worker                          DAG.getConstant(Conversion.XORValue, DL, MVT::i32));
2215*9880d681SAndroid Build Coastguard Worker 
2216*9880d681SAndroid Build Coastguard Worker   if (Conversion.AddValue)
2217*9880d681SAndroid Build Coastguard Worker     Result = DAG.getNode(ISD::ADD, DL, MVT::i32, Result,
2218*9880d681SAndroid Build Coastguard Worker                          DAG.getConstant(Conversion.AddValue, DL, MVT::i32));
2219*9880d681SAndroid Build Coastguard Worker 
2220*9880d681SAndroid Build Coastguard Worker   // The SHR/AND sequence should get optimized to an RISBG.
2221*9880d681SAndroid Build Coastguard Worker   Result = DAG.getNode(ISD::SRL, DL, MVT::i32, Result,
2222*9880d681SAndroid Build Coastguard Worker                        DAG.getConstant(Conversion.Bit, DL, MVT::i32));
2223*9880d681SAndroid Build Coastguard Worker   if (Conversion.Bit != 31)
2224*9880d681SAndroid Build Coastguard Worker     Result = DAG.getNode(ISD::AND, DL, MVT::i32, Result,
2225*9880d681SAndroid Build Coastguard Worker                          DAG.getConstant(1, DL, MVT::i32));
2226*9880d681SAndroid Build Coastguard Worker   return Result;
2227*9880d681SAndroid Build Coastguard Worker }
2228*9880d681SAndroid Build Coastguard Worker 
2229*9880d681SAndroid Build Coastguard Worker // Return the SystemISD vector comparison operation for CC, or 0 if it cannot
2230*9880d681SAndroid Build Coastguard Worker // be done directly.  IsFP is true if CC is for a floating-point rather than
2231*9880d681SAndroid Build Coastguard Worker // integer comparison.
getVectorComparison(ISD::CondCode CC,bool IsFP)2232*9880d681SAndroid Build Coastguard Worker static unsigned getVectorComparison(ISD::CondCode CC, bool IsFP) {
2233*9880d681SAndroid Build Coastguard Worker   switch (CC) {
2234*9880d681SAndroid Build Coastguard Worker   case ISD::SETOEQ:
2235*9880d681SAndroid Build Coastguard Worker   case ISD::SETEQ:
2236*9880d681SAndroid Build Coastguard Worker     return IsFP ? SystemZISD::VFCMPE : SystemZISD::VICMPE;
2237*9880d681SAndroid Build Coastguard Worker 
2238*9880d681SAndroid Build Coastguard Worker   case ISD::SETOGE:
2239*9880d681SAndroid Build Coastguard Worker   case ISD::SETGE:
2240*9880d681SAndroid Build Coastguard Worker     return IsFP ? SystemZISD::VFCMPHE : static_cast<SystemZISD::NodeType>(0);
2241*9880d681SAndroid Build Coastguard Worker 
2242*9880d681SAndroid Build Coastguard Worker   case ISD::SETOGT:
2243*9880d681SAndroid Build Coastguard Worker   case ISD::SETGT:
2244*9880d681SAndroid Build Coastguard Worker     return IsFP ? SystemZISD::VFCMPH : SystemZISD::VICMPH;
2245*9880d681SAndroid Build Coastguard Worker 
2246*9880d681SAndroid Build Coastguard Worker   case ISD::SETUGT:
2247*9880d681SAndroid Build Coastguard Worker     return IsFP ? static_cast<SystemZISD::NodeType>(0) : SystemZISD::VICMPHL;
2248*9880d681SAndroid Build Coastguard Worker 
2249*9880d681SAndroid Build Coastguard Worker   default:
2250*9880d681SAndroid Build Coastguard Worker     return 0;
2251*9880d681SAndroid Build Coastguard Worker   }
2252*9880d681SAndroid Build Coastguard Worker }
2253*9880d681SAndroid Build Coastguard Worker 
2254*9880d681SAndroid Build Coastguard Worker // Return the SystemZISD vector comparison operation for CC or its inverse,
2255*9880d681SAndroid Build Coastguard Worker // or 0 if neither can be done directly.  Indicate in Invert whether the
2256*9880d681SAndroid Build Coastguard Worker // result is for the inverse of CC.  IsFP is true if CC is for a
2257*9880d681SAndroid Build Coastguard Worker // floating-point rather than integer comparison.
getVectorComparisonOrInvert(ISD::CondCode CC,bool IsFP,bool & Invert)2258*9880d681SAndroid Build Coastguard Worker static unsigned getVectorComparisonOrInvert(ISD::CondCode CC, bool IsFP,
2259*9880d681SAndroid Build Coastguard Worker                                             bool &Invert) {
2260*9880d681SAndroid Build Coastguard Worker   if (unsigned Opcode = getVectorComparison(CC, IsFP)) {
2261*9880d681SAndroid Build Coastguard Worker     Invert = false;
2262*9880d681SAndroid Build Coastguard Worker     return Opcode;
2263*9880d681SAndroid Build Coastguard Worker   }
2264*9880d681SAndroid Build Coastguard Worker 
2265*9880d681SAndroid Build Coastguard Worker   CC = ISD::getSetCCInverse(CC, !IsFP);
2266*9880d681SAndroid Build Coastguard Worker   if (unsigned Opcode = getVectorComparison(CC, IsFP)) {
2267*9880d681SAndroid Build Coastguard Worker     Invert = true;
2268*9880d681SAndroid Build Coastguard Worker     return Opcode;
2269*9880d681SAndroid Build Coastguard Worker   }
2270*9880d681SAndroid Build Coastguard Worker 
2271*9880d681SAndroid Build Coastguard Worker   return 0;
2272*9880d681SAndroid Build Coastguard Worker }
2273*9880d681SAndroid Build Coastguard Worker 
2274*9880d681SAndroid Build Coastguard Worker // Return a v2f64 that contains the extended form of elements Start and Start+1
2275*9880d681SAndroid Build Coastguard Worker // of v4f32 value Op.
expandV4F32ToV2F64(SelectionDAG & DAG,int Start,const SDLoc & DL,SDValue Op)2276*9880d681SAndroid Build Coastguard Worker static SDValue expandV4F32ToV2F64(SelectionDAG &DAG, int Start, const SDLoc &DL,
2277*9880d681SAndroid Build Coastguard Worker                                   SDValue Op) {
2278*9880d681SAndroid Build Coastguard Worker   int Mask[] = { Start, -1, Start + 1, -1 };
2279*9880d681SAndroid Build Coastguard Worker   Op = DAG.getVectorShuffle(MVT::v4f32, DL, Op, DAG.getUNDEF(MVT::v4f32), Mask);
2280*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(SystemZISD::VEXTEND, DL, MVT::v2f64, Op);
2281*9880d681SAndroid Build Coastguard Worker }
2282*9880d681SAndroid Build Coastguard Worker 
2283*9880d681SAndroid Build Coastguard Worker // Build a comparison of vectors CmpOp0 and CmpOp1 using opcode Opcode,
2284*9880d681SAndroid Build Coastguard Worker // producing a result of type VT.
getVectorCmp(SelectionDAG & DAG,unsigned Opcode,const SDLoc & DL,EVT VT,SDValue CmpOp0,SDValue CmpOp1)2285*9880d681SAndroid Build Coastguard Worker static SDValue getVectorCmp(SelectionDAG &DAG, unsigned Opcode, const SDLoc &DL,
2286*9880d681SAndroid Build Coastguard Worker                             EVT VT, SDValue CmpOp0, SDValue CmpOp1) {
2287*9880d681SAndroid Build Coastguard Worker   // There is no hardware support for v4f32, so extend the vector into
2288*9880d681SAndroid Build Coastguard Worker   // two v2f64s and compare those.
2289*9880d681SAndroid Build Coastguard Worker   if (CmpOp0.getValueType() == MVT::v4f32) {
2290*9880d681SAndroid Build Coastguard Worker     SDValue H0 = expandV4F32ToV2F64(DAG, 0, DL, CmpOp0);
2291*9880d681SAndroid Build Coastguard Worker     SDValue L0 = expandV4F32ToV2F64(DAG, 2, DL, CmpOp0);
2292*9880d681SAndroid Build Coastguard Worker     SDValue H1 = expandV4F32ToV2F64(DAG, 0, DL, CmpOp1);
2293*9880d681SAndroid Build Coastguard Worker     SDValue L1 = expandV4F32ToV2F64(DAG, 2, DL, CmpOp1);
2294*9880d681SAndroid Build Coastguard Worker     SDValue HRes = DAG.getNode(Opcode, DL, MVT::v2i64, H0, H1);
2295*9880d681SAndroid Build Coastguard Worker     SDValue LRes = DAG.getNode(Opcode, DL, MVT::v2i64, L0, L1);
2296*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(SystemZISD::PACK, DL, VT, HRes, LRes);
2297*9880d681SAndroid Build Coastguard Worker   }
2298*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(Opcode, DL, VT, CmpOp0, CmpOp1);
2299*9880d681SAndroid Build Coastguard Worker }
2300*9880d681SAndroid Build Coastguard Worker 
2301*9880d681SAndroid Build Coastguard Worker // Lower a vector comparison of type CC between CmpOp0 and CmpOp1, producing
2302*9880d681SAndroid Build Coastguard Worker // an integer mask of type VT.
lowerVectorSETCC(SelectionDAG & DAG,const SDLoc & DL,EVT VT,ISD::CondCode CC,SDValue CmpOp0,SDValue CmpOp1)2303*9880d681SAndroid Build Coastguard Worker static SDValue lowerVectorSETCC(SelectionDAG &DAG, const SDLoc &DL, EVT VT,
2304*9880d681SAndroid Build Coastguard Worker                                 ISD::CondCode CC, SDValue CmpOp0,
2305*9880d681SAndroid Build Coastguard Worker                                 SDValue CmpOp1) {
2306*9880d681SAndroid Build Coastguard Worker   bool IsFP = CmpOp0.getValueType().isFloatingPoint();
2307*9880d681SAndroid Build Coastguard Worker   bool Invert = false;
2308*9880d681SAndroid Build Coastguard Worker   SDValue Cmp;
2309*9880d681SAndroid Build Coastguard Worker   switch (CC) {
2310*9880d681SAndroid Build Coastguard Worker     // Handle tests for order using (or (ogt y x) (oge x y)).
2311*9880d681SAndroid Build Coastguard Worker   case ISD::SETUO:
2312*9880d681SAndroid Build Coastguard Worker     Invert = true;
2313*9880d681SAndroid Build Coastguard Worker   case ISD::SETO: {
2314*9880d681SAndroid Build Coastguard Worker     assert(IsFP && "Unexpected integer comparison");
2315*9880d681SAndroid Build Coastguard Worker     SDValue LT = getVectorCmp(DAG, SystemZISD::VFCMPH, DL, VT, CmpOp1, CmpOp0);
2316*9880d681SAndroid Build Coastguard Worker     SDValue GE = getVectorCmp(DAG, SystemZISD::VFCMPHE, DL, VT, CmpOp0, CmpOp1);
2317*9880d681SAndroid Build Coastguard Worker     Cmp = DAG.getNode(ISD::OR, DL, VT, LT, GE);
2318*9880d681SAndroid Build Coastguard Worker     break;
2319*9880d681SAndroid Build Coastguard Worker   }
2320*9880d681SAndroid Build Coastguard Worker 
2321*9880d681SAndroid Build Coastguard Worker     // Handle <> tests using (or (ogt y x) (ogt x y)).
2322*9880d681SAndroid Build Coastguard Worker   case ISD::SETUEQ:
2323*9880d681SAndroid Build Coastguard Worker     Invert = true;
2324*9880d681SAndroid Build Coastguard Worker   case ISD::SETONE: {
2325*9880d681SAndroid Build Coastguard Worker     assert(IsFP && "Unexpected integer comparison");
2326*9880d681SAndroid Build Coastguard Worker     SDValue LT = getVectorCmp(DAG, SystemZISD::VFCMPH, DL, VT, CmpOp1, CmpOp0);
2327*9880d681SAndroid Build Coastguard Worker     SDValue GT = getVectorCmp(DAG, SystemZISD::VFCMPH, DL, VT, CmpOp0, CmpOp1);
2328*9880d681SAndroid Build Coastguard Worker     Cmp = DAG.getNode(ISD::OR, DL, VT, LT, GT);
2329*9880d681SAndroid Build Coastguard Worker     break;
2330*9880d681SAndroid Build Coastguard Worker   }
2331*9880d681SAndroid Build Coastguard Worker 
2332*9880d681SAndroid Build Coastguard Worker     // Otherwise a single comparison is enough.  It doesn't really
2333*9880d681SAndroid Build Coastguard Worker     // matter whether we try the inversion or the swap first, since
2334*9880d681SAndroid Build Coastguard Worker     // there are no cases where both work.
2335*9880d681SAndroid Build Coastguard Worker   default:
2336*9880d681SAndroid Build Coastguard Worker     if (unsigned Opcode = getVectorComparisonOrInvert(CC, IsFP, Invert))
2337*9880d681SAndroid Build Coastguard Worker       Cmp = getVectorCmp(DAG, Opcode, DL, VT, CmpOp0, CmpOp1);
2338*9880d681SAndroid Build Coastguard Worker     else {
2339*9880d681SAndroid Build Coastguard Worker       CC = ISD::getSetCCSwappedOperands(CC);
2340*9880d681SAndroid Build Coastguard Worker       if (unsigned Opcode = getVectorComparisonOrInvert(CC, IsFP, Invert))
2341*9880d681SAndroid Build Coastguard Worker         Cmp = getVectorCmp(DAG, Opcode, DL, VT, CmpOp1, CmpOp0);
2342*9880d681SAndroid Build Coastguard Worker       else
2343*9880d681SAndroid Build Coastguard Worker         llvm_unreachable("Unhandled comparison");
2344*9880d681SAndroid Build Coastguard Worker     }
2345*9880d681SAndroid Build Coastguard Worker     break;
2346*9880d681SAndroid Build Coastguard Worker   }
2347*9880d681SAndroid Build Coastguard Worker   if (Invert) {
2348*9880d681SAndroid Build Coastguard Worker     SDValue Mask = DAG.getNode(SystemZISD::BYTE_MASK, DL, MVT::v16i8,
2349*9880d681SAndroid Build Coastguard Worker                                DAG.getConstant(65535, DL, MVT::i32));
2350*9880d681SAndroid Build Coastguard Worker     Mask = DAG.getNode(ISD::BITCAST, DL, VT, Mask);
2351*9880d681SAndroid Build Coastguard Worker     Cmp = DAG.getNode(ISD::XOR, DL, VT, Cmp, Mask);
2352*9880d681SAndroid Build Coastguard Worker   }
2353*9880d681SAndroid Build Coastguard Worker   return Cmp;
2354*9880d681SAndroid Build Coastguard Worker }
2355*9880d681SAndroid Build Coastguard Worker 
lowerSETCC(SDValue Op,SelectionDAG & DAG) const2356*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerSETCC(SDValue Op,
2357*9880d681SAndroid Build Coastguard Worker                                           SelectionDAG &DAG) const {
2358*9880d681SAndroid Build Coastguard Worker   SDValue CmpOp0   = Op.getOperand(0);
2359*9880d681SAndroid Build Coastguard Worker   SDValue CmpOp1   = Op.getOperand(1);
2360*9880d681SAndroid Build Coastguard Worker   ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
2361*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
2362*9880d681SAndroid Build Coastguard Worker   EVT VT = Op.getValueType();
2363*9880d681SAndroid Build Coastguard Worker   if (VT.isVector())
2364*9880d681SAndroid Build Coastguard Worker     return lowerVectorSETCC(DAG, DL, VT, CC, CmpOp0, CmpOp1);
2365*9880d681SAndroid Build Coastguard Worker 
2366*9880d681SAndroid Build Coastguard Worker   Comparison C(getCmp(DAG, CmpOp0, CmpOp1, CC, DL));
2367*9880d681SAndroid Build Coastguard Worker   SDValue Glue = emitCmp(DAG, DL, C);
2368*9880d681SAndroid Build Coastguard Worker   return emitSETCC(DAG, DL, Glue, C.CCValid, C.CCMask);
2369*9880d681SAndroid Build Coastguard Worker }
2370*9880d681SAndroid Build Coastguard Worker 
lowerBR_CC(SDValue Op,SelectionDAG & DAG) const2371*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
2372*9880d681SAndroid Build Coastguard Worker   ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
2373*9880d681SAndroid Build Coastguard Worker   SDValue CmpOp0   = Op.getOperand(2);
2374*9880d681SAndroid Build Coastguard Worker   SDValue CmpOp1   = Op.getOperand(3);
2375*9880d681SAndroid Build Coastguard Worker   SDValue Dest     = Op.getOperand(4);
2376*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
2377*9880d681SAndroid Build Coastguard Worker 
2378*9880d681SAndroid Build Coastguard Worker   Comparison C(getCmp(DAG, CmpOp0, CmpOp1, CC, DL));
2379*9880d681SAndroid Build Coastguard Worker   SDValue Glue = emitCmp(DAG, DL, C);
2380*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(SystemZISD::BR_CCMASK, DL, Op.getValueType(),
2381*9880d681SAndroid Build Coastguard Worker                      Op.getOperand(0), DAG.getConstant(C.CCValid, DL, MVT::i32),
2382*9880d681SAndroid Build Coastguard Worker                      DAG.getConstant(C.CCMask, DL, MVT::i32), Dest, Glue);
2383*9880d681SAndroid Build Coastguard Worker }
2384*9880d681SAndroid Build Coastguard Worker 
2385*9880d681SAndroid Build Coastguard Worker // Return true if Pos is CmpOp and Neg is the negative of CmpOp,
2386*9880d681SAndroid Build Coastguard Worker // allowing Pos and Neg to be wider than CmpOp.
isAbsolute(SDValue CmpOp,SDValue Pos,SDValue Neg)2387*9880d681SAndroid Build Coastguard Worker static bool isAbsolute(SDValue CmpOp, SDValue Pos, SDValue Neg) {
2388*9880d681SAndroid Build Coastguard Worker   return (Neg.getOpcode() == ISD::SUB &&
2389*9880d681SAndroid Build Coastguard Worker           Neg.getOperand(0).getOpcode() == ISD::Constant &&
2390*9880d681SAndroid Build Coastguard Worker           cast<ConstantSDNode>(Neg.getOperand(0))->getZExtValue() == 0 &&
2391*9880d681SAndroid Build Coastguard Worker           Neg.getOperand(1) == Pos &&
2392*9880d681SAndroid Build Coastguard Worker           (Pos == CmpOp ||
2393*9880d681SAndroid Build Coastguard Worker            (Pos.getOpcode() == ISD::SIGN_EXTEND &&
2394*9880d681SAndroid Build Coastguard Worker             Pos.getOperand(0) == CmpOp)));
2395*9880d681SAndroid Build Coastguard Worker }
2396*9880d681SAndroid Build Coastguard Worker 
2397*9880d681SAndroid Build Coastguard Worker // Return the absolute or negative absolute of Op; IsNegative decides which.
getAbsolute(SelectionDAG & DAG,const SDLoc & DL,SDValue Op,bool IsNegative)2398*9880d681SAndroid Build Coastguard Worker static SDValue getAbsolute(SelectionDAG &DAG, const SDLoc &DL, SDValue Op,
2399*9880d681SAndroid Build Coastguard Worker                            bool IsNegative) {
2400*9880d681SAndroid Build Coastguard Worker   Op = DAG.getNode(SystemZISD::IABS, DL, Op.getValueType(), Op);
2401*9880d681SAndroid Build Coastguard Worker   if (IsNegative)
2402*9880d681SAndroid Build Coastguard Worker     Op = DAG.getNode(ISD::SUB, DL, Op.getValueType(),
2403*9880d681SAndroid Build Coastguard Worker                      DAG.getConstant(0, DL, Op.getValueType()), Op);
2404*9880d681SAndroid Build Coastguard Worker   return Op;
2405*9880d681SAndroid Build Coastguard Worker }
2406*9880d681SAndroid Build Coastguard Worker 
lowerSELECT_CC(SDValue Op,SelectionDAG & DAG) const2407*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerSELECT_CC(SDValue Op,
2408*9880d681SAndroid Build Coastguard Worker                                               SelectionDAG &DAG) const {
2409*9880d681SAndroid Build Coastguard Worker   SDValue CmpOp0   = Op.getOperand(0);
2410*9880d681SAndroid Build Coastguard Worker   SDValue CmpOp1   = Op.getOperand(1);
2411*9880d681SAndroid Build Coastguard Worker   SDValue TrueOp   = Op.getOperand(2);
2412*9880d681SAndroid Build Coastguard Worker   SDValue FalseOp  = Op.getOperand(3);
2413*9880d681SAndroid Build Coastguard Worker   ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
2414*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
2415*9880d681SAndroid Build Coastguard Worker 
2416*9880d681SAndroid Build Coastguard Worker   Comparison C(getCmp(DAG, CmpOp0, CmpOp1, CC, DL));
2417*9880d681SAndroid Build Coastguard Worker 
2418*9880d681SAndroid Build Coastguard Worker   // Check for absolute and negative-absolute selections, including those
2419*9880d681SAndroid Build Coastguard Worker   // where the comparison value is sign-extended (for LPGFR and LNGFR).
2420*9880d681SAndroid Build Coastguard Worker   // This check supplements the one in DAGCombiner.
2421*9880d681SAndroid Build Coastguard Worker   if (C.Opcode == SystemZISD::ICMP &&
2422*9880d681SAndroid Build Coastguard Worker       C.CCMask != SystemZ::CCMASK_CMP_EQ &&
2423*9880d681SAndroid Build Coastguard Worker       C.CCMask != SystemZ::CCMASK_CMP_NE &&
2424*9880d681SAndroid Build Coastguard Worker       C.Op1.getOpcode() == ISD::Constant &&
2425*9880d681SAndroid Build Coastguard Worker       cast<ConstantSDNode>(C.Op1)->getZExtValue() == 0) {
2426*9880d681SAndroid Build Coastguard Worker     if (isAbsolute(C.Op0, TrueOp, FalseOp))
2427*9880d681SAndroid Build Coastguard Worker       return getAbsolute(DAG, DL, TrueOp, C.CCMask & SystemZ::CCMASK_CMP_LT);
2428*9880d681SAndroid Build Coastguard Worker     if (isAbsolute(C.Op0, FalseOp, TrueOp))
2429*9880d681SAndroid Build Coastguard Worker       return getAbsolute(DAG, DL, FalseOp, C.CCMask & SystemZ::CCMASK_CMP_GT);
2430*9880d681SAndroid Build Coastguard Worker   }
2431*9880d681SAndroid Build Coastguard Worker 
2432*9880d681SAndroid Build Coastguard Worker   SDValue Glue = emitCmp(DAG, DL, C);
2433*9880d681SAndroid Build Coastguard Worker 
2434*9880d681SAndroid Build Coastguard Worker   // Special case for handling -1/0 results.  The shifts we use here
2435*9880d681SAndroid Build Coastguard Worker   // should get optimized with the IPM conversion sequence.
2436*9880d681SAndroid Build Coastguard Worker   auto *TrueC = dyn_cast<ConstantSDNode>(TrueOp);
2437*9880d681SAndroid Build Coastguard Worker   auto *FalseC = dyn_cast<ConstantSDNode>(FalseOp);
2438*9880d681SAndroid Build Coastguard Worker   if (TrueC && FalseC) {
2439*9880d681SAndroid Build Coastguard Worker     int64_t TrueVal = TrueC->getSExtValue();
2440*9880d681SAndroid Build Coastguard Worker     int64_t FalseVal = FalseC->getSExtValue();
2441*9880d681SAndroid Build Coastguard Worker     if ((TrueVal == -1 && FalseVal == 0) || (TrueVal == 0 && FalseVal == -1)) {
2442*9880d681SAndroid Build Coastguard Worker       // Invert the condition if we want -1 on false.
2443*9880d681SAndroid Build Coastguard Worker       if (TrueVal == 0)
2444*9880d681SAndroid Build Coastguard Worker         C.CCMask ^= C.CCValid;
2445*9880d681SAndroid Build Coastguard Worker       SDValue Result = emitSETCC(DAG, DL, Glue, C.CCValid, C.CCMask);
2446*9880d681SAndroid Build Coastguard Worker       EVT VT = Op.getValueType();
2447*9880d681SAndroid Build Coastguard Worker       // Extend the result to VT.  Upper bits are ignored.
2448*9880d681SAndroid Build Coastguard Worker       if (!is32Bit(VT))
2449*9880d681SAndroid Build Coastguard Worker         Result = DAG.getNode(ISD::ANY_EXTEND, DL, VT, Result);
2450*9880d681SAndroid Build Coastguard Worker       // Sign-extend from the low bit.
2451*9880d681SAndroid Build Coastguard Worker       SDValue ShAmt = DAG.getConstant(VT.getSizeInBits() - 1, DL, MVT::i32);
2452*9880d681SAndroid Build Coastguard Worker       SDValue Shl = DAG.getNode(ISD::SHL, DL, VT, Result, ShAmt);
2453*9880d681SAndroid Build Coastguard Worker       return DAG.getNode(ISD::SRA, DL, VT, Shl, ShAmt);
2454*9880d681SAndroid Build Coastguard Worker     }
2455*9880d681SAndroid Build Coastguard Worker   }
2456*9880d681SAndroid Build Coastguard Worker 
2457*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = {TrueOp, FalseOp, DAG.getConstant(C.CCValid, DL, MVT::i32),
2458*9880d681SAndroid Build Coastguard Worker                    DAG.getConstant(C.CCMask, DL, MVT::i32), Glue};
2459*9880d681SAndroid Build Coastguard Worker 
2460*9880d681SAndroid Build Coastguard Worker   SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
2461*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(SystemZISD::SELECT_CCMASK, DL, VTs, Ops);
2462*9880d681SAndroid Build Coastguard Worker }
2463*9880d681SAndroid Build Coastguard Worker 
lowerGlobalAddress(GlobalAddressSDNode * Node,SelectionDAG & DAG) const2464*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerGlobalAddress(GlobalAddressSDNode *Node,
2465*9880d681SAndroid Build Coastguard Worker                                                   SelectionDAG &DAG) const {
2466*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Node);
2467*9880d681SAndroid Build Coastguard Worker   const GlobalValue *GV = Node->getGlobal();
2468*9880d681SAndroid Build Coastguard Worker   int64_t Offset = Node->getOffset();
2469*9880d681SAndroid Build Coastguard Worker   EVT PtrVT = getPointerTy(DAG.getDataLayout());
2470*9880d681SAndroid Build Coastguard Worker   CodeModel::Model CM = DAG.getTarget().getCodeModel();
2471*9880d681SAndroid Build Coastguard Worker 
2472*9880d681SAndroid Build Coastguard Worker   SDValue Result;
2473*9880d681SAndroid Build Coastguard Worker   if (Subtarget.isPC32DBLSymbol(GV, CM)) {
2474*9880d681SAndroid Build Coastguard Worker     // Assign anchors at 1<<12 byte boundaries.
2475*9880d681SAndroid Build Coastguard Worker     uint64_t Anchor = Offset & ~uint64_t(0xfff);
2476*9880d681SAndroid Build Coastguard Worker     Result = DAG.getTargetGlobalAddress(GV, DL, PtrVT, Anchor);
2477*9880d681SAndroid Build Coastguard Worker     Result = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result);
2478*9880d681SAndroid Build Coastguard Worker 
2479*9880d681SAndroid Build Coastguard Worker     // The offset can be folded into the address if it is aligned to a halfword.
2480*9880d681SAndroid Build Coastguard Worker     Offset -= Anchor;
2481*9880d681SAndroid Build Coastguard Worker     if (Offset != 0 && (Offset & 1) == 0) {
2482*9880d681SAndroid Build Coastguard Worker       SDValue Full = DAG.getTargetGlobalAddress(GV, DL, PtrVT, Anchor + Offset);
2483*9880d681SAndroid Build Coastguard Worker       Result = DAG.getNode(SystemZISD::PCREL_OFFSET, DL, PtrVT, Full, Result);
2484*9880d681SAndroid Build Coastguard Worker       Offset = 0;
2485*9880d681SAndroid Build Coastguard Worker     }
2486*9880d681SAndroid Build Coastguard Worker   } else {
2487*9880d681SAndroid Build Coastguard Worker     Result = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, SystemZII::MO_GOT);
2488*9880d681SAndroid Build Coastguard Worker     Result = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result);
2489*9880d681SAndroid Build Coastguard Worker     Result = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Result,
2490*9880d681SAndroid Build Coastguard Worker                          MachinePointerInfo::getGOT(DAG.getMachineFunction()),
2491*9880d681SAndroid Build Coastguard Worker                          false, false, false, 0);
2492*9880d681SAndroid Build Coastguard Worker   }
2493*9880d681SAndroid Build Coastguard Worker 
2494*9880d681SAndroid Build Coastguard Worker   // If there was a non-zero offset that we didn't fold, create an explicit
2495*9880d681SAndroid Build Coastguard Worker   // addition for it.
2496*9880d681SAndroid Build Coastguard Worker   if (Offset != 0)
2497*9880d681SAndroid Build Coastguard Worker     Result = DAG.getNode(ISD::ADD, DL, PtrVT, Result,
2498*9880d681SAndroid Build Coastguard Worker                          DAG.getConstant(Offset, DL, PtrVT));
2499*9880d681SAndroid Build Coastguard Worker 
2500*9880d681SAndroid Build Coastguard Worker   return Result;
2501*9880d681SAndroid Build Coastguard Worker }
2502*9880d681SAndroid Build Coastguard Worker 
lowerTLSGetOffset(GlobalAddressSDNode * Node,SelectionDAG & DAG,unsigned Opcode,SDValue GOTOffset) const2503*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerTLSGetOffset(GlobalAddressSDNode *Node,
2504*9880d681SAndroid Build Coastguard Worker                                                  SelectionDAG &DAG,
2505*9880d681SAndroid Build Coastguard Worker                                                  unsigned Opcode,
2506*9880d681SAndroid Build Coastguard Worker                                                  SDValue GOTOffset) const {
2507*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Node);
2508*9880d681SAndroid Build Coastguard Worker   EVT PtrVT = getPointerTy(DAG.getDataLayout());
2509*9880d681SAndroid Build Coastguard Worker   SDValue Chain = DAG.getEntryNode();
2510*9880d681SAndroid Build Coastguard Worker   SDValue Glue;
2511*9880d681SAndroid Build Coastguard Worker 
2512*9880d681SAndroid Build Coastguard Worker   // __tls_get_offset takes the GOT offset in %r2 and the GOT in %r12.
2513*9880d681SAndroid Build Coastguard Worker   SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(PtrVT);
2514*9880d681SAndroid Build Coastguard Worker   Chain = DAG.getCopyToReg(Chain, DL, SystemZ::R12D, GOT, Glue);
2515*9880d681SAndroid Build Coastguard Worker   Glue = Chain.getValue(1);
2516*9880d681SAndroid Build Coastguard Worker   Chain = DAG.getCopyToReg(Chain, DL, SystemZ::R2D, GOTOffset, Glue);
2517*9880d681SAndroid Build Coastguard Worker   Glue = Chain.getValue(1);
2518*9880d681SAndroid Build Coastguard Worker 
2519*9880d681SAndroid Build Coastguard Worker   // The first call operand is the chain and the second is the TLS symbol.
2520*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, 8> Ops;
2521*9880d681SAndroid Build Coastguard Worker   Ops.push_back(Chain);
2522*9880d681SAndroid Build Coastguard Worker   Ops.push_back(DAG.getTargetGlobalAddress(Node->getGlobal(), DL,
2523*9880d681SAndroid Build Coastguard Worker                                            Node->getValueType(0),
2524*9880d681SAndroid Build Coastguard Worker                                            0, 0));
2525*9880d681SAndroid Build Coastguard Worker 
2526*9880d681SAndroid Build Coastguard Worker   // Add argument registers to the end of the list so that they are
2527*9880d681SAndroid Build Coastguard Worker   // known live into the call.
2528*9880d681SAndroid Build Coastguard Worker   Ops.push_back(DAG.getRegister(SystemZ::R2D, PtrVT));
2529*9880d681SAndroid Build Coastguard Worker   Ops.push_back(DAG.getRegister(SystemZ::R12D, PtrVT));
2530*9880d681SAndroid Build Coastguard Worker 
2531*9880d681SAndroid Build Coastguard Worker   // Add a register mask operand representing the call-preserved registers.
2532*9880d681SAndroid Build Coastguard Worker   const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
2533*9880d681SAndroid Build Coastguard Worker   const uint32_t *Mask =
2534*9880d681SAndroid Build Coastguard Worker       TRI->getCallPreservedMask(DAG.getMachineFunction(), CallingConv::C);
2535*9880d681SAndroid Build Coastguard Worker   assert(Mask && "Missing call preserved mask for calling convention");
2536*9880d681SAndroid Build Coastguard Worker   Ops.push_back(DAG.getRegisterMask(Mask));
2537*9880d681SAndroid Build Coastguard Worker 
2538*9880d681SAndroid Build Coastguard Worker   // Glue the call to the argument copies.
2539*9880d681SAndroid Build Coastguard Worker   Ops.push_back(Glue);
2540*9880d681SAndroid Build Coastguard Worker 
2541*9880d681SAndroid Build Coastguard Worker   // Emit the call.
2542*9880d681SAndroid Build Coastguard Worker   SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
2543*9880d681SAndroid Build Coastguard Worker   Chain = DAG.getNode(Opcode, DL, NodeTys, Ops);
2544*9880d681SAndroid Build Coastguard Worker   Glue = Chain.getValue(1);
2545*9880d681SAndroid Build Coastguard Worker 
2546*9880d681SAndroid Build Coastguard Worker   // Copy the return value from %r2.
2547*9880d681SAndroid Build Coastguard Worker   return DAG.getCopyFromReg(Chain, DL, SystemZ::R2D, PtrVT, Glue);
2548*9880d681SAndroid Build Coastguard Worker }
2549*9880d681SAndroid Build Coastguard Worker 
lowerThreadPointer(const SDLoc & DL,SelectionDAG & DAG) const2550*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerThreadPointer(const SDLoc &DL,
2551*9880d681SAndroid Build Coastguard Worker                                                   SelectionDAG &DAG) const {
2552*9880d681SAndroid Build Coastguard Worker   EVT PtrVT = getPointerTy(DAG.getDataLayout());
2553*9880d681SAndroid Build Coastguard Worker 
2554*9880d681SAndroid Build Coastguard Worker   // The high part of the thread pointer is in access register 0.
2555*9880d681SAndroid Build Coastguard Worker   SDValue TPHi = DAG.getNode(SystemZISD::EXTRACT_ACCESS, DL, MVT::i32,
2556*9880d681SAndroid Build Coastguard Worker                              DAG.getConstant(0, DL, MVT::i32));
2557*9880d681SAndroid Build Coastguard Worker   TPHi = DAG.getNode(ISD::ANY_EXTEND, DL, PtrVT, TPHi);
2558*9880d681SAndroid Build Coastguard Worker 
2559*9880d681SAndroid Build Coastguard Worker   // The low part of the thread pointer is in access register 1.
2560*9880d681SAndroid Build Coastguard Worker   SDValue TPLo = DAG.getNode(SystemZISD::EXTRACT_ACCESS, DL, MVT::i32,
2561*9880d681SAndroid Build Coastguard Worker                              DAG.getConstant(1, DL, MVT::i32));
2562*9880d681SAndroid Build Coastguard Worker   TPLo = DAG.getNode(ISD::ZERO_EXTEND, DL, PtrVT, TPLo);
2563*9880d681SAndroid Build Coastguard Worker 
2564*9880d681SAndroid Build Coastguard Worker   // Merge them into a single 64-bit address.
2565*9880d681SAndroid Build Coastguard Worker   SDValue TPHiShifted = DAG.getNode(ISD::SHL, DL, PtrVT, TPHi,
2566*9880d681SAndroid Build Coastguard Worker                                     DAG.getConstant(32, DL, PtrVT));
2567*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(ISD::OR, DL, PtrVT, TPHiShifted, TPLo);
2568*9880d681SAndroid Build Coastguard Worker }
2569*9880d681SAndroid Build Coastguard Worker 
lowerGlobalTLSAddress(GlobalAddressSDNode * Node,SelectionDAG & DAG) const2570*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerGlobalTLSAddress(GlobalAddressSDNode *Node,
2571*9880d681SAndroid Build Coastguard Worker                                                      SelectionDAG &DAG) const {
2572*9880d681SAndroid Build Coastguard Worker   if (DAG.getTarget().Options.EmulatedTLS)
2573*9880d681SAndroid Build Coastguard Worker     return LowerToTLSEmulatedModel(Node, DAG);
2574*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Node);
2575*9880d681SAndroid Build Coastguard Worker   const GlobalValue *GV = Node->getGlobal();
2576*9880d681SAndroid Build Coastguard Worker   EVT PtrVT = getPointerTy(DAG.getDataLayout());
2577*9880d681SAndroid Build Coastguard Worker   TLSModel::Model model = DAG.getTarget().getTLSModel(GV);
2578*9880d681SAndroid Build Coastguard Worker 
2579*9880d681SAndroid Build Coastguard Worker   SDValue TP = lowerThreadPointer(DL, DAG);
2580*9880d681SAndroid Build Coastguard Worker 
2581*9880d681SAndroid Build Coastguard Worker   // Get the offset of GA from the thread pointer, based on the TLS model.
2582*9880d681SAndroid Build Coastguard Worker   SDValue Offset;
2583*9880d681SAndroid Build Coastguard Worker   switch (model) {
2584*9880d681SAndroid Build Coastguard Worker     case TLSModel::GeneralDynamic: {
2585*9880d681SAndroid Build Coastguard Worker       // Load the GOT offset of the tls_index (module ID / per-symbol offset).
2586*9880d681SAndroid Build Coastguard Worker       SystemZConstantPoolValue *CPV =
2587*9880d681SAndroid Build Coastguard Worker         SystemZConstantPoolValue::Create(GV, SystemZCP::TLSGD);
2588*9880d681SAndroid Build Coastguard Worker 
2589*9880d681SAndroid Build Coastguard Worker       Offset = DAG.getConstantPool(CPV, PtrVT, 8);
2590*9880d681SAndroid Build Coastguard Worker       Offset = DAG.getLoad(
2591*9880d681SAndroid Build Coastguard Worker           PtrVT, DL, DAG.getEntryNode(), Offset,
2592*9880d681SAndroid Build Coastguard Worker           MachinePointerInfo::getConstantPool(DAG.getMachineFunction()), false,
2593*9880d681SAndroid Build Coastguard Worker           false, false, 0);
2594*9880d681SAndroid Build Coastguard Worker 
2595*9880d681SAndroid Build Coastguard Worker       // Call __tls_get_offset to retrieve the offset.
2596*9880d681SAndroid Build Coastguard Worker       Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_GDCALL, Offset);
2597*9880d681SAndroid Build Coastguard Worker       break;
2598*9880d681SAndroid Build Coastguard Worker     }
2599*9880d681SAndroid Build Coastguard Worker 
2600*9880d681SAndroid Build Coastguard Worker     case TLSModel::LocalDynamic: {
2601*9880d681SAndroid Build Coastguard Worker       // Load the GOT offset of the module ID.
2602*9880d681SAndroid Build Coastguard Worker       SystemZConstantPoolValue *CPV =
2603*9880d681SAndroid Build Coastguard Worker         SystemZConstantPoolValue::Create(GV, SystemZCP::TLSLDM);
2604*9880d681SAndroid Build Coastguard Worker 
2605*9880d681SAndroid Build Coastguard Worker       Offset = DAG.getConstantPool(CPV, PtrVT, 8);
2606*9880d681SAndroid Build Coastguard Worker       Offset = DAG.getLoad(
2607*9880d681SAndroid Build Coastguard Worker           PtrVT, DL, DAG.getEntryNode(), Offset,
2608*9880d681SAndroid Build Coastguard Worker           MachinePointerInfo::getConstantPool(DAG.getMachineFunction()), false,
2609*9880d681SAndroid Build Coastguard Worker           false, false, 0);
2610*9880d681SAndroid Build Coastguard Worker 
2611*9880d681SAndroid Build Coastguard Worker       // Call __tls_get_offset to retrieve the module base offset.
2612*9880d681SAndroid Build Coastguard Worker       Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_LDCALL, Offset);
2613*9880d681SAndroid Build Coastguard Worker 
2614*9880d681SAndroid Build Coastguard Worker       // Note: The SystemZLDCleanupPass will remove redundant computations
2615*9880d681SAndroid Build Coastguard Worker       // of the module base offset.  Count total number of local-dynamic
2616*9880d681SAndroid Build Coastguard Worker       // accesses to trigger execution of that pass.
2617*9880d681SAndroid Build Coastguard Worker       SystemZMachineFunctionInfo* MFI =
2618*9880d681SAndroid Build Coastguard Worker         DAG.getMachineFunction().getInfo<SystemZMachineFunctionInfo>();
2619*9880d681SAndroid Build Coastguard Worker       MFI->incNumLocalDynamicTLSAccesses();
2620*9880d681SAndroid Build Coastguard Worker 
2621*9880d681SAndroid Build Coastguard Worker       // Add the per-symbol offset.
2622*9880d681SAndroid Build Coastguard Worker       CPV = SystemZConstantPoolValue::Create(GV, SystemZCP::DTPOFF);
2623*9880d681SAndroid Build Coastguard Worker 
2624*9880d681SAndroid Build Coastguard Worker       SDValue DTPOffset = DAG.getConstantPool(CPV, PtrVT, 8);
2625*9880d681SAndroid Build Coastguard Worker       DTPOffset = DAG.getLoad(
2626*9880d681SAndroid Build Coastguard Worker           PtrVT, DL, DAG.getEntryNode(), DTPOffset,
2627*9880d681SAndroid Build Coastguard Worker           MachinePointerInfo::getConstantPool(DAG.getMachineFunction()), false,
2628*9880d681SAndroid Build Coastguard Worker           false, false, 0);
2629*9880d681SAndroid Build Coastguard Worker 
2630*9880d681SAndroid Build Coastguard Worker       Offset = DAG.getNode(ISD::ADD, DL, PtrVT, Offset, DTPOffset);
2631*9880d681SAndroid Build Coastguard Worker       break;
2632*9880d681SAndroid Build Coastguard Worker     }
2633*9880d681SAndroid Build Coastguard Worker 
2634*9880d681SAndroid Build Coastguard Worker     case TLSModel::InitialExec: {
2635*9880d681SAndroid Build Coastguard Worker       // Load the offset from the GOT.
2636*9880d681SAndroid Build Coastguard Worker       Offset = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0,
2637*9880d681SAndroid Build Coastguard Worker                                           SystemZII::MO_INDNTPOFF);
2638*9880d681SAndroid Build Coastguard Worker       Offset = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Offset);
2639*9880d681SAndroid Build Coastguard Worker       Offset = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Offset,
2640*9880d681SAndroid Build Coastguard Worker                            MachinePointerInfo::getGOT(DAG.getMachineFunction()),
2641*9880d681SAndroid Build Coastguard Worker                            false, false, false, 0);
2642*9880d681SAndroid Build Coastguard Worker       break;
2643*9880d681SAndroid Build Coastguard Worker     }
2644*9880d681SAndroid Build Coastguard Worker 
2645*9880d681SAndroid Build Coastguard Worker     case TLSModel::LocalExec: {
2646*9880d681SAndroid Build Coastguard Worker       // Force the offset into the constant pool and load it from there.
2647*9880d681SAndroid Build Coastguard Worker       SystemZConstantPoolValue *CPV =
2648*9880d681SAndroid Build Coastguard Worker         SystemZConstantPoolValue::Create(GV, SystemZCP::NTPOFF);
2649*9880d681SAndroid Build Coastguard Worker 
2650*9880d681SAndroid Build Coastguard Worker       Offset = DAG.getConstantPool(CPV, PtrVT, 8);
2651*9880d681SAndroid Build Coastguard Worker       Offset = DAG.getLoad(
2652*9880d681SAndroid Build Coastguard Worker           PtrVT, DL, DAG.getEntryNode(), Offset,
2653*9880d681SAndroid Build Coastguard Worker           MachinePointerInfo::getConstantPool(DAG.getMachineFunction()), false,
2654*9880d681SAndroid Build Coastguard Worker           false, false, 0);
2655*9880d681SAndroid Build Coastguard Worker       break;
2656*9880d681SAndroid Build Coastguard Worker     }
2657*9880d681SAndroid Build Coastguard Worker   }
2658*9880d681SAndroid Build Coastguard Worker 
2659*9880d681SAndroid Build Coastguard Worker   // Add the base and offset together.
2660*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(ISD::ADD, DL, PtrVT, TP, Offset);
2661*9880d681SAndroid Build Coastguard Worker }
2662*9880d681SAndroid Build Coastguard Worker 
lowerBlockAddress(BlockAddressSDNode * Node,SelectionDAG & DAG) const2663*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerBlockAddress(BlockAddressSDNode *Node,
2664*9880d681SAndroid Build Coastguard Worker                                                  SelectionDAG &DAG) const {
2665*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Node);
2666*9880d681SAndroid Build Coastguard Worker   const BlockAddress *BA = Node->getBlockAddress();
2667*9880d681SAndroid Build Coastguard Worker   int64_t Offset = Node->getOffset();
2668*9880d681SAndroid Build Coastguard Worker   EVT PtrVT = getPointerTy(DAG.getDataLayout());
2669*9880d681SAndroid Build Coastguard Worker 
2670*9880d681SAndroid Build Coastguard Worker   SDValue Result = DAG.getTargetBlockAddress(BA, PtrVT, Offset);
2671*9880d681SAndroid Build Coastguard Worker   Result = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result);
2672*9880d681SAndroid Build Coastguard Worker   return Result;
2673*9880d681SAndroid Build Coastguard Worker }
2674*9880d681SAndroid Build Coastguard Worker 
lowerJumpTable(JumpTableSDNode * JT,SelectionDAG & DAG) const2675*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerJumpTable(JumpTableSDNode *JT,
2676*9880d681SAndroid Build Coastguard Worker                                               SelectionDAG &DAG) const {
2677*9880d681SAndroid Build Coastguard Worker   SDLoc DL(JT);
2678*9880d681SAndroid Build Coastguard Worker   EVT PtrVT = getPointerTy(DAG.getDataLayout());
2679*9880d681SAndroid Build Coastguard Worker   SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
2680*9880d681SAndroid Build Coastguard Worker 
2681*9880d681SAndroid Build Coastguard Worker   // Use LARL to load the address of the table.
2682*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result);
2683*9880d681SAndroid Build Coastguard Worker }
2684*9880d681SAndroid Build Coastguard Worker 
lowerConstantPool(ConstantPoolSDNode * CP,SelectionDAG & DAG) const2685*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerConstantPool(ConstantPoolSDNode *CP,
2686*9880d681SAndroid Build Coastguard Worker                                                  SelectionDAG &DAG) const {
2687*9880d681SAndroid Build Coastguard Worker   SDLoc DL(CP);
2688*9880d681SAndroid Build Coastguard Worker   EVT PtrVT = getPointerTy(DAG.getDataLayout());
2689*9880d681SAndroid Build Coastguard Worker 
2690*9880d681SAndroid Build Coastguard Worker   SDValue Result;
2691*9880d681SAndroid Build Coastguard Worker   if (CP->isMachineConstantPoolEntry())
2692*9880d681SAndroid Build Coastguard Worker     Result = DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT,
2693*9880d681SAndroid Build Coastguard Worker                                        CP->getAlignment());
2694*9880d681SAndroid Build Coastguard Worker   else
2695*9880d681SAndroid Build Coastguard Worker     Result = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT,
2696*9880d681SAndroid Build Coastguard Worker                                        CP->getAlignment(), CP->getOffset());
2697*9880d681SAndroid Build Coastguard Worker 
2698*9880d681SAndroid Build Coastguard Worker   // Use LARL to load the address of the constant pool entry.
2699*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result);
2700*9880d681SAndroid Build Coastguard Worker }
2701*9880d681SAndroid Build Coastguard Worker 
lowerFRAMEADDR(SDValue Op,SelectionDAG & DAG) const2702*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerFRAMEADDR(SDValue Op,
2703*9880d681SAndroid Build Coastguard Worker                                               SelectionDAG &DAG) const {
2704*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = DAG.getMachineFunction();
2705*9880d681SAndroid Build Coastguard Worker   MachineFrameInfo *MFI = MF.getFrameInfo();
2706*9880d681SAndroid Build Coastguard Worker   MFI->setFrameAddressIsTaken(true);
2707*9880d681SAndroid Build Coastguard Worker 
2708*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
2709*9880d681SAndroid Build Coastguard Worker   unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
2710*9880d681SAndroid Build Coastguard Worker   EVT PtrVT = getPointerTy(DAG.getDataLayout());
2711*9880d681SAndroid Build Coastguard Worker 
2712*9880d681SAndroid Build Coastguard Worker   // If the back chain frame index has not been allocated yet, do so.
2713*9880d681SAndroid Build Coastguard Worker   SystemZMachineFunctionInfo *FI = MF.getInfo<SystemZMachineFunctionInfo>();
2714*9880d681SAndroid Build Coastguard Worker   int BackChainIdx = FI->getFramePointerSaveIndex();
2715*9880d681SAndroid Build Coastguard Worker   if (!BackChainIdx) {
2716*9880d681SAndroid Build Coastguard Worker     // By definition, the frame address is the address of the back chain.
2717*9880d681SAndroid Build Coastguard Worker     BackChainIdx = MFI->CreateFixedObject(8, -SystemZMC::CallFrameSize, false);
2718*9880d681SAndroid Build Coastguard Worker     FI->setFramePointerSaveIndex(BackChainIdx);
2719*9880d681SAndroid Build Coastguard Worker   }
2720*9880d681SAndroid Build Coastguard Worker   SDValue BackChain = DAG.getFrameIndex(BackChainIdx, PtrVT);
2721*9880d681SAndroid Build Coastguard Worker 
2722*9880d681SAndroid Build Coastguard Worker   // FIXME The frontend should detect this case.
2723*9880d681SAndroid Build Coastguard Worker   if (Depth > 0) {
2724*9880d681SAndroid Build Coastguard Worker     report_fatal_error("Unsupported stack frame traversal count");
2725*9880d681SAndroid Build Coastguard Worker   }
2726*9880d681SAndroid Build Coastguard Worker 
2727*9880d681SAndroid Build Coastguard Worker   return BackChain;
2728*9880d681SAndroid Build Coastguard Worker }
2729*9880d681SAndroid Build Coastguard Worker 
lowerRETURNADDR(SDValue Op,SelectionDAG & DAG) const2730*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerRETURNADDR(SDValue Op,
2731*9880d681SAndroid Build Coastguard Worker                                                SelectionDAG &DAG) const {
2732*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = DAG.getMachineFunction();
2733*9880d681SAndroid Build Coastguard Worker   MachineFrameInfo *MFI = MF.getFrameInfo();
2734*9880d681SAndroid Build Coastguard Worker   MFI->setReturnAddressIsTaken(true);
2735*9880d681SAndroid Build Coastguard Worker 
2736*9880d681SAndroid Build Coastguard Worker   if (verifyReturnAddressArgumentIsConstant(Op, DAG))
2737*9880d681SAndroid Build Coastguard Worker     return SDValue();
2738*9880d681SAndroid Build Coastguard Worker 
2739*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
2740*9880d681SAndroid Build Coastguard Worker   unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
2741*9880d681SAndroid Build Coastguard Worker   EVT PtrVT = getPointerTy(DAG.getDataLayout());
2742*9880d681SAndroid Build Coastguard Worker 
2743*9880d681SAndroid Build Coastguard Worker   // FIXME The frontend should detect this case.
2744*9880d681SAndroid Build Coastguard Worker   if (Depth > 0) {
2745*9880d681SAndroid Build Coastguard Worker     report_fatal_error("Unsupported stack frame traversal count");
2746*9880d681SAndroid Build Coastguard Worker   }
2747*9880d681SAndroid Build Coastguard Worker 
2748*9880d681SAndroid Build Coastguard Worker   // Return R14D, which has the return address. Mark it an implicit live-in.
2749*9880d681SAndroid Build Coastguard Worker   unsigned LinkReg = MF.addLiveIn(SystemZ::R14D, &SystemZ::GR64BitRegClass);
2750*9880d681SAndroid Build Coastguard Worker   return DAG.getCopyFromReg(DAG.getEntryNode(), DL, LinkReg, PtrVT);
2751*9880d681SAndroid Build Coastguard Worker }
2752*9880d681SAndroid Build Coastguard Worker 
lowerBITCAST(SDValue Op,SelectionDAG & DAG) const2753*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerBITCAST(SDValue Op,
2754*9880d681SAndroid Build Coastguard Worker                                             SelectionDAG &DAG) const {
2755*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
2756*9880d681SAndroid Build Coastguard Worker   SDValue In = Op.getOperand(0);
2757*9880d681SAndroid Build Coastguard Worker   EVT InVT = In.getValueType();
2758*9880d681SAndroid Build Coastguard Worker   EVT ResVT = Op.getValueType();
2759*9880d681SAndroid Build Coastguard Worker 
2760*9880d681SAndroid Build Coastguard Worker   // Convert loads directly.  This is normally done by DAGCombiner,
2761*9880d681SAndroid Build Coastguard Worker   // but we need this case for bitcasts that are created during lowering
2762*9880d681SAndroid Build Coastguard Worker   // and which are then lowered themselves.
2763*9880d681SAndroid Build Coastguard Worker   if (auto *LoadN = dyn_cast<LoadSDNode>(In))
2764*9880d681SAndroid Build Coastguard Worker     return DAG.getLoad(ResVT, DL, LoadN->getChain(), LoadN->getBasePtr(),
2765*9880d681SAndroid Build Coastguard Worker                        LoadN->getMemOperand());
2766*9880d681SAndroid Build Coastguard Worker 
2767*9880d681SAndroid Build Coastguard Worker   if (InVT == MVT::i32 && ResVT == MVT::f32) {
2768*9880d681SAndroid Build Coastguard Worker     SDValue In64;
2769*9880d681SAndroid Build Coastguard Worker     if (Subtarget.hasHighWord()) {
2770*9880d681SAndroid Build Coastguard Worker       SDNode *U64 = DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL,
2771*9880d681SAndroid Build Coastguard Worker                                        MVT::i64);
2772*9880d681SAndroid Build Coastguard Worker       In64 = DAG.getTargetInsertSubreg(SystemZ::subreg_h32, DL,
2773*9880d681SAndroid Build Coastguard Worker                                        MVT::i64, SDValue(U64, 0), In);
2774*9880d681SAndroid Build Coastguard Worker     } else {
2775*9880d681SAndroid Build Coastguard Worker       In64 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, In);
2776*9880d681SAndroid Build Coastguard Worker       In64 = DAG.getNode(ISD::SHL, DL, MVT::i64, In64,
2777*9880d681SAndroid Build Coastguard Worker                          DAG.getConstant(32, DL, MVT::i64));
2778*9880d681SAndroid Build Coastguard Worker     }
2779*9880d681SAndroid Build Coastguard Worker     SDValue Out64 = DAG.getNode(ISD::BITCAST, DL, MVT::f64, In64);
2780*9880d681SAndroid Build Coastguard Worker     return DAG.getTargetExtractSubreg(SystemZ::subreg_r32,
2781*9880d681SAndroid Build Coastguard Worker                                       DL, MVT::f32, Out64);
2782*9880d681SAndroid Build Coastguard Worker   }
2783*9880d681SAndroid Build Coastguard Worker   if (InVT == MVT::f32 && ResVT == MVT::i32) {
2784*9880d681SAndroid Build Coastguard Worker     SDNode *U64 = DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::f64);
2785*9880d681SAndroid Build Coastguard Worker     SDValue In64 = DAG.getTargetInsertSubreg(SystemZ::subreg_r32, DL,
2786*9880d681SAndroid Build Coastguard Worker                                              MVT::f64, SDValue(U64, 0), In);
2787*9880d681SAndroid Build Coastguard Worker     SDValue Out64 = DAG.getNode(ISD::BITCAST, DL, MVT::i64, In64);
2788*9880d681SAndroid Build Coastguard Worker     if (Subtarget.hasHighWord())
2789*9880d681SAndroid Build Coastguard Worker       return DAG.getTargetExtractSubreg(SystemZ::subreg_h32, DL,
2790*9880d681SAndroid Build Coastguard Worker                                         MVT::i32, Out64);
2791*9880d681SAndroid Build Coastguard Worker     SDValue Shift = DAG.getNode(ISD::SRL, DL, MVT::i64, Out64,
2792*9880d681SAndroid Build Coastguard Worker                                 DAG.getConstant(32, DL, MVT::i64));
2793*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Shift);
2794*9880d681SAndroid Build Coastguard Worker   }
2795*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Unexpected bitcast combination");
2796*9880d681SAndroid Build Coastguard Worker }
2797*9880d681SAndroid Build Coastguard Worker 
lowerVASTART(SDValue Op,SelectionDAG & DAG) const2798*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerVASTART(SDValue Op,
2799*9880d681SAndroid Build Coastguard Worker                                             SelectionDAG &DAG) const {
2800*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = DAG.getMachineFunction();
2801*9880d681SAndroid Build Coastguard Worker   SystemZMachineFunctionInfo *FuncInfo =
2802*9880d681SAndroid Build Coastguard Worker     MF.getInfo<SystemZMachineFunctionInfo>();
2803*9880d681SAndroid Build Coastguard Worker   EVT PtrVT = getPointerTy(DAG.getDataLayout());
2804*9880d681SAndroid Build Coastguard Worker 
2805*9880d681SAndroid Build Coastguard Worker   SDValue Chain   = Op.getOperand(0);
2806*9880d681SAndroid Build Coastguard Worker   SDValue Addr    = Op.getOperand(1);
2807*9880d681SAndroid Build Coastguard Worker   const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
2808*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
2809*9880d681SAndroid Build Coastguard Worker 
2810*9880d681SAndroid Build Coastguard Worker   // The initial values of each field.
2811*9880d681SAndroid Build Coastguard Worker   const unsigned NumFields = 4;
2812*9880d681SAndroid Build Coastguard Worker   SDValue Fields[NumFields] = {
2813*9880d681SAndroid Build Coastguard Worker     DAG.getConstant(FuncInfo->getVarArgsFirstGPR(), DL, PtrVT),
2814*9880d681SAndroid Build Coastguard Worker     DAG.getConstant(FuncInfo->getVarArgsFirstFPR(), DL, PtrVT),
2815*9880d681SAndroid Build Coastguard Worker     DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT),
2816*9880d681SAndroid Build Coastguard Worker     DAG.getFrameIndex(FuncInfo->getRegSaveFrameIndex(), PtrVT)
2817*9880d681SAndroid Build Coastguard Worker   };
2818*9880d681SAndroid Build Coastguard Worker 
2819*9880d681SAndroid Build Coastguard Worker   // Store each field into its respective slot.
2820*9880d681SAndroid Build Coastguard Worker   SDValue MemOps[NumFields];
2821*9880d681SAndroid Build Coastguard Worker   unsigned Offset = 0;
2822*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0; I < NumFields; ++I) {
2823*9880d681SAndroid Build Coastguard Worker     SDValue FieldAddr = Addr;
2824*9880d681SAndroid Build Coastguard Worker     if (Offset != 0)
2825*9880d681SAndroid Build Coastguard Worker       FieldAddr = DAG.getNode(ISD::ADD, DL, PtrVT, FieldAddr,
2826*9880d681SAndroid Build Coastguard Worker                               DAG.getIntPtrConstant(Offset, DL));
2827*9880d681SAndroid Build Coastguard Worker     MemOps[I] = DAG.getStore(Chain, DL, Fields[I], FieldAddr,
2828*9880d681SAndroid Build Coastguard Worker                              MachinePointerInfo(SV, Offset),
2829*9880d681SAndroid Build Coastguard Worker                              false, false, 0);
2830*9880d681SAndroid Build Coastguard Worker     Offset += 8;
2831*9880d681SAndroid Build Coastguard Worker   }
2832*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOps);
2833*9880d681SAndroid Build Coastguard Worker }
2834*9880d681SAndroid Build Coastguard Worker 
lowerVACOPY(SDValue Op,SelectionDAG & DAG) const2835*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerVACOPY(SDValue Op,
2836*9880d681SAndroid Build Coastguard Worker                                            SelectionDAG &DAG) const {
2837*9880d681SAndroid Build Coastguard Worker   SDValue Chain      = Op.getOperand(0);
2838*9880d681SAndroid Build Coastguard Worker   SDValue DstPtr     = Op.getOperand(1);
2839*9880d681SAndroid Build Coastguard Worker   SDValue SrcPtr     = Op.getOperand(2);
2840*9880d681SAndroid Build Coastguard Worker   const Value *DstSV = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();
2841*9880d681SAndroid Build Coastguard Worker   const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
2842*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
2843*9880d681SAndroid Build Coastguard Worker 
2844*9880d681SAndroid Build Coastguard Worker   return DAG.getMemcpy(Chain, DL, DstPtr, SrcPtr, DAG.getIntPtrConstant(32, DL),
2845*9880d681SAndroid Build Coastguard Worker                        /*Align*/8, /*isVolatile*/false, /*AlwaysInline*/false,
2846*9880d681SAndroid Build Coastguard Worker                        /*isTailCall*/false,
2847*9880d681SAndroid Build Coastguard Worker                        MachinePointerInfo(DstSV), MachinePointerInfo(SrcSV));
2848*9880d681SAndroid Build Coastguard Worker }
2849*9880d681SAndroid Build Coastguard Worker 
2850*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::
lowerDYNAMIC_STACKALLOC(SDValue Op,SelectionDAG & DAG) const2851*9880d681SAndroid Build Coastguard Worker lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const {
2852*9880d681SAndroid Build Coastguard Worker   const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
2853*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = DAG.getMachineFunction();
2854*9880d681SAndroid Build Coastguard Worker   bool RealignOpt = !MF.getFunction()-> hasFnAttribute("no-realign-stack");
2855*9880d681SAndroid Build Coastguard Worker   bool StoreBackchain = MF.getFunction()->hasFnAttribute("backchain");
2856*9880d681SAndroid Build Coastguard Worker 
2857*9880d681SAndroid Build Coastguard Worker   SDValue Chain = Op.getOperand(0);
2858*9880d681SAndroid Build Coastguard Worker   SDValue Size  = Op.getOperand(1);
2859*9880d681SAndroid Build Coastguard Worker   SDValue Align = Op.getOperand(2);
2860*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
2861*9880d681SAndroid Build Coastguard Worker 
2862*9880d681SAndroid Build Coastguard Worker   // If user has set the no alignment function attribute, ignore
2863*9880d681SAndroid Build Coastguard Worker   // alloca alignments.
2864*9880d681SAndroid Build Coastguard Worker   uint64_t AlignVal = (RealignOpt ?
2865*9880d681SAndroid Build Coastguard Worker                        dyn_cast<ConstantSDNode>(Align)->getZExtValue() : 0);
2866*9880d681SAndroid Build Coastguard Worker 
2867*9880d681SAndroid Build Coastguard Worker   uint64_t StackAlign = TFI->getStackAlignment();
2868*9880d681SAndroid Build Coastguard Worker   uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
2869*9880d681SAndroid Build Coastguard Worker   uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
2870*9880d681SAndroid Build Coastguard Worker 
2871*9880d681SAndroid Build Coastguard Worker   unsigned SPReg = getStackPointerRegisterToSaveRestore();
2872*9880d681SAndroid Build Coastguard Worker   SDValue NeededSpace = Size;
2873*9880d681SAndroid Build Coastguard Worker 
2874*9880d681SAndroid Build Coastguard Worker   // Get a reference to the stack pointer.
2875*9880d681SAndroid Build Coastguard Worker   SDValue OldSP = DAG.getCopyFromReg(Chain, DL, SPReg, MVT::i64);
2876*9880d681SAndroid Build Coastguard Worker 
2877*9880d681SAndroid Build Coastguard Worker   // If we need a backchain, save it now.
2878*9880d681SAndroid Build Coastguard Worker   SDValue Backchain;
2879*9880d681SAndroid Build Coastguard Worker   if (StoreBackchain)
2880*9880d681SAndroid Build Coastguard Worker     Backchain = DAG.getLoad(MVT::i64, DL, Chain, OldSP, MachinePointerInfo(),
2881*9880d681SAndroid Build Coastguard Worker                             false, false, false, 0);
2882*9880d681SAndroid Build Coastguard Worker 
2883*9880d681SAndroid Build Coastguard Worker   // Add extra space for alignment if needed.
2884*9880d681SAndroid Build Coastguard Worker   if (ExtraAlignSpace)
2885*9880d681SAndroid Build Coastguard Worker     NeededSpace = DAG.getNode(ISD::ADD, DL, MVT::i64, NeededSpace,
2886*9880d681SAndroid Build Coastguard Worker                               DAG.getConstant(ExtraAlignSpace, DL, MVT::i64));
2887*9880d681SAndroid Build Coastguard Worker 
2888*9880d681SAndroid Build Coastguard Worker   // Get the new stack pointer value.
2889*9880d681SAndroid Build Coastguard Worker   SDValue NewSP = DAG.getNode(ISD::SUB, DL, MVT::i64, OldSP, NeededSpace);
2890*9880d681SAndroid Build Coastguard Worker 
2891*9880d681SAndroid Build Coastguard Worker   // Copy the new stack pointer back.
2892*9880d681SAndroid Build Coastguard Worker   Chain = DAG.getCopyToReg(Chain, DL, SPReg, NewSP);
2893*9880d681SAndroid Build Coastguard Worker 
2894*9880d681SAndroid Build Coastguard Worker   // The allocated data lives above the 160 bytes allocated for the standard
2895*9880d681SAndroid Build Coastguard Worker   // frame, plus any outgoing stack arguments.  We don't know how much that
2896*9880d681SAndroid Build Coastguard Worker   // amounts to yet, so emit a special ADJDYNALLOC placeholder.
2897*9880d681SAndroid Build Coastguard Worker   SDValue ArgAdjust = DAG.getNode(SystemZISD::ADJDYNALLOC, DL, MVT::i64);
2898*9880d681SAndroid Build Coastguard Worker   SDValue Result = DAG.getNode(ISD::ADD, DL, MVT::i64, NewSP, ArgAdjust);
2899*9880d681SAndroid Build Coastguard Worker 
2900*9880d681SAndroid Build Coastguard Worker   // Dynamically realign if needed.
2901*9880d681SAndroid Build Coastguard Worker   if (RequiredAlign > StackAlign) {
2902*9880d681SAndroid Build Coastguard Worker     Result =
2903*9880d681SAndroid Build Coastguard Worker       DAG.getNode(ISD::ADD, DL, MVT::i64, Result,
2904*9880d681SAndroid Build Coastguard Worker                   DAG.getConstant(ExtraAlignSpace, DL, MVT::i64));
2905*9880d681SAndroid Build Coastguard Worker     Result =
2906*9880d681SAndroid Build Coastguard Worker       DAG.getNode(ISD::AND, DL, MVT::i64, Result,
2907*9880d681SAndroid Build Coastguard Worker                   DAG.getConstant(~(RequiredAlign - 1), DL, MVT::i64));
2908*9880d681SAndroid Build Coastguard Worker   }
2909*9880d681SAndroid Build Coastguard Worker 
2910*9880d681SAndroid Build Coastguard Worker   if (StoreBackchain)
2911*9880d681SAndroid Build Coastguard Worker     Chain = DAG.getStore(Chain, DL, Backchain, NewSP, MachinePointerInfo(),
2912*9880d681SAndroid Build Coastguard Worker                          false, false, 0);
2913*9880d681SAndroid Build Coastguard Worker 
2914*9880d681SAndroid Build Coastguard Worker   SDValue Ops[2] = { Result, Chain };
2915*9880d681SAndroid Build Coastguard Worker   return DAG.getMergeValues(Ops, DL);
2916*9880d681SAndroid Build Coastguard Worker }
2917*9880d681SAndroid Build Coastguard Worker 
lowerGET_DYNAMIC_AREA_OFFSET(SDValue Op,SelectionDAG & DAG) const2918*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerGET_DYNAMIC_AREA_OFFSET(
2919*9880d681SAndroid Build Coastguard Worker     SDValue Op, SelectionDAG &DAG) const {
2920*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
2921*9880d681SAndroid Build Coastguard Worker 
2922*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(SystemZISD::ADJDYNALLOC, DL, MVT::i64);
2923*9880d681SAndroid Build Coastguard Worker }
2924*9880d681SAndroid Build Coastguard Worker 
lowerSMUL_LOHI(SDValue Op,SelectionDAG & DAG) const2925*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerSMUL_LOHI(SDValue Op,
2926*9880d681SAndroid Build Coastguard Worker                                               SelectionDAG &DAG) const {
2927*9880d681SAndroid Build Coastguard Worker   EVT VT = Op.getValueType();
2928*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
2929*9880d681SAndroid Build Coastguard Worker   SDValue Ops[2];
2930*9880d681SAndroid Build Coastguard Worker   if (is32Bit(VT))
2931*9880d681SAndroid Build Coastguard Worker     // Just do a normal 64-bit multiplication and extract the results.
2932*9880d681SAndroid Build Coastguard Worker     // We define this so that it can be used for constant division.
2933*9880d681SAndroid Build Coastguard Worker     lowerMUL_LOHI32(DAG, DL, ISD::SIGN_EXTEND, Op.getOperand(0),
2934*9880d681SAndroid Build Coastguard Worker                     Op.getOperand(1), Ops[1], Ops[0]);
2935*9880d681SAndroid Build Coastguard Worker   else {
2936*9880d681SAndroid Build Coastguard Worker     // Do a full 128-bit multiplication based on UMUL_LOHI64:
2937*9880d681SAndroid Build Coastguard Worker     //
2938*9880d681SAndroid Build Coastguard Worker     //   (ll * rl) + ((lh * rl) << 64) + ((ll * rh) << 64)
2939*9880d681SAndroid Build Coastguard Worker     //
2940*9880d681SAndroid Build Coastguard Worker     // but using the fact that the upper halves are either all zeros
2941*9880d681SAndroid Build Coastguard Worker     // or all ones:
2942*9880d681SAndroid Build Coastguard Worker     //
2943*9880d681SAndroid Build Coastguard Worker     //   (ll * rl) - ((lh & rl) << 64) - ((ll & rh) << 64)
2944*9880d681SAndroid Build Coastguard Worker     //
2945*9880d681SAndroid Build Coastguard Worker     // and grouping the right terms together since they are quicker than the
2946*9880d681SAndroid Build Coastguard Worker     // multiplication:
2947*9880d681SAndroid Build Coastguard Worker     //
2948*9880d681SAndroid Build Coastguard Worker     //   (ll * rl) - (((lh & rl) + (ll & rh)) << 64)
2949*9880d681SAndroid Build Coastguard Worker     SDValue C63 = DAG.getConstant(63, DL, MVT::i64);
2950*9880d681SAndroid Build Coastguard Worker     SDValue LL = Op.getOperand(0);
2951*9880d681SAndroid Build Coastguard Worker     SDValue RL = Op.getOperand(1);
2952*9880d681SAndroid Build Coastguard Worker     SDValue LH = DAG.getNode(ISD::SRA, DL, VT, LL, C63);
2953*9880d681SAndroid Build Coastguard Worker     SDValue RH = DAG.getNode(ISD::SRA, DL, VT, RL, C63);
2954*9880d681SAndroid Build Coastguard Worker     // UMUL_LOHI64 returns the low result in the odd register and the high
2955*9880d681SAndroid Build Coastguard Worker     // result in the even register.  SMUL_LOHI is defined to return the
2956*9880d681SAndroid Build Coastguard Worker     // low half first, so the results are in reverse order.
2957*9880d681SAndroid Build Coastguard Worker     lowerGR128Binary(DAG, DL, VT, SystemZ::AEXT128_64, SystemZISD::UMUL_LOHI64,
2958*9880d681SAndroid Build Coastguard Worker                      LL, RL, Ops[1], Ops[0]);
2959*9880d681SAndroid Build Coastguard Worker     SDValue NegLLTimesRH = DAG.getNode(ISD::AND, DL, VT, LL, RH);
2960*9880d681SAndroid Build Coastguard Worker     SDValue NegLHTimesRL = DAG.getNode(ISD::AND, DL, VT, LH, RL);
2961*9880d681SAndroid Build Coastguard Worker     SDValue NegSum = DAG.getNode(ISD::ADD, DL, VT, NegLLTimesRH, NegLHTimesRL);
2962*9880d681SAndroid Build Coastguard Worker     Ops[1] = DAG.getNode(ISD::SUB, DL, VT, Ops[1], NegSum);
2963*9880d681SAndroid Build Coastguard Worker   }
2964*9880d681SAndroid Build Coastguard Worker   return DAG.getMergeValues(Ops, DL);
2965*9880d681SAndroid Build Coastguard Worker }
2966*9880d681SAndroid Build Coastguard Worker 
lowerUMUL_LOHI(SDValue Op,SelectionDAG & DAG) const2967*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerUMUL_LOHI(SDValue Op,
2968*9880d681SAndroid Build Coastguard Worker                                               SelectionDAG &DAG) const {
2969*9880d681SAndroid Build Coastguard Worker   EVT VT = Op.getValueType();
2970*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
2971*9880d681SAndroid Build Coastguard Worker   SDValue Ops[2];
2972*9880d681SAndroid Build Coastguard Worker   if (is32Bit(VT))
2973*9880d681SAndroid Build Coastguard Worker     // Just do a normal 64-bit multiplication and extract the results.
2974*9880d681SAndroid Build Coastguard Worker     // We define this so that it can be used for constant division.
2975*9880d681SAndroid Build Coastguard Worker     lowerMUL_LOHI32(DAG, DL, ISD::ZERO_EXTEND, Op.getOperand(0),
2976*9880d681SAndroid Build Coastguard Worker                     Op.getOperand(1), Ops[1], Ops[0]);
2977*9880d681SAndroid Build Coastguard Worker   else
2978*9880d681SAndroid Build Coastguard Worker     // UMUL_LOHI64 returns the low result in the odd register and the high
2979*9880d681SAndroid Build Coastguard Worker     // result in the even register.  UMUL_LOHI is defined to return the
2980*9880d681SAndroid Build Coastguard Worker     // low half first, so the results are in reverse order.
2981*9880d681SAndroid Build Coastguard Worker     lowerGR128Binary(DAG, DL, VT, SystemZ::AEXT128_64, SystemZISD::UMUL_LOHI64,
2982*9880d681SAndroid Build Coastguard Worker                      Op.getOperand(0), Op.getOperand(1), Ops[1], Ops[0]);
2983*9880d681SAndroid Build Coastguard Worker   return DAG.getMergeValues(Ops, DL);
2984*9880d681SAndroid Build Coastguard Worker }
2985*9880d681SAndroid Build Coastguard Worker 
lowerSDIVREM(SDValue Op,SelectionDAG & DAG) const2986*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerSDIVREM(SDValue Op,
2987*9880d681SAndroid Build Coastguard Worker                                             SelectionDAG &DAG) const {
2988*9880d681SAndroid Build Coastguard Worker   SDValue Op0 = Op.getOperand(0);
2989*9880d681SAndroid Build Coastguard Worker   SDValue Op1 = Op.getOperand(1);
2990*9880d681SAndroid Build Coastguard Worker   EVT VT = Op.getValueType();
2991*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
2992*9880d681SAndroid Build Coastguard Worker   unsigned Opcode;
2993*9880d681SAndroid Build Coastguard Worker 
2994*9880d681SAndroid Build Coastguard Worker   // We use DSGF for 32-bit division.
2995*9880d681SAndroid Build Coastguard Worker   if (is32Bit(VT)) {
2996*9880d681SAndroid Build Coastguard Worker     Op0 = DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, Op0);
2997*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::SDIVREM32;
2998*9880d681SAndroid Build Coastguard Worker   } else if (DAG.ComputeNumSignBits(Op1) > 32) {
2999*9880d681SAndroid Build Coastguard Worker     Op1 = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Op1);
3000*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::SDIVREM32;
3001*9880d681SAndroid Build Coastguard Worker   } else
3002*9880d681SAndroid Build Coastguard Worker     Opcode = SystemZISD::SDIVREM64;
3003*9880d681SAndroid Build Coastguard Worker 
3004*9880d681SAndroid Build Coastguard Worker   // DSG(F) takes a 64-bit dividend, so the even register in the GR128
3005*9880d681SAndroid Build Coastguard Worker   // input is "don't care".  The instruction returns the remainder in
3006*9880d681SAndroid Build Coastguard Worker   // the even register and the quotient in the odd register.
3007*9880d681SAndroid Build Coastguard Worker   SDValue Ops[2];
3008*9880d681SAndroid Build Coastguard Worker   lowerGR128Binary(DAG, DL, VT, SystemZ::AEXT128_64, Opcode,
3009*9880d681SAndroid Build Coastguard Worker                    Op0, Op1, Ops[1], Ops[0]);
3010*9880d681SAndroid Build Coastguard Worker   return DAG.getMergeValues(Ops, DL);
3011*9880d681SAndroid Build Coastguard Worker }
3012*9880d681SAndroid Build Coastguard Worker 
lowerUDIVREM(SDValue Op,SelectionDAG & DAG) const3013*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerUDIVREM(SDValue Op,
3014*9880d681SAndroid Build Coastguard Worker                                             SelectionDAG &DAG) const {
3015*9880d681SAndroid Build Coastguard Worker   EVT VT = Op.getValueType();
3016*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
3017*9880d681SAndroid Build Coastguard Worker 
3018*9880d681SAndroid Build Coastguard Worker   // DL(G) uses a double-width dividend, so we need to clear the even
3019*9880d681SAndroid Build Coastguard Worker   // register in the GR128 input.  The instruction returns the remainder
3020*9880d681SAndroid Build Coastguard Worker   // in the even register and the quotient in the odd register.
3021*9880d681SAndroid Build Coastguard Worker   SDValue Ops[2];
3022*9880d681SAndroid Build Coastguard Worker   if (is32Bit(VT))
3023*9880d681SAndroid Build Coastguard Worker     lowerGR128Binary(DAG, DL, VT, SystemZ::ZEXT128_32, SystemZISD::UDIVREM32,
3024*9880d681SAndroid Build Coastguard Worker                      Op.getOperand(0), Op.getOperand(1), Ops[1], Ops[0]);
3025*9880d681SAndroid Build Coastguard Worker   else
3026*9880d681SAndroid Build Coastguard Worker     lowerGR128Binary(DAG, DL, VT, SystemZ::ZEXT128_64, SystemZISD::UDIVREM64,
3027*9880d681SAndroid Build Coastguard Worker                      Op.getOperand(0), Op.getOperand(1), Ops[1], Ops[0]);
3028*9880d681SAndroid Build Coastguard Worker   return DAG.getMergeValues(Ops, DL);
3029*9880d681SAndroid Build Coastguard Worker }
3030*9880d681SAndroid Build Coastguard Worker 
lowerOR(SDValue Op,SelectionDAG & DAG) const3031*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerOR(SDValue Op, SelectionDAG &DAG) const {
3032*9880d681SAndroid Build Coastguard Worker   assert(Op.getValueType() == MVT::i64 && "Should be 64-bit operation");
3033*9880d681SAndroid Build Coastguard Worker 
3034*9880d681SAndroid Build Coastguard Worker   // Get the known-zero masks for each operand.
3035*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1) };
3036*9880d681SAndroid Build Coastguard Worker   APInt KnownZero[2], KnownOne[2];
3037*9880d681SAndroid Build Coastguard Worker   DAG.computeKnownBits(Ops[0], KnownZero[0], KnownOne[0]);
3038*9880d681SAndroid Build Coastguard Worker   DAG.computeKnownBits(Ops[1], KnownZero[1], KnownOne[1]);
3039*9880d681SAndroid Build Coastguard Worker 
3040*9880d681SAndroid Build Coastguard Worker   // See if the upper 32 bits of one operand and the lower 32 bits of the
3041*9880d681SAndroid Build Coastguard Worker   // other are known zero.  They are the low and high operands respectively.
3042*9880d681SAndroid Build Coastguard Worker   uint64_t Masks[] = { KnownZero[0].getZExtValue(),
3043*9880d681SAndroid Build Coastguard Worker                        KnownZero[1].getZExtValue() };
3044*9880d681SAndroid Build Coastguard Worker   unsigned High, Low;
3045*9880d681SAndroid Build Coastguard Worker   if ((Masks[0] >> 32) == 0xffffffff && uint32_t(Masks[1]) == 0xffffffff)
3046*9880d681SAndroid Build Coastguard Worker     High = 1, Low = 0;
3047*9880d681SAndroid Build Coastguard Worker   else if ((Masks[1] >> 32) == 0xffffffff && uint32_t(Masks[0]) == 0xffffffff)
3048*9880d681SAndroid Build Coastguard Worker     High = 0, Low = 1;
3049*9880d681SAndroid Build Coastguard Worker   else
3050*9880d681SAndroid Build Coastguard Worker     return Op;
3051*9880d681SAndroid Build Coastguard Worker 
3052*9880d681SAndroid Build Coastguard Worker   SDValue LowOp = Ops[Low];
3053*9880d681SAndroid Build Coastguard Worker   SDValue HighOp = Ops[High];
3054*9880d681SAndroid Build Coastguard Worker 
3055*9880d681SAndroid Build Coastguard Worker   // If the high part is a constant, we're better off using IILH.
3056*9880d681SAndroid Build Coastguard Worker   if (HighOp.getOpcode() == ISD::Constant)
3057*9880d681SAndroid Build Coastguard Worker     return Op;
3058*9880d681SAndroid Build Coastguard Worker 
3059*9880d681SAndroid Build Coastguard Worker   // If the low part is a constant that is outside the range of LHI,
3060*9880d681SAndroid Build Coastguard Worker   // then we're better off using IILF.
3061*9880d681SAndroid Build Coastguard Worker   if (LowOp.getOpcode() == ISD::Constant) {
3062*9880d681SAndroid Build Coastguard Worker     int64_t Value = int32_t(cast<ConstantSDNode>(LowOp)->getZExtValue());
3063*9880d681SAndroid Build Coastguard Worker     if (!isInt<16>(Value))
3064*9880d681SAndroid Build Coastguard Worker       return Op;
3065*9880d681SAndroid Build Coastguard Worker   }
3066*9880d681SAndroid Build Coastguard Worker 
3067*9880d681SAndroid Build Coastguard Worker   // Check whether the high part is an AND that doesn't change the
3068*9880d681SAndroid Build Coastguard Worker   // high 32 bits and just masks out low bits.  We can skip it if so.
3069*9880d681SAndroid Build Coastguard Worker   if (HighOp.getOpcode() == ISD::AND &&
3070*9880d681SAndroid Build Coastguard Worker       HighOp.getOperand(1).getOpcode() == ISD::Constant) {
3071*9880d681SAndroid Build Coastguard Worker     SDValue HighOp0 = HighOp.getOperand(0);
3072*9880d681SAndroid Build Coastguard Worker     uint64_t Mask = cast<ConstantSDNode>(HighOp.getOperand(1))->getZExtValue();
3073*9880d681SAndroid Build Coastguard Worker     if (DAG.MaskedValueIsZero(HighOp0, APInt(64, ~(Mask | 0xffffffff))))
3074*9880d681SAndroid Build Coastguard Worker       HighOp = HighOp0;
3075*9880d681SAndroid Build Coastguard Worker   }
3076*9880d681SAndroid Build Coastguard Worker 
3077*9880d681SAndroid Build Coastguard Worker   // Take advantage of the fact that all GR32 operations only change the
3078*9880d681SAndroid Build Coastguard Worker   // low 32 bits by truncating Low to an i32 and inserting it directly
3079*9880d681SAndroid Build Coastguard Worker   // using a subreg.  The interesting cases are those where the truncation
3080*9880d681SAndroid Build Coastguard Worker   // can be folded.
3081*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
3082*9880d681SAndroid Build Coastguard Worker   SDValue Low32 = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, LowOp);
3083*9880d681SAndroid Build Coastguard Worker   return DAG.getTargetInsertSubreg(SystemZ::subreg_l32, DL,
3084*9880d681SAndroid Build Coastguard Worker                                    MVT::i64, HighOp, Low32);
3085*9880d681SAndroid Build Coastguard Worker }
3086*9880d681SAndroid Build Coastguard Worker 
lowerCTPOP(SDValue Op,SelectionDAG & DAG) const3087*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerCTPOP(SDValue Op,
3088*9880d681SAndroid Build Coastguard Worker                                           SelectionDAG &DAG) const {
3089*9880d681SAndroid Build Coastguard Worker   EVT VT = Op.getValueType();
3090*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
3091*9880d681SAndroid Build Coastguard Worker   Op = Op.getOperand(0);
3092*9880d681SAndroid Build Coastguard Worker 
3093*9880d681SAndroid Build Coastguard Worker   // Handle vector types via VPOPCT.
3094*9880d681SAndroid Build Coastguard Worker   if (VT.isVector()) {
3095*9880d681SAndroid Build Coastguard Worker     Op = DAG.getNode(ISD::BITCAST, DL, MVT::v16i8, Op);
3096*9880d681SAndroid Build Coastguard Worker     Op = DAG.getNode(SystemZISD::POPCNT, DL, MVT::v16i8, Op);
3097*9880d681SAndroid Build Coastguard Worker     switch (VT.getVectorElementType().getSizeInBits()) {
3098*9880d681SAndroid Build Coastguard Worker     case 8:
3099*9880d681SAndroid Build Coastguard Worker       break;
3100*9880d681SAndroid Build Coastguard Worker     case 16: {
3101*9880d681SAndroid Build Coastguard Worker       Op = DAG.getNode(ISD::BITCAST, DL, VT, Op);
3102*9880d681SAndroid Build Coastguard Worker       SDValue Shift = DAG.getConstant(8, DL, MVT::i32);
3103*9880d681SAndroid Build Coastguard Worker       SDValue Tmp = DAG.getNode(SystemZISD::VSHL_BY_SCALAR, DL, VT, Op, Shift);
3104*9880d681SAndroid Build Coastguard Worker       Op = DAG.getNode(ISD::ADD, DL, VT, Op, Tmp);
3105*9880d681SAndroid Build Coastguard Worker       Op = DAG.getNode(SystemZISD::VSRL_BY_SCALAR, DL, VT, Op, Shift);
3106*9880d681SAndroid Build Coastguard Worker       break;
3107*9880d681SAndroid Build Coastguard Worker     }
3108*9880d681SAndroid Build Coastguard Worker     case 32: {
3109*9880d681SAndroid Build Coastguard Worker       SDValue Tmp = DAG.getNode(SystemZISD::BYTE_MASK, DL, MVT::v16i8,
3110*9880d681SAndroid Build Coastguard Worker                                 DAG.getConstant(0, DL, MVT::i32));
3111*9880d681SAndroid Build Coastguard Worker       Op = DAG.getNode(SystemZISD::VSUM, DL, VT, Op, Tmp);
3112*9880d681SAndroid Build Coastguard Worker       break;
3113*9880d681SAndroid Build Coastguard Worker     }
3114*9880d681SAndroid Build Coastguard Worker     case 64: {
3115*9880d681SAndroid Build Coastguard Worker       SDValue Tmp = DAG.getNode(SystemZISD::BYTE_MASK, DL, MVT::v16i8,
3116*9880d681SAndroid Build Coastguard Worker                                 DAG.getConstant(0, DL, MVT::i32));
3117*9880d681SAndroid Build Coastguard Worker       Op = DAG.getNode(SystemZISD::VSUM, DL, MVT::v4i32, Op, Tmp);
3118*9880d681SAndroid Build Coastguard Worker       Op = DAG.getNode(SystemZISD::VSUM, DL, VT, Op, Tmp);
3119*9880d681SAndroid Build Coastguard Worker       break;
3120*9880d681SAndroid Build Coastguard Worker     }
3121*9880d681SAndroid Build Coastguard Worker     default:
3122*9880d681SAndroid Build Coastguard Worker       llvm_unreachable("Unexpected type");
3123*9880d681SAndroid Build Coastguard Worker     }
3124*9880d681SAndroid Build Coastguard Worker     return Op;
3125*9880d681SAndroid Build Coastguard Worker   }
3126*9880d681SAndroid Build Coastguard Worker 
3127*9880d681SAndroid Build Coastguard Worker   // Get the known-zero mask for the operand.
3128*9880d681SAndroid Build Coastguard Worker   APInt KnownZero, KnownOne;
3129*9880d681SAndroid Build Coastguard Worker   DAG.computeKnownBits(Op, KnownZero, KnownOne);
3130*9880d681SAndroid Build Coastguard Worker   unsigned NumSignificantBits = (~KnownZero).getActiveBits();
3131*9880d681SAndroid Build Coastguard Worker   if (NumSignificantBits == 0)
3132*9880d681SAndroid Build Coastguard Worker     return DAG.getConstant(0, DL, VT);
3133*9880d681SAndroid Build Coastguard Worker 
3134*9880d681SAndroid Build Coastguard Worker   // Skip known-zero high parts of the operand.
3135*9880d681SAndroid Build Coastguard Worker   int64_t OrigBitSize = VT.getSizeInBits();
3136*9880d681SAndroid Build Coastguard Worker   int64_t BitSize = (int64_t)1 << Log2_32_Ceil(NumSignificantBits);
3137*9880d681SAndroid Build Coastguard Worker   BitSize = std::min(BitSize, OrigBitSize);
3138*9880d681SAndroid Build Coastguard Worker 
3139*9880d681SAndroid Build Coastguard Worker   // The POPCNT instruction counts the number of bits in each byte.
3140*9880d681SAndroid Build Coastguard Worker   Op = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op);
3141*9880d681SAndroid Build Coastguard Worker   Op = DAG.getNode(SystemZISD::POPCNT, DL, MVT::i64, Op);
3142*9880d681SAndroid Build Coastguard Worker   Op = DAG.getNode(ISD::TRUNCATE, DL, VT, Op);
3143*9880d681SAndroid Build Coastguard Worker 
3144*9880d681SAndroid Build Coastguard Worker   // Add up per-byte counts in a binary tree.  All bits of Op at
3145*9880d681SAndroid Build Coastguard Worker   // position larger than BitSize remain zero throughout.
3146*9880d681SAndroid Build Coastguard Worker   for (int64_t I = BitSize / 2; I >= 8; I = I / 2) {
3147*9880d681SAndroid Build Coastguard Worker     SDValue Tmp = DAG.getNode(ISD::SHL, DL, VT, Op, DAG.getConstant(I, DL, VT));
3148*9880d681SAndroid Build Coastguard Worker     if (BitSize != OrigBitSize)
3149*9880d681SAndroid Build Coastguard Worker       Tmp = DAG.getNode(ISD::AND, DL, VT, Tmp,
3150*9880d681SAndroid Build Coastguard Worker                         DAG.getConstant(((uint64_t)1 << BitSize) - 1, DL, VT));
3151*9880d681SAndroid Build Coastguard Worker     Op = DAG.getNode(ISD::ADD, DL, VT, Op, Tmp);
3152*9880d681SAndroid Build Coastguard Worker   }
3153*9880d681SAndroid Build Coastguard Worker 
3154*9880d681SAndroid Build Coastguard Worker   // Extract overall result from high byte.
3155*9880d681SAndroid Build Coastguard Worker   if (BitSize > 8)
3156*9880d681SAndroid Build Coastguard Worker     Op = DAG.getNode(ISD::SRL, DL, VT, Op,
3157*9880d681SAndroid Build Coastguard Worker                      DAG.getConstant(BitSize - 8, DL, VT));
3158*9880d681SAndroid Build Coastguard Worker 
3159*9880d681SAndroid Build Coastguard Worker   return Op;
3160*9880d681SAndroid Build Coastguard Worker }
3161*9880d681SAndroid Build Coastguard Worker 
lowerATOMIC_FENCE(SDValue Op,SelectionDAG & DAG) const3162*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerATOMIC_FENCE(SDValue Op,
3163*9880d681SAndroid Build Coastguard Worker                                                  SelectionDAG &DAG) const {
3164*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
3165*9880d681SAndroid Build Coastguard Worker   AtomicOrdering FenceOrdering = static_cast<AtomicOrdering>(
3166*9880d681SAndroid Build Coastguard Worker     cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue());
3167*9880d681SAndroid Build Coastguard Worker   SynchronizationScope FenceScope = static_cast<SynchronizationScope>(
3168*9880d681SAndroid Build Coastguard Worker     cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue());
3169*9880d681SAndroid Build Coastguard Worker 
3170*9880d681SAndroid Build Coastguard Worker   // The only fence that needs an instruction is a sequentially-consistent
3171*9880d681SAndroid Build Coastguard Worker   // cross-thread fence.
3172*9880d681SAndroid Build Coastguard Worker   if (FenceOrdering == AtomicOrdering::SequentiallyConsistent &&
3173*9880d681SAndroid Build Coastguard Worker       FenceScope == CrossThread) {
3174*9880d681SAndroid Build Coastguard Worker     return SDValue(DAG.getMachineNode(SystemZ::Serialize, DL, MVT::Other,
3175*9880d681SAndroid Build Coastguard Worker                                       Op.getOperand(0)),
3176*9880d681SAndroid Build Coastguard Worker                    0);
3177*9880d681SAndroid Build Coastguard Worker   }
3178*9880d681SAndroid Build Coastguard Worker 
3179*9880d681SAndroid Build Coastguard Worker   // MEMBARRIER is a compiler barrier; it codegens to a no-op.
3180*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(SystemZISD::MEMBARRIER, DL, MVT::Other, Op.getOperand(0));
3181*9880d681SAndroid Build Coastguard Worker }
3182*9880d681SAndroid Build Coastguard Worker 
3183*9880d681SAndroid Build Coastguard Worker // Op is an atomic load.  Lower it into a normal volatile load.
lowerATOMIC_LOAD(SDValue Op,SelectionDAG & DAG) const3184*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerATOMIC_LOAD(SDValue Op,
3185*9880d681SAndroid Build Coastguard Worker                                                 SelectionDAG &DAG) const {
3186*9880d681SAndroid Build Coastguard Worker   auto *Node = cast<AtomicSDNode>(Op.getNode());
3187*9880d681SAndroid Build Coastguard Worker   return DAG.getExtLoad(ISD::EXTLOAD, SDLoc(Op), Op.getValueType(),
3188*9880d681SAndroid Build Coastguard Worker                         Node->getChain(), Node->getBasePtr(),
3189*9880d681SAndroid Build Coastguard Worker                         Node->getMemoryVT(), Node->getMemOperand());
3190*9880d681SAndroid Build Coastguard Worker }
3191*9880d681SAndroid Build Coastguard Worker 
3192*9880d681SAndroid Build Coastguard Worker // Op is an atomic store.  Lower it into a normal volatile store followed
3193*9880d681SAndroid Build Coastguard Worker // by a serialization.
lowerATOMIC_STORE(SDValue Op,SelectionDAG & DAG) const3194*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerATOMIC_STORE(SDValue Op,
3195*9880d681SAndroid Build Coastguard Worker                                                  SelectionDAG &DAG) const {
3196*9880d681SAndroid Build Coastguard Worker   auto *Node = cast<AtomicSDNode>(Op.getNode());
3197*9880d681SAndroid Build Coastguard Worker   SDValue Chain = DAG.getTruncStore(Node->getChain(), SDLoc(Op), Node->getVal(),
3198*9880d681SAndroid Build Coastguard Worker                                     Node->getBasePtr(), Node->getMemoryVT(),
3199*9880d681SAndroid Build Coastguard Worker                                     Node->getMemOperand());
3200*9880d681SAndroid Build Coastguard Worker   return SDValue(DAG.getMachineNode(SystemZ::Serialize, SDLoc(Op), MVT::Other,
3201*9880d681SAndroid Build Coastguard Worker                                     Chain), 0);
3202*9880d681SAndroid Build Coastguard Worker }
3203*9880d681SAndroid Build Coastguard Worker 
3204*9880d681SAndroid Build Coastguard Worker // Op is an 8-, 16-bit or 32-bit ATOMIC_LOAD_* operation.  Lower the first
3205*9880d681SAndroid Build Coastguard Worker // two into the fullword ATOMIC_LOADW_* operation given by Opcode.
lowerATOMIC_LOAD_OP(SDValue Op,SelectionDAG & DAG,unsigned Opcode) const3206*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerATOMIC_LOAD_OP(SDValue Op,
3207*9880d681SAndroid Build Coastguard Worker                                                    SelectionDAG &DAG,
3208*9880d681SAndroid Build Coastguard Worker                                                    unsigned Opcode) const {
3209*9880d681SAndroid Build Coastguard Worker   auto *Node = cast<AtomicSDNode>(Op.getNode());
3210*9880d681SAndroid Build Coastguard Worker 
3211*9880d681SAndroid Build Coastguard Worker   // 32-bit operations need no code outside the main loop.
3212*9880d681SAndroid Build Coastguard Worker   EVT NarrowVT = Node->getMemoryVT();
3213*9880d681SAndroid Build Coastguard Worker   EVT WideVT = MVT::i32;
3214*9880d681SAndroid Build Coastguard Worker   if (NarrowVT == WideVT)
3215*9880d681SAndroid Build Coastguard Worker     return Op;
3216*9880d681SAndroid Build Coastguard Worker 
3217*9880d681SAndroid Build Coastguard Worker   int64_t BitSize = NarrowVT.getSizeInBits();
3218*9880d681SAndroid Build Coastguard Worker   SDValue ChainIn = Node->getChain();
3219*9880d681SAndroid Build Coastguard Worker   SDValue Addr = Node->getBasePtr();
3220*9880d681SAndroid Build Coastguard Worker   SDValue Src2 = Node->getVal();
3221*9880d681SAndroid Build Coastguard Worker   MachineMemOperand *MMO = Node->getMemOperand();
3222*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Node);
3223*9880d681SAndroid Build Coastguard Worker   EVT PtrVT = Addr.getValueType();
3224*9880d681SAndroid Build Coastguard Worker 
3225*9880d681SAndroid Build Coastguard Worker   // Convert atomic subtracts of constants into additions.
3226*9880d681SAndroid Build Coastguard Worker   if (Opcode == SystemZISD::ATOMIC_LOADW_SUB)
3227*9880d681SAndroid Build Coastguard Worker     if (auto *Const = dyn_cast<ConstantSDNode>(Src2)) {
3228*9880d681SAndroid Build Coastguard Worker       Opcode = SystemZISD::ATOMIC_LOADW_ADD;
3229*9880d681SAndroid Build Coastguard Worker       Src2 = DAG.getConstant(-Const->getSExtValue(), DL, Src2.getValueType());
3230*9880d681SAndroid Build Coastguard Worker     }
3231*9880d681SAndroid Build Coastguard Worker 
3232*9880d681SAndroid Build Coastguard Worker   // Get the address of the containing word.
3233*9880d681SAndroid Build Coastguard Worker   SDValue AlignedAddr = DAG.getNode(ISD::AND, DL, PtrVT, Addr,
3234*9880d681SAndroid Build Coastguard Worker                                     DAG.getConstant(-4, DL, PtrVT));
3235*9880d681SAndroid Build Coastguard Worker 
3236*9880d681SAndroid Build Coastguard Worker   // Get the number of bits that the word must be rotated left in order
3237*9880d681SAndroid Build Coastguard Worker   // to bring the field to the top bits of a GR32.
3238*9880d681SAndroid Build Coastguard Worker   SDValue BitShift = DAG.getNode(ISD::SHL, DL, PtrVT, Addr,
3239*9880d681SAndroid Build Coastguard Worker                                  DAG.getConstant(3, DL, PtrVT));
3240*9880d681SAndroid Build Coastguard Worker   BitShift = DAG.getNode(ISD::TRUNCATE, DL, WideVT, BitShift);
3241*9880d681SAndroid Build Coastguard Worker 
3242*9880d681SAndroid Build Coastguard Worker   // Get the complementing shift amount, for rotating a field in the top
3243*9880d681SAndroid Build Coastguard Worker   // bits back to its proper position.
3244*9880d681SAndroid Build Coastguard Worker   SDValue NegBitShift = DAG.getNode(ISD::SUB, DL, WideVT,
3245*9880d681SAndroid Build Coastguard Worker                                     DAG.getConstant(0, DL, WideVT), BitShift);
3246*9880d681SAndroid Build Coastguard Worker 
3247*9880d681SAndroid Build Coastguard Worker   // Extend the source operand to 32 bits and prepare it for the inner loop.
3248*9880d681SAndroid Build Coastguard Worker   // ATOMIC_SWAPW uses RISBG to rotate the field left, but all other
3249*9880d681SAndroid Build Coastguard Worker   // operations require the source to be shifted in advance.  (This shift
3250*9880d681SAndroid Build Coastguard Worker   // can be folded if the source is constant.)  For AND and NAND, the lower
3251*9880d681SAndroid Build Coastguard Worker   // bits must be set, while for other opcodes they should be left clear.
3252*9880d681SAndroid Build Coastguard Worker   if (Opcode != SystemZISD::ATOMIC_SWAPW)
3253*9880d681SAndroid Build Coastguard Worker     Src2 = DAG.getNode(ISD::SHL, DL, WideVT, Src2,
3254*9880d681SAndroid Build Coastguard Worker                        DAG.getConstant(32 - BitSize, DL, WideVT));
3255*9880d681SAndroid Build Coastguard Worker   if (Opcode == SystemZISD::ATOMIC_LOADW_AND ||
3256*9880d681SAndroid Build Coastguard Worker       Opcode == SystemZISD::ATOMIC_LOADW_NAND)
3257*9880d681SAndroid Build Coastguard Worker     Src2 = DAG.getNode(ISD::OR, DL, WideVT, Src2,
3258*9880d681SAndroid Build Coastguard Worker                        DAG.getConstant(uint32_t(-1) >> BitSize, DL, WideVT));
3259*9880d681SAndroid Build Coastguard Worker 
3260*9880d681SAndroid Build Coastguard Worker   // Construct the ATOMIC_LOADW_* node.
3261*9880d681SAndroid Build Coastguard Worker   SDVTList VTList = DAG.getVTList(WideVT, MVT::Other);
3262*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { ChainIn, AlignedAddr, Src2, BitShift, NegBitShift,
3263*9880d681SAndroid Build Coastguard Worker                     DAG.getConstant(BitSize, DL, WideVT) };
3264*9880d681SAndroid Build Coastguard Worker   SDValue AtomicOp = DAG.getMemIntrinsicNode(Opcode, DL, VTList, Ops,
3265*9880d681SAndroid Build Coastguard Worker                                              NarrowVT, MMO);
3266*9880d681SAndroid Build Coastguard Worker 
3267*9880d681SAndroid Build Coastguard Worker   // Rotate the result of the final CS so that the field is in the lower
3268*9880d681SAndroid Build Coastguard Worker   // bits of a GR32, then truncate it.
3269*9880d681SAndroid Build Coastguard Worker   SDValue ResultShift = DAG.getNode(ISD::ADD, DL, WideVT, BitShift,
3270*9880d681SAndroid Build Coastguard Worker                                     DAG.getConstant(BitSize, DL, WideVT));
3271*9880d681SAndroid Build Coastguard Worker   SDValue Result = DAG.getNode(ISD::ROTL, DL, WideVT, AtomicOp, ResultShift);
3272*9880d681SAndroid Build Coastguard Worker 
3273*9880d681SAndroid Build Coastguard Worker   SDValue RetOps[2] = { Result, AtomicOp.getValue(1) };
3274*9880d681SAndroid Build Coastguard Worker   return DAG.getMergeValues(RetOps, DL);
3275*9880d681SAndroid Build Coastguard Worker }
3276*9880d681SAndroid Build Coastguard Worker 
3277*9880d681SAndroid Build Coastguard Worker // Op is an ATOMIC_LOAD_SUB operation.  Lower 8- and 16-bit operations
3278*9880d681SAndroid Build Coastguard Worker // into ATOMIC_LOADW_SUBs and decide whether to convert 32- and 64-bit
3279*9880d681SAndroid Build Coastguard Worker // operations into additions.
lowerATOMIC_LOAD_SUB(SDValue Op,SelectionDAG & DAG) const3280*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerATOMIC_LOAD_SUB(SDValue Op,
3281*9880d681SAndroid Build Coastguard Worker                                                     SelectionDAG &DAG) const {
3282*9880d681SAndroid Build Coastguard Worker   auto *Node = cast<AtomicSDNode>(Op.getNode());
3283*9880d681SAndroid Build Coastguard Worker   EVT MemVT = Node->getMemoryVT();
3284*9880d681SAndroid Build Coastguard Worker   if (MemVT == MVT::i32 || MemVT == MVT::i64) {
3285*9880d681SAndroid Build Coastguard Worker     // A full-width operation.
3286*9880d681SAndroid Build Coastguard Worker     assert(Op.getValueType() == MemVT && "Mismatched VTs");
3287*9880d681SAndroid Build Coastguard Worker     SDValue Src2 = Node->getVal();
3288*9880d681SAndroid Build Coastguard Worker     SDValue NegSrc2;
3289*9880d681SAndroid Build Coastguard Worker     SDLoc DL(Src2);
3290*9880d681SAndroid Build Coastguard Worker 
3291*9880d681SAndroid Build Coastguard Worker     if (auto *Op2 = dyn_cast<ConstantSDNode>(Src2)) {
3292*9880d681SAndroid Build Coastguard Worker       // Use an addition if the operand is constant and either LAA(G) is
3293*9880d681SAndroid Build Coastguard Worker       // available or the negative value is in the range of A(G)FHI.
3294*9880d681SAndroid Build Coastguard Worker       int64_t Value = (-Op2->getAPIntValue()).getSExtValue();
3295*9880d681SAndroid Build Coastguard Worker       if (isInt<32>(Value) || Subtarget.hasInterlockedAccess1())
3296*9880d681SAndroid Build Coastguard Worker         NegSrc2 = DAG.getConstant(Value, DL, MemVT);
3297*9880d681SAndroid Build Coastguard Worker     } else if (Subtarget.hasInterlockedAccess1())
3298*9880d681SAndroid Build Coastguard Worker       // Use LAA(G) if available.
3299*9880d681SAndroid Build Coastguard Worker       NegSrc2 = DAG.getNode(ISD::SUB, DL, MemVT, DAG.getConstant(0, DL, MemVT),
3300*9880d681SAndroid Build Coastguard Worker                             Src2);
3301*9880d681SAndroid Build Coastguard Worker 
3302*9880d681SAndroid Build Coastguard Worker     if (NegSrc2.getNode())
3303*9880d681SAndroid Build Coastguard Worker       return DAG.getAtomic(ISD::ATOMIC_LOAD_ADD, DL, MemVT,
3304*9880d681SAndroid Build Coastguard Worker                            Node->getChain(), Node->getBasePtr(), NegSrc2,
3305*9880d681SAndroid Build Coastguard Worker                            Node->getMemOperand(), Node->getOrdering(),
3306*9880d681SAndroid Build Coastguard Worker                            Node->getSynchScope());
3307*9880d681SAndroid Build Coastguard Worker 
3308*9880d681SAndroid Build Coastguard Worker     // Use the node as-is.
3309*9880d681SAndroid Build Coastguard Worker     return Op;
3310*9880d681SAndroid Build Coastguard Worker   }
3311*9880d681SAndroid Build Coastguard Worker 
3312*9880d681SAndroid Build Coastguard Worker   return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_SUB);
3313*9880d681SAndroid Build Coastguard Worker }
3314*9880d681SAndroid Build Coastguard Worker 
3315*9880d681SAndroid Build Coastguard Worker // Node is an 8- or 16-bit ATOMIC_CMP_SWAP operation.  Lower the first two
3316*9880d681SAndroid Build Coastguard Worker // into a fullword ATOMIC_CMP_SWAPW operation.
lowerATOMIC_CMP_SWAP(SDValue Op,SelectionDAG & DAG) const3317*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerATOMIC_CMP_SWAP(SDValue Op,
3318*9880d681SAndroid Build Coastguard Worker                                                     SelectionDAG &DAG) const {
3319*9880d681SAndroid Build Coastguard Worker   auto *Node = cast<AtomicSDNode>(Op.getNode());
3320*9880d681SAndroid Build Coastguard Worker 
3321*9880d681SAndroid Build Coastguard Worker   // We have native support for 32-bit compare and swap.
3322*9880d681SAndroid Build Coastguard Worker   EVT NarrowVT = Node->getMemoryVT();
3323*9880d681SAndroid Build Coastguard Worker   EVT WideVT = MVT::i32;
3324*9880d681SAndroid Build Coastguard Worker   if (NarrowVT == WideVT)
3325*9880d681SAndroid Build Coastguard Worker     return Op;
3326*9880d681SAndroid Build Coastguard Worker 
3327*9880d681SAndroid Build Coastguard Worker   int64_t BitSize = NarrowVT.getSizeInBits();
3328*9880d681SAndroid Build Coastguard Worker   SDValue ChainIn = Node->getOperand(0);
3329*9880d681SAndroid Build Coastguard Worker   SDValue Addr = Node->getOperand(1);
3330*9880d681SAndroid Build Coastguard Worker   SDValue CmpVal = Node->getOperand(2);
3331*9880d681SAndroid Build Coastguard Worker   SDValue SwapVal = Node->getOperand(3);
3332*9880d681SAndroid Build Coastguard Worker   MachineMemOperand *MMO = Node->getMemOperand();
3333*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Node);
3334*9880d681SAndroid Build Coastguard Worker   EVT PtrVT = Addr.getValueType();
3335*9880d681SAndroid Build Coastguard Worker 
3336*9880d681SAndroid Build Coastguard Worker   // Get the address of the containing word.
3337*9880d681SAndroid Build Coastguard Worker   SDValue AlignedAddr = DAG.getNode(ISD::AND, DL, PtrVT, Addr,
3338*9880d681SAndroid Build Coastguard Worker                                     DAG.getConstant(-4, DL, PtrVT));
3339*9880d681SAndroid Build Coastguard Worker 
3340*9880d681SAndroid Build Coastguard Worker   // Get the number of bits that the word must be rotated left in order
3341*9880d681SAndroid Build Coastguard Worker   // to bring the field to the top bits of a GR32.
3342*9880d681SAndroid Build Coastguard Worker   SDValue BitShift = DAG.getNode(ISD::SHL, DL, PtrVT, Addr,
3343*9880d681SAndroid Build Coastguard Worker                                  DAG.getConstant(3, DL, PtrVT));
3344*9880d681SAndroid Build Coastguard Worker   BitShift = DAG.getNode(ISD::TRUNCATE, DL, WideVT, BitShift);
3345*9880d681SAndroid Build Coastguard Worker 
3346*9880d681SAndroid Build Coastguard Worker   // Get the complementing shift amount, for rotating a field in the top
3347*9880d681SAndroid Build Coastguard Worker   // bits back to its proper position.
3348*9880d681SAndroid Build Coastguard Worker   SDValue NegBitShift = DAG.getNode(ISD::SUB, DL, WideVT,
3349*9880d681SAndroid Build Coastguard Worker                                     DAG.getConstant(0, DL, WideVT), BitShift);
3350*9880d681SAndroid Build Coastguard Worker 
3351*9880d681SAndroid Build Coastguard Worker   // Construct the ATOMIC_CMP_SWAPW node.
3352*9880d681SAndroid Build Coastguard Worker   SDVTList VTList = DAG.getVTList(WideVT, MVT::Other);
3353*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = { ChainIn, AlignedAddr, CmpVal, SwapVal, BitShift,
3354*9880d681SAndroid Build Coastguard Worker                     NegBitShift, DAG.getConstant(BitSize, DL, WideVT) };
3355*9880d681SAndroid Build Coastguard Worker   SDValue AtomicOp = DAG.getMemIntrinsicNode(SystemZISD::ATOMIC_CMP_SWAPW, DL,
3356*9880d681SAndroid Build Coastguard Worker                                              VTList, Ops, NarrowVT, MMO);
3357*9880d681SAndroid Build Coastguard Worker   return AtomicOp;
3358*9880d681SAndroid Build Coastguard Worker }
3359*9880d681SAndroid Build Coastguard Worker 
lowerSTACKSAVE(SDValue Op,SelectionDAG & DAG) const3360*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerSTACKSAVE(SDValue Op,
3361*9880d681SAndroid Build Coastguard Worker                                               SelectionDAG &DAG) const {
3362*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = DAG.getMachineFunction();
3363*9880d681SAndroid Build Coastguard Worker   MF.getInfo<SystemZMachineFunctionInfo>()->setManipulatesSP(true);
3364*9880d681SAndroid Build Coastguard Worker   return DAG.getCopyFromReg(Op.getOperand(0), SDLoc(Op),
3365*9880d681SAndroid Build Coastguard Worker                             SystemZ::R15D, Op.getValueType());
3366*9880d681SAndroid Build Coastguard Worker }
3367*9880d681SAndroid Build Coastguard Worker 
lowerSTACKRESTORE(SDValue Op,SelectionDAG & DAG) const3368*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerSTACKRESTORE(SDValue Op,
3369*9880d681SAndroid Build Coastguard Worker                                                  SelectionDAG &DAG) const {
3370*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = DAG.getMachineFunction();
3371*9880d681SAndroid Build Coastguard Worker   MF.getInfo<SystemZMachineFunctionInfo>()->setManipulatesSP(true);
3372*9880d681SAndroid Build Coastguard Worker   bool StoreBackchain = MF.getFunction()->hasFnAttribute("backchain");
3373*9880d681SAndroid Build Coastguard Worker 
3374*9880d681SAndroid Build Coastguard Worker   SDValue Chain = Op.getOperand(0);
3375*9880d681SAndroid Build Coastguard Worker   SDValue NewSP = Op.getOperand(1);
3376*9880d681SAndroid Build Coastguard Worker   SDValue Backchain;
3377*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
3378*9880d681SAndroid Build Coastguard Worker 
3379*9880d681SAndroid Build Coastguard Worker   if (StoreBackchain) {
3380*9880d681SAndroid Build Coastguard Worker     SDValue OldSP = DAG.getCopyFromReg(Chain, DL, SystemZ::R15D, MVT::i64);
3381*9880d681SAndroid Build Coastguard Worker     Backchain = DAG.getLoad(MVT::i64, DL, Chain, OldSP, MachinePointerInfo(),
3382*9880d681SAndroid Build Coastguard Worker                             false, false, false, 0);
3383*9880d681SAndroid Build Coastguard Worker   }
3384*9880d681SAndroid Build Coastguard Worker 
3385*9880d681SAndroid Build Coastguard Worker   Chain = DAG.getCopyToReg(Chain, DL, SystemZ::R15D, NewSP);
3386*9880d681SAndroid Build Coastguard Worker 
3387*9880d681SAndroid Build Coastguard Worker   if (StoreBackchain)
3388*9880d681SAndroid Build Coastguard Worker     Chain = DAG.getStore(Chain, DL, Backchain, NewSP, MachinePointerInfo(),
3389*9880d681SAndroid Build Coastguard Worker                          false, false, 0);
3390*9880d681SAndroid Build Coastguard Worker 
3391*9880d681SAndroid Build Coastguard Worker   return Chain;
3392*9880d681SAndroid Build Coastguard Worker }
3393*9880d681SAndroid Build Coastguard Worker 
lowerPREFETCH(SDValue Op,SelectionDAG & DAG) const3394*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerPREFETCH(SDValue Op,
3395*9880d681SAndroid Build Coastguard Worker                                              SelectionDAG &DAG) const {
3396*9880d681SAndroid Build Coastguard Worker   bool IsData = cast<ConstantSDNode>(Op.getOperand(4))->getZExtValue();
3397*9880d681SAndroid Build Coastguard Worker   if (!IsData)
3398*9880d681SAndroid Build Coastguard Worker     // Just preserve the chain.
3399*9880d681SAndroid Build Coastguard Worker     return Op.getOperand(0);
3400*9880d681SAndroid Build Coastguard Worker 
3401*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
3402*9880d681SAndroid Build Coastguard Worker   bool IsWrite = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue();
3403*9880d681SAndroid Build Coastguard Worker   unsigned Code = IsWrite ? SystemZ::PFD_WRITE : SystemZ::PFD_READ;
3404*9880d681SAndroid Build Coastguard Worker   auto *Node = cast<MemIntrinsicSDNode>(Op.getNode());
3405*9880d681SAndroid Build Coastguard Worker   SDValue Ops[] = {
3406*9880d681SAndroid Build Coastguard Worker     Op.getOperand(0),
3407*9880d681SAndroid Build Coastguard Worker     DAG.getConstant(Code, DL, MVT::i32),
3408*9880d681SAndroid Build Coastguard Worker     Op.getOperand(1)
3409*9880d681SAndroid Build Coastguard Worker   };
3410*9880d681SAndroid Build Coastguard Worker   return DAG.getMemIntrinsicNode(SystemZISD::PREFETCH, DL,
3411*9880d681SAndroid Build Coastguard Worker                                  Node->getVTList(), Ops,
3412*9880d681SAndroid Build Coastguard Worker                                  Node->getMemoryVT(), Node->getMemOperand());
3413*9880d681SAndroid Build Coastguard Worker }
3414*9880d681SAndroid Build Coastguard Worker 
3415*9880d681SAndroid Build Coastguard Worker // Return an i32 that contains the value of CC immediately after After,
3416*9880d681SAndroid Build Coastguard Worker // whose final operand must be MVT::Glue.
getCCResult(SelectionDAG & DAG,SDNode * After)3417*9880d681SAndroid Build Coastguard Worker static SDValue getCCResult(SelectionDAG &DAG, SDNode *After) {
3418*9880d681SAndroid Build Coastguard Worker   SDLoc DL(After);
3419*9880d681SAndroid Build Coastguard Worker   SDValue Glue = SDValue(After, After->getNumValues() - 1);
3420*9880d681SAndroid Build Coastguard Worker   SDValue IPM = DAG.getNode(SystemZISD::IPM, DL, MVT::i32, Glue);
3421*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(ISD::SRL, DL, MVT::i32, IPM,
3422*9880d681SAndroid Build Coastguard Worker                      DAG.getConstant(SystemZ::IPM_CC, DL, MVT::i32));
3423*9880d681SAndroid Build Coastguard Worker }
3424*9880d681SAndroid Build Coastguard Worker 
3425*9880d681SAndroid Build Coastguard Worker SDValue
lowerINTRINSIC_W_CHAIN(SDValue Op,SelectionDAG & DAG) const3426*9880d681SAndroid Build Coastguard Worker SystemZTargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
3427*9880d681SAndroid Build Coastguard Worker                                               SelectionDAG &DAG) const {
3428*9880d681SAndroid Build Coastguard Worker   unsigned Opcode, CCValid;
3429*9880d681SAndroid Build Coastguard Worker   if (isIntrinsicWithCCAndChain(Op, Opcode, CCValid)) {
3430*9880d681SAndroid Build Coastguard Worker     assert(Op->getNumValues() == 2 && "Expected only CC result and chain");
3431*9880d681SAndroid Build Coastguard Worker     SDValue Glued = emitIntrinsicWithChainAndGlue(DAG, Op, Opcode);
3432*9880d681SAndroid Build Coastguard Worker     SDValue CC = getCCResult(DAG, Glued.getNode());
3433*9880d681SAndroid Build Coastguard Worker     DAG.ReplaceAllUsesOfValueWith(SDValue(Op.getNode(), 0), CC);
3434*9880d681SAndroid Build Coastguard Worker     return SDValue();
3435*9880d681SAndroid Build Coastguard Worker   }
3436*9880d681SAndroid Build Coastguard Worker 
3437*9880d681SAndroid Build Coastguard Worker   return SDValue();
3438*9880d681SAndroid Build Coastguard Worker }
3439*9880d681SAndroid Build Coastguard Worker 
3440*9880d681SAndroid Build Coastguard Worker SDValue
lowerINTRINSIC_WO_CHAIN(SDValue Op,SelectionDAG & DAG) const3441*9880d681SAndroid Build Coastguard Worker SystemZTargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
3442*9880d681SAndroid Build Coastguard Worker                                                SelectionDAG &DAG) const {
3443*9880d681SAndroid Build Coastguard Worker   unsigned Opcode, CCValid;
3444*9880d681SAndroid Build Coastguard Worker   if (isIntrinsicWithCC(Op, Opcode, CCValid)) {
3445*9880d681SAndroid Build Coastguard Worker     SDValue Glued = emitIntrinsicWithGlue(DAG, Op, Opcode);
3446*9880d681SAndroid Build Coastguard Worker     SDValue CC = getCCResult(DAG, Glued.getNode());
3447*9880d681SAndroid Build Coastguard Worker     if (Op->getNumValues() == 1)
3448*9880d681SAndroid Build Coastguard Worker       return CC;
3449*9880d681SAndroid Build Coastguard Worker     assert(Op->getNumValues() == 2 && "Expected a CC and non-CC result");
3450*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(ISD::MERGE_VALUES, SDLoc(Op), Op->getVTList(), Glued,
3451*9880d681SAndroid Build Coastguard Worker                        CC);
3452*9880d681SAndroid Build Coastguard Worker   }
3453*9880d681SAndroid Build Coastguard Worker 
3454*9880d681SAndroid Build Coastguard Worker   unsigned Id = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
3455*9880d681SAndroid Build Coastguard Worker   switch (Id) {
3456*9880d681SAndroid Build Coastguard Worker   case Intrinsic::thread_pointer:
3457*9880d681SAndroid Build Coastguard Worker     return lowerThreadPointer(SDLoc(Op), DAG);
3458*9880d681SAndroid Build Coastguard Worker 
3459*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vpdi:
3460*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(SystemZISD::PERMUTE_DWORDS, SDLoc(Op), Op.getValueType(),
3461*9880d681SAndroid Build Coastguard Worker                        Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
3462*9880d681SAndroid Build Coastguard Worker 
3463*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vperm:
3464*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(SystemZISD::PERMUTE, SDLoc(Op), Op.getValueType(),
3465*9880d681SAndroid Build Coastguard Worker                        Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
3466*9880d681SAndroid Build Coastguard Worker 
3467*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vuphb:
3468*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vuphh:
3469*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vuphf:
3470*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(SystemZISD::UNPACK_HIGH, SDLoc(Op), Op.getValueType(),
3471*9880d681SAndroid Build Coastguard Worker                        Op.getOperand(1));
3472*9880d681SAndroid Build Coastguard Worker 
3473*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vuplhb:
3474*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vuplhh:
3475*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vuplhf:
3476*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(SystemZISD::UNPACKL_HIGH, SDLoc(Op), Op.getValueType(),
3477*9880d681SAndroid Build Coastguard Worker                        Op.getOperand(1));
3478*9880d681SAndroid Build Coastguard Worker 
3479*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vuplb:
3480*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vuplhw:
3481*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vuplf:
3482*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(SystemZISD::UNPACK_LOW, SDLoc(Op), Op.getValueType(),
3483*9880d681SAndroid Build Coastguard Worker                        Op.getOperand(1));
3484*9880d681SAndroid Build Coastguard Worker 
3485*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vupllb:
3486*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vupllh:
3487*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vupllf:
3488*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(SystemZISD::UNPACKL_LOW, SDLoc(Op), Op.getValueType(),
3489*9880d681SAndroid Build Coastguard Worker                        Op.getOperand(1));
3490*9880d681SAndroid Build Coastguard Worker 
3491*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vsumb:
3492*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vsumh:
3493*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vsumgh:
3494*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vsumgf:
3495*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vsumqf:
3496*9880d681SAndroid Build Coastguard Worker   case Intrinsic::s390_vsumqg:
3497*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(SystemZISD::VSUM, SDLoc(Op), Op.getValueType(),
3498*9880d681SAndroid Build Coastguard Worker                        Op.getOperand(1), Op.getOperand(2));
3499*9880d681SAndroid Build Coastguard Worker   }
3500*9880d681SAndroid Build Coastguard Worker 
3501*9880d681SAndroid Build Coastguard Worker   return SDValue();
3502*9880d681SAndroid Build Coastguard Worker }
3503*9880d681SAndroid Build Coastguard Worker 
3504*9880d681SAndroid Build Coastguard Worker namespace {
3505*9880d681SAndroid Build Coastguard Worker // Says that SystemZISD operation Opcode can be used to perform the equivalent
3506*9880d681SAndroid Build Coastguard Worker // of a VPERM with permute vector Bytes.  If Opcode takes three operands,
3507*9880d681SAndroid Build Coastguard Worker // Operand is the constant third operand, otherwise it is the number of
3508*9880d681SAndroid Build Coastguard Worker // bytes in each element of the result.
3509*9880d681SAndroid Build Coastguard Worker struct Permute {
3510*9880d681SAndroid Build Coastguard Worker   unsigned Opcode;
3511*9880d681SAndroid Build Coastguard Worker   unsigned Operand;
3512*9880d681SAndroid Build Coastguard Worker   unsigned char Bytes[SystemZ::VectorBytes];
3513*9880d681SAndroid Build Coastguard Worker };
3514*9880d681SAndroid Build Coastguard Worker }
3515*9880d681SAndroid Build Coastguard Worker 
3516*9880d681SAndroid Build Coastguard Worker static const Permute PermuteForms[] = {
3517*9880d681SAndroid Build Coastguard Worker   // VMRHG
3518*9880d681SAndroid Build Coastguard Worker   { SystemZISD::MERGE_HIGH, 8,
3519*9880d681SAndroid Build Coastguard Worker     { 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 } },
3520*9880d681SAndroid Build Coastguard Worker   // VMRHF
3521*9880d681SAndroid Build Coastguard Worker   { SystemZISD::MERGE_HIGH, 4,
3522*9880d681SAndroid Build Coastguard Worker     { 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23 } },
3523*9880d681SAndroid Build Coastguard Worker   // VMRHH
3524*9880d681SAndroid Build Coastguard Worker   { SystemZISD::MERGE_HIGH, 2,
3525*9880d681SAndroid Build Coastguard Worker     { 0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23 } },
3526*9880d681SAndroid Build Coastguard Worker   // VMRHB
3527*9880d681SAndroid Build Coastguard Worker   { SystemZISD::MERGE_HIGH, 1,
3528*9880d681SAndroid Build Coastguard Worker     { 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23 } },
3529*9880d681SAndroid Build Coastguard Worker   // VMRLG
3530*9880d681SAndroid Build Coastguard Worker   { SystemZISD::MERGE_LOW, 8,
3531*9880d681SAndroid Build Coastguard Worker     { 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31 } },
3532*9880d681SAndroid Build Coastguard Worker   // VMRLF
3533*9880d681SAndroid Build Coastguard Worker   { SystemZISD::MERGE_LOW, 4,
3534*9880d681SAndroid Build Coastguard Worker     { 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31 } },
3535*9880d681SAndroid Build Coastguard Worker   // VMRLH
3536*9880d681SAndroid Build Coastguard Worker   { SystemZISD::MERGE_LOW, 2,
3537*9880d681SAndroid Build Coastguard Worker     { 8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31 } },
3538*9880d681SAndroid Build Coastguard Worker   // VMRLB
3539*9880d681SAndroid Build Coastguard Worker   { SystemZISD::MERGE_LOW, 1,
3540*9880d681SAndroid Build Coastguard Worker     { 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31 } },
3541*9880d681SAndroid Build Coastguard Worker   // VPKG
3542*9880d681SAndroid Build Coastguard Worker   { SystemZISD::PACK, 4,
3543*9880d681SAndroid Build Coastguard Worker     { 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 } },
3544*9880d681SAndroid Build Coastguard Worker   // VPKF
3545*9880d681SAndroid Build Coastguard Worker   { SystemZISD::PACK, 2,
3546*9880d681SAndroid Build Coastguard Worker     { 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 } },
3547*9880d681SAndroid Build Coastguard Worker   // VPKH
3548*9880d681SAndroid Build Coastguard Worker   { SystemZISD::PACK, 1,
3549*9880d681SAndroid Build Coastguard Worker     { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 } },
3550*9880d681SAndroid Build Coastguard Worker   // VPDI V1, V2, 4  (low half of V1, high half of V2)
3551*9880d681SAndroid Build Coastguard Worker   { SystemZISD::PERMUTE_DWORDS, 4,
3552*9880d681SAndroid Build Coastguard Worker     { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 } },
3553*9880d681SAndroid Build Coastguard Worker   // VPDI V1, V2, 1  (high half of V1, low half of V2)
3554*9880d681SAndroid Build Coastguard Worker   { SystemZISD::PERMUTE_DWORDS, 1,
3555*9880d681SAndroid Build Coastguard Worker     { 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31 } }
3556*9880d681SAndroid Build Coastguard Worker };
3557*9880d681SAndroid Build Coastguard Worker 
3558*9880d681SAndroid Build Coastguard Worker // Called after matching a vector shuffle against a particular pattern.
3559*9880d681SAndroid Build Coastguard Worker // Both the original shuffle and the pattern have two vector operands.
3560*9880d681SAndroid Build Coastguard Worker // OpNos[0] is the operand of the original shuffle that should be used for
3561*9880d681SAndroid Build Coastguard Worker // operand 0 of the pattern, or -1 if operand 0 of the pattern can be anything.
3562*9880d681SAndroid Build Coastguard Worker // OpNos[1] is the same for operand 1 of the pattern.  Resolve these -1s and
3563*9880d681SAndroid Build Coastguard Worker // set OpNo0 and OpNo1 to the shuffle operands that should actually be used
3564*9880d681SAndroid Build Coastguard Worker // for operands 0 and 1 of the pattern.
chooseShuffleOpNos(int * OpNos,unsigned & OpNo0,unsigned & OpNo1)3565*9880d681SAndroid Build Coastguard Worker static bool chooseShuffleOpNos(int *OpNos, unsigned &OpNo0, unsigned &OpNo1) {
3566*9880d681SAndroid Build Coastguard Worker   if (OpNos[0] < 0) {
3567*9880d681SAndroid Build Coastguard Worker     if (OpNos[1] < 0)
3568*9880d681SAndroid Build Coastguard Worker       return false;
3569*9880d681SAndroid Build Coastguard Worker     OpNo0 = OpNo1 = OpNos[1];
3570*9880d681SAndroid Build Coastguard Worker   } else if (OpNos[1] < 0) {
3571*9880d681SAndroid Build Coastguard Worker     OpNo0 = OpNo1 = OpNos[0];
3572*9880d681SAndroid Build Coastguard Worker   } else {
3573*9880d681SAndroid Build Coastguard Worker     OpNo0 = OpNos[0];
3574*9880d681SAndroid Build Coastguard Worker     OpNo1 = OpNos[1];
3575*9880d681SAndroid Build Coastguard Worker   }
3576*9880d681SAndroid Build Coastguard Worker   return true;
3577*9880d681SAndroid Build Coastguard Worker }
3578*9880d681SAndroid Build Coastguard Worker 
3579*9880d681SAndroid Build Coastguard Worker // Bytes is a VPERM-like permute vector, except that -1 is used for
3580*9880d681SAndroid Build Coastguard Worker // undefined bytes.  Return true if the VPERM can be implemented using P.
3581*9880d681SAndroid Build Coastguard Worker // When returning true set OpNo0 to the VPERM operand that should be
3582*9880d681SAndroid Build Coastguard Worker // used for operand 0 of P and likewise OpNo1 for operand 1 of P.
3583*9880d681SAndroid Build Coastguard Worker //
3584*9880d681SAndroid Build Coastguard Worker // For example, if swapping the VPERM operands allows P to match, OpNo0
3585*9880d681SAndroid Build Coastguard Worker // will be 1 and OpNo1 will be 0.  If instead Bytes only refers to one
3586*9880d681SAndroid Build Coastguard Worker // operand, but rewriting it to use two duplicated operands allows it to
3587*9880d681SAndroid Build Coastguard Worker // match P, then OpNo0 and OpNo1 will be the same.
matchPermute(const SmallVectorImpl<int> & Bytes,const Permute & P,unsigned & OpNo0,unsigned & OpNo1)3588*9880d681SAndroid Build Coastguard Worker static bool matchPermute(const SmallVectorImpl<int> &Bytes, const Permute &P,
3589*9880d681SAndroid Build Coastguard Worker                          unsigned &OpNo0, unsigned &OpNo1) {
3590*9880d681SAndroid Build Coastguard Worker   int OpNos[] = { -1, -1 };
3591*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0; I < SystemZ::VectorBytes; ++I) {
3592*9880d681SAndroid Build Coastguard Worker     int Elt = Bytes[I];
3593*9880d681SAndroid Build Coastguard Worker     if (Elt >= 0) {
3594*9880d681SAndroid Build Coastguard Worker       // Make sure that the two permute vectors use the same suboperand
3595*9880d681SAndroid Build Coastguard Worker       // byte number.  Only the operand numbers (the high bits) are
3596*9880d681SAndroid Build Coastguard Worker       // allowed to differ.
3597*9880d681SAndroid Build Coastguard Worker       if ((Elt ^ P.Bytes[I]) & (SystemZ::VectorBytes - 1))
3598*9880d681SAndroid Build Coastguard Worker         return false;
3599*9880d681SAndroid Build Coastguard Worker       int ModelOpNo = P.Bytes[I] / SystemZ::VectorBytes;
3600*9880d681SAndroid Build Coastguard Worker       int RealOpNo = unsigned(Elt) / SystemZ::VectorBytes;
3601*9880d681SAndroid Build Coastguard Worker       // Make sure that the operand mappings are consistent with previous
3602*9880d681SAndroid Build Coastguard Worker       // elements.
3603*9880d681SAndroid Build Coastguard Worker       if (OpNos[ModelOpNo] == 1 - RealOpNo)
3604*9880d681SAndroid Build Coastguard Worker         return false;
3605*9880d681SAndroid Build Coastguard Worker       OpNos[ModelOpNo] = RealOpNo;
3606*9880d681SAndroid Build Coastguard Worker     }
3607*9880d681SAndroid Build Coastguard Worker   }
3608*9880d681SAndroid Build Coastguard Worker   return chooseShuffleOpNos(OpNos, OpNo0, OpNo1);
3609*9880d681SAndroid Build Coastguard Worker }
3610*9880d681SAndroid Build Coastguard Worker 
3611*9880d681SAndroid Build Coastguard Worker // As above, but search for a matching permute.
matchPermute(const SmallVectorImpl<int> & Bytes,unsigned & OpNo0,unsigned & OpNo1)3612*9880d681SAndroid Build Coastguard Worker static const Permute *matchPermute(const SmallVectorImpl<int> &Bytes,
3613*9880d681SAndroid Build Coastguard Worker                                    unsigned &OpNo0, unsigned &OpNo1) {
3614*9880d681SAndroid Build Coastguard Worker   for (auto &P : PermuteForms)
3615*9880d681SAndroid Build Coastguard Worker     if (matchPermute(Bytes, P, OpNo0, OpNo1))
3616*9880d681SAndroid Build Coastguard Worker       return &P;
3617*9880d681SAndroid Build Coastguard Worker   return nullptr;
3618*9880d681SAndroid Build Coastguard Worker }
3619*9880d681SAndroid Build Coastguard Worker 
3620*9880d681SAndroid Build Coastguard Worker // Bytes is a VPERM-like permute vector, except that -1 is used for
3621*9880d681SAndroid Build Coastguard Worker // undefined bytes.  This permute is an operand of an outer permute.
3622*9880d681SAndroid Build Coastguard Worker // See whether redistributing the -1 bytes gives a shuffle that can be
3623*9880d681SAndroid Build Coastguard Worker // implemented using P.  If so, set Transform to a VPERM-like permute vector
3624*9880d681SAndroid Build Coastguard Worker // that, when applied to the result of P, gives the original permute in Bytes.
matchDoublePermute(const SmallVectorImpl<int> & Bytes,const Permute & P,SmallVectorImpl<int> & Transform)3625*9880d681SAndroid Build Coastguard Worker static bool matchDoublePermute(const SmallVectorImpl<int> &Bytes,
3626*9880d681SAndroid Build Coastguard Worker                                const Permute &P,
3627*9880d681SAndroid Build Coastguard Worker                                SmallVectorImpl<int> &Transform) {
3628*9880d681SAndroid Build Coastguard Worker   unsigned To = 0;
3629*9880d681SAndroid Build Coastguard Worker   for (unsigned From = 0; From < SystemZ::VectorBytes; ++From) {
3630*9880d681SAndroid Build Coastguard Worker     int Elt = Bytes[From];
3631*9880d681SAndroid Build Coastguard Worker     if (Elt < 0)
3632*9880d681SAndroid Build Coastguard Worker       // Byte number From of the result is undefined.
3633*9880d681SAndroid Build Coastguard Worker       Transform[From] = -1;
3634*9880d681SAndroid Build Coastguard Worker     else {
3635*9880d681SAndroid Build Coastguard Worker       while (P.Bytes[To] != Elt) {
3636*9880d681SAndroid Build Coastguard Worker         To += 1;
3637*9880d681SAndroid Build Coastguard Worker         if (To == SystemZ::VectorBytes)
3638*9880d681SAndroid Build Coastguard Worker           return false;
3639*9880d681SAndroid Build Coastguard Worker       }
3640*9880d681SAndroid Build Coastguard Worker       Transform[From] = To;
3641*9880d681SAndroid Build Coastguard Worker     }
3642*9880d681SAndroid Build Coastguard Worker   }
3643*9880d681SAndroid Build Coastguard Worker   return true;
3644*9880d681SAndroid Build Coastguard Worker }
3645*9880d681SAndroid Build Coastguard Worker 
3646*9880d681SAndroid Build Coastguard Worker // As above, but search for a matching permute.
matchDoublePermute(const SmallVectorImpl<int> & Bytes,SmallVectorImpl<int> & Transform)3647*9880d681SAndroid Build Coastguard Worker static const Permute *matchDoublePermute(const SmallVectorImpl<int> &Bytes,
3648*9880d681SAndroid Build Coastguard Worker                                          SmallVectorImpl<int> &Transform) {
3649*9880d681SAndroid Build Coastguard Worker   for (auto &P : PermuteForms)
3650*9880d681SAndroid Build Coastguard Worker     if (matchDoublePermute(Bytes, P, Transform))
3651*9880d681SAndroid Build Coastguard Worker       return &P;
3652*9880d681SAndroid Build Coastguard Worker   return nullptr;
3653*9880d681SAndroid Build Coastguard Worker }
3654*9880d681SAndroid Build Coastguard Worker 
3655*9880d681SAndroid Build Coastguard Worker // Convert the mask of the given VECTOR_SHUFFLE into a byte-level mask,
3656*9880d681SAndroid Build Coastguard Worker // as if it had type vNi8.
getVPermMask(ShuffleVectorSDNode * VSN,SmallVectorImpl<int> & Bytes)3657*9880d681SAndroid Build Coastguard Worker static void getVPermMask(ShuffleVectorSDNode *VSN,
3658*9880d681SAndroid Build Coastguard Worker                          SmallVectorImpl<int> &Bytes) {
3659*9880d681SAndroid Build Coastguard Worker   EVT VT = VSN->getValueType(0);
3660*9880d681SAndroid Build Coastguard Worker   unsigned NumElements = VT.getVectorNumElements();
3661*9880d681SAndroid Build Coastguard Worker   unsigned BytesPerElement = VT.getVectorElementType().getStoreSize();
3662*9880d681SAndroid Build Coastguard Worker   Bytes.resize(NumElements * BytesPerElement, -1);
3663*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0; I < NumElements; ++I) {
3664*9880d681SAndroid Build Coastguard Worker     int Index = VSN->getMaskElt(I);
3665*9880d681SAndroid Build Coastguard Worker     if (Index >= 0)
3666*9880d681SAndroid Build Coastguard Worker       for (unsigned J = 0; J < BytesPerElement; ++J)
3667*9880d681SAndroid Build Coastguard Worker         Bytes[I * BytesPerElement + J] = Index * BytesPerElement + J;
3668*9880d681SAndroid Build Coastguard Worker   }
3669*9880d681SAndroid Build Coastguard Worker }
3670*9880d681SAndroid Build Coastguard Worker 
3671*9880d681SAndroid Build Coastguard Worker // Bytes is a VPERM-like permute vector, except that -1 is used for
3672*9880d681SAndroid Build Coastguard Worker // undefined bytes.  See whether bytes [Start, Start + BytesPerElement) of
3673*9880d681SAndroid Build Coastguard Worker // the result come from a contiguous sequence of bytes from one input.
3674*9880d681SAndroid Build Coastguard Worker // Set Base to the selector for the first byte if so.
getShuffleInput(const SmallVectorImpl<int> & Bytes,unsigned Start,unsigned BytesPerElement,int & Base)3675*9880d681SAndroid Build Coastguard Worker static bool getShuffleInput(const SmallVectorImpl<int> &Bytes, unsigned Start,
3676*9880d681SAndroid Build Coastguard Worker                             unsigned BytesPerElement, int &Base) {
3677*9880d681SAndroid Build Coastguard Worker   Base = -1;
3678*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0; I < BytesPerElement; ++I) {
3679*9880d681SAndroid Build Coastguard Worker     if (Bytes[Start + I] >= 0) {
3680*9880d681SAndroid Build Coastguard Worker       unsigned Elem = Bytes[Start + I];
3681*9880d681SAndroid Build Coastguard Worker       if (Base < 0) {
3682*9880d681SAndroid Build Coastguard Worker         Base = Elem - I;
3683*9880d681SAndroid Build Coastguard Worker         // Make sure the bytes would come from one input operand.
3684*9880d681SAndroid Build Coastguard Worker         if (unsigned(Base) % Bytes.size() + BytesPerElement > Bytes.size())
3685*9880d681SAndroid Build Coastguard Worker           return false;
3686*9880d681SAndroid Build Coastguard Worker       } else if (unsigned(Base) != Elem - I)
3687*9880d681SAndroid Build Coastguard Worker         return false;
3688*9880d681SAndroid Build Coastguard Worker     }
3689*9880d681SAndroid Build Coastguard Worker   }
3690*9880d681SAndroid Build Coastguard Worker   return true;
3691*9880d681SAndroid Build Coastguard Worker }
3692*9880d681SAndroid Build Coastguard Worker 
3693*9880d681SAndroid Build Coastguard Worker // Bytes is a VPERM-like permute vector, except that -1 is used for
3694*9880d681SAndroid Build Coastguard Worker // undefined bytes.  Return true if it can be performed using VSLDI.
3695*9880d681SAndroid Build Coastguard Worker // When returning true, set StartIndex to the shift amount and OpNo0
3696*9880d681SAndroid Build Coastguard Worker // and OpNo1 to the VPERM operands that should be used as the first
3697*9880d681SAndroid Build Coastguard Worker // and second shift operand respectively.
isShlDoublePermute(const SmallVectorImpl<int> & Bytes,unsigned & StartIndex,unsigned & OpNo0,unsigned & OpNo1)3698*9880d681SAndroid Build Coastguard Worker static bool isShlDoublePermute(const SmallVectorImpl<int> &Bytes,
3699*9880d681SAndroid Build Coastguard Worker                                unsigned &StartIndex, unsigned &OpNo0,
3700*9880d681SAndroid Build Coastguard Worker                                unsigned &OpNo1) {
3701*9880d681SAndroid Build Coastguard Worker   int OpNos[] = { -1, -1 };
3702*9880d681SAndroid Build Coastguard Worker   int Shift = -1;
3703*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0; I < 16; ++I) {
3704*9880d681SAndroid Build Coastguard Worker     int Index = Bytes[I];
3705*9880d681SAndroid Build Coastguard Worker     if (Index >= 0) {
3706*9880d681SAndroid Build Coastguard Worker       int ExpectedShift = (Index - I) % SystemZ::VectorBytes;
3707*9880d681SAndroid Build Coastguard Worker       int ModelOpNo = unsigned(ExpectedShift + I) / SystemZ::VectorBytes;
3708*9880d681SAndroid Build Coastguard Worker       int RealOpNo = unsigned(Index) / SystemZ::VectorBytes;
3709*9880d681SAndroid Build Coastguard Worker       if (Shift < 0)
3710*9880d681SAndroid Build Coastguard Worker         Shift = ExpectedShift;
3711*9880d681SAndroid Build Coastguard Worker       else if (Shift != ExpectedShift)
3712*9880d681SAndroid Build Coastguard Worker         return false;
3713*9880d681SAndroid Build Coastguard Worker       // Make sure that the operand mappings are consistent with previous
3714*9880d681SAndroid Build Coastguard Worker       // elements.
3715*9880d681SAndroid Build Coastguard Worker       if (OpNos[ModelOpNo] == 1 - RealOpNo)
3716*9880d681SAndroid Build Coastguard Worker         return false;
3717*9880d681SAndroid Build Coastguard Worker       OpNos[ModelOpNo] = RealOpNo;
3718*9880d681SAndroid Build Coastguard Worker     }
3719*9880d681SAndroid Build Coastguard Worker   }
3720*9880d681SAndroid Build Coastguard Worker   StartIndex = Shift;
3721*9880d681SAndroid Build Coastguard Worker   return chooseShuffleOpNos(OpNos, OpNo0, OpNo1);
3722*9880d681SAndroid Build Coastguard Worker }
3723*9880d681SAndroid Build Coastguard Worker 
3724*9880d681SAndroid Build Coastguard Worker // Create a node that performs P on operands Op0 and Op1, casting the
3725*9880d681SAndroid Build Coastguard Worker // operands to the appropriate type.  The type of the result is determined by P.
getPermuteNode(SelectionDAG & DAG,const SDLoc & DL,const Permute & P,SDValue Op0,SDValue Op1)3726*9880d681SAndroid Build Coastguard Worker static SDValue getPermuteNode(SelectionDAG &DAG, const SDLoc &DL,
3727*9880d681SAndroid Build Coastguard Worker                               const Permute &P, SDValue Op0, SDValue Op1) {
3728*9880d681SAndroid Build Coastguard Worker   // VPDI (PERMUTE_DWORDS) always operates on v2i64s.  The input
3729*9880d681SAndroid Build Coastguard Worker   // elements of a PACK are twice as wide as the outputs.
3730*9880d681SAndroid Build Coastguard Worker   unsigned InBytes = (P.Opcode == SystemZISD::PERMUTE_DWORDS ? 8 :
3731*9880d681SAndroid Build Coastguard Worker                       P.Opcode == SystemZISD::PACK ? P.Operand * 2 :
3732*9880d681SAndroid Build Coastguard Worker                       P.Operand);
3733*9880d681SAndroid Build Coastguard Worker   // Cast both operands to the appropriate type.
3734*9880d681SAndroid Build Coastguard Worker   MVT InVT = MVT::getVectorVT(MVT::getIntegerVT(InBytes * 8),
3735*9880d681SAndroid Build Coastguard Worker                               SystemZ::VectorBytes / InBytes);
3736*9880d681SAndroid Build Coastguard Worker   Op0 = DAG.getNode(ISD::BITCAST, DL, InVT, Op0);
3737*9880d681SAndroid Build Coastguard Worker   Op1 = DAG.getNode(ISD::BITCAST, DL, InVT, Op1);
3738*9880d681SAndroid Build Coastguard Worker   SDValue Op;
3739*9880d681SAndroid Build Coastguard Worker   if (P.Opcode == SystemZISD::PERMUTE_DWORDS) {
3740*9880d681SAndroid Build Coastguard Worker     SDValue Op2 = DAG.getConstant(P.Operand, DL, MVT::i32);
3741*9880d681SAndroid Build Coastguard Worker     Op = DAG.getNode(SystemZISD::PERMUTE_DWORDS, DL, InVT, Op0, Op1, Op2);
3742*9880d681SAndroid Build Coastguard Worker   } else if (P.Opcode == SystemZISD::PACK) {
3743*9880d681SAndroid Build Coastguard Worker     MVT OutVT = MVT::getVectorVT(MVT::getIntegerVT(P.Operand * 8),
3744*9880d681SAndroid Build Coastguard Worker                                  SystemZ::VectorBytes / P.Operand);
3745*9880d681SAndroid Build Coastguard Worker     Op = DAG.getNode(SystemZISD::PACK, DL, OutVT, Op0, Op1);
3746*9880d681SAndroid Build Coastguard Worker   } else {
3747*9880d681SAndroid Build Coastguard Worker     Op = DAG.getNode(P.Opcode, DL, InVT, Op0, Op1);
3748*9880d681SAndroid Build Coastguard Worker   }
3749*9880d681SAndroid Build Coastguard Worker   return Op;
3750*9880d681SAndroid Build Coastguard Worker }
3751*9880d681SAndroid Build Coastguard Worker 
3752*9880d681SAndroid Build Coastguard Worker // Bytes is a VPERM-like permute vector, except that -1 is used for
3753*9880d681SAndroid Build Coastguard Worker // undefined bytes.  Implement it on operands Ops[0] and Ops[1] using
3754*9880d681SAndroid Build Coastguard Worker // VSLDI or VPERM.
getGeneralPermuteNode(SelectionDAG & DAG,const SDLoc & DL,SDValue * Ops,const SmallVectorImpl<int> & Bytes)3755*9880d681SAndroid Build Coastguard Worker static SDValue getGeneralPermuteNode(SelectionDAG &DAG, const SDLoc &DL,
3756*9880d681SAndroid Build Coastguard Worker                                      SDValue *Ops,
3757*9880d681SAndroid Build Coastguard Worker                                      const SmallVectorImpl<int> &Bytes) {
3758*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0; I < 2; ++I)
3759*9880d681SAndroid Build Coastguard Worker     Ops[I] = DAG.getNode(ISD::BITCAST, DL, MVT::v16i8, Ops[I]);
3760*9880d681SAndroid Build Coastguard Worker 
3761*9880d681SAndroid Build Coastguard Worker   // First see whether VSLDI can be used.
3762*9880d681SAndroid Build Coastguard Worker   unsigned StartIndex, OpNo0, OpNo1;
3763*9880d681SAndroid Build Coastguard Worker   if (isShlDoublePermute(Bytes, StartIndex, OpNo0, OpNo1))
3764*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(SystemZISD::SHL_DOUBLE, DL, MVT::v16i8, Ops[OpNo0],
3765*9880d681SAndroid Build Coastguard Worker                        Ops[OpNo1], DAG.getConstant(StartIndex, DL, MVT::i32));
3766*9880d681SAndroid Build Coastguard Worker 
3767*9880d681SAndroid Build Coastguard Worker   // Fall back on VPERM.  Construct an SDNode for the permute vector.
3768*9880d681SAndroid Build Coastguard Worker   SDValue IndexNodes[SystemZ::VectorBytes];
3769*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0; I < SystemZ::VectorBytes; ++I)
3770*9880d681SAndroid Build Coastguard Worker     if (Bytes[I] >= 0)
3771*9880d681SAndroid Build Coastguard Worker       IndexNodes[I] = DAG.getConstant(Bytes[I], DL, MVT::i32);
3772*9880d681SAndroid Build Coastguard Worker     else
3773*9880d681SAndroid Build Coastguard Worker       IndexNodes[I] = DAG.getUNDEF(MVT::i32);
3774*9880d681SAndroid Build Coastguard Worker   SDValue Op2 = DAG.getBuildVector(MVT::v16i8, DL, IndexNodes);
3775*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(SystemZISD::PERMUTE, DL, MVT::v16i8, Ops[0], Ops[1], Op2);
3776*9880d681SAndroid Build Coastguard Worker }
3777*9880d681SAndroid Build Coastguard Worker 
3778*9880d681SAndroid Build Coastguard Worker namespace {
3779*9880d681SAndroid Build Coastguard Worker // Describes a general N-operand vector shuffle.
3780*9880d681SAndroid Build Coastguard Worker struct GeneralShuffle {
GeneralShuffle__anon8c72947f0311::GeneralShuffle3781*9880d681SAndroid Build Coastguard Worker   GeneralShuffle(EVT vt) : VT(vt) {}
3782*9880d681SAndroid Build Coastguard Worker   void addUndef();
3783*9880d681SAndroid Build Coastguard Worker   void add(SDValue, unsigned);
3784*9880d681SAndroid Build Coastguard Worker   SDValue getNode(SelectionDAG &, const SDLoc &);
3785*9880d681SAndroid Build Coastguard Worker 
3786*9880d681SAndroid Build Coastguard Worker   // The operands of the shuffle.
3787*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, SystemZ::VectorBytes> Ops;
3788*9880d681SAndroid Build Coastguard Worker 
3789*9880d681SAndroid Build Coastguard Worker   // Index I is -1 if byte I of the result is undefined.  Otherwise the
3790*9880d681SAndroid Build Coastguard Worker   // result comes from byte Bytes[I] % SystemZ::VectorBytes of operand
3791*9880d681SAndroid Build Coastguard Worker   // Bytes[I] / SystemZ::VectorBytes.
3792*9880d681SAndroid Build Coastguard Worker   SmallVector<int, SystemZ::VectorBytes> Bytes;
3793*9880d681SAndroid Build Coastguard Worker 
3794*9880d681SAndroid Build Coastguard Worker   // The type of the shuffle result.
3795*9880d681SAndroid Build Coastguard Worker   EVT VT;
3796*9880d681SAndroid Build Coastguard Worker };
3797*9880d681SAndroid Build Coastguard Worker }
3798*9880d681SAndroid Build Coastguard Worker 
3799*9880d681SAndroid Build Coastguard Worker // Add an extra undefined element to the shuffle.
addUndef()3800*9880d681SAndroid Build Coastguard Worker void GeneralShuffle::addUndef() {
3801*9880d681SAndroid Build Coastguard Worker   unsigned BytesPerElement = VT.getVectorElementType().getStoreSize();
3802*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0; I < BytesPerElement; ++I)
3803*9880d681SAndroid Build Coastguard Worker     Bytes.push_back(-1);
3804*9880d681SAndroid Build Coastguard Worker }
3805*9880d681SAndroid Build Coastguard Worker 
3806*9880d681SAndroid Build Coastguard Worker // Add an extra element to the shuffle, taking it from element Elem of Op.
3807*9880d681SAndroid Build Coastguard Worker // A null Op indicates a vector input whose value will be calculated later;
3808*9880d681SAndroid Build Coastguard Worker // there is at most one such input per shuffle and it always has the same
3809*9880d681SAndroid Build Coastguard Worker // type as the result.
add(SDValue Op,unsigned Elem)3810*9880d681SAndroid Build Coastguard Worker void GeneralShuffle::add(SDValue Op, unsigned Elem) {
3811*9880d681SAndroid Build Coastguard Worker   unsigned BytesPerElement = VT.getVectorElementType().getStoreSize();
3812*9880d681SAndroid Build Coastguard Worker 
3813*9880d681SAndroid Build Coastguard Worker   // The source vector can have wider elements than the result,
3814*9880d681SAndroid Build Coastguard Worker   // either through an explicit TRUNCATE or because of type legalization.
3815*9880d681SAndroid Build Coastguard Worker   // We want the least significant part.
3816*9880d681SAndroid Build Coastguard Worker   EVT FromVT = Op.getNode() ? Op.getValueType() : VT;
3817*9880d681SAndroid Build Coastguard Worker   unsigned FromBytesPerElement = FromVT.getVectorElementType().getStoreSize();
3818*9880d681SAndroid Build Coastguard Worker   assert(FromBytesPerElement >= BytesPerElement &&
3819*9880d681SAndroid Build Coastguard Worker          "Invalid EXTRACT_VECTOR_ELT");
3820*9880d681SAndroid Build Coastguard Worker   unsigned Byte = ((Elem * FromBytesPerElement) % SystemZ::VectorBytes +
3821*9880d681SAndroid Build Coastguard Worker                    (FromBytesPerElement - BytesPerElement));
3822*9880d681SAndroid Build Coastguard Worker 
3823*9880d681SAndroid Build Coastguard Worker   // Look through things like shuffles and bitcasts.
3824*9880d681SAndroid Build Coastguard Worker   while (Op.getNode()) {
3825*9880d681SAndroid Build Coastguard Worker     if (Op.getOpcode() == ISD::BITCAST)
3826*9880d681SAndroid Build Coastguard Worker       Op = Op.getOperand(0);
3827*9880d681SAndroid Build Coastguard Worker     else if (Op.getOpcode() == ISD::VECTOR_SHUFFLE && Op.hasOneUse()) {
3828*9880d681SAndroid Build Coastguard Worker       // See whether the bytes we need come from a contiguous part of one
3829*9880d681SAndroid Build Coastguard Worker       // operand.
3830*9880d681SAndroid Build Coastguard Worker       SmallVector<int, SystemZ::VectorBytes> OpBytes;
3831*9880d681SAndroid Build Coastguard Worker       getVPermMask(cast<ShuffleVectorSDNode>(Op), OpBytes);
3832*9880d681SAndroid Build Coastguard Worker       int NewByte;
3833*9880d681SAndroid Build Coastguard Worker       if (!getShuffleInput(OpBytes, Byte, BytesPerElement, NewByte))
3834*9880d681SAndroid Build Coastguard Worker         break;
3835*9880d681SAndroid Build Coastguard Worker       if (NewByte < 0) {
3836*9880d681SAndroid Build Coastguard Worker         addUndef();
3837*9880d681SAndroid Build Coastguard Worker         return;
3838*9880d681SAndroid Build Coastguard Worker       }
3839*9880d681SAndroid Build Coastguard Worker       Op = Op.getOperand(unsigned(NewByte) / SystemZ::VectorBytes);
3840*9880d681SAndroid Build Coastguard Worker       Byte = unsigned(NewByte) % SystemZ::VectorBytes;
3841*9880d681SAndroid Build Coastguard Worker     } else if (Op.isUndef()) {
3842*9880d681SAndroid Build Coastguard Worker       addUndef();
3843*9880d681SAndroid Build Coastguard Worker       return;
3844*9880d681SAndroid Build Coastguard Worker     } else
3845*9880d681SAndroid Build Coastguard Worker       break;
3846*9880d681SAndroid Build Coastguard Worker   }
3847*9880d681SAndroid Build Coastguard Worker 
3848*9880d681SAndroid Build Coastguard Worker   // Make sure that the source of the extraction is in Ops.
3849*9880d681SAndroid Build Coastguard Worker   unsigned OpNo = 0;
3850*9880d681SAndroid Build Coastguard Worker   for (; OpNo < Ops.size(); ++OpNo)
3851*9880d681SAndroid Build Coastguard Worker     if (Ops[OpNo] == Op)
3852*9880d681SAndroid Build Coastguard Worker       break;
3853*9880d681SAndroid Build Coastguard Worker   if (OpNo == Ops.size())
3854*9880d681SAndroid Build Coastguard Worker     Ops.push_back(Op);
3855*9880d681SAndroid Build Coastguard Worker 
3856*9880d681SAndroid Build Coastguard Worker   // Add the element to Bytes.
3857*9880d681SAndroid Build Coastguard Worker   unsigned Base = OpNo * SystemZ::VectorBytes + Byte;
3858*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0; I < BytesPerElement; ++I)
3859*9880d681SAndroid Build Coastguard Worker     Bytes.push_back(Base + I);
3860*9880d681SAndroid Build Coastguard Worker }
3861*9880d681SAndroid Build Coastguard Worker 
3862*9880d681SAndroid Build Coastguard Worker // Return SDNodes for the completed shuffle.
getNode(SelectionDAG & DAG,const SDLoc & DL)3863*9880d681SAndroid Build Coastguard Worker SDValue GeneralShuffle::getNode(SelectionDAG &DAG, const SDLoc &DL) {
3864*9880d681SAndroid Build Coastguard Worker   assert(Bytes.size() == SystemZ::VectorBytes && "Incomplete vector");
3865*9880d681SAndroid Build Coastguard Worker 
3866*9880d681SAndroid Build Coastguard Worker   if (Ops.size() == 0)
3867*9880d681SAndroid Build Coastguard Worker     return DAG.getUNDEF(VT);
3868*9880d681SAndroid Build Coastguard Worker 
3869*9880d681SAndroid Build Coastguard Worker   // Make sure that there are at least two shuffle operands.
3870*9880d681SAndroid Build Coastguard Worker   if (Ops.size() == 1)
3871*9880d681SAndroid Build Coastguard Worker     Ops.push_back(DAG.getUNDEF(MVT::v16i8));
3872*9880d681SAndroid Build Coastguard Worker 
3873*9880d681SAndroid Build Coastguard Worker   // Create a tree of shuffles, deferring root node until after the loop.
3874*9880d681SAndroid Build Coastguard Worker   // Try to redistribute the undefined elements of non-root nodes so that
3875*9880d681SAndroid Build Coastguard Worker   // the non-root shuffles match something like a pack or merge, then adjust
3876*9880d681SAndroid Build Coastguard Worker   // the parent node's permute vector to compensate for the new order.
3877*9880d681SAndroid Build Coastguard Worker   // Among other things, this copes with vectors like <2 x i16> that were
3878*9880d681SAndroid Build Coastguard Worker   // padded with undefined elements during type legalization.
3879*9880d681SAndroid Build Coastguard Worker   //
3880*9880d681SAndroid Build Coastguard Worker   // In the best case this redistribution will lead to the whole tree
3881*9880d681SAndroid Build Coastguard Worker   // using packs and merges.  It should rarely be a loss in other cases.
3882*9880d681SAndroid Build Coastguard Worker   unsigned Stride = 1;
3883*9880d681SAndroid Build Coastguard Worker   for (; Stride * 2 < Ops.size(); Stride *= 2) {
3884*9880d681SAndroid Build Coastguard Worker     for (unsigned I = 0; I < Ops.size() - Stride; I += Stride * 2) {
3885*9880d681SAndroid Build Coastguard Worker       SDValue SubOps[] = { Ops[I], Ops[I + Stride] };
3886*9880d681SAndroid Build Coastguard Worker 
3887*9880d681SAndroid Build Coastguard Worker       // Create a mask for just these two operands.
3888*9880d681SAndroid Build Coastguard Worker       SmallVector<int, SystemZ::VectorBytes> NewBytes(SystemZ::VectorBytes);
3889*9880d681SAndroid Build Coastguard Worker       for (unsigned J = 0; J < SystemZ::VectorBytes; ++J) {
3890*9880d681SAndroid Build Coastguard Worker         unsigned OpNo = unsigned(Bytes[J]) / SystemZ::VectorBytes;
3891*9880d681SAndroid Build Coastguard Worker         unsigned Byte = unsigned(Bytes[J]) % SystemZ::VectorBytes;
3892*9880d681SAndroid Build Coastguard Worker         if (OpNo == I)
3893*9880d681SAndroid Build Coastguard Worker           NewBytes[J] = Byte;
3894*9880d681SAndroid Build Coastguard Worker         else if (OpNo == I + Stride)
3895*9880d681SAndroid Build Coastguard Worker           NewBytes[J] = SystemZ::VectorBytes + Byte;
3896*9880d681SAndroid Build Coastguard Worker         else
3897*9880d681SAndroid Build Coastguard Worker           NewBytes[J] = -1;
3898*9880d681SAndroid Build Coastguard Worker       }
3899*9880d681SAndroid Build Coastguard Worker       // See if it would be better to reorganize NewMask to avoid using VPERM.
3900*9880d681SAndroid Build Coastguard Worker       SmallVector<int, SystemZ::VectorBytes> NewBytesMap(SystemZ::VectorBytes);
3901*9880d681SAndroid Build Coastguard Worker       if (const Permute *P = matchDoublePermute(NewBytes, NewBytesMap)) {
3902*9880d681SAndroid Build Coastguard Worker         Ops[I] = getPermuteNode(DAG, DL, *P, SubOps[0], SubOps[1]);
3903*9880d681SAndroid Build Coastguard Worker         // Applying NewBytesMap to Ops[I] gets back to NewBytes.
3904*9880d681SAndroid Build Coastguard Worker         for (unsigned J = 0; J < SystemZ::VectorBytes; ++J) {
3905*9880d681SAndroid Build Coastguard Worker           if (NewBytes[J] >= 0) {
3906*9880d681SAndroid Build Coastguard Worker             assert(unsigned(NewBytesMap[J]) < SystemZ::VectorBytes &&
3907*9880d681SAndroid Build Coastguard Worker                    "Invalid double permute");
3908*9880d681SAndroid Build Coastguard Worker             Bytes[J] = I * SystemZ::VectorBytes + NewBytesMap[J];
3909*9880d681SAndroid Build Coastguard Worker           } else
3910*9880d681SAndroid Build Coastguard Worker             assert(NewBytesMap[J] < 0 && "Invalid double permute");
3911*9880d681SAndroid Build Coastguard Worker         }
3912*9880d681SAndroid Build Coastguard Worker       } else {
3913*9880d681SAndroid Build Coastguard Worker         // Just use NewBytes on the operands.
3914*9880d681SAndroid Build Coastguard Worker         Ops[I] = getGeneralPermuteNode(DAG, DL, SubOps, NewBytes);
3915*9880d681SAndroid Build Coastguard Worker         for (unsigned J = 0; J < SystemZ::VectorBytes; ++J)
3916*9880d681SAndroid Build Coastguard Worker           if (NewBytes[J] >= 0)
3917*9880d681SAndroid Build Coastguard Worker             Bytes[J] = I * SystemZ::VectorBytes + J;
3918*9880d681SAndroid Build Coastguard Worker       }
3919*9880d681SAndroid Build Coastguard Worker     }
3920*9880d681SAndroid Build Coastguard Worker   }
3921*9880d681SAndroid Build Coastguard Worker 
3922*9880d681SAndroid Build Coastguard Worker   // Now we just have 2 inputs.  Put the second operand in Ops[1].
3923*9880d681SAndroid Build Coastguard Worker   if (Stride > 1) {
3924*9880d681SAndroid Build Coastguard Worker     Ops[1] = Ops[Stride];
3925*9880d681SAndroid Build Coastguard Worker     for (unsigned I = 0; I < SystemZ::VectorBytes; ++I)
3926*9880d681SAndroid Build Coastguard Worker       if (Bytes[I] >= int(SystemZ::VectorBytes))
3927*9880d681SAndroid Build Coastguard Worker         Bytes[I] -= (Stride - 1) * SystemZ::VectorBytes;
3928*9880d681SAndroid Build Coastguard Worker   }
3929*9880d681SAndroid Build Coastguard Worker 
3930*9880d681SAndroid Build Coastguard Worker   // Look for an instruction that can do the permute without resorting
3931*9880d681SAndroid Build Coastguard Worker   // to VPERM.
3932*9880d681SAndroid Build Coastguard Worker   unsigned OpNo0, OpNo1;
3933*9880d681SAndroid Build Coastguard Worker   SDValue Op;
3934*9880d681SAndroid Build Coastguard Worker   if (const Permute *P = matchPermute(Bytes, OpNo0, OpNo1))
3935*9880d681SAndroid Build Coastguard Worker     Op = getPermuteNode(DAG, DL, *P, Ops[OpNo0], Ops[OpNo1]);
3936*9880d681SAndroid Build Coastguard Worker   else
3937*9880d681SAndroid Build Coastguard Worker     Op = getGeneralPermuteNode(DAG, DL, &Ops[0], Bytes);
3938*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(ISD::BITCAST, DL, VT, Op);
3939*9880d681SAndroid Build Coastguard Worker }
3940*9880d681SAndroid Build Coastguard Worker 
3941*9880d681SAndroid Build Coastguard Worker // Return true if the given BUILD_VECTOR is a scalar-to-vector conversion.
isScalarToVector(SDValue Op)3942*9880d681SAndroid Build Coastguard Worker static bool isScalarToVector(SDValue Op) {
3943*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 1, E = Op.getNumOperands(); I != E; ++I)
3944*9880d681SAndroid Build Coastguard Worker     if (!Op.getOperand(I).isUndef())
3945*9880d681SAndroid Build Coastguard Worker       return false;
3946*9880d681SAndroid Build Coastguard Worker   return true;
3947*9880d681SAndroid Build Coastguard Worker }
3948*9880d681SAndroid Build Coastguard Worker 
3949*9880d681SAndroid Build Coastguard Worker // Return a vector of type VT that contains Value in the first element.
3950*9880d681SAndroid Build Coastguard Worker // The other elements don't matter.
buildScalarToVector(SelectionDAG & DAG,const SDLoc & DL,EVT VT,SDValue Value)3951*9880d681SAndroid Build Coastguard Worker static SDValue buildScalarToVector(SelectionDAG &DAG, const SDLoc &DL, EVT VT,
3952*9880d681SAndroid Build Coastguard Worker                                    SDValue Value) {
3953*9880d681SAndroid Build Coastguard Worker   // If we have a constant, replicate it to all elements and let the
3954*9880d681SAndroid Build Coastguard Worker   // BUILD_VECTOR lowering take care of it.
3955*9880d681SAndroid Build Coastguard Worker   if (Value.getOpcode() == ISD::Constant ||
3956*9880d681SAndroid Build Coastguard Worker       Value.getOpcode() == ISD::ConstantFP) {
3957*9880d681SAndroid Build Coastguard Worker     SmallVector<SDValue, 16> Ops(VT.getVectorNumElements(), Value);
3958*9880d681SAndroid Build Coastguard Worker     return DAG.getBuildVector(VT, DL, Ops);
3959*9880d681SAndroid Build Coastguard Worker   }
3960*9880d681SAndroid Build Coastguard Worker   if (Value.isUndef())
3961*9880d681SAndroid Build Coastguard Worker     return DAG.getUNDEF(VT);
3962*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VT, Value);
3963*9880d681SAndroid Build Coastguard Worker }
3964*9880d681SAndroid Build Coastguard Worker 
3965*9880d681SAndroid Build Coastguard Worker // Return a vector of type VT in which Op0 is in element 0 and Op1 is in
3966*9880d681SAndroid Build Coastguard Worker // element 1.  Used for cases in which replication is cheap.
buildMergeScalars(SelectionDAG & DAG,const SDLoc & DL,EVT VT,SDValue Op0,SDValue Op1)3967*9880d681SAndroid Build Coastguard Worker static SDValue buildMergeScalars(SelectionDAG &DAG, const SDLoc &DL, EVT VT,
3968*9880d681SAndroid Build Coastguard Worker                                  SDValue Op0, SDValue Op1) {
3969*9880d681SAndroid Build Coastguard Worker   if (Op0.isUndef()) {
3970*9880d681SAndroid Build Coastguard Worker     if (Op1.isUndef())
3971*9880d681SAndroid Build Coastguard Worker       return DAG.getUNDEF(VT);
3972*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(SystemZISD::REPLICATE, DL, VT, Op1);
3973*9880d681SAndroid Build Coastguard Worker   }
3974*9880d681SAndroid Build Coastguard Worker   if (Op1.isUndef())
3975*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(SystemZISD::REPLICATE, DL, VT, Op0);
3976*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(SystemZISD::MERGE_HIGH, DL, VT,
3977*9880d681SAndroid Build Coastguard Worker                      buildScalarToVector(DAG, DL, VT, Op0),
3978*9880d681SAndroid Build Coastguard Worker                      buildScalarToVector(DAG, DL, VT, Op1));
3979*9880d681SAndroid Build Coastguard Worker }
3980*9880d681SAndroid Build Coastguard Worker 
3981*9880d681SAndroid Build Coastguard Worker // Extend GPR scalars Op0 and Op1 to doublewords and return a v2i64
3982*9880d681SAndroid Build Coastguard Worker // vector for them.
joinDwords(SelectionDAG & DAG,const SDLoc & DL,SDValue Op0,SDValue Op1)3983*9880d681SAndroid Build Coastguard Worker static SDValue joinDwords(SelectionDAG &DAG, const SDLoc &DL, SDValue Op0,
3984*9880d681SAndroid Build Coastguard Worker                           SDValue Op1) {
3985*9880d681SAndroid Build Coastguard Worker   if (Op0.isUndef() && Op1.isUndef())
3986*9880d681SAndroid Build Coastguard Worker     return DAG.getUNDEF(MVT::v2i64);
3987*9880d681SAndroid Build Coastguard Worker   // If one of the two inputs is undefined then replicate the other one,
3988*9880d681SAndroid Build Coastguard Worker   // in order to avoid using another register unnecessarily.
3989*9880d681SAndroid Build Coastguard Worker   if (Op0.isUndef())
3990*9880d681SAndroid Build Coastguard Worker     Op0 = Op1 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op1);
3991*9880d681SAndroid Build Coastguard Worker   else if (Op1.isUndef())
3992*9880d681SAndroid Build Coastguard Worker     Op0 = Op1 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op0);
3993*9880d681SAndroid Build Coastguard Worker   else {
3994*9880d681SAndroid Build Coastguard Worker     Op0 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op0);
3995*9880d681SAndroid Build Coastguard Worker     Op1 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op1);
3996*9880d681SAndroid Build Coastguard Worker   }
3997*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(SystemZISD::JOIN_DWORDS, DL, MVT::v2i64, Op0, Op1);
3998*9880d681SAndroid Build Coastguard Worker }
3999*9880d681SAndroid Build Coastguard Worker 
4000*9880d681SAndroid Build Coastguard Worker // Try to represent constant BUILD_VECTOR node BVN using a
4001*9880d681SAndroid Build Coastguard Worker // SystemZISD::BYTE_MASK-style mask.  Store the mask value in Mask
4002*9880d681SAndroid Build Coastguard Worker // on success.
tryBuildVectorByteMask(BuildVectorSDNode * BVN,uint64_t & Mask)4003*9880d681SAndroid Build Coastguard Worker static bool tryBuildVectorByteMask(BuildVectorSDNode *BVN, uint64_t &Mask) {
4004*9880d681SAndroid Build Coastguard Worker   EVT ElemVT = BVN->getValueType(0).getVectorElementType();
4005*9880d681SAndroid Build Coastguard Worker   unsigned BytesPerElement = ElemVT.getStoreSize();
4006*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0, E = BVN->getNumOperands(); I != E; ++I) {
4007*9880d681SAndroid Build Coastguard Worker     SDValue Op = BVN->getOperand(I);
4008*9880d681SAndroid Build Coastguard Worker     if (!Op.isUndef()) {
4009*9880d681SAndroid Build Coastguard Worker       uint64_t Value;
4010*9880d681SAndroid Build Coastguard Worker       if (Op.getOpcode() == ISD::Constant)
4011*9880d681SAndroid Build Coastguard Worker         Value = dyn_cast<ConstantSDNode>(Op)->getZExtValue();
4012*9880d681SAndroid Build Coastguard Worker       else if (Op.getOpcode() == ISD::ConstantFP)
4013*9880d681SAndroid Build Coastguard Worker         Value = (dyn_cast<ConstantFPSDNode>(Op)->getValueAPF().bitcastToAPInt()
4014*9880d681SAndroid Build Coastguard Worker                  .getZExtValue());
4015*9880d681SAndroid Build Coastguard Worker       else
4016*9880d681SAndroid Build Coastguard Worker         return false;
4017*9880d681SAndroid Build Coastguard Worker       for (unsigned J = 0; J < BytesPerElement; ++J) {
4018*9880d681SAndroid Build Coastguard Worker         uint64_t Byte = (Value >> (J * 8)) & 0xff;
4019*9880d681SAndroid Build Coastguard Worker         if (Byte == 0xff)
4020*9880d681SAndroid Build Coastguard Worker           Mask |= 1ULL << ((E - I - 1) * BytesPerElement + J);
4021*9880d681SAndroid Build Coastguard Worker         else if (Byte != 0)
4022*9880d681SAndroid Build Coastguard Worker           return false;
4023*9880d681SAndroid Build Coastguard Worker       }
4024*9880d681SAndroid Build Coastguard Worker     }
4025*9880d681SAndroid Build Coastguard Worker   }
4026*9880d681SAndroid Build Coastguard Worker   return true;
4027*9880d681SAndroid Build Coastguard Worker }
4028*9880d681SAndroid Build Coastguard Worker 
4029*9880d681SAndroid Build Coastguard Worker // Try to load a vector constant in which BitsPerElement-bit value Value
4030*9880d681SAndroid Build Coastguard Worker // is replicated to fill the vector.  VT is the type of the resulting
4031*9880d681SAndroid Build Coastguard Worker // constant, which may have elements of a different size from BitsPerElement.
4032*9880d681SAndroid Build Coastguard Worker // Return the SDValue of the constant on success, otherwise return
4033*9880d681SAndroid Build Coastguard Worker // an empty value.
tryBuildVectorReplicate(SelectionDAG & DAG,const SystemZInstrInfo * TII,const SDLoc & DL,EVT VT,uint64_t Value,unsigned BitsPerElement)4034*9880d681SAndroid Build Coastguard Worker static SDValue tryBuildVectorReplicate(SelectionDAG &DAG,
4035*9880d681SAndroid Build Coastguard Worker                                        const SystemZInstrInfo *TII,
4036*9880d681SAndroid Build Coastguard Worker                                        const SDLoc &DL, EVT VT, uint64_t Value,
4037*9880d681SAndroid Build Coastguard Worker                                        unsigned BitsPerElement) {
4038*9880d681SAndroid Build Coastguard Worker   // Signed 16-bit values can be replicated using VREPI.
4039*9880d681SAndroid Build Coastguard Worker   int64_t SignedValue = SignExtend64(Value, BitsPerElement);
4040*9880d681SAndroid Build Coastguard Worker   if (isInt<16>(SignedValue)) {
4041*9880d681SAndroid Build Coastguard Worker     MVT VecVT = MVT::getVectorVT(MVT::getIntegerVT(BitsPerElement),
4042*9880d681SAndroid Build Coastguard Worker                                  SystemZ::VectorBits / BitsPerElement);
4043*9880d681SAndroid Build Coastguard Worker     SDValue Op = DAG.getNode(SystemZISD::REPLICATE, DL, VecVT,
4044*9880d681SAndroid Build Coastguard Worker                              DAG.getConstant(SignedValue, DL, MVT::i32));
4045*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(ISD::BITCAST, DL, VT, Op);
4046*9880d681SAndroid Build Coastguard Worker   }
4047*9880d681SAndroid Build Coastguard Worker   // See whether rotating the constant left some N places gives a value that
4048*9880d681SAndroid Build Coastguard Worker   // is one less than a power of 2 (i.e. all zeros followed by all ones).
4049*9880d681SAndroid Build Coastguard Worker   // If so we can use VGM.
4050*9880d681SAndroid Build Coastguard Worker   unsigned Start, End;
4051*9880d681SAndroid Build Coastguard Worker   if (TII->isRxSBGMask(Value, BitsPerElement, Start, End)) {
4052*9880d681SAndroid Build Coastguard Worker     // isRxSBGMask returns the bit numbers for a full 64-bit value,
4053*9880d681SAndroid Build Coastguard Worker     // with 0 denoting 1 << 63 and 63 denoting 1.  Convert them to
4054*9880d681SAndroid Build Coastguard Worker     // bit numbers for an BitsPerElement value, so that 0 denotes
4055*9880d681SAndroid Build Coastguard Worker     // 1 << (BitsPerElement-1).
4056*9880d681SAndroid Build Coastguard Worker     Start -= 64 - BitsPerElement;
4057*9880d681SAndroid Build Coastguard Worker     End -= 64 - BitsPerElement;
4058*9880d681SAndroid Build Coastguard Worker     MVT VecVT = MVT::getVectorVT(MVT::getIntegerVT(BitsPerElement),
4059*9880d681SAndroid Build Coastguard Worker                                  SystemZ::VectorBits / BitsPerElement);
4060*9880d681SAndroid Build Coastguard Worker     SDValue Op = DAG.getNode(SystemZISD::ROTATE_MASK, DL, VecVT,
4061*9880d681SAndroid Build Coastguard Worker                              DAG.getConstant(Start, DL, MVT::i32),
4062*9880d681SAndroid Build Coastguard Worker                              DAG.getConstant(End, DL, MVT::i32));
4063*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(ISD::BITCAST, DL, VT, Op);
4064*9880d681SAndroid Build Coastguard Worker   }
4065*9880d681SAndroid Build Coastguard Worker   return SDValue();
4066*9880d681SAndroid Build Coastguard Worker }
4067*9880d681SAndroid Build Coastguard Worker 
4068*9880d681SAndroid Build Coastguard Worker // If a BUILD_VECTOR contains some EXTRACT_VECTOR_ELTs, it's usually
4069*9880d681SAndroid Build Coastguard Worker // better to use VECTOR_SHUFFLEs on them, only using BUILD_VECTOR for
4070*9880d681SAndroid Build Coastguard Worker // the non-EXTRACT_VECTOR_ELT elements.  See if the given BUILD_VECTOR
4071*9880d681SAndroid Build Coastguard Worker // would benefit from this representation and return it if so.
tryBuildVectorShuffle(SelectionDAG & DAG,BuildVectorSDNode * BVN)4072*9880d681SAndroid Build Coastguard Worker static SDValue tryBuildVectorShuffle(SelectionDAG &DAG,
4073*9880d681SAndroid Build Coastguard Worker                                      BuildVectorSDNode *BVN) {
4074*9880d681SAndroid Build Coastguard Worker   EVT VT = BVN->getValueType(0);
4075*9880d681SAndroid Build Coastguard Worker   unsigned NumElements = VT.getVectorNumElements();
4076*9880d681SAndroid Build Coastguard Worker 
4077*9880d681SAndroid Build Coastguard Worker   // Represent the BUILD_VECTOR as an N-operand VECTOR_SHUFFLE-like operation
4078*9880d681SAndroid Build Coastguard Worker   // on byte vectors.  If there are non-EXTRACT_VECTOR_ELT elements that still
4079*9880d681SAndroid Build Coastguard Worker   // need a BUILD_VECTOR, add an additional placeholder operand for that
4080*9880d681SAndroid Build Coastguard Worker   // BUILD_VECTOR and store its operands in ResidueOps.
4081*9880d681SAndroid Build Coastguard Worker   GeneralShuffle GS(VT);
4082*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, SystemZ::VectorBytes> ResidueOps;
4083*9880d681SAndroid Build Coastguard Worker   bool FoundOne = false;
4084*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0; I < NumElements; ++I) {
4085*9880d681SAndroid Build Coastguard Worker     SDValue Op = BVN->getOperand(I);
4086*9880d681SAndroid Build Coastguard Worker     if (Op.getOpcode() == ISD::TRUNCATE)
4087*9880d681SAndroid Build Coastguard Worker       Op = Op.getOperand(0);
4088*9880d681SAndroid Build Coastguard Worker     if (Op.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
4089*9880d681SAndroid Build Coastguard Worker         Op.getOperand(1).getOpcode() == ISD::Constant) {
4090*9880d681SAndroid Build Coastguard Worker       unsigned Elem = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
4091*9880d681SAndroid Build Coastguard Worker       GS.add(Op.getOperand(0), Elem);
4092*9880d681SAndroid Build Coastguard Worker       FoundOne = true;
4093*9880d681SAndroid Build Coastguard Worker     } else if (Op.isUndef()) {
4094*9880d681SAndroid Build Coastguard Worker       GS.addUndef();
4095*9880d681SAndroid Build Coastguard Worker     } else {
4096*9880d681SAndroid Build Coastguard Worker       GS.add(SDValue(), ResidueOps.size());
4097*9880d681SAndroid Build Coastguard Worker       ResidueOps.push_back(BVN->getOperand(I));
4098*9880d681SAndroid Build Coastguard Worker     }
4099*9880d681SAndroid Build Coastguard Worker   }
4100*9880d681SAndroid Build Coastguard Worker 
4101*9880d681SAndroid Build Coastguard Worker   // Nothing to do if there are no EXTRACT_VECTOR_ELTs.
4102*9880d681SAndroid Build Coastguard Worker   if (!FoundOne)
4103*9880d681SAndroid Build Coastguard Worker     return SDValue();
4104*9880d681SAndroid Build Coastguard Worker 
4105*9880d681SAndroid Build Coastguard Worker   // Create the BUILD_VECTOR for the remaining elements, if any.
4106*9880d681SAndroid Build Coastguard Worker   if (!ResidueOps.empty()) {
4107*9880d681SAndroid Build Coastguard Worker     while (ResidueOps.size() < NumElements)
4108*9880d681SAndroid Build Coastguard Worker       ResidueOps.push_back(DAG.getUNDEF(ResidueOps[0].getValueType()));
4109*9880d681SAndroid Build Coastguard Worker     for (auto &Op : GS.Ops) {
4110*9880d681SAndroid Build Coastguard Worker       if (!Op.getNode()) {
4111*9880d681SAndroid Build Coastguard Worker         Op = DAG.getBuildVector(VT, SDLoc(BVN), ResidueOps);
4112*9880d681SAndroid Build Coastguard Worker         break;
4113*9880d681SAndroid Build Coastguard Worker       }
4114*9880d681SAndroid Build Coastguard Worker     }
4115*9880d681SAndroid Build Coastguard Worker   }
4116*9880d681SAndroid Build Coastguard Worker   return GS.getNode(DAG, SDLoc(BVN));
4117*9880d681SAndroid Build Coastguard Worker }
4118*9880d681SAndroid Build Coastguard Worker 
4119*9880d681SAndroid Build Coastguard Worker // Combine GPR scalar values Elems into a vector of type VT.
buildVector(SelectionDAG & DAG,const SDLoc & DL,EVT VT,SmallVectorImpl<SDValue> & Elems)4120*9880d681SAndroid Build Coastguard Worker static SDValue buildVector(SelectionDAG &DAG, const SDLoc &DL, EVT VT,
4121*9880d681SAndroid Build Coastguard Worker                            SmallVectorImpl<SDValue> &Elems) {
4122*9880d681SAndroid Build Coastguard Worker   // See whether there is a single replicated value.
4123*9880d681SAndroid Build Coastguard Worker   SDValue Single;
4124*9880d681SAndroid Build Coastguard Worker   unsigned int NumElements = Elems.size();
4125*9880d681SAndroid Build Coastguard Worker   unsigned int Count = 0;
4126*9880d681SAndroid Build Coastguard Worker   for (auto Elem : Elems) {
4127*9880d681SAndroid Build Coastguard Worker     if (!Elem.isUndef()) {
4128*9880d681SAndroid Build Coastguard Worker       if (!Single.getNode())
4129*9880d681SAndroid Build Coastguard Worker         Single = Elem;
4130*9880d681SAndroid Build Coastguard Worker       else if (Elem != Single) {
4131*9880d681SAndroid Build Coastguard Worker         Single = SDValue();
4132*9880d681SAndroid Build Coastguard Worker         break;
4133*9880d681SAndroid Build Coastguard Worker       }
4134*9880d681SAndroid Build Coastguard Worker       Count += 1;
4135*9880d681SAndroid Build Coastguard Worker     }
4136*9880d681SAndroid Build Coastguard Worker   }
4137*9880d681SAndroid Build Coastguard Worker   // There are three cases here:
4138*9880d681SAndroid Build Coastguard Worker   //
4139*9880d681SAndroid Build Coastguard Worker   // - if the only defined element is a loaded one, the best sequence
4140*9880d681SAndroid Build Coastguard Worker   //   is a replicating load.
4141*9880d681SAndroid Build Coastguard Worker   //
4142*9880d681SAndroid Build Coastguard Worker   // - otherwise, if the only defined element is an i64 value, we will
4143*9880d681SAndroid Build Coastguard Worker   //   end up with the same VLVGP sequence regardless of whether we short-cut
4144*9880d681SAndroid Build Coastguard Worker   //   for replication or fall through to the later code.
4145*9880d681SAndroid Build Coastguard Worker   //
4146*9880d681SAndroid Build Coastguard Worker   // - otherwise, if the only defined element is an i32 or smaller value,
4147*9880d681SAndroid Build Coastguard Worker   //   we would need 2 instructions to replicate it: VLVGP followed by VREPx.
4148*9880d681SAndroid Build Coastguard Worker   //   This is only a win if the single defined element is used more than once.
4149*9880d681SAndroid Build Coastguard Worker   //   In other cases we're better off using a single VLVGx.
4150*9880d681SAndroid Build Coastguard Worker   if (Single.getNode() && (Count > 1 || Single.getOpcode() == ISD::LOAD))
4151*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(SystemZISD::REPLICATE, DL, VT, Single);
4152*9880d681SAndroid Build Coastguard Worker 
4153*9880d681SAndroid Build Coastguard Worker   // The best way of building a v2i64 from two i64s is to use VLVGP.
4154*9880d681SAndroid Build Coastguard Worker   if (VT == MVT::v2i64)
4155*9880d681SAndroid Build Coastguard Worker     return joinDwords(DAG, DL, Elems[0], Elems[1]);
4156*9880d681SAndroid Build Coastguard Worker 
4157*9880d681SAndroid Build Coastguard Worker   // Use a 64-bit merge high to combine two doubles.
4158*9880d681SAndroid Build Coastguard Worker   if (VT == MVT::v2f64)
4159*9880d681SAndroid Build Coastguard Worker     return buildMergeScalars(DAG, DL, VT, Elems[0], Elems[1]);
4160*9880d681SAndroid Build Coastguard Worker 
4161*9880d681SAndroid Build Coastguard Worker   // Build v4f32 values directly from the FPRs:
4162*9880d681SAndroid Build Coastguard Worker   //
4163*9880d681SAndroid Build Coastguard Worker   //   <Axxx> <Bxxx> <Cxxxx> <Dxxx>
4164*9880d681SAndroid Build Coastguard Worker   //         V              V         VMRHF
4165*9880d681SAndroid Build Coastguard Worker   //      <ABxx>         <CDxx>
4166*9880d681SAndroid Build Coastguard Worker   //                V                 VMRHG
4167*9880d681SAndroid Build Coastguard Worker   //              <ABCD>
4168*9880d681SAndroid Build Coastguard Worker   if (VT == MVT::v4f32) {
4169*9880d681SAndroid Build Coastguard Worker     SDValue Op01 = buildMergeScalars(DAG, DL, VT, Elems[0], Elems[1]);
4170*9880d681SAndroid Build Coastguard Worker     SDValue Op23 = buildMergeScalars(DAG, DL, VT, Elems[2], Elems[3]);
4171*9880d681SAndroid Build Coastguard Worker     // Avoid unnecessary undefs by reusing the other operand.
4172*9880d681SAndroid Build Coastguard Worker     if (Op01.isUndef())
4173*9880d681SAndroid Build Coastguard Worker       Op01 = Op23;
4174*9880d681SAndroid Build Coastguard Worker     else if (Op23.isUndef())
4175*9880d681SAndroid Build Coastguard Worker       Op23 = Op01;
4176*9880d681SAndroid Build Coastguard Worker     // Merging identical replications is a no-op.
4177*9880d681SAndroid Build Coastguard Worker     if (Op01.getOpcode() == SystemZISD::REPLICATE && Op01 == Op23)
4178*9880d681SAndroid Build Coastguard Worker       return Op01;
4179*9880d681SAndroid Build Coastguard Worker     Op01 = DAG.getNode(ISD::BITCAST, DL, MVT::v2i64, Op01);
4180*9880d681SAndroid Build Coastguard Worker     Op23 = DAG.getNode(ISD::BITCAST, DL, MVT::v2i64, Op23);
4181*9880d681SAndroid Build Coastguard Worker     SDValue Op = DAG.getNode(SystemZISD::MERGE_HIGH,
4182*9880d681SAndroid Build Coastguard Worker                              DL, MVT::v2i64, Op01, Op23);
4183*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(ISD::BITCAST, DL, VT, Op);
4184*9880d681SAndroid Build Coastguard Worker   }
4185*9880d681SAndroid Build Coastguard Worker 
4186*9880d681SAndroid Build Coastguard Worker   // Collect the constant terms.
4187*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, SystemZ::VectorBytes> Constants(NumElements, SDValue());
4188*9880d681SAndroid Build Coastguard Worker   SmallVector<bool, SystemZ::VectorBytes> Done(NumElements, false);
4189*9880d681SAndroid Build Coastguard Worker 
4190*9880d681SAndroid Build Coastguard Worker   unsigned NumConstants = 0;
4191*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0; I < NumElements; ++I) {
4192*9880d681SAndroid Build Coastguard Worker     SDValue Elem = Elems[I];
4193*9880d681SAndroid Build Coastguard Worker     if (Elem.getOpcode() == ISD::Constant ||
4194*9880d681SAndroid Build Coastguard Worker         Elem.getOpcode() == ISD::ConstantFP) {
4195*9880d681SAndroid Build Coastguard Worker       NumConstants += 1;
4196*9880d681SAndroid Build Coastguard Worker       Constants[I] = Elem;
4197*9880d681SAndroid Build Coastguard Worker       Done[I] = true;
4198*9880d681SAndroid Build Coastguard Worker     }
4199*9880d681SAndroid Build Coastguard Worker   }
4200*9880d681SAndroid Build Coastguard Worker   // If there was at least one constant, fill in the other elements of
4201*9880d681SAndroid Build Coastguard Worker   // Constants with undefs to get a full vector constant and use that
4202*9880d681SAndroid Build Coastguard Worker   // as the starting point.
4203*9880d681SAndroid Build Coastguard Worker   SDValue Result;
4204*9880d681SAndroid Build Coastguard Worker   if (NumConstants > 0) {
4205*9880d681SAndroid Build Coastguard Worker     for (unsigned I = 0; I < NumElements; ++I)
4206*9880d681SAndroid Build Coastguard Worker       if (!Constants[I].getNode())
4207*9880d681SAndroid Build Coastguard Worker         Constants[I] = DAG.getUNDEF(Elems[I].getValueType());
4208*9880d681SAndroid Build Coastguard Worker     Result = DAG.getBuildVector(VT, DL, Constants);
4209*9880d681SAndroid Build Coastguard Worker   } else {
4210*9880d681SAndroid Build Coastguard Worker     // Otherwise try to use VLVGP to start the sequence in order to
4211*9880d681SAndroid Build Coastguard Worker     // avoid a false dependency on any previous contents of the vector
4212*9880d681SAndroid Build Coastguard Worker     // register.  This only makes sense if one of the associated elements
4213*9880d681SAndroid Build Coastguard Worker     // is defined.
4214*9880d681SAndroid Build Coastguard Worker     unsigned I1 = NumElements / 2 - 1;
4215*9880d681SAndroid Build Coastguard Worker     unsigned I2 = NumElements - 1;
4216*9880d681SAndroid Build Coastguard Worker     bool Def1 = !Elems[I1].isUndef();
4217*9880d681SAndroid Build Coastguard Worker     bool Def2 = !Elems[I2].isUndef();
4218*9880d681SAndroid Build Coastguard Worker     if (Def1 || Def2) {
4219*9880d681SAndroid Build Coastguard Worker       SDValue Elem1 = Elems[Def1 ? I1 : I2];
4220*9880d681SAndroid Build Coastguard Worker       SDValue Elem2 = Elems[Def2 ? I2 : I1];
4221*9880d681SAndroid Build Coastguard Worker       Result = DAG.getNode(ISD::BITCAST, DL, VT,
4222*9880d681SAndroid Build Coastguard Worker                            joinDwords(DAG, DL, Elem1, Elem2));
4223*9880d681SAndroid Build Coastguard Worker       Done[I1] = true;
4224*9880d681SAndroid Build Coastguard Worker       Done[I2] = true;
4225*9880d681SAndroid Build Coastguard Worker     } else
4226*9880d681SAndroid Build Coastguard Worker       Result = DAG.getUNDEF(VT);
4227*9880d681SAndroid Build Coastguard Worker   }
4228*9880d681SAndroid Build Coastguard Worker 
4229*9880d681SAndroid Build Coastguard Worker   // Use VLVGx to insert the other elements.
4230*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0; I < NumElements; ++I)
4231*9880d681SAndroid Build Coastguard Worker     if (!Done[I] && !Elems[I].isUndef())
4232*9880d681SAndroid Build Coastguard Worker       Result = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, VT, Result, Elems[I],
4233*9880d681SAndroid Build Coastguard Worker                            DAG.getConstant(I, DL, MVT::i32));
4234*9880d681SAndroid Build Coastguard Worker   return Result;
4235*9880d681SAndroid Build Coastguard Worker }
4236*9880d681SAndroid Build Coastguard Worker 
lowerBUILD_VECTOR(SDValue Op,SelectionDAG & DAG) const4237*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerBUILD_VECTOR(SDValue Op,
4238*9880d681SAndroid Build Coastguard Worker                                                  SelectionDAG &DAG) const {
4239*9880d681SAndroid Build Coastguard Worker   const SystemZInstrInfo *TII =
4240*9880d681SAndroid Build Coastguard Worker     static_cast<const SystemZInstrInfo *>(Subtarget.getInstrInfo());
4241*9880d681SAndroid Build Coastguard Worker   auto *BVN = cast<BuildVectorSDNode>(Op.getNode());
4242*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
4243*9880d681SAndroid Build Coastguard Worker   EVT VT = Op.getValueType();
4244*9880d681SAndroid Build Coastguard Worker 
4245*9880d681SAndroid Build Coastguard Worker   if (BVN->isConstant()) {
4246*9880d681SAndroid Build Coastguard Worker     // Try using VECTOR GENERATE BYTE MASK.  This is the architecturally-
4247*9880d681SAndroid Build Coastguard Worker     // preferred way of creating all-zero and all-one vectors so give it
4248*9880d681SAndroid Build Coastguard Worker     // priority over other methods below.
4249*9880d681SAndroid Build Coastguard Worker     uint64_t Mask = 0;
4250*9880d681SAndroid Build Coastguard Worker     if (tryBuildVectorByteMask(BVN, Mask)) {
4251*9880d681SAndroid Build Coastguard Worker       SDValue Op = DAG.getNode(SystemZISD::BYTE_MASK, DL, MVT::v16i8,
4252*9880d681SAndroid Build Coastguard Worker                                DAG.getConstant(Mask, DL, MVT::i32));
4253*9880d681SAndroid Build Coastguard Worker       return DAG.getNode(ISD::BITCAST, DL, VT, Op);
4254*9880d681SAndroid Build Coastguard Worker     }
4255*9880d681SAndroid Build Coastguard Worker 
4256*9880d681SAndroid Build Coastguard Worker     // Try using some form of replication.
4257*9880d681SAndroid Build Coastguard Worker     APInt SplatBits, SplatUndef;
4258*9880d681SAndroid Build Coastguard Worker     unsigned SplatBitSize;
4259*9880d681SAndroid Build Coastguard Worker     bool HasAnyUndefs;
4260*9880d681SAndroid Build Coastguard Worker     if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
4261*9880d681SAndroid Build Coastguard Worker                              8, true) &&
4262*9880d681SAndroid Build Coastguard Worker         SplatBitSize <= 64) {
4263*9880d681SAndroid Build Coastguard Worker       // First try assuming that any undefined bits above the highest set bit
4264*9880d681SAndroid Build Coastguard Worker       // and below the lowest set bit are 1s.  This increases the likelihood of
4265*9880d681SAndroid Build Coastguard Worker       // being able to use a sign-extended element value in VECTOR REPLICATE
4266*9880d681SAndroid Build Coastguard Worker       // IMMEDIATE or a wraparound mask in VECTOR GENERATE MASK.
4267*9880d681SAndroid Build Coastguard Worker       uint64_t SplatBitsZ = SplatBits.getZExtValue();
4268*9880d681SAndroid Build Coastguard Worker       uint64_t SplatUndefZ = SplatUndef.getZExtValue();
4269*9880d681SAndroid Build Coastguard Worker       uint64_t Lower = (SplatUndefZ
4270*9880d681SAndroid Build Coastguard Worker                         & ((uint64_t(1) << findFirstSet(SplatBitsZ)) - 1));
4271*9880d681SAndroid Build Coastguard Worker       uint64_t Upper = (SplatUndefZ
4272*9880d681SAndroid Build Coastguard Worker                         & ~((uint64_t(1) << findLastSet(SplatBitsZ)) - 1));
4273*9880d681SAndroid Build Coastguard Worker       uint64_t Value = SplatBitsZ | Upper | Lower;
4274*9880d681SAndroid Build Coastguard Worker       SDValue Op = tryBuildVectorReplicate(DAG, TII, DL, VT, Value,
4275*9880d681SAndroid Build Coastguard Worker                                            SplatBitSize);
4276*9880d681SAndroid Build Coastguard Worker       if (Op.getNode())
4277*9880d681SAndroid Build Coastguard Worker         return Op;
4278*9880d681SAndroid Build Coastguard Worker 
4279*9880d681SAndroid Build Coastguard Worker       // Now try assuming that any undefined bits between the first and
4280*9880d681SAndroid Build Coastguard Worker       // last defined set bits are set.  This increases the chances of
4281*9880d681SAndroid Build Coastguard Worker       // using a non-wraparound mask.
4282*9880d681SAndroid Build Coastguard Worker       uint64_t Middle = SplatUndefZ & ~Upper & ~Lower;
4283*9880d681SAndroid Build Coastguard Worker       Value = SplatBitsZ | Middle;
4284*9880d681SAndroid Build Coastguard Worker       Op = tryBuildVectorReplicate(DAG, TII, DL, VT, Value, SplatBitSize);
4285*9880d681SAndroid Build Coastguard Worker       if (Op.getNode())
4286*9880d681SAndroid Build Coastguard Worker         return Op;
4287*9880d681SAndroid Build Coastguard Worker     }
4288*9880d681SAndroid Build Coastguard Worker 
4289*9880d681SAndroid Build Coastguard Worker     // Fall back to loading it from memory.
4290*9880d681SAndroid Build Coastguard Worker     return SDValue();
4291*9880d681SAndroid Build Coastguard Worker   }
4292*9880d681SAndroid Build Coastguard Worker 
4293*9880d681SAndroid Build Coastguard Worker   // See if we should use shuffles to construct the vector from other vectors.
4294*9880d681SAndroid Build Coastguard Worker   if (SDValue Res = tryBuildVectorShuffle(DAG, BVN))
4295*9880d681SAndroid Build Coastguard Worker     return Res;
4296*9880d681SAndroid Build Coastguard Worker 
4297*9880d681SAndroid Build Coastguard Worker   // Detect SCALAR_TO_VECTOR conversions.
4298*9880d681SAndroid Build Coastguard Worker   if (isOperationLegal(ISD::SCALAR_TO_VECTOR, VT) && isScalarToVector(Op))
4299*9880d681SAndroid Build Coastguard Worker     return buildScalarToVector(DAG, DL, VT, Op.getOperand(0));
4300*9880d681SAndroid Build Coastguard Worker 
4301*9880d681SAndroid Build Coastguard Worker   // Otherwise use buildVector to build the vector up from GPRs.
4302*9880d681SAndroid Build Coastguard Worker   unsigned NumElements = Op.getNumOperands();
4303*9880d681SAndroid Build Coastguard Worker   SmallVector<SDValue, SystemZ::VectorBytes> Ops(NumElements);
4304*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0; I < NumElements; ++I)
4305*9880d681SAndroid Build Coastguard Worker     Ops[I] = Op.getOperand(I);
4306*9880d681SAndroid Build Coastguard Worker   return buildVector(DAG, DL, VT, Ops);
4307*9880d681SAndroid Build Coastguard Worker }
4308*9880d681SAndroid Build Coastguard Worker 
lowerVECTOR_SHUFFLE(SDValue Op,SelectionDAG & DAG) const4309*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
4310*9880d681SAndroid Build Coastguard Worker                                                    SelectionDAG &DAG) const {
4311*9880d681SAndroid Build Coastguard Worker   auto *VSN = cast<ShuffleVectorSDNode>(Op.getNode());
4312*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
4313*9880d681SAndroid Build Coastguard Worker   EVT VT = Op.getValueType();
4314*9880d681SAndroid Build Coastguard Worker   unsigned NumElements = VT.getVectorNumElements();
4315*9880d681SAndroid Build Coastguard Worker 
4316*9880d681SAndroid Build Coastguard Worker   if (VSN->isSplat()) {
4317*9880d681SAndroid Build Coastguard Worker     SDValue Op0 = Op.getOperand(0);
4318*9880d681SAndroid Build Coastguard Worker     unsigned Index = VSN->getSplatIndex();
4319*9880d681SAndroid Build Coastguard Worker     assert(Index < VT.getVectorNumElements() &&
4320*9880d681SAndroid Build Coastguard Worker            "Splat index should be defined and in first operand");
4321*9880d681SAndroid Build Coastguard Worker     // See whether the value we're splatting is directly available as a scalar.
4322*9880d681SAndroid Build Coastguard Worker     if ((Index == 0 && Op0.getOpcode() == ISD::SCALAR_TO_VECTOR) ||
4323*9880d681SAndroid Build Coastguard Worker         Op0.getOpcode() == ISD::BUILD_VECTOR)
4324*9880d681SAndroid Build Coastguard Worker       return DAG.getNode(SystemZISD::REPLICATE, DL, VT, Op0.getOperand(Index));
4325*9880d681SAndroid Build Coastguard Worker     // Otherwise keep it as a vector-to-vector operation.
4326*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(SystemZISD::SPLAT, DL, VT, Op.getOperand(0),
4327*9880d681SAndroid Build Coastguard Worker                        DAG.getConstant(Index, DL, MVT::i32));
4328*9880d681SAndroid Build Coastguard Worker   }
4329*9880d681SAndroid Build Coastguard Worker 
4330*9880d681SAndroid Build Coastguard Worker   GeneralShuffle GS(VT);
4331*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0; I < NumElements; ++I) {
4332*9880d681SAndroid Build Coastguard Worker     int Elt = VSN->getMaskElt(I);
4333*9880d681SAndroid Build Coastguard Worker     if (Elt < 0)
4334*9880d681SAndroid Build Coastguard Worker       GS.addUndef();
4335*9880d681SAndroid Build Coastguard Worker     else
4336*9880d681SAndroid Build Coastguard Worker       GS.add(Op.getOperand(unsigned(Elt) / NumElements),
4337*9880d681SAndroid Build Coastguard Worker              unsigned(Elt) % NumElements);
4338*9880d681SAndroid Build Coastguard Worker   }
4339*9880d681SAndroid Build Coastguard Worker   return GS.getNode(DAG, SDLoc(VSN));
4340*9880d681SAndroid Build Coastguard Worker }
4341*9880d681SAndroid Build Coastguard Worker 
lowerSCALAR_TO_VECTOR(SDValue Op,SelectionDAG & DAG) const4342*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerSCALAR_TO_VECTOR(SDValue Op,
4343*9880d681SAndroid Build Coastguard Worker                                                      SelectionDAG &DAG) const {
4344*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
4345*9880d681SAndroid Build Coastguard Worker   // Just insert the scalar into element 0 of an undefined vector.
4346*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(ISD::INSERT_VECTOR_ELT, DL,
4347*9880d681SAndroid Build Coastguard Worker                      Op.getValueType(), DAG.getUNDEF(Op.getValueType()),
4348*9880d681SAndroid Build Coastguard Worker                      Op.getOperand(0), DAG.getConstant(0, DL, MVT::i32));
4349*9880d681SAndroid Build Coastguard Worker }
4350*9880d681SAndroid Build Coastguard Worker 
lowerINSERT_VECTOR_ELT(SDValue Op,SelectionDAG & DAG) const4351*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerINSERT_VECTOR_ELT(SDValue Op,
4352*9880d681SAndroid Build Coastguard Worker                                                       SelectionDAG &DAG) const {
4353*9880d681SAndroid Build Coastguard Worker   // Handle insertions of floating-point values.
4354*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
4355*9880d681SAndroid Build Coastguard Worker   SDValue Op0 = Op.getOperand(0);
4356*9880d681SAndroid Build Coastguard Worker   SDValue Op1 = Op.getOperand(1);
4357*9880d681SAndroid Build Coastguard Worker   SDValue Op2 = Op.getOperand(2);
4358*9880d681SAndroid Build Coastguard Worker   EVT VT = Op.getValueType();
4359*9880d681SAndroid Build Coastguard Worker 
4360*9880d681SAndroid Build Coastguard Worker   // Insertions into constant indices of a v2f64 can be done using VPDI.
4361*9880d681SAndroid Build Coastguard Worker   // However, if the inserted value is a bitcast or a constant then it's
4362*9880d681SAndroid Build Coastguard Worker   // better to use GPRs, as below.
4363*9880d681SAndroid Build Coastguard Worker   if (VT == MVT::v2f64 &&
4364*9880d681SAndroid Build Coastguard Worker       Op1.getOpcode() != ISD::BITCAST &&
4365*9880d681SAndroid Build Coastguard Worker       Op1.getOpcode() != ISD::ConstantFP &&
4366*9880d681SAndroid Build Coastguard Worker       Op2.getOpcode() == ISD::Constant) {
4367*9880d681SAndroid Build Coastguard Worker     uint64_t Index = dyn_cast<ConstantSDNode>(Op2)->getZExtValue();
4368*9880d681SAndroid Build Coastguard Worker     unsigned Mask = VT.getVectorNumElements() - 1;
4369*9880d681SAndroid Build Coastguard Worker     if (Index <= Mask)
4370*9880d681SAndroid Build Coastguard Worker       return Op;
4371*9880d681SAndroid Build Coastguard Worker   }
4372*9880d681SAndroid Build Coastguard Worker 
4373*9880d681SAndroid Build Coastguard Worker   // Otherwise bitcast to the equivalent integer form and insert via a GPR.
4374*9880d681SAndroid Build Coastguard Worker   MVT IntVT = MVT::getIntegerVT(VT.getVectorElementType().getSizeInBits());
4375*9880d681SAndroid Build Coastguard Worker   MVT IntVecVT = MVT::getVectorVT(IntVT, VT.getVectorNumElements());
4376*9880d681SAndroid Build Coastguard Worker   SDValue Res = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, IntVecVT,
4377*9880d681SAndroid Build Coastguard Worker                             DAG.getNode(ISD::BITCAST, DL, IntVecVT, Op0),
4378*9880d681SAndroid Build Coastguard Worker                             DAG.getNode(ISD::BITCAST, DL, IntVT, Op1), Op2);
4379*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(ISD::BITCAST, DL, VT, Res);
4380*9880d681SAndroid Build Coastguard Worker }
4381*9880d681SAndroid Build Coastguard Worker 
4382*9880d681SAndroid Build Coastguard Worker SDValue
lowerEXTRACT_VECTOR_ELT(SDValue Op,SelectionDAG & DAG) const4383*9880d681SAndroid Build Coastguard Worker SystemZTargetLowering::lowerEXTRACT_VECTOR_ELT(SDValue Op,
4384*9880d681SAndroid Build Coastguard Worker                                                SelectionDAG &DAG) const {
4385*9880d681SAndroid Build Coastguard Worker   // Handle extractions of floating-point values.
4386*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
4387*9880d681SAndroid Build Coastguard Worker   SDValue Op0 = Op.getOperand(0);
4388*9880d681SAndroid Build Coastguard Worker   SDValue Op1 = Op.getOperand(1);
4389*9880d681SAndroid Build Coastguard Worker   EVT VT = Op.getValueType();
4390*9880d681SAndroid Build Coastguard Worker   EVT VecVT = Op0.getValueType();
4391*9880d681SAndroid Build Coastguard Worker 
4392*9880d681SAndroid Build Coastguard Worker   // Extractions of constant indices can be done directly.
4393*9880d681SAndroid Build Coastguard Worker   if (auto *CIndexN = dyn_cast<ConstantSDNode>(Op1)) {
4394*9880d681SAndroid Build Coastguard Worker     uint64_t Index = CIndexN->getZExtValue();
4395*9880d681SAndroid Build Coastguard Worker     unsigned Mask = VecVT.getVectorNumElements() - 1;
4396*9880d681SAndroid Build Coastguard Worker     if (Index <= Mask)
4397*9880d681SAndroid Build Coastguard Worker       return Op;
4398*9880d681SAndroid Build Coastguard Worker   }
4399*9880d681SAndroid Build Coastguard Worker 
4400*9880d681SAndroid Build Coastguard Worker   // Otherwise bitcast to the equivalent integer form and extract via a GPR.
4401*9880d681SAndroid Build Coastguard Worker   MVT IntVT = MVT::getIntegerVT(VT.getSizeInBits());
4402*9880d681SAndroid Build Coastguard Worker   MVT IntVecVT = MVT::getVectorVT(IntVT, VecVT.getVectorNumElements());
4403*9880d681SAndroid Build Coastguard Worker   SDValue Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, IntVT,
4404*9880d681SAndroid Build Coastguard Worker                             DAG.getNode(ISD::BITCAST, DL, IntVecVT, Op0), Op1);
4405*9880d681SAndroid Build Coastguard Worker   return DAG.getNode(ISD::BITCAST, DL, VT, Res);
4406*9880d681SAndroid Build Coastguard Worker }
4407*9880d681SAndroid Build Coastguard Worker 
4408*9880d681SAndroid Build Coastguard Worker SDValue
lowerExtendVectorInreg(SDValue Op,SelectionDAG & DAG,unsigned UnpackHigh) const4409*9880d681SAndroid Build Coastguard Worker SystemZTargetLowering::lowerExtendVectorInreg(SDValue Op, SelectionDAG &DAG,
4410*9880d681SAndroid Build Coastguard Worker                                               unsigned UnpackHigh) const {
4411*9880d681SAndroid Build Coastguard Worker   SDValue PackedOp = Op.getOperand(0);
4412*9880d681SAndroid Build Coastguard Worker   EVT OutVT = Op.getValueType();
4413*9880d681SAndroid Build Coastguard Worker   EVT InVT = PackedOp.getValueType();
4414*9880d681SAndroid Build Coastguard Worker   unsigned ToBits = OutVT.getVectorElementType().getSizeInBits();
4415*9880d681SAndroid Build Coastguard Worker   unsigned FromBits = InVT.getVectorElementType().getSizeInBits();
4416*9880d681SAndroid Build Coastguard Worker   do {
4417*9880d681SAndroid Build Coastguard Worker     FromBits *= 2;
4418*9880d681SAndroid Build Coastguard Worker     EVT OutVT = MVT::getVectorVT(MVT::getIntegerVT(FromBits),
4419*9880d681SAndroid Build Coastguard Worker                                  SystemZ::VectorBits / FromBits);
4420*9880d681SAndroid Build Coastguard Worker     PackedOp = DAG.getNode(UnpackHigh, SDLoc(PackedOp), OutVT, PackedOp);
4421*9880d681SAndroid Build Coastguard Worker   } while (FromBits != ToBits);
4422*9880d681SAndroid Build Coastguard Worker   return PackedOp;
4423*9880d681SAndroid Build Coastguard Worker }
4424*9880d681SAndroid Build Coastguard Worker 
lowerShift(SDValue Op,SelectionDAG & DAG,unsigned ByScalar) const4425*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::lowerShift(SDValue Op, SelectionDAG &DAG,
4426*9880d681SAndroid Build Coastguard Worker                                           unsigned ByScalar) const {
4427*9880d681SAndroid Build Coastguard Worker   // Look for cases where a vector shift can use the *_BY_SCALAR form.
4428*9880d681SAndroid Build Coastguard Worker   SDValue Op0 = Op.getOperand(0);
4429*9880d681SAndroid Build Coastguard Worker   SDValue Op1 = Op.getOperand(1);
4430*9880d681SAndroid Build Coastguard Worker   SDLoc DL(Op);
4431*9880d681SAndroid Build Coastguard Worker   EVT VT = Op.getValueType();
4432*9880d681SAndroid Build Coastguard Worker   unsigned ElemBitSize = VT.getVectorElementType().getSizeInBits();
4433*9880d681SAndroid Build Coastguard Worker 
4434*9880d681SAndroid Build Coastguard Worker   // See whether the shift vector is a splat represented as BUILD_VECTOR.
4435*9880d681SAndroid Build Coastguard Worker   if (auto *BVN = dyn_cast<BuildVectorSDNode>(Op1)) {
4436*9880d681SAndroid Build Coastguard Worker     APInt SplatBits, SplatUndef;
4437*9880d681SAndroid Build Coastguard Worker     unsigned SplatBitSize;
4438*9880d681SAndroid Build Coastguard Worker     bool HasAnyUndefs;
4439*9880d681SAndroid Build Coastguard Worker     // Check for constant splats.  Use ElemBitSize as the minimum element
4440*9880d681SAndroid Build Coastguard Worker     // width and reject splats that need wider elements.
4441*9880d681SAndroid Build Coastguard Worker     if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
4442*9880d681SAndroid Build Coastguard Worker                              ElemBitSize, true) &&
4443*9880d681SAndroid Build Coastguard Worker         SplatBitSize == ElemBitSize) {
4444*9880d681SAndroid Build Coastguard Worker       SDValue Shift = DAG.getConstant(SplatBits.getZExtValue() & 0xfff,
4445*9880d681SAndroid Build Coastguard Worker                                       DL, MVT::i32);
4446*9880d681SAndroid Build Coastguard Worker       return DAG.getNode(ByScalar, DL, VT, Op0, Shift);
4447*9880d681SAndroid Build Coastguard Worker     }
4448*9880d681SAndroid Build Coastguard Worker     // Check for variable splats.
4449*9880d681SAndroid Build Coastguard Worker     BitVector UndefElements;
4450*9880d681SAndroid Build Coastguard Worker     SDValue Splat = BVN->getSplatValue(&UndefElements);
4451*9880d681SAndroid Build Coastguard Worker     if (Splat) {
4452*9880d681SAndroid Build Coastguard Worker       // Since i32 is the smallest legal type, we either need a no-op
4453*9880d681SAndroid Build Coastguard Worker       // or a truncation.
4454*9880d681SAndroid Build Coastguard Worker       SDValue Shift = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Splat);
4455*9880d681SAndroid Build Coastguard Worker       return DAG.getNode(ByScalar, DL, VT, Op0, Shift);
4456*9880d681SAndroid Build Coastguard Worker     }
4457*9880d681SAndroid Build Coastguard Worker   }
4458*9880d681SAndroid Build Coastguard Worker 
4459*9880d681SAndroid Build Coastguard Worker   // See whether the shift vector is a splat represented as SHUFFLE_VECTOR,
4460*9880d681SAndroid Build Coastguard Worker   // and the shift amount is directly available in a GPR.
4461*9880d681SAndroid Build Coastguard Worker   if (auto *VSN = dyn_cast<ShuffleVectorSDNode>(Op1)) {
4462*9880d681SAndroid Build Coastguard Worker     if (VSN->isSplat()) {
4463*9880d681SAndroid Build Coastguard Worker       SDValue VSNOp0 = VSN->getOperand(0);
4464*9880d681SAndroid Build Coastguard Worker       unsigned Index = VSN->getSplatIndex();
4465*9880d681SAndroid Build Coastguard Worker       assert(Index < VT.getVectorNumElements() &&
4466*9880d681SAndroid Build Coastguard Worker              "Splat index should be defined and in first operand");
4467*9880d681SAndroid Build Coastguard Worker       if ((Index == 0 && VSNOp0.getOpcode() == ISD::SCALAR_TO_VECTOR) ||
4468*9880d681SAndroid Build Coastguard Worker           VSNOp0.getOpcode() == ISD::BUILD_VECTOR) {
4469*9880d681SAndroid Build Coastguard Worker         // Since i32 is the smallest legal type, we either need a no-op
4470*9880d681SAndroid Build Coastguard Worker         // or a truncation.
4471*9880d681SAndroid Build Coastguard Worker         SDValue Shift = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32,
4472*9880d681SAndroid Build Coastguard Worker                                     VSNOp0.getOperand(Index));
4473*9880d681SAndroid Build Coastguard Worker         return DAG.getNode(ByScalar, DL, VT, Op0, Shift);
4474*9880d681SAndroid Build Coastguard Worker       }
4475*9880d681SAndroid Build Coastguard Worker     }
4476*9880d681SAndroid Build Coastguard Worker   }
4477*9880d681SAndroid Build Coastguard Worker 
4478*9880d681SAndroid Build Coastguard Worker   // Otherwise just treat the current form as legal.
4479*9880d681SAndroid Build Coastguard Worker   return Op;
4480*9880d681SAndroid Build Coastguard Worker }
4481*9880d681SAndroid Build Coastguard Worker 
LowerOperation(SDValue Op,SelectionDAG & DAG) const4482*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::LowerOperation(SDValue Op,
4483*9880d681SAndroid Build Coastguard Worker                                               SelectionDAG &DAG) const {
4484*9880d681SAndroid Build Coastguard Worker   switch (Op.getOpcode()) {
4485*9880d681SAndroid Build Coastguard Worker   case ISD::FRAMEADDR:
4486*9880d681SAndroid Build Coastguard Worker     return lowerFRAMEADDR(Op, DAG);
4487*9880d681SAndroid Build Coastguard Worker   case ISD::RETURNADDR:
4488*9880d681SAndroid Build Coastguard Worker     return lowerRETURNADDR(Op, DAG);
4489*9880d681SAndroid Build Coastguard Worker   case ISD::BR_CC:
4490*9880d681SAndroid Build Coastguard Worker     return lowerBR_CC(Op, DAG);
4491*9880d681SAndroid Build Coastguard Worker   case ISD::SELECT_CC:
4492*9880d681SAndroid Build Coastguard Worker     return lowerSELECT_CC(Op, DAG);
4493*9880d681SAndroid Build Coastguard Worker   case ISD::SETCC:
4494*9880d681SAndroid Build Coastguard Worker     return lowerSETCC(Op, DAG);
4495*9880d681SAndroid Build Coastguard Worker   case ISD::GlobalAddress:
4496*9880d681SAndroid Build Coastguard Worker     return lowerGlobalAddress(cast<GlobalAddressSDNode>(Op), DAG);
4497*9880d681SAndroid Build Coastguard Worker   case ISD::GlobalTLSAddress:
4498*9880d681SAndroid Build Coastguard Worker     return lowerGlobalTLSAddress(cast<GlobalAddressSDNode>(Op), DAG);
4499*9880d681SAndroid Build Coastguard Worker   case ISD::BlockAddress:
4500*9880d681SAndroid Build Coastguard Worker     return lowerBlockAddress(cast<BlockAddressSDNode>(Op), DAG);
4501*9880d681SAndroid Build Coastguard Worker   case ISD::JumpTable:
4502*9880d681SAndroid Build Coastguard Worker     return lowerJumpTable(cast<JumpTableSDNode>(Op), DAG);
4503*9880d681SAndroid Build Coastguard Worker   case ISD::ConstantPool:
4504*9880d681SAndroid Build Coastguard Worker     return lowerConstantPool(cast<ConstantPoolSDNode>(Op), DAG);
4505*9880d681SAndroid Build Coastguard Worker   case ISD::BITCAST:
4506*9880d681SAndroid Build Coastguard Worker     return lowerBITCAST(Op, DAG);
4507*9880d681SAndroid Build Coastguard Worker   case ISD::VASTART:
4508*9880d681SAndroid Build Coastguard Worker     return lowerVASTART(Op, DAG);
4509*9880d681SAndroid Build Coastguard Worker   case ISD::VACOPY:
4510*9880d681SAndroid Build Coastguard Worker     return lowerVACOPY(Op, DAG);
4511*9880d681SAndroid Build Coastguard Worker   case ISD::DYNAMIC_STACKALLOC:
4512*9880d681SAndroid Build Coastguard Worker     return lowerDYNAMIC_STACKALLOC(Op, DAG);
4513*9880d681SAndroid Build Coastguard Worker   case ISD::GET_DYNAMIC_AREA_OFFSET:
4514*9880d681SAndroid Build Coastguard Worker     return lowerGET_DYNAMIC_AREA_OFFSET(Op, DAG);
4515*9880d681SAndroid Build Coastguard Worker   case ISD::SMUL_LOHI:
4516*9880d681SAndroid Build Coastguard Worker     return lowerSMUL_LOHI(Op, DAG);
4517*9880d681SAndroid Build Coastguard Worker   case ISD::UMUL_LOHI:
4518*9880d681SAndroid Build Coastguard Worker     return lowerUMUL_LOHI(Op, DAG);
4519*9880d681SAndroid Build Coastguard Worker   case ISD::SDIVREM:
4520*9880d681SAndroid Build Coastguard Worker     return lowerSDIVREM(Op, DAG);
4521*9880d681SAndroid Build Coastguard Worker   case ISD::UDIVREM:
4522*9880d681SAndroid Build Coastguard Worker     return lowerUDIVREM(Op, DAG);
4523*9880d681SAndroid Build Coastguard Worker   case ISD::OR:
4524*9880d681SAndroid Build Coastguard Worker     return lowerOR(Op, DAG);
4525*9880d681SAndroid Build Coastguard Worker   case ISD::CTPOP:
4526*9880d681SAndroid Build Coastguard Worker     return lowerCTPOP(Op, DAG);
4527*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_FENCE:
4528*9880d681SAndroid Build Coastguard Worker     return lowerATOMIC_FENCE(Op, DAG);
4529*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_SWAP:
4530*9880d681SAndroid Build Coastguard Worker     return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_SWAPW);
4531*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_STORE:
4532*9880d681SAndroid Build Coastguard Worker     return lowerATOMIC_STORE(Op, DAG);
4533*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD:
4534*9880d681SAndroid Build Coastguard Worker     return lowerATOMIC_LOAD(Op, DAG);
4535*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_ADD:
4536*9880d681SAndroid Build Coastguard Worker     return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_ADD);
4537*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_SUB:
4538*9880d681SAndroid Build Coastguard Worker     return lowerATOMIC_LOAD_SUB(Op, DAG);
4539*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_AND:
4540*9880d681SAndroid Build Coastguard Worker     return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_AND);
4541*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_OR:
4542*9880d681SAndroid Build Coastguard Worker     return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_OR);
4543*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_XOR:
4544*9880d681SAndroid Build Coastguard Worker     return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_XOR);
4545*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_NAND:
4546*9880d681SAndroid Build Coastguard Worker     return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_NAND);
4547*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_MIN:
4548*9880d681SAndroid Build Coastguard Worker     return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_MIN);
4549*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_MAX:
4550*9880d681SAndroid Build Coastguard Worker     return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_MAX);
4551*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_UMIN:
4552*9880d681SAndroid Build Coastguard Worker     return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_UMIN);
4553*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_LOAD_UMAX:
4554*9880d681SAndroid Build Coastguard Worker     return lowerATOMIC_LOAD_OP(Op, DAG, SystemZISD::ATOMIC_LOADW_UMAX);
4555*9880d681SAndroid Build Coastguard Worker   case ISD::ATOMIC_CMP_SWAP:
4556*9880d681SAndroid Build Coastguard Worker     return lowerATOMIC_CMP_SWAP(Op, DAG);
4557*9880d681SAndroid Build Coastguard Worker   case ISD::STACKSAVE:
4558*9880d681SAndroid Build Coastguard Worker     return lowerSTACKSAVE(Op, DAG);
4559*9880d681SAndroid Build Coastguard Worker   case ISD::STACKRESTORE:
4560*9880d681SAndroid Build Coastguard Worker     return lowerSTACKRESTORE(Op, DAG);
4561*9880d681SAndroid Build Coastguard Worker   case ISD::PREFETCH:
4562*9880d681SAndroid Build Coastguard Worker     return lowerPREFETCH(Op, DAG);
4563*9880d681SAndroid Build Coastguard Worker   case ISD::INTRINSIC_W_CHAIN:
4564*9880d681SAndroid Build Coastguard Worker     return lowerINTRINSIC_W_CHAIN(Op, DAG);
4565*9880d681SAndroid Build Coastguard Worker   case ISD::INTRINSIC_WO_CHAIN:
4566*9880d681SAndroid Build Coastguard Worker     return lowerINTRINSIC_WO_CHAIN(Op, DAG);
4567*9880d681SAndroid Build Coastguard Worker   case ISD::BUILD_VECTOR:
4568*9880d681SAndroid Build Coastguard Worker     return lowerBUILD_VECTOR(Op, DAG);
4569*9880d681SAndroid Build Coastguard Worker   case ISD::VECTOR_SHUFFLE:
4570*9880d681SAndroid Build Coastguard Worker     return lowerVECTOR_SHUFFLE(Op, DAG);
4571*9880d681SAndroid Build Coastguard Worker   case ISD::SCALAR_TO_VECTOR:
4572*9880d681SAndroid Build Coastguard Worker     return lowerSCALAR_TO_VECTOR(Op, DAG);
4573*9880d681SAndroid Build Coastguard Worker   case ISD::INSERT_VECTOR_ELT:
4574*9880d681SAndroid Build Coastguard Worker     return lowerINSERT_VECTOR_ELT(Op, DAG);
4575*9880d681SAndroid Build Coastguard Worker   case ISD::EXTRACT_VECTOR_ELT:
4576*9880d681SAndroid Build Coastguard Worker     return lowerEXTRACT_VECTOR_ELT(Op, DAG);
4577*9880d681SAndroid Build Coastguard Worker   case ISD::SIGN_EXTEND_VECTOR_INREG:
4578*9880d681SAndroid Build Coastguard Worker     return lowerExtendVectorInreg(Op, DAG, SystemZISD::UNPACK_HIGH);
4579*9880d681SAndroid Build Coastguard Worker   case ISD::ZERO_EXTEND_VECTOR_INREG:
4580*9880d681SAndroid Build Coastguard Worker     return lowerExtendVectorInreg(Op, DAG, SystemZISD::UNPACKL_HIGH);
4581*9880d681SAndroid Build Coastguard Worker   case ISD::SHL:
4582*9880d681SAndroid Build Coastguard Worker     return lowerShift(Op, DAG, SystemZISD::VSHL_BY_SCALAR);
4583*9880d681SAndroid Build Coastguard Worker   case ISD::SRL:
4584*9880d681SAndroid Build Coastguard Worker     return lowerShift(Op, DAG, SystemZISD::VSRL_BY_SCALAR);
4585*9880d681SAndroid Build Coastguard Worker   case ISD::SRA:
4586*9880d681SAndroid Build Coastguard Worker     return lowerShift(Op, DAG, SystemZISD::VSRA_BY_SCALAR);
4587*9880d681SAndroid Build Coastguard Worker   default:
4588*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Unexpected node to lower");
4589*9880d681SAndroid Build Coastguard Worker   }
4590*9880d681SAndroid Build Coastguard Worker }
4591*9880d681SAndroid Build Coastguard Worker 
getTargetNodeName(unsigned Opcode) const4592*9880d681SAndroid Build Coastguard Worker const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const {
4593*9880d681SAndroid Build Coastguard Worker #define OPCODE(NAME) case SystemZISD::NAME: return "SystemZISD::" #NAME
4594*9880d681SAndroid Build Coastguard Worker   switch ((SystemZISD::NodeType)Opcode) {
4595*9880d681SAndroid Build Coastguard Worker     case SystemZISD::FIRST_NUMBER: break;
4596*9880d681SAndroid Build Coastguard Worker     OPCODE(RET_FLAG);
4597*9880d681SAndroid Build Coastguard Worker     OPCODE(CALL);
4598*9880d681SAndroid Build Coastguard Worker     OPCODE(SIBCALL);
4599*9880d681SAndroid Build Coastguard Worker     OPCODE(TLS_GDCALL);
4600*9880d681SAndroid Build Coastguard Worker     OPCODE(TLS_LDCALL);
4601*9880d681SAndroid Build Coastguard Worker     OPCODE(PCREL_WRAPPER);
4602*9880d681SAndroid Build Coastguard Worker     OPCODE(PCREL_OFFSET);
4603*9880d681SAndroid Build Coastguard Worker     OPCODE(IABS);
4604*9880d681SAndroid Build Coastguard Worker     OPCODE(ICMP);
4605*9880d681SAndroid Build Coastguard Worker     OPCODE(FCMP);
4606*9880d681SAndroid Build Coastguard Worker     OPCODE(TM);
4607*9880d681SAndroid Build Coastguard Worker     OPCODE(BR_CCMASK);
4608*9880d681SAndroid Build Coastguard Worker     OPCODE(SELECT_CCMASK);
4609*9880d681SAndroid Build Coastguard Worker     OPCODE(ADJDYNALLOC);
4610*9880d681SAndroid Build Coastguard Worker     OPCODE(EXTRACT_ACCESS);
4611*9880d681SAndroid Build Coastguard Worker     OPCODE(POPCNT);
4612*9880d681SAndroid Build Coastguard Worker     OPCODE(UMUL_LOHI64);
4613*9880d681SAndroid Build Coastguard Worker     OPCODE(SDIVREM32);
4614*9880d681SAndroid Build Coastguard Worker     OPCODE(SDIVREM64);
4615*9880d681SAndroid Build Coastguard Worker     OPCODE(UDIVREM32);
4616*9880d681SAndroid Build Coastguard Worker     OPCODE(UDIVREM64);
4617*9880d681SAndroid Build Coastguard Worker     OPCODE(MVC);
4618*9880d681SAndroid Build Coastguard Worker     OPCODE(MVC_LOOP);
4619*9880d681SAndroid Build Coastguard Worker     OPCODE(NC);
4620*9880d681SAndroid Build Coastguard Worker     OPCODE(NC_LOOP);
4621*9880d681SAndroid Build Coastguard Worker     OPCODE(OC);
4622*9880d681SAndroid Build Coastguard Worker     OPCODE(OC_LOOP);
4623*9880d681SAndroid Build Coastguard Worker     OPCODE(XC);
4624*9880d681SAndroid Build Coastguard Worker     OPCODE(XC_LOOP);
4625*9880d681SAndroid Build Coastguard Worker     OPCODE(CLC);
4626*9880d681SAndroid Build Coastguard Worker     OPCODE(CLC_LOOP);
4627*9880d681SAndroid Build Coastguard Worker     OPCODE(STPCPY);
4628*9880d681SAndroid Build Coastguard Worker     OPCODE(STRCMP);
4629*9880d681SAndroid Build Coastguard Worker     OPCODE(SEARCH_STRING);
4630*9880d681SAndroid Build Coastguard Worker     OPCODE(IPM);
4631*9880d681SAndroid Build Coastguard Worker     OPCODE(SERIALIZE);
4632*9880d681SAndroid Build Coastguard Worker     OPCODE(MEMBARRIER);
4633*9880d681SAndroid Build Coastguard Worker     OPCODE(TBEGIN);
4634*9880d681SAndroid Build Coastguard Worker     OPCODE(TBEGIN_NOFLOAT);
4635*9880d681SAndroid Build Coastguard Worker     OPCODE(TEND);
4636*9880d681SAndroid Build Coastguard Worker     OPCODE(BYTE_MASK);
4637*9880d681SAndroid Build Coastguard Worker     OPCODE(ROTATE_MASK);
4638*9880d681SAndroid Build Coastguard Worker     OPCODE(REPLICATE);
4639*9880d681SAndroid Build Coastguard Worker     OPCODE(JOIN_DWORDS);
4640*9880d681SAndroid Build Coastguard Worker     OPCODE(SPLAT);
4641*9880d681SAndroid Build Coastguard Worker     OPCODE(MERGE_HIGH);
4642*9880d681SAndroid Build Coastguard Worker     OPCODE(MERGE_LOW);
4643*9880d681SAndroid Build Coastguard Worker     OPCODE(SHL_DOUBLE);
4644*9880d681SAndroid Build Coastguard Worker     OPCODE(PERMUTE_DWORDS);
4645*9880d681SAndroid Build Coastguard Worker     OPCODE(PERMUTE);
4646*9880d681SAndroid Build Coastguard Worker     OPCODE(PACK);
4647*9880d681SAndroid Build Coastguard Worker     OPCODE(PACKS_CC);
4648*9880d681SAndroid Build Coastguard Worker     OPCODE(PACKLS_CC);
4649*9880d681SAndroid Build Coastguard Worker     OPCODE(UNPACK_HIGH);
4650*9880d681SAndroid Build Coastguard Worker     OPCODE(UNPACKL_HIGH);
4651*9880d681SAndroid Build Coastguard Worker     OPCODE(UNPACK_LOW);
4652*9880d681SAndroid Build Coastguard Worker     OPCODE(UNPACKL_LOW);
4653*9880d681SAndroid Build Coastguard Worker     OPCODE(VSHL_BY_SCALAR);
4654*9880d681SAndroid Build Coastguard Worker     OPCODE(VSRL_BY_SCALAR);
4655*9880d681SAndroid Build Coastguard Worker     OPCODE(VSRA_BY_SCALAR);
4656*9880d681SAndroid Build Coastguard Worker     OPCODE(VSUM);
4657*9880d681SAndroid Build Coastguard Worker     OPCODE(VICMPE);
4658*9880d681SAndroid Build Coastguard Worker     OPCODE(VICMPH);
4659*9880d681SAndroid Build Coastguard Worker     OPCODE(VICMPHL);
4660*9880d681SAndroid Build Coastguard Worker     OPCODE(VICMPES);
4661*9880d681SAndroid Build Coastguard Worker     OPCODE(VICMPHS);
4662*9880d681SAndroid Build Coastguard Worker     OPCODE(VICMPHLS);
4663*9880d681SAndroid Build Coastguard Worker     OPCODE(VFCMPE);
4664*9880d681SAndroid Build Coastguard Worker     OPCODE(VFCMPH);
4665*9880d681SAndroid Build Coastguard Worker     OPCODE(VFCMPHE);
4666*9880d681SAndroid Build Coastguard Worker     OPCODE(VFCMPES);
4667*9880d681SAndroid Build Coastguard Worker     OPCODE(VFCMPHS);
4668*9880d681SAndroid Build Coastguard Worker     OPCODE(VFCMPHES);
4669*9880d681SAndroid Build Coastguard Worker     OPCODE(VFTCI);
4670*9880d681SAndroid Build Coastguard Worker     OPCODE(VEXTEND);
4671*9880d681SAndroid Build Coastguard Worker     OPCODE(VROUND);
4672*9880d681SAndroid Build Coastguard Worker     OPCODE(VTM);
4673*9880d681SAndroid Build Coastguard Worker     OPCODE(VFAE_CC);
4674*9880d681SAndroid Build Coastguard Worker     OPCODE(VFAEZ_CC);
4675*9880d681SAndroid Build Coastguard Worker     OPCODE(VFEE_CC);
4676*9880d681SAndroid Build Coastguard Worker     OPCODE(VFEEZ_CC);
4677*9880d681SAndroid Build Coastguard Worker     OPCODE(VFENE_CC);
4678*9880d681SAndroid Build Coastguard Worker     OPCODE(VFENEZ_CC);
4679*9880d681SAndroid Build Coastguard Worker     OPCODE(VISTR_CC);
4680*9880d681SAndroid Build Coastguard Worker     OPCODE(VSTRC_CC);
4681*9880d681SAndroid Build Coastguard Worker     OPCODE(VSTRCZ_CC);
4682*9880d681SAndroid Build Coastguard Worker     OPCODE(TDC);
4683*9880d681SAndroid Build Coastguard Worker     OPCODE(ATOMIC_SWAPW);
4684*9880d681SAndroid Build Coastguard Worker     OPCODE(ATOMIC_LOADW_ADD);
4685*9880d681SAndroid Build Coastguard Worker     OPCODE(ATOMIC_LOADW_SUB);
4686*9880d681SAndroid Build Coastguard Worker     OPCODE(ATOMIC_LOADW_AND);
4687*9880d681SAndroid Build Coastguard Worker     OPCODE(ATOMIC_LOADW_OR);
4688*9880d681SAndroid Build Coastguard Worker     OPCODE(ATOMIC_LOADW_XOR);
4689*9880d681SAndroid Build Coastguard Worker     OPCODE(ATOMIC_LOADW_NAND);
4690*9880d681SAndroid Build Coastguard Worker     OPCODE(ATOMIC_LOADW_MIN);
4691*9880d681SAndroid Build Coastguard Worker     OPCODE(ATOMIC_LOADW_MAX);
4692*9880d681SAndroid Build Coastguard Worker     OPCODE(ATOMIC_LOADW_UMIN);
4693*9880d681SAndroid Build Coastguard Worker     OPCODE(ATOMIC_LOADW_UMAX);
4694*9880d681SAndroid Build Coastguard Worker     OPCODE(ATOMIC_CMP_SWAPW);
4695*9880d681SAndroid Build Coastguard Worker     OPCODE(LRV);
4696*9880d681SAndroid Build Coastguard Worker     OPCODE(STRV);
4697*9880d681SAndroid Build Coastguard Worker     OPCODE(PREFETCH);
4698*9880d681SAndroid Build Coastguard Worker   }
4699*9880d681SAndroid Build Coastguard Worker   return nullptr;
4700*9880d681SAndroid Build Coastguard Worker #undef OPCODE
4701*9880d681SAndroid Build Coastguard Worker }
4702*9880d681SAndroid Build Coastguard Worker 
4703*9880d681SAndroid Build Coastguard Worker // Return true if VT is a vector whose elements are a whole number of bytes
4704*9880d681SAndroid Build Coastguard Worker // in width.
canTreatAsByteVector(EVT VT)4705*9880d681SAndroid Build Coastguard Worker static bool canTreatAsByteVector(EVT VT) {
4706*9880d681SAndroid Build Coastguard Worker   return VT.isVector() && VT.getVectorElementType().getSizeInBits() % 8 == 0;
4707*9880d681SAndroid Build Coastguard Worker }
4708*9880d681SAndroid Build Coastguard Worker 
4709*9880d681SAndroid Build Coastguard Worker // Try to simplify an EXTRACT_VECTOR_ELT from a vector of type VecVT
4710*9880d681SAndroid Build Coastguard Worker // producing a result of type ResVT.  Op is a possibly bitcast version
4711*9880d681SAndroid Build Coastguard Worker // of the input vector and Index is the index (based on type VecVT) that
4712*9880d681SAndroid Build Coastguard Worker // should be extracted.  Return the new extraction if a simplification
4713*9880d681SAndroid Build Coastguard Worker // was possible or if Force is true.
combineExtract(const SDLoc & DL,EVT ResVT,EVT VecVT,SDValue Op,unsigned Index,DAGCombinerInfo & DCI,bool Force) const4714*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::combineExtract(const SDLoc &DL, EVT ResVT,
4715*9880d681SAndroid Build Coastguard Worker                                               EVT VecVT, SDValue Op,
4716*9880d681SAndroid Build Coastguard Worker                                               unsigned Index,
4717*9880d681SAndroid Build Coastguard Worker                                               DAGCombinerInfo &DCI,
4718*9880d681SAndroid Build Coastguard Worker                                               bool Force) const {
4719*9880d681SAndroid Build Coastguard Worker   SelectionDAG &DAG = DCI.DAG;
4720*9880d681SAndroid Build Coastguard Worker 
4721*9880d681SAndroid Build Coastguard Worker   // The number of bytes being extracted.
4722*9880d681SAndroid Build Coastguard Worker   unsigned BytesPerElement = VecVT.getVectorElementType().getStoreSize();
4723*9880d681SAndroid Build Coastguard Worker 
4724*9880d681SAndroid Build Coastguard Worker   for (;;) {
4725*9880d681SAndroid Build Coastguard Worker     unsigned Opcode = Op.getOpcode();
4726*9880d681SAndroid Build Coastguard Worker     if (Opcode == ISD::BITCAST)
4727*9880d681SAndroid Build Coastguard Worker       // Look through bitcasts.
4728*9880d681SAndroid Build Coastguard Worker       Op = Op.getOperand(0);
4729*9880d681SAndroid Build Coastguard Worker     else if (Opcode == ISD::VECTOR_SHUFFLE &&
4730*9880d681SAndroid Build Coastguard Worker              canTreatAsByteVector(Op.getValueType())) {
4731*9880d681SAndroid Build Coastguard Worker       // Get a VPERM-like permute mask and see whether the bytes covered
4732*9880d681SAndroid Build Coastguard Worker       // by the extracted element are a contiguous sequence from one
4733*9880d681SAndroid Build Coastguard Worker       // source operand.
4734*9880d681SAndroid Build Coastguard Worker       SmallVector<int, SystemZ::VectorBytes> Bytes;
4735*9880d681SAndroid Build Coastguard Worker       getVPermMask(cast<ShuffleVectorSDNode>(Op), Bytes);
4736*9880d681SAndroid Build Coastguard Worker       int First;
4737*9880d681SAndroid Build Coastguard Worker       if (!getShuffleInput(Bytes, Index * BytesPerElement,
4738*9880d681SAndroid Build Coastguard Worker                            BytesPerElement, First))
4739*9880d681SAndroid Build Coastguard Worker         break;
4740*9880d681SAndroid Build Coastguard Worker       if (First < 0)
4741*9880d681SAndroid Build Coastguard Worker         return DAG.getUNDEF(ResVT);
4742*9880d681SAndroid Build Coastguard Worker       // Make sure the contiguous sequence starts at a multiple of the
4743*9880d681SAndroid Build Coastguard Worker       // original element size.
4744*9880d681SAndroid Build Coastguard Worker       unsigned Byte = unsigned(First) % Bytes.size();
4745*9880d681SAndroid Build Coastguard Worker       if (Byte % BytesPerElement != 0)
4746*9880d681SAndroid Build Coastguard Worker         break;
4747*9880d681SAndroid Build Coastguard Worker       // We can get the extracted value directly from an input.
4748*9880d681SAndroid Build Coastguard Worker       Index = Byte / BytesPerElement;
4749*9880d681SAndroid Build Coastguard Worker       Op = Op.getOperand(unsigned(First) / Bytes.size());
4750*9880d681SAndroid Build Coastguard Worker       Force = true;
4751*9880d681SAndroid Build Coastguard Worker     } else if (Opcode == ISD::BUILD_VECTOR &&
4752*9880d681SAndroid Build Coastguard Worker                canTreatAsByteVector(Op.getValueType())) {
4753*9880d681SAndroid Build Coastguard Worker       // We can only optimize this case if the BUILD_VECTOR elements are
4754*9880d681SAndroid Build Coastguard Worker       // at least as wide as the extracted value.
4755*9880d681SAndroid Build Coastguard Worker       EVT OpVT = Op.getValueType();
4756*9880d681SAndroid Build Coastguard Worker       unsigned OpBytesPerElement = OpVT.getVectorElementType().getStoreSize();
4757*9880d681SAndroid Build Coastguard Worker       if (OpBytesPerElement < BytesPerElement)
4758*9880d681SAndroid Build Coastguard Worker         break;
4759*9880d681SAndroid Build Coastguard Worker       // Make sure that the least-significant bit of the extracted value
4760*9880d681SAndroid Build Coastguard Worker       // is the least significant bit of an input.
4761*9880d681SAndroid Build Coastguard Worker       unsigned End = (Index + 1) * BytesPerElement;
4762*9880d681SAndroid Build Coastguard Worker       if (End % OpBytesPerElement != 0)
4763*9880d681SAndroid Build Coastguard Worker         break;
4764*9880d681SAndroid Build Coastguard Worker       // We're extracting the low part of one operand of the BUILD_VECTOR.
4765*9880d681SAndroid Build Coastguard Worker       Op = Op.getOperand(End / OpBytesPerElement - 1);
4766*9880d681SAndroid Build Coastguard Worker       if (!Op.getValueType().isInteger()) {
4767*9880d681SAndroid Build Coastguard Worker         EVT VT = MVT::getIntegerVT(Op.getValueType().getSizeInBits());
4768*9880d681SAndroid Build Coastguard Worker         Op = DAG.getNode(ISD::BITCAST, DL, VT, Op);
4769*9880d681SAndroid Build Coastguard Worker         DCI.AddToWorklist(Op.getNode());
4770*9880d681SAndroid Build Coastguard Worker       }
4771*9880d681SAndroid Build Coastguard Worker       EVT VT = MVT::getIntegerVT(ResVT.getSizeInBits());
4772*9880d681SAndroid Build Coastguard Worker       Op = DAG.getNode(ISD::TRUNCATE, DL, VT, Op);
4773*9880d681SAndroid Build Coastguard Worker       if (VT != ResVT) {
4774*9880d681SAndroid Build Coastguard Worker         DCI.AddToWorklist(Op.getNode());
4775*9880d681SAndroid Build Coastguard Worker         Op = DAG.getNode(ISD::BITCAST, DL, ResVT, Op);
4776*9880d681SAndroid Build Coastguard Worker       }
4777*9880d681SAndroid Build Coastguard Worker       return Op;
4778*9880d681SAndroid Build Coastguard Worker     } else if ((Opcode == ISD::SIGN_EXTEND_VECTOR_INREG ||
4779*9880d681SAndroid Build Coastguard Worker                 Opcode == ISD::ZERO_EXTEND_VECTOR_INREG ||
4780*9880d681SAndroid Build Coastguard Worker                 Opcode == ISD::ANY_EXTEND_VECTOR_INREG) &&
4781*9880d681SAndroid Build Coastguard Worker                canTreatAsByteVector(Op.getValueType()) &&
4782*9880d681SAndroid Build Coastguard Worker                canTreatAsByteVector(Op.getOperand(0).getValueType())) {
4783*9880d681SAndroid Build Coastguard Worker       // Make sure that only the unextended bits are significant.
4784*9880d681SAndroid Build Coastguard Worker       EVT ExtVT = Op.getValueType();
4785*9880d681SAndroid Build Coastguard Worker       EVT OpVT = Op.getOperand(0).getValueType();
4786*9880d681SAndroid Build Coastguard Worker       unsigned ExtBytesPerElement = ExtVT.getVectorElementType().getStoreSize();
4787*9880d681SAndroid Build Coastguard Worker       unsigned OpBytesPerElement = OpVT.getVectorElementType().getStoreSize();
4788*9880d681SAndroid Build Coastguard Worker       unsigned Byte = Index * BytesPerElement;
4789*9880d681SAndroid Build Coastguard Worker       unsigned SubByte = Byte % ExtBytesPerElement;
4790*9880d681SAndroid Build Coastguard Worker       unsigned MinSubByte = ExtBytesPerElement - OpBytesPerElement;
4791*9880d681SAndroid Build Coastguard Worker       if (SubByte < MinSubByte ||
4792*9880d681SAndroid Build Coastguard Worker           SubByte + BytesPerElement > ExtBytesPerElement)
4793*9880d681SAndroid Build Coastguard Worker         break;
4794*9880d681SAndroid Build Coastguard Worker       // Get the byte offset of the unextended element
4795*9880d681SAndroid Build Coastguard Worker       Byte = Byte / ExtBytesPerElement * OpBytesPerElement;
4796*9880d681SAndroid Build Coastguard Worker       // ...then add the byte offset relative to that element.
4797*9880d681SAndroid Build Coastguard Worker       Byte += SubByte - MinSubByte;
4798*9880d681SAndroid Build Coastguard Worker       if (Byte % BytesPerElement != 0)
4799*9880d681SAndroid Build Coastguard Worker         break;
4800*9880d681SAndroid Build Coastguard Worker       Op = Op.getOperand(0);
4801*9880d681SAndroid Build Coastguard Worker       Index = Byte / BytesPerElement;
4802*9880d681SAndroid Build Coastguard Worker       Force = true;
4803*9880d681SAndroid Build Coastguard Worker     } else
4804*9880d681SAndroid Build Coastguard Worker       break;
4805*9880d681SAndroid Build Coastguard Worker   }
4806*9880d681SAndroid Build Coastguard Worker   if (Force) {
4807*9880d681SAndroid Build Coastguard Worker     if (Op.getValueType() != VecVT) {
4808*9880d681SAndroid Build Coastguard Worker       Op = DAG.getNode(ISD::BITCAST, DL, VecVT, Op);
4809*9880d681SAndroid Build Coastguard Worker       DCI.AddToWorklist(Op.getNode());
4810*9880d681SAndroid Build Coastguard Worker     }
4811*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ResVT, Op,
4812*9880d681SAndroid Build Coastguard Worker                        DAG.getConstant(Index, DL, MVT::i32));
4813*9880d681SAndroid Build Coastguard Worker   }
4814*9880d681SAndroid Build Coastguard Worker   return SDValue();
4815*9880d681SAndroid Build Coastguard Worker }
4816*9880d681SAndroid Build Coastguard Worker 
4817*9880d681SAndroid Build Coastguard Worker // Optimize vector operations in scalar value Op on the basis that Op
4818*9880d681SAndroid Build Coastguard Worker // is truncated to TruncVT.
combineTruncateExtract(const SDLoc & DL,EVT TruncVT,SDValue Op,DAGCombinerInfo & DCI) const4819*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::combineTruncateExtract(
4820*9880d681SAndroid Build Coastguard Worker     const SDLoc &DL, EVT TruncVT, SDValue Op, DAGCombinerInfo &DCI) const {
4821*9880d681SAndroid Build Coastguard Worker   // If we have (trunc (extract_vector_elt X, Y)), try to turn it into
4822*9880d681SAndroid Build Coastguard Worker   // (extract_vector_elt (bitcast X), Y'), where (bitcast X) has elements
4823*9880d681SAndroid Build Coastguard Worker   // of type TruncVT.
4824*9880d681SAndroid Build Coastguard Worker   if (Op.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
4825*9880d681SAndroid Build Coastguard Worker       TruncVT.getSizeInBits() % 8 == 0) {
4826*9880d681SAndroid Build Coastguard Worker     SDValue Vec = Op.getOperand(0);
4827*9880d681SAndroid Build Coastguard Worker     EVT VecVT = Vec.getValueType();
4828*9880d681SAndroid Build Coastguard Worker     if (canTreatAsByteVector(VecVT)) {
4829*9880d681SAndroid Build Coastguard Worker       if (auto *IndexN = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
4830*9880d681SAndroid Build Coastguard Worker         unsigned BytesPerElement = VecVT.getVectorElementType().getStoreSize();
4831*9880d681SAndroid Build Coastguard Worker         unsigned TruncBytes = TruncVT.getStoreSize();
4832*9880d681SAndroid Build Coastguard Worker         if (BytesPerElement % TruncBytes == 0) {
4833*9880d681SAndroid Build Coastguard Worker           // Calculate the value of Y' in the above description.  We are
4834*9880d681SAndroid Build Coastguard Worker           // splitting the original elements into Scale equal-sized pieces
4835*9880d681SAndroid Build Coastguard Worker           // and for truncation purposes want the last (least-significant)
4836*9880d681SAndroid Build Coastguard Worker           // of these pieces for IndexN.  This is easiest to do by calculating
4837*9880d681SAndroid Build Coastguard Worker           // the start index of the following element and then subtracting 1.
4838*9880d681SAndroid Build Coastguard Worker           unsigned Scale = BytesPerElement / TruncBytes;
4839*9880d681SAndroid Build Coastguard Worker           unsigned NewIndex = (IndexN->getZExtValue() + 1) * Scale - 1;
4840*9880d681SAndroid Build Coastguard Worker 
4841*9880d681SAndroid Build Coastguard Worker           // Defer the creation of the bitcast from X to combineExtract,
4842*9880d681SAndroid Build Coastguard Worker           // which might be able to optimize the extraction.
4843*9880d681SAndroid Build Coastguard Worker           VecVT = MVT::getVectorVT(MVT::getIntegerVT(TruncBytes * 8),
4844*9880d681SAndroid Build Coastguard Worker                                    VecVT.getStoreSize() / TruncBytes);
4845*9880d681SAndroid Build Coastguard Worker           EVT ResVT = (TruncBytes < 4 ? MVT::i32 : TruncVT);
4846*9880d681SAndroid Build Coastguard Worker           return combineExtract(DL, ResVT, VecVT, Vec, NewIndex, DCI, true);
4847*9880d681SAndroid Build Coastguard Worker         }
4848*9880d681SAndroid Build Coastguard Worker       }
4849*9880d681SAndroid Build Coastguard Worker     }
4850*9880d681SAndroid Build Coastguard Worker   }
4851*9880d681SAndroid Build Coastguard Worker   return SDValue();
4852*9880d681SAndroid Build Coastguard Worker }
4853*9880d681SAndroid Build Coastguard Worker 
combineSIGN_EXTEND(SDNode * N,DAGCombinerInfo & DCI) const4854*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::combineSIGN_EXTEND(
4855*9880d681SAndroid Build Coastguard Worker     SDNode *N, DAGCombinerInfo &DCI) const {
4856*9880d681SAndroid Build Coastguard Worker   // Convert (sext (ashr (shl X, C1), C2)) to
4857*9880d681SAndroid Build Coastguard Worker   // (ashr (shl (anyext X), C1'), C2')), since wider shifts are as
4858*9880d681SAndroid Build Coastguard Worker   // cheap as narrower ones.
4859*9880d681SAndroid Build Coastguard Worker   SelectionDAG &DAG = DCI.DAG;
4860*9880d681SAndroid Build Coastguard Worker   SDValue N0 = N->getOperand(0);
4861*9880d681SAndroid Build Coastguard Worker   EVT VT = N->getValueType(0);
4862*9880d681SAndroid Build Coastguard Worker   if (N0.hasOneUse() && N0.getOpcode() == ISD::SRA) {
4863*9880d681SAndroid Build Coastguard Worker     auto *SraAmt = dyn_cast<ConstantSDNode>(N0.getOperand(1));
4864*9880d681SAndroid Build Coastguard Worker     SDValue Inner = N0.getOperand(0);
4865*9880d681SAndroid Build Coastguard Worker     if (SraAmt && Inner.hasOneUse() && Inner.getOpcode() == ISD::SHL) {
4866*9880d681SAndroid Build Coastguard Worker       if (auto *ShlAmt = dyn_cast<ConstantSDNode>(Inner.getOperand(1))) {
4867*9880d681SAndroid Build Coastguard Worker         unsigned Extra = (VT.getSizeInBits() -
4868*9880d681SAndroid Build Coastguard Worker                           N0.getValueType().getSizeInBits());
4869*9880d681SAndroid Build Coastguard Worker         unsigned NewShlAmt = ShlAmt->getZExtValue() + Extra;
4870*9880d681SAndroid Build Coastguard Worker         unsigned NewSraAmt = SraAmt->getZExtValue() + Extra;
4871*9880d681SAndroid Build Coastguard Worker         EVT ShiftVT = N0.getOperand(1).getValueType();
4872*9880d681SAndroid Build Coastguard Worker         SDValue Ext = DAG.getNode(ISD::ANY_EXTEND, SDLoc(Inner), VT,
4873*9880d681SAndroid Build Coastguard Worker                                   Inner.getOperand(0));
4874*9880d681SAndroid Build Coastguard Worker         SDValue Shl = DAG.getNode(ISD::SHL, SDLoc(Inner), VT, Ext,
4875*9880d681SAndroid Build Coastguard Worker                                   DAG.getConstant(NewShlAmt, SDLoc(Inner),
4876*9880d681SAndroid Build Coastguard Worker                                                   ShiftVT));
4877*9880d681SAndroid Build Coastguard Worker         return DAG.getNode(ISD::SRA, SDLoc(N0), VT, Shl,
4878*9880d681SAndroid Build Coastguard Worker                            DAG.getConstant(NewSraAmt, SDLoc(N0), ShiftVT));
4879*9880d681SAndroid Build Coastguard Worker       }
4880*9880d681SAndroid Build Coastguard Worker     }
4881*9880d681SAndroid Build Coastguard Worker   }
4882*9880d681SAndroid Build Coastguard Worker   return SDValue();
4883*9880d681SAndroid Build Coastguard Worker }
4884*9880d681SAndroid Build Coastguard Worker 
combineMERGE(SDNode * N,DAGCombinerInfo & DCI) const4885*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::combineMERGE(
4886*9880d681SAndroid Build Coastguard Worker     SDNode *N, DAGCombinerInfo &DCI) const {
4887*9880d681SAndroid Build Coastguard Worker   SelectionDAG &DAG = DCI.DAG;
4888*9880d681SAndroid Build Coastguard Worker   unsigned Opcode = N->getOpcode();
4889*9880d681SAndroid Build Coastguard Worker   SDValue Op0 = N->getOperand(0);
4890*9880d681SAndroid Build Coastguard Worker   SDValue Op1 = N->getOperand(1);
4891*9880d681SAndroid Build Coastguard Worker   if (Op0.getOpcode() == ISD::BITCAST)
4892*9880d681SAndroid Build Coastguard Worker     Op0 = Op0.getOperand(0);
4893*9880d681SAndroid Build Coastguard Worker   if (Op0.getOpcode() == SystemZISD::BYTE_MASK &&
4894*9880d681SAndroid Build Coastguard Worker       cast<ConstantSDNode>(Op0.getOperand(0))->getZExtValue() == 0) {
4895*9880d681SAndroid Build Coastguard Worker     // (z_merge_* 0, 0) -> 0.  This is mostly useful for using VLLEZF
4896*9880d681SAndroid Build Coastguard Worker     // for v4f32.
4897*9880d681SAndroid Build Coastguard Worker     if (Op1 == N->getOperand(0))
4898*9880d681SAndroid Build Coastguard Worker       return Op1;
4899*9880d681SAndroid Build Coastguard Worker     // (z_merge_? 0, X) -> (z_unpackl_? 0, X).
4900*9880d681SAndroid Build Coastguard Worker     EVT VT = Op1.getValueType();
4901*9880d681SAndroid Build Coastguard Worker     unsigned ElemBytes = VT.getVectorElementType().getStoreSize();
4902*9880d681SAndroid Build Coastguard Worker     if (ElemBytes <= 4) {
4903*9880d681SAndroid Build Coastguard Worker       Opcode = (Opcode == SystemZISD::MERGE_HIGH ?
4904*9880d681SAndroid Build Coastguard Worker                 SystemZISD::UNPACKL_HIGH : SystemZISD::UNPACKL_LOW);
4905*9880d681SAndroid Build Coastguard Worker       EVT InVT = VT.changeVectorElementTypeToInteger();
4906*9880d681SAndroid Build Coastguard Worker       EVT OutVT = MVT::getVectorVT(MVT::getIntegerVT(ElemBytes * 16),
4907*9880d681SAndroid Build Coastguard Worker                                    SystemZ::VectorBytes / ElemBytes / 2);
4908*9880d681SAndroid Build Coastguard Worker       if (VT != InVT) {
4909*9880d681SAndroid Build Coastguard Worker         Op1 = DAG.getNode(ISD::BITCAST, SDLoc(N), InVT, Op1);
4910*9880d681SAndroid Build Coastguard Worker         DCI.AddToWorklist(Op1.getNode());
4911*9880d681SAndroid Build Coastguard Worker       }
4912*9880d681SAndroid Build Coastguard Worker       SDValue Op = DAG.getNode(Opcode, SDLoc(N), OutVT, Op1);
4913*9880d681SAndroid Build Coastguard Worker       DCI.AddToWorklist(Op.getNode());
4914*9880d681SAndroid Build Coastguard Worker       return DAG.getNode(ISD::BITCAST, SDLoc(N), VT, Op);
4915*9880d681SAndroid Build Coastguard Worker     }
4916*9880d681SAndroid Build Coastguard Worker   }
4917*9880d681SAndroid Build Coastguard Worker   return SDValue();
4918*9880d681SAndroid Build Coastguard Worker }
4919*9880d681SAndroid Build Coastguard Worker 
combineSTORE(SDNode * N,DAGCombinerInfo & DCI) const4920*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::combineSTORE(
4921*9880d681SAndroid Build Coastguard Worker     SDNode *N, DAGCombinerInfo &DCI) const {
4922*9880d681SAndroid Build Coastguard Worker   SelectionDAG &DAG = DCI.DAG;
4923*9880d681SAndroid Build Coastguard Worker   auto *SN = cast<StoreSDNode>(N);
4924*9880d681SAndroid Build Coastguard Worker   auto &Op1 = N->getOperand(1);
4925*9880d681SAndroid Build Coastguard Worker   EVT MemVT = SN->getMemoryVT();
4926*9880d681SAndroid Build Coastguard Worker   // If we have (truncstoreiN (extract_vector_elt X, Y), Z) then it is better
4927*9880d681SAndroid Build Coastguard Worker   // for the extraction to be done on a vMiN value, so that we can use VSTE.
4928*9880d681SAndroid Build Coastguard Worker   // If X has wider elements then convert it to:
4929*9880d681SAndroid Build Coastguard Worker   // (truncstoreiN (extract_vector_elt (bitcast X), Y2), Z).
4930*9880d681SAndroid Build Coastguard Worker   if (MemVT.isInteger()) {
4931*9880d681SAndroid Build Coastguard Worker     if (SDValue Value =
4932*9880d681SAndroid Build Coastguard Worker             combineTruncateExtract(SDLoc(N), MemVT, SN->getValue(), DCI)) {
4933*9880d681SAndroid Build Coastguard Worker       DCI.AddToWorklist(Value.getNode());
4934*9880d681SAndroid Build Coastguard Worker 
4935*9880d681SAndroid Build Coastguard Worker       // Rewrite the store with the new form of stored value.
4936*9880d681SAndroid Build Coastguard Worker       return DAG.getTruncStore(SN->getChain(), SDLoc(SN), Value,
4937*9880d681SAndroid Build Coastguard Worker                                SN->getBasePtr(), SN->getMemoryVT(),
4938*9880d681SAndroid Build Coastguard Worker                                SN->getMemOperand());
4939*9880d681SAndroid Build Coastguard Worker     }
4940*9880d681SAndroid Build Coastguard Worker   }
4941*9880d681SAndroid Build Coastguard Worker   // Combine STORE (BSWAP) into STRVH/STRV/STRVG
4942*9880d681SAndroid Build Coastguard Worker   // See comment in combineBSWAP about volatile accesses.
4943*9880d681SAndroid Build Coastguard Worker   if (!SN->isVolatile() &&
4944*9880d681SAndroid Build Coastguard Worker       Op1.getOpcode() == ISD::BSWAP &&
4945*9880d681SAndroid Build Coastguard Worker       Op1.getNode()->hasOneUse() &&
4946*9880d681SAndroid Build Coastguard Worker       (Op1.getValueType() == MVT::i16 ||
4947*9880d681SAndroid Build Coastguard Worker        Op1.getValueType() == MVT::i32 ||
4948*9880d681SAndroid Build Coastguard Worker        Op1.getValueType() == MVT::i64)) {
4949*9880d681SAndroid Build Coastguard Worker 
4950*9880d681SAndroid Build Coastguard Worker       SDValue BSwapOp = Op1.getOperand(0);
4951*9880d681SAndroid Build Coastguard Worker 
4952*9880d681SAndroid Build Coastguard Worker       if (BSwapOp.getValueType() == MVT::i16)
4953*9880d681SAndroid Build Coastguard Worker         BSwapOp = DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), MVT::i32, BSwapOp);
4954*9880d681SAndroid Build Coastguard Worker 
4955*9880d681SAndroid Build Coastguard Worker       SDValue Ops[] = {
4956*9880d681SAndroid Build Coastguard Worker         N->getOperand(0), BSwapOp, N->getOperand(2),
4957*9880d681SAndroid Build Coastguard Worker         DAG.getValueType(Op1.getValueType())
4958*9880d681SAndroid Build Coastguard Worker       };
4959*9880d681SAndroid Build Coastguard Worker 
4960*9880d681SAndroid Build Coastguard Worker       return
4961*9880d681SAndroid Build Coastguard Worker         DAG.getMemIntrinsicNode(SystemZISD::STRV, SDLoc(N), DAG.getVTList(MVT::Other),
4962*9880d681SAndroid Build Coastguard Worker                                 Ops, MemVT, SN->getMemOperand());
4963*9880d681SAndroid Build Coastguard Worker     }
4964*9880d681SAndroid Build Coastguard Worker   return SDValue();
4965*9880d681SAndroid Build Coastguard Worker }
4966*9880d681SAndroid Build Coastguard Worker 
combineEXTRACT_VECTOR_ELT(SDNode * N,DAGCombinerInfo & DCI) const4967*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::combineEXTRACT_VECTOR_ELT(
4968*9880d681SAndroid Build Coastguard Worker     SDNode *N, DAGCombinerInfo &DCI) const {
4969*9880d681SAndroid Build Coastguard Worker   // Try to simplify a vector extraction.
4970*9880d681SAndroid Build Coastguard Worker   if (auto *IndexN = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
4971*9880d681SAndroid Build Coastguard Worker     SDValue Op0 = N->getOperand(0);
4972*9880d681SAndroid Build Coastguard Worker     EVT VecVT = Op0.getValueType();
4973*9880d681SAndroid Build Coastguard Worker     return combineExtract(SDLoc(N), N->getValueType(0), VecVT, Op0,
4974*9880d681SAndroid Build Coastguard Worker                           IndexN->getZExtValue(), DCI, false);
4975*9880d681SAndroid Build Coastguard Worker   }
4976*9880d681SAndroid Build Coastguard Worker   return SDValue();
4977*9880d681SAndroid Build Coastguard Worker }
4978*9880d681SAndroid Build Coastguard Worker 
combineJOIN_DWORDS(SDNode * N,DAGCombinerInfo & DCI) const4979*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::combineJOIN_DWORDS(
4980*9880d681SAndroid Build Coastguard Worker     SDNode *N, DAGCombinerInfo &DCI) const {
4981*9880d681SAndroid Build Coastguard Worker   SelectionDAG &DAG = DCI.DAG;
4982*9880d681SAndroid Build Coastguard Worker   // (join_dwords X, X) == (replicate X)
4983*9880d681SAndroid Build Coastguard Worker   if (N->getOperand(0) == N->getOperand(1))
4984*9880d681SAndroid Build Coastguard Worker     return DAG.getNode(SystemZISD::REPLICATE, SDLoc(N), N->getValueType(0),
4985*9880d681SAndroid Build Coastguard Worker                        N->getOperand(0));
4986*9880d681SAndroid Build Coastguard Worker   return SDValue();
4987*9880d681SAndroid Build Coastguard Worker }
4988*9880d681SAndroid Build Coastguard Worker 
combineFP_ROUND(SDNode * N,DAGCombinerInfo & DCI) const4989*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::combineFP_ROUND(
4990*9880d681SAndroid Build Coastguard Worker     SDNode *N, DAGCombinerInfo &DCI) const {
4991*9880d681SAndroid Build Coastguard Worker   // (fround (extract_vector_elt X 0))
4992*9880d681SAndroid Build Coastguard Worker   // (fround (extract_vector_elt X 1)) ->
4993*9880d681SAndroid Build Coastguard Worker   // (extract_vector_elt (VROUND X) 0)
4994*9880d681SAndroid Build Coastguard Worker   // (extract_vector_elt (VROUND X) 1)
4995*9880d681SAndroid Build Coastguard Worker   //
4996*9880d681SAndroid Build Coastguard Worker   // This is a special case since the target doesn't really support v2f32s.
4997*9880d681SAndroid Build Coastguard Worker   SelectionDAG &DAG = DCI.DAG;
4998*9880d681SAndroid Build Coastguard Worker   SDValue Op0 = N->getOperand(0);
4999*9880d681SAndroid Build Coastguard Worker   if (N->getValueType(0) == MVT::f32 &&
5000*9880d681SAndroid Build Coastguard Worker       Op0.hasOneUse() &&
5001*9880d681SAndroid Build Coastguard Worker       Op0.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
5002*9880d681SAndroid Build Coastguard Worker       Op0.getOperand(0).getValueType() == MVT::v2f64 &&
5003*9880d681SAndroid Build Coastguard Worker       Op0.getOperand(1).getOpcode() == ISD::Constant &&
5004*9880d681SAndroid Build Coastguard Worker       cast<ConstantSDNode>(Op0.getOperand(1))->getZExtValue() == 0) {
5005*9880d681SAndroid Build Coastguard Worker     SDValue Vec = Op0.getOperand(0);
5006*9880d681SAndroid Build Coastguard Worker     for (auto *U : Vec->uses()) {
5007*9880d681SAndroid Build Coastguard Worker       if (U != Op0.getNode() &&
5008*9880d681SAndroid Build Coastguard Worker           U->hasOneUse() &&
5009*9880d681SAndroid Build Coastguard Worker           U->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
5010*9880d681SAndroid Build Coastguard Worker           U->getOperand(0) == Vec &&
5011*9880d681SAndroid Build Coastguard Worker           U->getOperand(1).getOpcode() == ISD::Constant &&
5012*9880d681SAndroid Build Coastguard Worker           cast<ConstantSDNode>(U->getOperand(1))->getZExtValue() == 1) {
5013*9880d681SAndroid Build Coastguard Worker         SDValue OtherRound = SDValue(*U->use_begin(), 0);
5014*9880d681SAndroid Build Coastguard Worker         if (OtherRound.getOpcode() == ISD::FP_ROUND &&
5015*9880d681SAndroid Build Coastguard Worker             OtherRound.getOperand(0) == SDValue(U, 0) &&
5016*9880d681SAndroid Build Coastguard Worker             OtherRound.getValueType() == MVT::f32) {
5017*9880d681SAndroid Build Coastguard Worker           SDValue VRound = DAG.getNode(SystemZISD::VROUND, SDLoc(N),
5018*9880d681SAndroid Build Coastguard Worker                                        MVT::v4f32, Vec);
5019*9880d681SAndroid Build Coastguard Worker           DCI.AddToWorklist(VRound.getNode());
5020*9880d681SAndroid Build Coastguard Worker           SDValue Extract1 =
5021*9880d681SAndroid Build Coastguard Worker             DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(U), MVT::f32,
5022*9880d681SAndroid Build Coastguard Worker                         VRound, DAG.getConstant(2, SDLoc(U), MVT::i32));
5023*9880d681SAndroid Build Coastguard Worker           DCI.AddToWorklist(Extract1.getNode());
5024*9880d681SAndroid Build Coastguard Worker           DAG.ReplaceAllUsesOfValueWith(OtherRound, Extract1);
5025*9880d681SAndroid Build Coastguard Worker           SDValue Extract0 =
5026*9880d681SAndroid Build Coastguard Worker             DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(Op0), MVT::f32,
5027*9880d681SAndroid Build Coastguard Worker                         VRound, DAG.getConstant(0, SDLoc(Op0), MVT::i32));
5028*9880d681SAndroid Build Coastguard Worker           return Extract0;
5029*9880d681SAndroid Build Coastguard Worker         }
5030*9880d681SAndroid Build Coastguard Worker       }
5031*9880d681SAndroid Build Coastguard Worker     }
5032*9880d681SAndroid Build Coastguard Worker   }
5033*9880d681SAndroid Build Coastguard Worker   return SDValue();
5034*9880d681SAndroid Build Coastguard Worker }
5035*9880d681SAndroid Build Coastguard Worker 
combineBSWAP(SDNode * N,DAGCombinerInfo & DCI) const5036*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::combineBSWAP(
5037*9880d681SAndroid Build Coastguard Worker     SDNode *N, DAGCombinerInfo &DCI) const {
5038*9880d681SAndroid Build Coastguard Worker   SelectionDAG &DAG = DCI.DAG;
5039*9880d681SAndroid Build Coastguard Worker   // Combine BSWAP (LOAD) into LRVH/LRV/LRVG
5040*9880d681SAndroid Build Coastguard Worker   // These loads are allowed to access memory multiple times, and so we must check
5041*9880d681SAndroid Build Coastguard Worker   // that the loads are not volatile before performing the combine.
5042*9880d681SAndroid Build Coastguard Worker   if (ISD::isNON_EXTLoad(N->getOperand(0).getNode()) &&
5043*9880d681SAndroid Build Coastguard Worker       N->getOperand(0).hasOneUse() &&
5044*9880d681SAndroid Build Coastguard Worker       (N->getValueType(0) == MVT::i16 || N->getValueType(0) == MVT::i32 ||
5045*9880d681SAndroid Build Coastguard Worker        N->getValueType(0) == MVT::i64) &&
5046*9880d681SAndroid Build Coastguard Worker        !cast<LoadSDNode>(N->getOperand(0))->isVolatile()) {
5047*9880d681SAndroid Build Coastguard Worker       SDValue Load = N->getOperand(0);
5048*9880d681SAndroid Build Coastguard Worker       LoadSDNode *LD = cast<LoadSDNode>(Load);
5049*9880d681SAndroid Build Coastguard Worker 
5050*9880d681SAndroid Build Coastguard Worker       // Create the byte-swapping load.
5051*9880d681SAndroid Build Coastguard Worker       SDValue Ops[] = {
5052*9880d681SAndroid Build Coastguard Worker         LD->getChain(),    // Chain
5053*9880d681SAndroid Build Coastguard Worker         LD->getBasePtr(),  // Ptr
5054*9880d681SAndroid Build Coastguard Worker         DAG.getValueType(N->getValueType(0)) // VT
5055*9880d681SAndroid Build Coastguard Worker       };
5056*9880d681SAndroid Build Coastguard Worker       SDValue BSLoad =
5057*9880d681SAndroid Build Coastguard Worker         DAG.getMemIntrinsicNode(SystemZISD::LRV, SDLoc(N),
5058*9880d681SAndroid Build Coastguard Worker                                 DAG.getVTList(N->getValueType(0) == MVT::i64 ?
5059*9880d681SAndroid Build Coastguard Worker                                               MVT::i64 : MVT::i32, MVT::Other),
5060*9880d681SAndroid Build Coastguard Worker                                 Ops, LD->getMemoryVT(), LD->getMemOperand());
5061*9880d681SAndroid Build Coastguard Worker 
5062*9880d681SAndroid Build Coastguard Worker       // If this is an i16 load, insert the truncate.
5063*9880d681SAndroid Build Coastguard Worker       SDValue ResVal = BSLoad;
5064*9880d681SAndroid Build Coastguard Worker       if (N->getValueType(0) == MVT::i16)
5065*9880d681SAndroid Build Coastguard Worker         ResVal = DAG.getNode(ISD::TRUNCATE, SDLoc(N), MVT::i16, BSLoad);
5066*9880d681SAndroid Build Coastguard Worker 
5067*9880d681SAndroid Build Coastguard Worker       // First, combine the bswap away.  This makes the value produced by the
5068*9880d681SAndroid Build Coastguard Worker       // load dead.
5069*9880d681SAndroid Build Coastguard Worker       DCI.CombineTo(N, ResVal);
5070*9880d681SAndroid Build Coastguard Worker 
5071*9880d681SAndroid Build Coastguard Worker       // Next, combine the load away, we give it a bogus result value but a real
5072*9880d681SAndroid Build Coastguard Worker       // chain result.  The result value is dead because the bswap is dead.
5073*9880d681SAndroid Build Coastguard Worker       DCI.CombineTo(Load.getNode(), ResVal, BSLoad.getValue(1));
5074*9880d681SAndroid Build Coastguard Worker 
5075*9880d681SAndroid Build Coastguard Worker       // Return N so it doesn't get rechecked!
5076*9880d681SAndroid Build Coastguard Worker       return SDValue(N, 0);
5077*9880d681SAndroid Build Coastguard Worker     }
5078*9880d681SAndroid Build Coastguard Worker   return SDValue();
5079*9880d681SAndroid Build Coastguard Worker }
5080*9880d681SAndroid Build Coastguard Worker 
combineSHIFTROT(SDNode * N,DAGCombinerInfo & DCI) const5081*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::combineSHIFTROT(
5082*9880d681SAndroid Build Coastguard Worker     SDNode *N, DAGCombinerInfo &DCI) const {
5083*9880d681SAndroid Build Coastguard Worker 
5084*9880d681SAndroid Build Coastguard Worker   SelectionDAG &DAG = DCI.DAG;
5085*9880d681SAndroid Build Coastguard Worker 
5086*9880d681SAndroid Build Coastguard Worker   // Shift/rotate instructions only use the last 6 bits of the second operand
5087*9880d681SAndroid Build Coastguard Worker   // register. If the second operand is the result of an AND with an immediate
5088*9880d681SAndroid Build Coastguard Worker   // value that has its last 6 bits set, we can safely remove the AND operation.
5089*9880d681SAndroid Build Coastguard Worker   SDValue N1 = N->getOperand(1);
5090*9880d681SAndroid Build Coastguard Worker   if (N1.getOpcode() == ISD::AND) {
5091*9880d681SAndroid Build Coastguard Worker     auto *AndMask = dyn_cast<ConstantSDNode>(N1.getOperand(1));
5092*9880d681SAndroid Build Coastguard Worker 
5093*9880d681SAndroid Build Coastguard Worker     // The AND mask is constant
5094*9880d681SAndroid Build Coastguard Worker     if (AndMask) {
5095*9880d681SAndroid Build Coastguard Worker       auto AmtVal = AndMask->getZExtValue();
5096*9880d681SAndroid Build Coastguard Worker 
5097*9880d681SAndroid Build Coastguard Worker       // Bottom 6 bits are set
5098*9880d681SAndroid Build Coastguard Worker       if ((AmtVal & 0x3f) == 0x3f) {
5099*9880d681SAndroid Build Coastguard Worker         SDValue AndOp = N1->getOperand(0);
5100*9880d681SAndroid Build Coastguard Worker 
5101*9880d681SAndroid Build Coastguard Worker         // This is the only use, so remove the node
5102*9880d681SAndroid Build Coastguard Worker         if (N1.hasOneUse()) {
5103*9880d681SAndroid Build Coastguard Worker           // Combine the AND away
5104*9880d681SAndroid Build Coastguard Worker           DCI.CombineTo(N1.getNode(), AndOp);
5105*9880d681SAndroid Build Coastguard Worker 
5106*9880d681SAndroid Build Coastguard Worker           // Return N so it isn't rechecked
5107*9880d681SAndroid Build Coastguard Worker           return SDValue(N, 0);
5108*9880d681SAndroid Build Coastguard Worker 
5109*9880d681SAndroid Build Coastguard Worker         // The node will be reused, so create a new node for this one use
5110*9880d681SAndroid Build Coastguard Worker         } else {
5111*9880d681SAndroid Build Coastguard Worker           SDValue Replace = DAG.getNode(N->getOpcode(), SDLoc(N),
5112*9880d681SAndroid Build Coastguard Worker                                         N->getValueType(0), N->getOperand(0),
5113*9880d681SAndroid Build Coastguard Worker                                         AndOp);
5114*9880d681SAndroid Build Coastguard Worker           DCI.AddToWorklist(Replace.getNode());
5115*9880d681SAndroid Build Coastguard Worker 
5116*9880d681SAndroid Build Coastguard Worker           return Replace;
5117*9880d681SAndroid Build Coastguard Worker         }
5118*9880d681SAndroid Build Coastguard Worker       }
5119*9880d681SAndroid Build Coastguard Worker     }
5120*9880d681SAndroid Build Coastguard Worker   }
5121*9880d681SAndroid Build Coastguard Worker 
5122*9880d681SAndroid Build Coastguard Worker   return SDValue();
5123*9880d681SAndroid Build Coastguard Worker }
5124*9880d681SAndroid Build Coastguard Worker 
PerformDAGCombine(SDNode * N,DAGCombinerInfo & DCI) const5125*9880d681SAndroid Build Coastguard Worker SDValue SystemZTargetLowering::PerformDAGCombine(SDNode *N,
5126*9880d681SAndroid Build Coastguard Worker                                                  DAGCombinerInfo &DCI) const {
5127*9880d681SAndroid Build Coastguard Worker   switch(N->getOpcode()) {
5128*9880d681SAndroid Build Coastguard Worker   default: break;
5129*9880d681SAndroid Build Coastguard Worker   case ISD::SIGN_EXTEND:        return combineSIGN_EXTEND(N, DCI);
5130*9880d681SAndroid Build Coastguard Worker   case SystemZISD::MERGE_HIGH:
5131*9880d681SAndroid Build Coastguard Worker   case SystemZISD::MERGE_LOW:   return combineMERGE(N, DCI);
5132*9880d681SAndroid Build Coastguard Worker   case ISD::STORE:              return combineSTORE(N, DCI);
5133*9880d681SAndroid Build Coastguard Worker   case ISD::EXTRACT_VECTOR_ELT: return combineEXTRACT_VECTOR_ELT(N, DCI);
5134*9880d681SAndroid Build Coastguard Worker   case SystemZISD::JOIN_DWORDS: return combineJOIN_DWORDS(N, DCI);
5135*9880d681SAndroid Build Coastguard Worker   case ISD::FP_ROUND:           return combineFP_ROUND(N, DCI);
5136*9880d681SAndroid Build Coastguard Worker   case ISD::BSWAP:              return combineBSWAP(N, DCI);
5137*9880d681SAndroid Build Coastguard Worker   case ISD::SHL:
5138*9880d681SAndroid Build Coastguard Worker   case ISD::SRA:
5139*9880d681SAndroid Build Coastguard Worker   case ISD::SRL:
5140*9880d681SAndroid Build Coastguard Worker   case ISD::ROTL:               return combineSHIFTROT(N, DCI);
5141*9880d681SAndroid Build Coastguard Worker   }
5142*9880d681SAndroid Build Coastguard Worker 
5143*9880d681SAndroid Build Coastguard Worker   return SDValue();
5144*9880d681SAndroid Build Coastguard Worker }
5145*9880d681SAndroid Build Coastguard Worker 
5146*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
5147*9880d681SAndroid Build Coastguard Worker // Custom insertion
5148*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
5149*9880d681SAndroid Build Coastguard Worker 
5150*9880d681SAndroid Build Coastguard Worker // Create a new basic block after MBB.
emitBlockAfter(MachineBasicBlock * MBB)5151*9880d681SAndroid Build Coastguard Worker static MachineBasicBlock *emitBlockAfter(MachineBasicBlock *MBB) {
5152*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB->getParent();
5153*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *NewMBB = MF.CreateMachineBasicBlock(MBB->getBasicBlock());
5154*9880d681SAndroid Build Coastguard Worker   MF.insert(std::next(MachineFunction::iterator(MBB)), NewMBB);
5155*9880d681SAndroid Build Coastguard Worker   return NewMBB;
5156*9880d681SAndroid Build Coastguard Worker }
5157*9880d681SAndroid Build Coastguard Worker 
5158*9880d681SAndroid Build Coastguard Worker // Split MBB after MI and return the new block (the one that contains
5159*9880d681SAndroid Build Coastguard Worker // instructions after MI).
splitBlockAfter(MachineBasicBlock::iterator MI,MachineBasicBlock * MBB)5160*9880d681SAndroid Build Coastguard Worker static MachineBasicBlock *splitBlockAfter(MachineBasicBlock::iterator MI,
5161*9880d681SAndroid Build Coastguard Worker                                           MachineBasicBlock *MBB) {
5162*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *NewMBB = emitBlockAfter(MBB);
5163*9880d681SAndroid Build Coastguard Worker   NewMBB->splice(NewMBB->begin(), MBB,
5164*9880d681SAndroid Build Coastguard Worker                  std::next(MachineBasicBlock::iterator(MI)), MBB->end());
5165*9880d681SAndroid Build Coastguard Worker   NewMBB->transferSuccessorsAndUpdatePHIs(MBB);
5166*9880d681SAndroid Build Coastguard Worker   return NewMBB;
5167*9880d681SAndroid Build Coastguard Worker }
5168*9880d681SAndroid Build Coastguard Worker 
5169*9880d681SAndroid Build Coastguard Worker // Split MBB before MI and return the new block (the one that contains MI).
splitBlockBefore(MachineBasicBlock::iterator MI,MachineBasicBlock * MBB)5170*9880d681SAndroid Build Coastguard Worker static MachineBasicBlock *splitBlockBefore(MachineBasicBlock::iterator MI,
5171*9880d681SAndroid Build Coastguard Worker                                            MachineBasicBlock *MBB) {
5172*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *NewMBB = emitBlockAfter(MBB);
5173*9880d681SAndroid Build Coastguard Worker   NewMBB->splice(NewMBB->begin(), MBB, MI, MBB->end());
5174*9880d681SAndroid Build Coastguard Worker   NewMBB->transferSuccessorsAndUpdatePHIs(MBB);
5175*9880d681SAndroid Build Coastguard Worker   return NewMBB;
5176*9880d681SAndroid Build Coastguard Worker }
5177*9880d681SAndroid Build Coastguard Worker 
5178*9880d681SAndroid Build Coastguard Worker // Force base value Base into a register before MI.  Return the register.
forceReg(MachineInstr & MI,MachineOperand & Base,const SystemZInstrInfo * TII)5179*9880d681SAndroid Build Coastguard Worker static unsigned forceReg(MachineInstr &MI, MachineOperand &Base,
5180*9880d681SAndroid Build Coastguard Worker                          const SystemZInstrInfo *TII) {
5181*9880d681SAndroid Build Coastguard Worker   if (Base.isReg())
5182*9880d681SAndroid Build Coastguard Worker     return Base.getReg();
5183*9880d681SAndroid Build Coastguard Worker 
5184*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *MBB = MI.getParent();
5185*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB->getParent();
5186*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo &MRI = MF.getRegInfo();
5187*9880d681SAndroid Build Coastguard Worker 
5188*9880d681SAndroid Build Coastguard Worker   unsigned Reg = MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
5189*9880d681SAndroid Build Coastguard Worker   BuildMI(*MBB, MI, MI.getDebugLoc(), TII->get(SystemZ::LA), Reg)
5190*9880d681SAndroid Build Coastguard Worker       .addOperand(Base)
5191*9880d681SAndroid Build Coastguard Worker       .addImm(0)
5192*9880d681SAndroid Build Coastguard Worker       .addReg(0);
5193*9880d681SAndroid Build Coastguard Worker   return Reg;
5194*9880d681SAndroid Build Coastguard Worker }
5195*9880d681SAndroid Build Coastguard Worker 
5196*9880d681SAndroid Build Coastguard Worker // Implement EmitInstrWithCustomInserter for pseudo Select* instruction MI.
5197*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *
emitSelect(MachineInstr & MI,MachineBasicBlock * MBB) const5198*9880d681SAndroid Build Coastguard Worker SystemZTargetLowering::emitSelect(MachineInstr &MI,
5199*9880d681SAndroid Build Coastguard Worker                                   MachineBasicBlock *MBB) const {
5200*9880d681SAndroid Build Coastguard Worker   const SystemZInstrInfo *TII =
5201*9880d681SAndroid Build Coastguard Worker       static_cast<const SystemZInstrInfo *>(Subtarget.getInstrInfo());
5202*9880d681SAndroid Build Coastguard Worker 
5203*9880d681SAndroid Build Coastguard Worker   unsigned DestReg = MI.getOperand(0).getReg();
5204*9880d681SAndroid Build Coastguard Worker   unsigned TrueReg = MI.getOperand(1).getReg();
5205*9880d681SAndroid Build Coastguard Worker   unsigned FalseReg = MI.getOperand(2).getReg();
5206*9880d681SAndroid Build Coastguard Worker   unsigned CCValid = MI.getOperand(3).getImm();
5207*9880d681SAndroid Build Coastguard Worker   unsigned CCMask = MI.getOperand(4).getImm();
5208*9880d681SAndroid Build Coastguard Worker   DebugLoc DL = MI.getDebugLoc();
5209*9880d681SAndroid Build Coastguard Worker 
5210*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *StartMBB = MBB;
5211*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *JoinMBB  = splitBlockBefore(MI, MBB);
5212*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *FalseMBB = emitBlockAfter(StartMBB);
5213*9880d681SAndroid Build Coastguard Worker 
5214*9880d681SAndroid Build Coastguard Worker   //  StartMBB:
5215*9880d681SAndroid Build Coastguard Worker   //   BRC CCMask, JoinMBB
5216*9880d681SAndroid Build Coastguard Worker   //   # fallthrough to FalseMBB
5217*9880d681SAndroid Build Coastguard Worker   MBB = StartMBB;
5218*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::BRC))
5219*9880d681SAndroid Build Coastguard Worker     .addImm(CCValid).addImm(CCMask).addMBB(JoinMBB);
5220*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(JoinMBB);
5221*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(FalseMBB);
5222*9880d681SAndroid Build Coastguard Worker 
5223*9880d681SAndroid Build Coastguard Worker   //  FalseMBB:
5224*9880d681SAndroid Build Coastguard Worker   //   # fallthrough to JoinMBB
5225*9880d681SAndroid Build Coastguard Worker   MBB = FalseMBB;
5226*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(JoinMBB);
5227*9880d681SAndroid Build Coastguard Worker 
5228*9880d681SAndroid Build Coastguard Worker   //  JoinMBB:
5229*9880d681SAndroid Build Coastguard Worker   //   %Result = phi [ %FalseReg, FalseMBB ], [ %TrueReg, StartMBB ]
5230*9880d681SAndroid Build Coastguard Worker   //  ...
5231*9880d681SAndroid Build Coastguard Worker   MBB = JoinMBB;
5232*9880d681SAndroid Build Coastguard Worker   BuildMI(*MBB, MI, DL, TII->get(SystemZ::PHI), DestReg)
5233*9880d681SAndroid Build Coastguard Worker     .addReg(TrueReg).addMBB(StartMBB)
5234*9880d681SAndroid Build Coastguard Worker     .addReg(FalseReg).addMBB(FalseMBB);
5235*9880d681SAndroid Build Coastguard Worker 
5236*9880d681SAndroid Build Coastguard Worker   MI.eraseFromParent();
5237*9880d681SAndroid Build Coastguard Worker   return JoinMBB;
5238*9880d681SAndroid Build Coastguard Worker }
5239*9880d681SAndroid Build Coastguard Worker 
5240*9880d681SAndroid Build Coastguard Worker // Implement EmitInstrWithCustomInserter for pseudo CondStore* instruction MI.
5241*9880d681SAndroid Build Coastguard Worker // StoreOpcode is the store to use and Invert says whether the store should
5242*9880d681SAndroid Build Coastguard Worker // happen when the condition is false rather than true.  If a STORE ON
5243*9880d681SAndroid Build Coastguard Worker // CONDITION is available, STOCOpcode is its opcode, otherwise it is 0.
emitCondStore(MachineInstr & MI,MachineBasicBlock * MBB,unsigned StoreOpcode,unsigned STOCOpcode,bool Invert) const5244*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *SystemZTargetLowering::emitCondStore(MachineInstr &MI,
5245*9880d681SAndroid Build Coastguard Worker                                                         MachineBasicBlock *MBB,
5246*9880d681SAndroid Build Coastguard Worker                                                         unsigned StoreOpcode,
5247*9880d681SAndroid Build Coastguard Worker                                                         unsigned STOCOpcode,
5248*9880d681SAndroid Build Coastguard Worker                                                         bool Invert) const {
5249*9880d681SAndroid Build Coastguard Worker   const SystemZInstrInfo *TII =
5250*9880d681SAndroid Build Coastguard Worker       static_cast<const SystemZInstrInfo *>(Subtarget.getInstrInfo());
5251*9880d681SAndroid Build Coastguard Worker 
5252*9880d681SAndroid Build Coastguard Worker   unsigned SrcReg = MI.getOperand(0).getReg();
5253*9880d681SAndroid Build Coastguard Worker   MachineOperand Base = MI.getOperand(1);
5254*9880d681SAndroid Build Coastguard Worker   int64_t Disp = MI.getOperand(2).getImm();
5255*9880d681SAndroid Build Coastguard Worker   unsigned IndexReg = MI.getOperand(3).getReg();
5256*9880d681SAndroid Build Coastguard Worker   unsigned CCValid = MI.getOperand(4).getImm();
5257*9880d681SAndroid Build Coastguard Worker   unsigned CCMask = MI.getOperand(5).getImm();
5258*9880d681SAndroid Build Coastguard Worker   DebugLoc DL = MI.getDebugLoc();
5259*9880d681SAndroid Build Coastguard Worker 
5260*9880d681SAndroid Build Coastguard Worker   StoreOpcode = TII->getOpcodeForOffset(StoreOpcode, Disp);
5261*9880d681SAndroid Build Coastguard Worker 
5262*9880d681SAndroid Build Coastguard Worker   // Use STOCOpcode if possible.  We could use different store patterns in
5263*9880d681SAndroid Build Coastguard Worker   // order to avoid matching the index register, but the performance trade-offs
5264*9880d681SAndroid Build Coastguard Worker   // might be more complicated in that case.
5265*9880d681SAndroid Build Coastguard Worker   if (STOCOpcode && !IndexReg && Subtarget.hasLoadStoreOnCond()) {
5266*9880d681SAndroid Build Coastguard Worker     if (Invert)
5267*9880d681SAndroid Build Coastguard Worker       CCMask ^= CCValid;
5268*9880d681SAndroid Build Coastguard Worker     BuildMI(*MBB, MI, DL, TII->get(STOCOpcode))
5269*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg).addOperand(Base).addImm(Disp)
5270*9880d681SAndroid Build Coastguard Worker       .addImm(CCValid).addImm(CCMask);
5271*9880d681SAndroid Build Coastguard Worker     MI.eraseFromParent();
5272*9880d681SAndroid Build Coastguard Worker     return MBB;
5273*9880d681SAndroid Build Coastguard Worker   }
5274*9880d681SAndroid Build Coastguard Worker 
5275*9880d681SAndroid Build Coastguard Worker   // Get the condition needed to branch around the store.
5276*9880d681SAndroid Build Coastguard Worker   if (!Invert)
5277*9880d681SAndroid Build Coastguard Worker     CCMask ^= CCValid;
5278*9880d681SAndroid Build Coastguard Worker 
5279*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *StartMBB = MBB;
5280*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *JoinMBB  = splitBlockBefore(MI, MBB);
5281*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *FalseMBB = emitBlockAfter(StartMBB);
5282*9880d681SAndroid Build Coastguard Worker 
5283*9880d681SAndroid Build Coastguard Worker   //  StartMBB:
5284*9880d681SAndroid Build Coastguard Worker   //   BRC CCMask, JoinMBB
5285*9880d681SAndroid Build Coastguard Worker   //   # fallthrough to FalseMBB
5286*9880d681SAndroid Build Coastguard Worker   MBB = StartMBB;
5287*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::BRC))
5288*9880d681SAndroid Build Coastguard Worker     .addImm(CCValid).addImm(CCMask).addMBB(JoinMBB);
5289*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(JoinMBB);
5290*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(FalseMBB);
5291*9880d681SAndroid Build Coastguard Worker 
5292*9880d681SAndroid Build Coastguard Worker   //  FalseMBB:
5293*9880d681SAndroid Build Coastguard Worker   //   store %SrcReg, %Disp(%Index,%Base)
5294*9880d681SAndroid Build Coastguard Worker   //   # fallthrough to JoinMBB
5295*9880d681SAndroid Build Coastguard Worker   MBB = FalseMBB;
5296*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(StoreOpcode))
5297*9880d681SAndroid Build Coastguard Worker     .addReg(SrcReg).addOperand(Base).addImm(Disp).addReg(IndexReg);
5298*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(JoinMBB);
5299*9880d681SAndroid Build Coastguard Worker 
5300*9880d681SAndroid Build Coastguard Worker   MI.eraseFromParent();
5301*9880d681SAndroid Build Coastguard Worker   return JoinMBB;
5302*9880d681SAndroid Build Coastguard Worker }
5303*9880d681SAndroid Build Coastguard Worker 
5304*9880d681SAndroid Build Coastguard Worker // Implement EmitInstrWithCustomInserter for pseudo ATOMIC_LOAD{,W}_*
5305*9880d681SAndroid Build Coastguard Worker // or ATOMIC_SWAP{,W} instruction MI.  BinOpcode is the instruction that
5306*9880d681SAndroid Build Coastguard Worker // performs the binary operation elided by "*", or 0 for ATOMIC_SWAP{,W}.
5307*9880d681SAndroid Build Coastguard Worker // BitSize is the width of the field in bits, or 0 if this is a partword
5308*9880d681SAndroid Build Coastguard Worker // ATOMIC_LOADW_* or ATOMIC_SWAPW instruction, in which case the bitsize
5309*9880d681SAndroid Build Coastguard Worker // is one of the operands.  Invert says whether the field should be
5310*9880d681SAndroid Build Coastguard Worker // inverted after performing BinOpcode (e.g. for NAND).
emitAtomicLoadBinary(MachineInstr & MI,MachineBasicBlock * MBB,unsigned BinOpcode,unsigned BitSize,bool Invert) const5311*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *SystemZTargetLowering::emitAtomicLoadBinary(
5312*9880d681SAndroid Build Coastguard Worker     MachineInstr &MI, MachineBasicBlock *MBB, unsigned BinOpcode,
5313*9880d681SAndroid Build Coastguard Worker     unsigned BitSize, bool Invert) const {
5314*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB->getParent();
5315*9880d681SAndroid Build Coastguard Worker   const SystemZInstrInfo *TII =
5316*9880d681SAndroid Build Coastguard Worker       static_cast<const SystemZInstrInfo *>(Subtarget.getInstrInfo());
5317*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo &MRI = MF.getRegInfo();
5318*9880d681SAndroid Build Coastguard Worker   bool IsSubWord = (BitSize < 32);
5319*9880d681SAndroid Build Coastguard Worker 
5320*9880d681SAndroid Build Coastguard Worker   // Extract the operands.  Base can be a register or a frame index.
5321*9880d681SAndroid Build Coastguard Worker   // Src2 can be a register or immediate.
5322*9880d681SAndroid Build Coastguard Worker   unsigned Dest = MI.getOperand(0).getReg();
5323*9880d681SAndroid Build Coastguard Worker   MachineOperand Base = earlyUseOperand(MI.getOperand(1));
5324*9880d681SAndroid Build Coastguard Worker   int64_t Disp = MI.getOperand(2).getImm();
5325*9880d681SAndroid Build Coastguard Worker   MachineOperand Src2 = earlyUseOperand(MI.getOperand(3));
5326*9880d681SAndroid Build Coastguard Worker   unsigned BitShift = (IsSubWord ? MI.getOperand(4).getReg() : 0);
5327*9880d681SAndroid Build Coastguard Worker   unsigned NegBitShift = (IsSubWord ? MI.getOperand(5).getReg() : 0);
5328*9880d681SAndroid Build Coastguard Worker   DebugLoc DL = MI.getDebugLoc();
5329*9880d681SAndroid Build Coastguard Worker   if (IsSubWord)
5330*9880d681SAndroid Build Coastguard Worker     BitSize = MI.getOperand(6).getImm();
5331*9880d681SAndroid Build Coastguard Worker 
5332*9880d681SAndroid Build Coastguard Worker   // Subword operations use 32-bit registers.
5333*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *RC = (BitSize <= 32 ?
5334*9880d681SAndroid Build Coastguard Worker                                    &SystemZ::GR32BitRegClass :
5335*9880d681SAndroid Build Coastguard Worker                                    &SystemZ::GR64BitRegClass);
5336*9880d681SAndroid Build Coastguard Worker   unsigned LOpcode  = BitSize <= 32 ? SystemZ::L  : SystemZ::LG;
5337*9880d681SAndroid Build Coastguard Worker   unsigned CSOpcode = BitSize <= 32 ? SystemZ::CS : SystemZ::CSG;
5338*9880d681SAndroid Build Coastguard Worker 
5339*9880d681SAndroid Build Coastguard Worker   // Get the right opcodes for the displacement.
5340*9880d681SAndroid Build Coastguard Worker   LOpcode  = TII->getOpcodeForOffset(LOpcode,  Disp);
5341*9880d681SAndroid Build Coastguard Worker   CSOpcode = TII->getOpcodeForOffset(CSOpcode, Disp);
5342*9880d681SAndroid Build Coastguard Worker   assert(LOpcode && CSOpcode && "Displacement out of range");
5343*9880d681SAndroid Build Coastguard Worker 
5344*9880d681SAndroid Build Coastguard Worker   // Create virtual registers for temporary results.
5345*9880d681SAndroid Build Coastguard Worker   unsigned OrigVal       = MRI.createVirtualRegister(RC);
5346*9880d681SAndroid Build Coastguard Worker   unsigned OldVal        = MRI.createVirtualRegister(RC);
5347*9880d681SAndroid Build Coastguard Worker   unsigned NewVal        = (BinOpcode || IsSubWord ?
5348*9880d681SAndroid Build Coastguard Worker                             MRI.createVirtualRegister(RC) : Src2.getReg());
5349*9880d681SAndroid Build Coastguard Worker   unsigned RotatedOldVal = (IsSubWord ? MRI.createVirtualRegister(RC) : OldVal);
5350*9880d681SAndroid Build Coastguard Worker   unsigned RotatedNewVal = (IsSubWord ? MRI.createVirtualRegister(RC) : NewVal);
5351*9880d681SAndroid Build Coastguard Worker 
5352*9880d681SAndroid Build Coastguard Worker   // Insert a basic block for the main loop.
5353*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *StartMBB = MBB;
5354*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *DoneMBB  = splitBlockBefore(MI, MBB);
5355*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *LoopMBB  = emitBlockAfter(StartMBB);
5356*9880d681SAndroid Build Coastguard Worker 
5357*9880d681SAndroid Build Coastguard Worker   //  StartMBB:
5358*9880d681SAndroid Build Coastguard Worker   //   ...
5359*9880d681SAndroid Build Coastguard Worker   //   %OrigVal = L Disp(%Base)
5360*9880d681SAndroid Build Coastguard Worker   //   # fall through to LoopMMB
5361*9880d681SAndroid Build Coastguard Worker   MBB = StartMBB;
5362*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(LOpcode), OrigVal)
5363*9880d681SAndroid Build Coastguard Worker     .addOperand(Base).addImm(Disp).addReg(0);
5364*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(LoopMBB);
5365*9880d681SAndroid Build Coastguard Worker 
5366*9880d681SAndroid Build Coastguard Worker   //  LoopMBB:
5367*9880d681SAndroid Build Coastguard Worker   //   %OldVal        = phi [ %OrigVal, StartMBB ], [ %Dest, LoopMBB ]
5368*9880d681SAndroid Build Coastguard Worker   //   %RotatedOldVal = RLL %OldVal, 0(%BitShift)
5369*9880d681SAndroid Build Coastguard Worker   //   %RotatedNewVal = OP %RotatedOldVal, %Src2
5370*9880d681SAndroid Build Coastguard Worker   //   %NewVal        = RLL %RotatedNewVal, 0(%NegBitShift)
5371*9880d681SAndroid Build Coastguard Worker   //   %Dest          = CS %OldVal, %NewVal, Disp(%Base)
5372*9880d681SAndroid Build Coastguard Worker   //   JNE LoopMBB
5373*9880d681SAndroid Build Coastguard Worker   //   # fall through to DoneMMB
5374*9880d681SAndroid Build Coastguard Worker   MBB = LoopMBB;
5375*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::PHI), OldVal)
5376*9880d681SAndroid Build Coastguard Worker     .addReg(OrigVal).addMBB(StartMBB)
5377*9880d681SAndroid Build Coastguard Worker     .addReg(Dest).addMBB(LoopMBB);
5378*9880d681SAndroid Build Coastguard Worker   if (IsSubWord)
5379*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, DL, TII->get(SystemZ::RLL), RotatedOldVal)
5380*9880d681SAndroid Build Coastguard Worker       .addReg(OldVal).addReg(BitShift).addImm(0);
5381*9880d681SAndroid Build Coastguard Worker   if (Invert) {
5382*9880d681SAndroid Build Coastguard Worker     // Perform the operation normally and then invert every bit of the field.
5383*9880d681SAndroid Build Coastguard Worker     unsigned Tmp = MRI.createVirtualRegister(RC);
5384*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, DL, TII->get(BinOpcode), Tmp)
5385*9880d681SAndroid Build Coastguard Worker       .addReg(RotatedOldVal).addOperand(Src2);
5386*9880d681SAndroid Build Coastguard Worker     if (BitSize <= 32)
5387*9880d681SAndroid Build Coastguard Worker       // XILF with the upper BitSize bits set.
5388*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, DL, TII->get(SystemZ::XILF), RotatedNewVal)
5389*9880d681SAndroid Build Coastguard Worker         .addReg(Tmp).addImm(-1U << (32 - BitSize));
5390*9880d681SAndroid Build Coastguard Worker     else {
5391*9880d681SAndroid Build Coastguard Worker       // Use LCGR and add -1 to the result, which is more compact than
5392*9880d681SAndroid Build Coastguard Worker       // an XILF, XILH pair.
5393*9880d681SAndroid Build Coastguard Worker       unsigned Tmp2 = MRI.createVirtualRegister(RC);
5394*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, DL, TII->get(SystemZ::LCGR), Tmp2).addReg(Tmp);
5395*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, DL, TII->get(SystemZ::AGHI), RotatedNewVal)
5396*9880d681SAndroid Build Coastguard Worker         .addReg(Tmp2).addImm(-1);
5397*9880d681SAndroid Build Coastguard Worker     }
5398*9880d681SAndroid Build Coastguard Worker   } else if (BinOpcode)
5399*9880d681SAndroid Build Coastguard Worker     // A simply binary operation.
5400*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, DL, TII->get(BinOpcode), RotatedNewVal)
5401*9880d681SAndroid Build Coastguard Worker       .addReg(RotatedOldVal).addOperand(Src2);
5402*9880d681SAndroid Build Coastguard Worker   else if (IsSubWord)
5403*9880d681SAndroid Build Coastguard Worker     // Use RISBG to rotate Src2 into position and use it to replace the
5404*9880d681SAndroid Build Coastguard Worker     // field in RotatedOldVal.
5405*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, DL, TII->get(SystemZ::RISBG32), RotatedNewVal)
5406*9880d681SAndroid Build Coastguard Worker       .addReg(RotatedOldVal).addReg(Src2.getReg())
5407*9880d681SAndroid Build Coastguard Worker       .addImm(32).addImm(31 + BitSize).addImm(32 - BitSize);
5408*9880d681SAndroid Build Coastguard Worker   if (IsSubWord)
5409*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, DL, TII->get(SystemZ::RLL), NewVal)
5410*9880d681SAndroid Build Coastguard Worker       .addReg(RotatedNewVal).addReg(NegBitShift).addImm(0);
5411*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(CSOpcode), Dest)
5412*9880d681SAndroid Build Coastguard Worker     .addReg(OldVal).addReg(NewVal).addOperand(Base).addImm(Disp);
5413*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::BRC))
5414*9880d681SAndroid Build Coastguard Worker     .addImm(SystemZ::CCMASK_CS).addImm(SystemZ::CCMASK_CS_NE).addMBB(LoopMBB);
5415*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(LoopMBB);
5416*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(DoneMBB);
5417*9880d681SAndroid Build Coastguard Worker 
5418*9880d681SAndroid Build Coastguard Worker   MI.eraseFromParent();
5419*9880d681SAndroid Build Coastguard Worker   return DoneMBB;
5420*9880d681SAndroid Build Coastguard Worker }
5421*9880d681SAndroid Build Coastguard Worker 
5422*9880d681SAndroid Build Coastguard Worker // Implement EmitInstrWithCustomInserter for pseudo
5423*9880d681SAndroid Build Coastguard Worker // ATOMIC_LOAD{,W}_{,U}{MIN,MAX} instruction MI.  CompareOpcode is the
5424*9880d681SAndroid Build Coastguard Worker // instruction that should be used to compare the current field with the
5425*9880d681SAndroid Build Coastguard Worker // minimum or maximum value.  KeepOldMask is the BRC condition-code mask
5426*9880d681SAndroid Build Coastguard Worker // for when the current field should be kept.  BitSize is the width of
5427*9880d681SAndroid Build Coastguard Worker // the field in bits, or 0 if this is a partword ATOMIC_LOADW_* instruction.
emitAtomicLoadMinMax(MachineInstr & MI,MachineBasicBlock * MBB,unsigned CompareOpcode,unsigned KeepOldMask,unsigned BitSize) const5428*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *SystemZTargetLowering::emitAtomicLoadMinMax(
5429*9880d681SAndroid Build Coastguard Worker     MachineInstr &MI, MachineBasicBlock *MBB, unsigned CompareOpcode,
5430*9880d681SAndroid Build Coastguard Worker     unsigned KeepOldMask, unsigned BitSize) const {
5431*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB->getParent();
5432*9880d681SAndroid Build Coastguard Worker   const SystemZInstrInfo *TII =
5433*9880d681SAndroid Build Coastguard Worker       static_cast<const SystemZInstrInfo *>(Subtarget.getInstrInfo());
5434*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo &MRI = MF.getRegInfo();
5435*9880d681SAndroid Build Coastguard Worker   bool IsSubWord = (BitSize < 32);
5436*9880d681SAndroid Build Coastguard Worker 
5437*9880d681SAndroid Build Coastguard Worker   // Extract the operands.  Base can be a register or a frame index.
5438*9880d681SAndroid Build Coastguard Worker   unsigned Dest = MI.getOperand(0).getReg();
5439*9880d681SAndroid Build Coastguard Worker   MachineOperand Base = earlyUseOperand(MI.getOperand(1));
5440*9880d681SAndroid Build Coastguard Worker   int64_t Disp = MI.getOperand(2).getImm();
5441*9880d681SAndroid Build Coastguard Worker   unsigned Src2 = MI.getOperand(3).getReg();
5442*9880d681SAndroid Build Coastguard Worker   unsigned BitShift = (IsSubWord ? MI.getOperand(4).getReg() : 0);
5443*9880d681SAndroid Build Coastguard Worker   unsigned NegBitShift = (IsSubWord ? MI.getOperand(5).getReg() : 0);
5444*9880d681SAndroid Build Coastguard Worker   DebugLoc DL = MI.getDebugLoc();
5445*9880d681SAndroid Build Coastguard Worker   if (IsSubWord)
5446*9880d681SAndroid Build Coastguard Worker     BitSize = MI.getOperand(6).getImm();
5447*9880d681SAndroid Build Coastguard Worker 
5448*9880d681SAndroid Build Coastguard Worker   // Subword operations use 32-bit registers.
5449*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *RC = (BitSize <= 32 ?
5450*9880d681SAndroid Build Coastguard Worker                                    &SystemZ::GR32BitRegClass :
5451*9880d681SAndroid Build Coastguard Worker                                    &SystemZ::GR64BitRegClass);
5452*9880d681SAndroid Build Coastguard Worker   unsigned LOpcode  = BitSize <= 32 ? SystemZ::L  : SystemZ::LG;
5453*9880d681SAndroid Build Coastguard Worker   unsigned CSOpcode = BitSize <= 32 ? SystemZ::CS : SystemZ::CSG;
5454*9880d681SAndroid Build Coastguard Worker 
5455*9880d681SAndroid Build Coastguard Worker   // Get the right opcodes for the displacement.
5456*9880d681SAndroid Build Coastguard Worker   LOpcode  = TII->getOpcodeForOffset(LOpcode,  Disp);
5457*9880d681SAndroid Build Coastguard Worker   CSOpcode = TII->getOpcodeForOffset(CSOpcode, Disp);
5458*9880d681SAndroid Build Coastguard Worker   assert(LOpcode && CSOpcode && "Displacement out of range");
5459*9880d681SAndroid Build Coastguard Worker 
5460*9880d681SAndroid Build Coastguard Worker   // Create virtual registers for temporary results.
5461*9880d681SAndroid Build Coastguard Worker   unsigned OrigVal       = MRI.createVirtualRegister(RC);
5462*9880d681SAndroid Build Coastguard Worker   unsigned OldVal        = MRI.createVirtualRegister(RC);
5463*9880d681SAndroid Build Coastguard Worker   unsigned NewVal        = MRI.createVirtualRegister(RC);
5464*9880d681SAndroid Build Coastguard Worker   unsigned RotatedOldVal = (IsSubWord ? MRI.createVirtualRegister(RC) : OldVal);
5465*9880d681SAndroid Build Coastguard Worker   unsigned RotatedAltVal = (IsSubWord ? MRI.createVirtualRegister(RC) : Src2);
5466*9880d681SAndroid Build Coastguard Worker   unsigned RotatedNewVal = (IsSubWord ? MRI.createVirtualRegister(RC) : NewVal);
5467*9880d681SAndroid Build Coastguard Worker 
5468*9880d681SAndroid Build Coastguard Worker   // Insert 3 basic blocks for the loop.
5469*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *StartMBB  = MBB;
5470*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *DoneMBB   = splitBlockBefore(MI, MBB);
5471*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *LoopMBB   = emitBlockAfter(StartMBB);
5472*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *UseAltMBB = emitBlockAfter(LoopMBB);
5473*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *UpdateMBB = emitBlockAfter(UseAltMBB);
5474*9880d681SAndroid Build Coastguard Worker 
5475*9880d681SAndroid Build Coastguard Worker   //  StartMBB:
5476*9880d681SAndroid Build Coastguard Worker   //   ...
5477*9880d681SAndroid Build Coastguard Worker   //   %OrigVal     = L Disp(%Base)
5478*9880d681SAndroid Build Coastguard Worker   //   # fall through to LoopMMB
5479*9880d681SAndroid Build Coastguard Worker   MBB = StartMBB;
5480*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(LOpcode), OrigVal)
5481*9880d681SAndroid Build Coastguard Worker     .addOperand(Base).addImm(Disp).addReg(0);
5482*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(LoopMBB);
5483*9880d681SAndroid Build Coastguard Worker 
5484*9880d681SAndroid Build Coastguard Worker   //  LoopMBB:
5485*9880d681SAndroid Build Coastguard Worker   //   %OldVal        = phi [ %OrigVal, StartMBB ], [ %Dest, UpdateMBB ]
5486*9880d681SAndroid Build Coastguard Worker   //   %RotatedOldVal = RLL %OldVal, 0(%BitShift)
5487*9880d681SAndroid Build Coastguard Worker   //   CompareOpcode %RotatedOldVal, %Src2
5488*9880d681SAndroid Build Coastguard Worker   //   BRC KeepOldMask, UpdateMBB
5489*9880d681SAndroid Build Coastguard Worker   MBB = LoopMBB;
5490*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::PHI), OldVal)
5491*9880d681SAndroid Build Coastguard Worker     .addReg(OrigVal).addMBB(StartMBB)
5492*9880d681SAndroid Build Coastguard Worker     .addReg(Dest).addMBB(UpdateMBB);
5493*9880d681SAndroid Build Coastguard Worker   if (IsSubWord)
5494*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, DL, TII->get(SystemZ::RLL), RotatedOldVal)
5495*9880d681SAndroid Build Coastguard Worker       .addReg(OldVal).addReg(BitShift).addImm(0);
5496*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(CompareOpcode))
5497*9880d681SAndroid Build Coastguard Worker     .addReg(RotatedOldVal).addReg(Src2);
5498*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::BRC))
5499*9880d681SAndroid Build Coastguard Worker     .addImm(SystemZ::CCMASK_ICMP).addImm(KeepOldMask).addMBB(UpdateMBB);
5500*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(UpdateMBB);
5501*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(UseAltMBB);
5502*9880d681SAndroid Build Coastguard Worker 
5503*9880d681SAndroid Build Coastguard Worker   //  UseAltMBB:
5504*9880d681SAndroid Build Coastguard Worker   //   %RotatedAltVal = RISBG %RotatedOldVal, %Src2, 32, 31 + BitSize, 0
5505*9880d681SAndroid Build Coastguard Worker   //   # fall through to UpdateMMB
5506*9880d681SAndroid Build Coastguard Worker   MBB = UseAltMBB;
5507*9880d681SAndroid Build Coastguard Worker   if (IsSubWord)
5508*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, DL, TII->get(SystemZ::RISBG32), RotatedAltVal)
5509*9880d681SAndroid Build Coastguard Worker       .addReg(RotatedOldVal).addReg(Src2)
5510*9880d681SAndroid Build Coastguard Worker       .addImm(32).addImm(31 + BitSize).addImm(0);
5511*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(UpdateMBB);
5512*9880d681SAndroid Build Coastguard Worker 
5513*9880d681SAndroid Build Coastguard Worker   //  UpdateMBB:
5514*9880d681SAndroid Build Coastguard Worker   //   %RotatedNewVal = PHI [ %RotatedOldVal, LoopMBB ],
5515*9880d681SAndroid Build Coastguard Worker   //                        [ %RotatedAltVal, UseAltMBB ]
5516*9880d681SAndroid Build Coastguard Worker   //   %NewVal        = RLL %RotatedNewVal, 0(%NegBitShift)
5517*9880d681SAndroid Build Coastguard Worker   //   %Dest          = CS %OldVal, %NewVal, Disp(%Base)
5518*9880d681SAndroid Build Coastguard Worker   //   JNE LoopMBB
5519*9880d681SAndroid Build Coastguard Worker   //   # fall through to DoneMMB
5520*9880d681SAndroid Build Coastguard Worker   MBB = UpdateMBB;
5521*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::PHI), RotatedNewVal)
5522*9880d681SAndroid Build Coastguard Worker     .addReg(RotatedOldVal).addMBB(LoopMBB)
5523*9880d681SAndroid Build Coastguard Worker     .addReg(RotatedAltVal).addMBB(UseAltMBB);
5524*9880d681SAndroid Build Coastguard Worker   if (IsSubWord)
5525*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, DL, TII->get(SystemZ::RLL), NewVal)
5526*9880d681SAndroid Build Coastguard Worker       .addReg(RotatedNewVal).addReg(NegBitShift).addImm(0);
5527*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(CSOpcode), Dest)
5528*9880d681SAndroid Build Coastguard Worker     .addReg(OldVal).addReg(NewVal).addOperand(Base).addImm(Disp);
5529*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::BRC))
5530*9880d681SAndroid Build Coastguard Worker     .addImm(SystemZ::CCMASK_CS).addImm(SystemZ::CCMASK_CS_NE).addMBB(LoopMBB);
5531*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(LoopMBB);
5532*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(DoneMBB);
5533*9880d681SAndroid Build Coastguard Worker 
5534*9880d681SAndroid Build Coastguard Worker   MI.eraseFromParent();
5535*9880d681SAndroid Build Coastguard Worker   return DoneMBB;
5536*9880d681SAndroid Build Coastguard Worker }
5537*9880d681SAndroid Build Coastguard Worker 
5538*9880d681SAndroid Build Coastguard Worker // Implement EmitInstrWithCustomInserter for pseudo ATOMIC_CMP_SWAPW
5539*9880d681SAndroid Build Coastguard Worker // instruction MI.
5540*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *
emitAtomicCmpSwapW(MachineInstr & MI,MachineBasicBlock * MBB) const5541*9880d681SAndroid Build Coastguard Worker SystemZTargetLowering::emitAtomicCmpSwapW(MachineInstr &MI,
5542*9880d681SAndroid Build Coastguard Worker                                           MachineBasicBlock *MBB) const {
5543*9880d681SAndroid Build Coastguard Worker 
5544*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB->getParent();
5545*9880d681SAndroid Build Coastguard Worker   const SystemZInstrInfo *TII =
5546*9880d681SAndroid Build Coastguard Worker       static_cast<const SystemZInstrInfo *>(Subtarget.getInstrInfo());
5547*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo &MRI = MF.getRegInfo();
5548*9880d681SAndroid Build Coastguard Worker 
5549*9880d681SAndroid Build Coastguard Worker   // Extract the operands.  Base can be a register or a frame index.
5550*9880d681SAndroid Build Coastguard Worker   unsigned Dest = MI.getOperand(0).getReg();
5551*9880d681SAndroid Build Coastguard Worker   MachineOperand Base = earlyUseOperand(MI.getOperand(1));
5552*9880d681SAndroid Build Coastguard Worker   int64_t Disp = MI.getOperand(2).getImm();
5553*9880d681SAndroid Build Coastguard Worker   unsigned OrigCmpVal = MI.getOperand(3).getReg();
5554*9880d681SAndroid Build Coastguard Worker   unsigned OrigSwapVal = MI.getOperand(4).getReg();
5555*9880d681SAndroid Build Coastguard Worker   unsigned BitShift = MI.getOperand(5).getReg();
5556*9880d681SAndroid Build Coastguard Worker   unsigned NegBitShift = MI.getOperand(6).getReg();
5557*9880d681SAndroid Build Coastguard Worker   int64_t BitSize = MI.getOperand(7).getImm();
5558*9880d681SAndroid Build Coastguard Worker   DebugLoc DL = MI.getDebugLoc();
5559*9880d681SAndroid Build Coastguard Worker 
5560*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *RC = &SystemZ::GR32BitRegClass;
5561*9880d681SAndroid Build Coastguard Worker 
5562*9880d681SAndroid Build Coastguard Worker   // Get the right opcodes for the displacement.
5563*9880d681SAndroid Build Coastguard Worker   unsigned LOpcode  = TII->getOpcodeForOffset(SystemZ::L,  Disp);
5564*9880d681SAndroid Build Coastguard Worker   unsigned CSOpcode = TII->getOpcodeForOffset(SystemZ::CS, Disp);
5565*9880d681SAndroid Build Coastguard Worker   assert(LOpcode && CSOpcode && "Displacement out of range");
5566*9880d681SAndroid Build Coastguard Worker 
5567*9880d681SAndroid Build Coastguard Worker   // Create virtual registers for temporary results.
5568*9880d681SAndroid Build Coastguard Worker   unsigned OrigOldVal   = MRI.createVirtualRegister(RC);
5569*9880d681SAndroid Build Coastguard Worker   unsigned OldVal       = MRI.createVirtualRegister(RC);
5570*9880d681SAndroid Build Coastguard Worker   unsigned CmpVal       = MRI.createVirtualRegister(RC);
5571*9880d681SAndroid Build Coastguard Worker   unsigned SwapVal      = MRI.createVirtualRegister(RC);
5572*9880d681SAndroid Build Coastguard Worker   unsigned StoreVal     = MRI.createVirtualRegister(RC);
5573*9880d681SAndroid Build Coastguard Worker   unsigned RetryOldVal  = MRI.createVirtualRegister(RC);
5574*9880d681SAndroid Build Coastguard Worker   unsigned RetryCmpVal  = MRI.createVirtualRegister(RC);
5575*9880d681SAndroid Build Coastguard Worker   unsigned RetrySwapVal = MRI.createVirtualRegister(RC);
5576*9880d681SAndroid Build Coastguard Worker 
5577*9880d681SAndroid Build Coastguard Worker   // Insert 2 basic blocks for the loop.
5578*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *StartMBB = MBB;
5579*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *DoneMBB  = splitBlockBefore(MI, MBB);
5580*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *LoopMBB  = emitBlockAfter(StartMBB);
5581*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *SetMBB   = emitBlockAfter(LoopMBB);
5582*9880d681SAndroid Build Coastguard Worker 
5583*9880d681SAndroid Build Coastguard Worker   //  StartMBB:
5584*9880d681SAndroid Build Coastguard Worker   //   ...
5585*9880d681SAndroid Build Coastguard Worker   //   %OrigOldVal     = L Disp(%Base)
5586*9880d681SAndroid Build Coastguard Worker   //   # fall through to LoopMMB
5587*9880d681SAndroid Build Coastguard Worker   MBB = StartMBB;
5588*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(LOpcode), OrigOldVal)
5589*9880d681SAndroid Build Coastguard Worker     .addOperand(Base).addImm(Disp).addReg(0);
5590*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(LoopMBB);
5591*9880d681SAndroid Build Coastguard Worker 
5592*9880d681SAndroid Build Coastguard Worker   //  LoopMBB:
5593*9880d681SAndroid Build Coastguard Worker   //   %OldVal        = phi [ %OrigOldVal, EntryBB ], [ %RetryOldVal, SetMBB ]
5594*9880d681SAndroid Build Coastguard Worker   //   %CmpVal        = phi [ %OrigCmpVal, EntryBB ], [ %RetryCmpVal, SetMBB ]
5595*9880d681SAndroid Build Coastguard Worker   //   %SwapVal       = phi [ %OrigSwapVal, EntryBB ], [ %RetrySwapVal, SetMBB ]
5596*9880d681SAndroid Build Coastguard Worker   //   %Dest          = RLL %OldVal, BitSize(%BitShift)
5597*9880d681SAndroid Build Coastguard Worker   //                      ^^ The low BitSize bits contain the field
5598*9880d681SAndroid Build Coastguard Worker   //                         of interest.
5599*9880d681SAndroid Build Coastguard Worker   //   %RetryCmpVal   = RISBG32 %CmpVal, %Dest, 32, 63-BitSize, 0
5600*9880d681SAndroid Build Coastguard Worker   //                      ^^ Replace the upper 32-BitSize bits of the
5601*9880d681SAndroid Build Coastguard Worker   //                         comparison value with those that we loaded,
5602*9880d681SAndroid Build Coastguard Worker   //                         so that we can use a full word comparison.
5603*9880d681SAndroid Build Coastguard Worker   //   CR %Dest, %RetryCmpVal
5604*9880d681SAndroid Build Coastguard Worker   //   JNE DoneMBB
5605*9880d681SAndroid Build Coastguard Worker   //   # Fall through to SetMBB
5606*9880d681SAndroid Build Coastguard Worker   MBB = LoopMBB;
5607*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::PHI), OldVal)
5608*9880d681SAndroid Build Coastguard Worker     .addReg(OrigOldVal).addMBB(StartMBB)
5609*9880d681SAndroid Build Coastguard Worker     .addReg(RetryOldVal).addMBB(SetMBB);
5610*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::PHI), CmpVal)
5611*9880d681SAndroid Build Coastguard Worker     .addReg(OrigCmpVal).addMBB(StartMBB)
5612*9880d681SAndroid Build Coastguard Worker     .addReg(RetryCmpVal).addMBB(SetMBB);
5613*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::PHI), SwapVal)
5614*9880d681SAndroid Build Coastguard Worker     .addReg(OrigSwapVal).addMBB(StartMBB)
5615*9880d681SAndroid Build Coastguard Worker     .addReg(RetrySwapVal).addMBB(SetMBB);
5616*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::RLL), Dest)
5617*9880d681SAndroid Build Coastguard Worker     .addReg(OldVal).addReg(BitShift).addImm(BitSize);
5618*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::RISBG32), RetryCmpVal)
5619*9880d681SAndroid Build Coastguard Worker     .addReg(CmpVal).addReg(Dest).addImm(32).addImm(63 - BitSize).addImm(0);
5620*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::CR))
5621*9880d681SAndroid Build Coastguard Worker     .addReg(Dest).addReg(RetryCmpVal);
5622*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::BRC))
5623*9880d681SAndroid Build Coastguard Worker     .addImm(SystemZ::CCMASK_ICMP)
5624*9880d681SAndroid Build Coastguard Worker     .addImm(SystemZ::CCMASK_CMP_NE).addMBB(DoneMBB);
5625*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(DoneMBB);
5626*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(SetMBB);
5627*9880d681SAndroid Build Coastguard Worker 
5628*9880d681SAndroid Build Coastguard Worker   //  SetMBB:
5629*9880d681SAndroid Build Coastguard Worker   //   %RetrySwapVal = RISBG32 %SwapVal, %Dest, 32, 63-BitSize, 0
5630*9880d681SAndroid Build Coastguard Worker   //                      ^^ Replace the upper 32-BitSize bits of the new
5631*9880d681SAndroid Build Coastguard Worker   //                         value with those that we loaded.
5632*9880d681SAndroid Build Coastguard Worker   //   %StoreVal    = RLL %RetrySwapVal, -BitSize(%NegBitShift)
5633*9880d681SAndroid Build Coastguard Worker   //                      ^^ Rotate the new field to its proper position.
5634*9880d681SAndroid Build Coastguard Worker   //   %RetryOldVal = CS %Dest, %StoreVal, Disp(%Base)
5635*9880d681SAndroid Build Coastguard Worker   //   JNE LoopMBB
5636*9880d681SAndroid Build Coastguard Worker   //   # fall through to ExitMMB
5637*9880d681SAndroid Build Coastguard Worker   MBB = SetMBB;
5638*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::RISBG32), RetrySwapVal)
5639*9880d681SAndroid Build Coastguard Worker     .addReg(SwapVal).addReg(Dest).addImm(32).addImm(63 - BitSize).addImm(0);
5640*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::RLL), StoreVal)
5641*9880d681SAndroid Build Coastguard Worker     .addReg(RetrySwapVal).addReg(NegBitShift).addImm(-BitSize);
5642*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(CSOpcode), RetryOldVal)
5643*9880d681SAndroid Build Coastguard Worker     .addReg(OldVal).addReg(StoreVal).addOperand(Base).addImm(Disp);
5644*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::BRC))
5645*9880d681SAndroid Build Coastguard Worker     .addImm(SystemZ::CCMASK_CS).addImm(SystemZ::CCMASK_CS_NE).addMBB(LoopMBB);
5646*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(LoopMBB);
5647*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(DoneMBB);
5648*9880d681SAndroid Build Coastguard Worker 
5649*9880d681SAndroid Build Coastguard Worker   MI.eraseFromParent();
5650*9880d681SAndroid Build Coastguard Worker   return DoneMBB;
5651*9880d681SAndroid Build Coastguard Worker }
5652*9880d681SAndroid Build Coastguard Worker 
5653*9880d681SAndroid Build Coastguard Worker // Emit an extension from a GR32 or GR64 to a GR128.  ClearEven is true
5654*9880d681SAndroid Build Coastguard Worker // if the high register of the GR128 value must be cleared or false if
5655*9880d681SAndroid Build Coastguard Worker // it's "don't care".  SubReg is subreg_l32 when extending a GR32
5656*9880d681SAndroid Build Coastguard Worker // and subreg_l64 when extending a GR64.
emitExt128(MachineInstr & MI,MachineBasicBlock * MBB,bool ClearEven,unsigned SubReg) const5657*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *SystemZTargetLowering::emitExt128(MachineInstr &MI,
5658*9880d681SAndroid Build Coastguard Worker                                                      MachineBasicBlock *MBB,
5659*9880d681SAndroid Build Coastguard Worker                                                      bool ClearEven,
5660*9880d681SAndroid Build Coastguard Worker                                                      unsigned SubReg) const {
5661*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB->getParent();
5662*9880d681SAndroid Build Coastguard Worker   const SystemZInstrInfo *TII =
5663*9880d681SAndroid Build Coastguard Worker       static_cast<const SystemZInstrInfo *>(Subtarget.getInstrInfo());
5664*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo &MRI = MF.getRegInfo();
5665*9880d681SAndroid Build Coastguard Worker   DebugLoc DL = MI.getDebugLoc();
5666*9880d681SAndroid Build Coastguard Worker 
5667*9880d681SAndroid Build Coastguard Worker   unsigned Dest = MI.getOperand(0).getReg();
5668*9880d681SAndroid Build Coastguard Worker   unsigned Src = MI.getOperand(1).getReg();
5669*9880d681SAndroid Build Coastguard Worker   unsigned In128 = MRI.createVirtualRegister(&SystemZ::GR128BitRegClass);
5670*9880d681SAndroid Build Coastguard Worker 
5671*9880d681SAndroid Build Coastguard Worker   BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::IMPLICIT_DEF), In128);
5672*9880d681SAndroid Build Coastguard Worker   if (ClearEven) {
5673*9880d681SAndroid Build Coastguard Worker     unsigned NewIn128 = MRI.createVirtualRegister(&SystemZ::GR128BitRegClass);
5674*9880d681SAndroid Build Coastguard Worker     unsigned Zero64   = MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
5675*9880d681SAndroid Build Coastguard Worker 
5676*9880d681SAndroid Build Coastguard Worker     BuildMI(*MBB, MI, DL, TII->get(SystemZ::LLILL), Zero64)
5677*9880d681SAndroid Build Coastguard Worker       .addImm(0);
5678*9880d681SAndroid Build Coastguard Worker     BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::INSERT_SUBREG), NewIn128)
5679*9880d681SAndroid Build Coastguard Worker       .addReg(In128).addReg(Zero64).addImm(SystemZ::subreg_h64);
5680*9880d681SAndroid Build Coastguard Worker     In128 = NewIn128;
5681*9880d681SAndroid Build Coastguard Worker   }
5682*9880d681SAndroid Build Coastguard Worker   BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::INSERT_SUBREG), Dest)
5683*9880d681SAndroid Build Coastguard Worker     .addReg(In128).addReg(Src).addImm(SubReg);
5684*9880d681SAndroid Build Coastguard Worker 
5685*9880d681SAndroid Build Coastguard Worker   MI.eraseFromParent();
5686*9880d681SAndroid Build Coastguard Worker   return MBB;
5687*9880d681SAndroid Build Coastguard Worker }
5688*9880d681SAndroid Build Coastguard Worker 
emitMemMemWrapper(MachineInstr & MI,MachineBasicBlock * MBB,unsigned Opcode) const5689*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *SystemZTargetLowering::emitMemMemWrapper(
5690*9880d681SAndroid Build Coastguard Worker     MachineInstr &MI, MachineBasicBlock *MBB, unsigned Opcode) const {
5691*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB->getParent();
5692*9880d681SAndroid Build Coastguard Worker   const SystemZInstrInfo *TII =
5693*9880d681SAndroid Build Coastguard Worker       static_cast<const SystemZInstrInfo *>(Subtarget.getInstrInfo());
5694*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo &MRI = MF.getRegInfo();
5695*9880d681SAndroid Build Coastguard Worker   DebugLoc DL = MI.getDebugLoc();
5696*9880d681SAndroid Build Coastguard Worker 
5697*9880d681SAndroid Build Coastguard Worker   MachineOperand DestBase = earlyUseOperand(MI.getOperand(0));
5698*9880d681SAndroid Build Coastguard Worker   uint64_t DestDisp = MI.getOperand(1).getImm();
5699*9880d681SAndroid Build Coastguard Worker   MachineOperand SrcBase = earlyUseOperand(MI.getOperand(2));
5700*9880d681SAndroid Build Coastguard Worker   uint64_t SrcDisp = MI.getOperand(3).getImm();
5701*9880d681SAndroid Build Coastguard Worker   uint64_t Length = MI.getOperand(4).getImm();
5702*9880d681SAndroid Build Coastguard Worker 
5703*9880d681SAndroid Build Coastguard Worker   // When generating more than one CLC, all but the last will need to
5704*9880d681SAndroid Build Coastguard Worker   // branch to the end when a difference is found.
5705*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *EndMBB = (Length > 256 && Opcode == SystemZ::CLC ?
5706*9880d681SAndroid Build Coastguard Worker                                splitBlockAfter(MI, MBB) : nullptr);
5707*9880d681SAndroid Build Coastguard Worker 
5708*9880d681SAndroid Build Coastguard Worker   // Check for the loop form, in which operand 5 is the trip count.
5709*9880d681SAndroid Build Coastguard Worker   if (MI.getNumExplicitOperands() > 5) {
5710*9880d681SAndroid Build Coastguard Worker     bool HaveSingleBase = DestBase.isIdenticalTo(SrcBase);
5711*9880d681SAndroid Build Coastguard Worker 
5712*9880d681SAndroid Build Coastguard Worker     uint64_t StartCountReg = MI.getOperand(5).getReg();
5713*9880d681SAndroid Build Coastguard Worker     uint64_t StartSrcReg   = forceReg(MI, SrcBase, TII);
5714*9880d681SAndroid Build Coastguard Worker     uint64_t StartDestReg  = (HaveSingleBase ? StartSrcReg :
5715*9880d681SAndroid Build Coastguard Worker                               forceReg(MI, DestBase, TII));
5716*9880d681SAndroid Build Coastguard Worker 
5717*9880d681SAndroid Build Coastguard Worker     const TargetRegisterClass *RC = &SystemZ::ADDR64BitRegClass;
5718*9880d681SAndroid Build Coastguard Worker     uint64_t ThisSrcReg  = MRI.createVirtualRegister(RC);
5719*9880d681SAndroid Build Coastguard Worker     uint64_t ThisDestReg = (HaveSingleBase ? ThisSrcReg :
5720*9880d681SAndroid Build Coastguard Worker                             MRI.createVirtualRegister(RC));
5721*9880d681SAndroid Build Coastguard Worker     uint64_t NextSrcReg  = MRI.createVirtualRegister(RC);
5722*9880d681SAndroid Build Coastguard Worker     uint64_t NextDestReg = (HaveSingleBase ? NextSrcReg :
5723*9880d681SAndroid Build Coastguard Worker                             MRI.createVirtualRegister(RC));
5724*9880d681SAndroid Build Coastguard Worker 
5725*9880d681SAndroid Build Coastguard Worker     RC = &SystemZ::GR64BitRegClass;
5726*9880d681SAndroid Build Coastguard Worker     uint64_t ThisCountReg = MRI.createVirtualRegister(RC);
5727*9880d681SAndroid Build Coastguard Worker     uint64_t NextCountReg = MRI.createVirtualRegister(RC);
5728*9880d681SAndroid Build Coastguard Worker 
5729*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *StartMBB = MBB;
5730*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *DoneMBB = splitBlockBefore(MI, MBB);
5731*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *LoopMBB = emitBlockAfter(StartMBB);
5732*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *NextMBB = (EndMBB ? emitBlockAfter(LoopMBB) : LoopMBB);
5733*9880d681SAndroid Build Coastguard Worker 
5734*9880d681SAndroid Build Coastguard Worker     //  StartMBB:
5735*9880d681SAndroid Build Coastguard Worker     //   # fall through to LoopMMB
5736*9880d681SAndroid Build Coastguard Worker     MBB->addSuccessor(LoopMBB);
5737*9880d681SAndroid Build Coastguard Worker 
5738*9880d681SAndroid Build Coastguard Worker     //  LoopMBB:
5739*9880d681SAndroid Build Coastguard Worker     //   %ThisDestReg = phi [ %StartDestReg, StartMBB ],
5740*9880d681SAndroid Build Coastguard Worker     //                      [ %NextDestReg, NextMBB ]
5741*9880d681SAndroid Build Coastguard Worker     //   %ThisSrcReg = phi [ %StartSrcReg, StartMBB ],
5742*9880d681SAndroid Build Coastguard Worker     //                     [ %NextSrcReg, NextMBB ]
5743*9880d681SAndroid Build Coastguard Worker     //   %ThisCountReg = phi [ %StartCountReg, StartMBB ],
5744*9880d681SAndroid Build Coastguard Worker     //                       [ %NextCountReg, NextMBB ]
5745*9880d681SAndroid Build Coastguard Worker     //   ( PFD 2, 768+DestDisp(%ThisDestReg) )
5746*9880d681SAndroid Build Coastguard Worker     //   Opcode DestDisp(256,%ThisDestReg), SrcDisp(%ThisSrcReg)
5747*9880d681SAndroid Build Coastguard Worker     //   ( JLH EndMBB )
5748*9880d681SAndroid Build Coastguard Worker     //
5749*9880d681SAndroid Build Coastguard Worker     // The prefetch is used only for MVC.  The JLH is used only for CLC.
5750*9880d681SAndroid Build Coastguard Worker     MBB = LoopMBB;
5751*9880d681SAndroid Build Coastguard Worker 
5752*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, DL, TII->get(SystemZ::PHI), ThisDestReg)
5753*9880d681SAndroid Build Coastguard Worker       .addReg(StartDestReg).addMBB(StartMBB)
5754*9880d681SAndroid Build Coastguard Worker       .addReg(NextDestReg).addMBB(NextMBB);
5755*9880d681SAndroid Build Coastguard Worker     if (!HaveSingleBase)
5756*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, DL, TII->get(SystemZ::PHI), ThisSrcReg)
5757*9880d681SAndroid Build Coastguard Worker         .addReg(StartSrcReg).addMBB(StartMBB)
5758*9880d681SAndroid Build Coastguard Worker         .addReg(NextSrcReg).addMBB(NextMBB);
5759*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, DL, TII->get(SystemZ::PHI), ThisCountReg)
5760*9880d681SAndroid Build Coastguard Worker       .addReg(StartCountReg).addMBB(StartMBB)
5761*9880d681SAndroid Build Coastguard Worker       .addReg(NextCountReg).addMBB(NextMBB);
5762*9880d681SAndroid Build Coastguard Worker     if (Opcode == SystemZ::MVC)
5763*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, DL, TII->get(SystemZ::PFD))
5764*9880d681SAndroid Build Coastguard Worker         .addImm(SystemZ::PFD_WRITE)
5765*9880d681SAndroid Build Coastguard Worker         .addReg(ThisDestReg).addImm(DestDisp + 768).addReg(0);
5766*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, DL, TII->get(Opcode))
5767*9880d681SAndroid Build Coastguard Worker       .addReg(ThisDestReg).addImm(DestDisp).addImm(256)
5768*9880d681SAndroid Build Coastguard Worker       .addReg(ThisSrcReg).addImm(SrcDisp);
5769*9880d681SAndroid Build Coastguard Worker     if (EndMBB) {
5770*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, DL, TII->get(SystemZ::BRC))
5771*9880d681SAndroid Build Coastguard Worker         .addImm(SystemZ::CCMASK_ICMP).addImm(SystemZ::CCMASK_CMP_NE)
5772*9880d681SAndroid Build Coastguard Worker         .addMBB(EndMBB);
5773*9880d681SAndroid Build Coastguard Worker       MBB->addSuccessor(EndMBB);
5774*9880d681SAndroid Build Coastguard Worker       MBB->addSuccessor(NextMBB);
5775*9880d681SAndroid Build Coastguard Worker     }
5776*9880d681SAndroid Build Coastguard Worker 
5777*9880d681SAndroid Build Coastguard Worker     // NextMBB:
5778*9880d681SAndroid Build Coastguard Worker     //   %NextDestReg = LA 256(%ThisDestReg)
5779*9880d681SAndroid Build Coastguard Worker     //   %NextSrcReg = LA 256(%ThisSrcReg)
5780*9880d681SAndroid Build Coastguard Worker     //   %NextCountReg = AGHI %ThisCountReg, -1
5781*9880d681SAndroid Build Coastguard Worker     //   CGHI %NextCountReg, 0
5782*9880d681SAndroid Build Coastguard Worker     //   JLH LoopMBB
5783*9880d681SAndroid Build Coastguard Worker     //   # fall through to DoneMMB
5784*9880d681SAndroid Build Coastguard Worker     //
5785*9880d681SAndroid Build Coastguard Worker     // The AGHI, CGHI and JLH should be converted to BRCTG by later passes.
5786*9880d681SAndroid Build Coastguard Worker     MBB = NextMBB;
5787*9880d681SAndroid Build Coastguard Worker 
5788*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, DL, TII->get(SystemZ::LA), NextDestReg)
5789*9880d681SAndroid Build Coastguard Worker       .addReg(ThisDestReg).addImm(256).addReg(0);
5790*9880d681SAndroid Build Coastguard Worker     if (!HaveSingleBase)
5791*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, DL, TII->get(SystemZ::LA), NextSrcReg)
5792*9880d681SAndroid Build Coastguard Worker         .addReg(ThisSrcReg).addImm(256).addReg(0);
5793*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, DL, TII->get(SystemZ::AGHI), NextCountReg)
5794*9880d681SAndroid Build Coastguard Worker       .addReg(ThisCountReg).addImm(-1);
5795*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, DL, TII->get(SystemZ::CGHI))
5796*9880d681SAndroid Build Coastguard Worker       .addReg(NextCountReg).addImm(0);
5797*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, DL, TII->get(SystemZ::BRC))
5798*9880d681SAndroid Build Coastguard Worker       .addImm(SystemZ::CCMASK_ICMP).addImm(SystemZ::CCMASK_CMP_NE)
5799*9880d681SAndroid Build Coastguard Worker       .addMBB(LoopMBB);
5800*9880d681SAndroid Build Coastguard Worker     MBB->addSuccessor(LoopMBB);
5801*9880d681SAndroid Build Coastguard Worker     MBB->addSuccessor(DoneMBB);
5802*9880d681SAndroid Build Coastguard Worker 
5803*9880d681SAndroid Build Coastguard Worker     DestBase = MachineOperand::CreateReg(NextDestReg, false);
5804*9880d681SAndroid Build Coastguard Worker     SrcBase = MachineOperand::CreateReg(NextSrcReg, false);
5805*9880d681SAndroid Build Coastguard Worker     Length &= 255;
5806*9880d681SAndroid Build Coastguard Worker     MBB = DoneMBB;
5807*9880d681SAndroid Build Coastguard Worker   }
5808*9880d681SAndroid Build Coastguard Worker   // Handle any remaining bytes with straight-line code.
5809*9880d681SAndroid Build Coastguard Worker   while (Length > 0) {
5810*9880d681SAndroid Build Coastguard Worker     uint64_t ThisLength = std::min(Length, uint64_t(256));
5811*9880d681SAndroid Build Coastguard Worker     // The previous iteration might have created out-of-range displacements.
5812*9880d681SAndroid Build Coastguard Worker     // Apply them using LAY if so.
5813*9880d681SAndroid Build Coastguard Worker     if (!isUInt<12>(DestDisp)) {
5814*9880d681SAndroid Build Coastguard Worker       unsigned Reg = MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
5815*9880d681SAndroid Build Coastguard Worker       BuildMI(*MBB, MI, MI.getDebugLoc(), TII->get(SystemZ::LAY), Reg)
5816*9880d681SAndroid Build Coastguard Worker           .addOperand(DestBase)
5817*9880d681SAndroid Build Coastguard Worker           .addImm(DestDisp)
5818*9880d681SAndroid Build Coastguard Worker           .addReg(0);
5819*9880d681SAndroid Build Coastguard Worker       DestBase = MachineOperand::CreateReg(Reg, false);
5820*9880d681SAndroid Build Coastguard Worker       DestDisp = 0;
5821*9880d681SAndroid Build Coastguard Worker     }
5822*9880d681SAndroid Build Coastguard Worker     if (!isUInt<12>(SrcDisp)) {
5823*9880d681SAndroid Build Coastguard Worker       unsigned Reg = MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
5824*9880d681SAndroid Build Coastguard Worker       BuildMI(*MBB, MI, MI.getDebugLoc(), TII->get(SystemZ::LAY), Reg)
5825*9880d681SAndroid Build Coastguard Worker           .addOperand(SrcBase)
5826*9880d681SAndroid Build Coastguard Worker           .addImm(SrcDisp)
5827*9880d681SAndroid Build Coastguard Worker           .addReg(0);
5828*9880d681SAndroid Build Coastguard Worker       SrcBase = MachineOperand::CreateReg(Reg, false);
5829*9880d681SAndroid Build Coastguard Worker       SrcDisp = 0;
5830*9880d681SAndroid Build Coastguard Worker     }
5831*9880d681SAndroid Build Coastguard Worker     BuildMI(*MBB, MI, DL, TII->get(Opcode))
5832*9880d681SAndroid Build Coastguard Worker       .addOperand(DestBase).addImm(DestDisp).addImm(ThisLength)
5833*9880d681SAndroid Build Coastguard Worker       .addOperand(SrcBase).addImm(SrcDisp);
5834*9880d681SAndroid Build Coastguard Worker     DestDisp += ThisLength;
5835*9880d681SAndroid Build Coastguard Worker     SrcDisp += ThisLength;
5836*9880d681SAndroid Build Coastguard Worker     Length -= ThisLength;
5837*9880d681SAndroid Build Coastguard Worker     // If there's another CLC to go, branch to the end if a difference
5838*9880d681SAndroid Build Coastguard Worker     // was found.
5839*9880d681SAndroid Build Coastguard Worker     if (EndMBB && Length > 0) {
5840*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock *NextMBB = splitBlockBefore(MI, MBB);
5841*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, DL, TII->get(SystemZ::BRC))
5842*9880d681SAndroid Build Coastguard Worker         .addImm(SystemZ::CCMASK_ICMP).addImm(SystemZ::CCMASK_CMP_NE)
5843*9880d681SAndroid Build Coastguard Worker         .addMBB(EndMBB);
5844*9880d681SAndroid Build Coastguard Worker       MBB->addSuccessor(EndMBB);
5845*9880d681SAndroid Build Coastguard Worker       MBB->addSuccessor(NextMBB);
5846*9880d681SAndroid Build Coastguard Worker       MBB = NextMBB;
5847*9880d681SAndroid Build Coastguard Worker     }
5848*9880d681SAndroid Build Coastguard Worker   }
5849*9880d681SAndroid Build Coastguard Worker   if (EndMBB) {
5850*9880d681SAndroid Build Coastguard Worker     MBB->addSuccessor(EndMBB);
5851*9880d681SAndroid Build Coastguard Worker     MBB = EndMBB;
5852*9880d681SAndroid Build Coastguard Worker     MBB->addLiveIn(SystemZ::CC);
5853*9880d681SAndroid Build Coastguard Worker   }
5854*9880d681SAndroid Build Coastguard Worker 
5855*9880d681SAndroid Build Coastguard Worker   MI.eraseFromParent();
5856*9880d681SAndroid Build Coastguard Worker   return MBB;
5857*9880d681SAndroid Build Coastguard Worker }
5858*9880d681SAndroid Build Coastguard Worker 
5859*9880d681SAndroid Build Coastguard Worker // Decompose string pseudo-instruction MI into a loop that continually performs
5860*9880d681SAndroid Build Coastguard Worker // Opcode until CC != 3.
emitStringWrapper(MachineInstr & MI,MachineBasicBlock * MBB,unsigned Opcode) const5861*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *SystemZTargetLowering::emitStringWrapper(
5862*9880d681SAndroid Build Coastguard Worker     MachineInstr &MI, MachineBasicBlock *MBB, unsigned Opcode) const {
5863*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB->getParent();
5864*9880d681SAndroid Build Coastguard Worker   const SystemZInstrInfo *TII =
5865*9880d681SAndroid Build Coastguard Worker       static_cast<const SystemZInstrInfo *>(Subtarget.getInstrInfo());
5866*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo &MRI = MF.getRegInfo();
5867*9880d681SAndroid Build Coastguard Worker   DebugLoc DL = MI.getDebugLoc();
5868*9880d681SAndroid Build Coastguard Worker 
5869*9880d681SAndroid Build Coastguard Worker   uint64_t End1Reg = MI.getOperand(0).getReg();
5870*9880d681SAndroid Build Coastguard Worker   uint64_t Start1Reg = MI.getOperand(1).getReg();
5871*9880d681SAndroid Build Coastguard Worker   uint64_t Start2Reg = MI.getOperand(2).getReg();
5872*9880d681SAndroid Build Coastguard Worker   uint64_t CharReg = MI.getOperand(3).getReg();
5873*9880d681SAndroid Build Coastguard Worker 
5874*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *RC = &SystemZ::GR64BitRegClass;
5875*9880d681SAndroid Build Coastguard Worker   uint64_t This1Reg = MRI.createVirtualRegister(RC);
5876*9880d681SAndroid Build Coastguard Worker   uint64_t This2Reg = MRI.createVirtualRegister(RC);
5877*9880d681SAndroid Build Coastguard Worker   uint64_t End2Reg  = MRI.createVirtualRegister(RC);
5878*9880d681SAndroid Build Coastguard Worker 
5879*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *StartMBB = MBB;
5880*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *DoneMBB = splitBlockBefore(MI, MBB);
5881*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *LoopMBB = emitBlockAfter(StartMBB);
5882*9880d681SAndroid Build Coastguard Worker 
5883*9880d681SAndroid Build Coastguard Worker   //  StartMBB:
5884*9880d681SAndroid Build Coastguard Worker   //   # fall through to LoopMMB
5885*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(LoopMBB);
5886*9880d681SAndroid Build Coastguard Worker 
5887*9880d681SAndroid Build Coastguard Worker   //  LoopMBB:
5888*9880d681SAndroid Build Coastguard Worker   //   %This1Reg = phi [ %Start1Reg, StartMBB ], [ %End1Reg, LoopMBB ]
5889*9880d681SAndroid Build Coastguard Worker   //   %This2Reg = phi [ %Start2Reg, StartMBB ], [ %End2Reg, LoopMBB ]
5890*9880d681SAndroid Build Coastguard Worker   //   R0L = %CharReg
5891*9880d681SAndroid Build Coastguard Worker   //   %End1Reg, %End2Reg = CLST %This1Reg, %This2Reg -- uses R0L
5892*9880d681SAndroid Build Coastguard Worker   //   JO LoopMBB
5893*9880d681SAndroid Build Coastguard Worker   //   # fall through to DoneMMB
5894*9880d681SAndroid Build Coastguard Worker   //
5895*9880d681SAndroid Build Coastguard Worker   // The load of R0L can be hoisted by post-RA LICM.
5896*9880d681SAndroid Build Coastguard Worker   MBB = LoopMBB;
5897*9880d681SAndroid Build Coastguard Worker 
5898*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::PHI), This1Reg)
5899*9880d681SAndroid Build Coastguard Worker     .addReg(Start1Reg).addMBB(StartMBB)
5900*9880d681SAndroid Build Coastguard Worker     .addReg(End1Reg).addMBB(LoopMBB);
5901*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::PHI), This2Reg)
5902*9880d681SAndroid Build Coastguard Worker     .addReg(Start2Reg).addMBB(StartMBB)
5903*9880d681SAndroid Build Coastguard Worker     .addReg(End2Reg).addMBB(LoopMBB);
5904*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(TargetOpcode::COPY), SystemZ::R0L).addReg(CharReg);
5905*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(Opcode))
5906*9880d681SAndroid Build Coastguard Worker     .addReg(End1Reg, RegState::Define).addReg(End2Reg, RegState::Define)
5907*9880d681SAndroid Build Coastguard Worker     .addReg(This1Reg).addReg(This2Reg);
5908*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, DL, TII->get(SystemZ::BRC))
5909*9880d681SAndroid Build Coastguard Worker     .addImm(SystemZ::CCMASK_ANY).addImm(SystemZ::CCMASK_3).addMBB(LoopMBB);
5910*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(LoopMBB);
5911*9880d681SAndroid Build Coastguard Worker   MBB->addSuccessor(DoneMBB);
5912*9880d681SAndroid Build Coastguard Worker 
5913*9880d681SAndroid Build Coastguard Worker   DoneMBB->addLiveIn(SystemZ::CC);
5914*9880d681SAndroid Build Coastguard Worker 
5915*9880d681SAndroid Build Coastguard Worker   MI.eraseFromParent();
5916*9880d681SAndroid Build Coastguard Worker   return DoneMBB;
5917*9880d681SAndroid Build Coastguard Worker }
5918*9880d681SAndroid Build Coastguard Worker 
5919*9880d681SAndroid Build Coastguard Worker // Update TBEGIN instruction with final opcode and register clobbers.
emitTransactionBegin(MachineInstr & MI,MachineBasicBlock * MBB,unsigned Opcode,bool NoFloat) const5920*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *SystemZTargetLowering::emitTransactionBegin(
5921*9880d681SAndroid Build Coastguard Worker     MachineInstr &MI, MachineBasicBlock *MBB, unsigned Opcode,
5922*9880d681SAndroid Build Coastguard Worker     bool NoFloat) const {
5923*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB->getParent();
5924*9880d681SAndroid Build Coastguard Worker   const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
5925*9880d681SAndroid Build Coastguard Worker   const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
5926*9880d681SAndroid Build Coastguard Worker 
5927*9880d681SAndroid Build Coastguard Worker   // Update opcode.
5928*9880d681SAndroid Build Coastguard Worker   MI.setDesc(TII->get(Opcode));
5929*9880d681SAndroid Build Coastguard Worker 
5930*9880d681SAndroid Build Coastguard Worker   // We cannot handle a TBEGIN that clobbers the stack or frame pointer.
5931*9880d681SAndroid Build Coastguard Worker   // Make sure to add the corresponding GRSM bits if they are missing.
5932*9880d681SAndroid Build Coastguard Worker   uint64_t Control = MI.getOperand(2).getImm();
5933*9880d681SAndroid Build Coastguard Worker   static const unsigned GPRControlBit[16] = {
5934*9880d681SAndroid Build Coastguard Worker     0x8000, 0x8000, 0x4000, 0x4000, 0x2000, 0x2000, 0x1000, 0x1000,
5935*9880d681SAndroid Build Coastguard Worker     0x0800, 0x0800, 0x0400, 0x0400, 0x0200, 0x0200, 0x0100, 0x0100
5936*9880d681SAndroid Build Coastguard Worker   };
5937*9880d681SAndroid Build Coastguard Worker   Control |= GPRControlBit[15];
5938*9880d681SAndroid Build Coastguard Worker   if (TFI->hasFP(MF))
5939*9880d681SAndroid Build Coastguard Worker     Control |= GPRControlBit[11];
5940*9880d681SAndroid Build Coastguard Worker   MI.getOperand(2).setImm(Control);
5941*9880d681SAndroid Build Coastguard Worker 
5942*9880d681SAndroid Build Coastguard Worker   // Add GPR clobbers.
5943*9880d681SAndroid Build Coastguard Worker   for (int I = 0; I < 16; I++) {
5944*9880d681SAndroid Build Coastguard Worker     if ((Control & GPRControlBit[I]) == 0) {
5945*9880d681SAndroid Build Coastguard Worker       unsigned Reg = SystemZMC::GR64Regs[I];
5946*9880d681SAndroid Build Coastguard Worker       MI.addOperand(MachineOperand::CreateReg(Reg, true, true));
5947*9880d681SAndroid Build Coastguard Worker     }
5948*9880d681SAndroid Build Coastguard Worker   }
5949*9880d681SAndroid Build Coastguard Worker 
5950*9880d681SAndroid Build Coastguard Worker   // Add FPR/VR clobbers.
5951*9880d681SAndroid Build Coastguard Worker   if (!NoFloat && (Control & 4) != 0) {
5952*9880d681SAndroid Build Coastguard Worker     if (Subtarget.hasVector()) {
5953*9880d681SAndroid Build Coastguard Worker       for (int I = 0; I < 32; I++) {
5954*9880d681SAndroid Build Coastguard Worker         unsigned Reg = SystemZMC::VR128Regs[I];
5955*9880d681SAndroid Build Coastguard Worker         MI.addOperand(MachineOperand::CreateReg(Reg, true, true));
5956*9880d681SAndroid Build Coastguard Worker       }
5957*9880d681SAndroid Build Coastguard Worker     } else {
5958*9880d681SAndroid Build Coastguard Worker       for (int I = 0; I < 16; I++) {
5959*9880d681SAndroid Build Coastguard Worker         unsigned Reg = SystemZMC::FP64Regs[I];
5960*9880d681SAndroid Build Coastguard Worker         MI.addOperand(MachineOperand::CreateReg(Reg, true, true));
5961*9880d681SAndroid Build Coastguard Worker       }
5962*9880d681SAndroid Build Coastguard Worker     }
5963*9880d681SAndroid Build Coastguard Worker   }
5964*9880d681SAndroid Build Coastguard Worker 
5965*9880d681SAndroid Build Coastguard Worker   return MBB;
5966*9880d681SAndroid Build Coastguard Worker }
5967*9880d681SAndroid Build Coastguard Worker 
emitLoadAndTestCmp0(MachineInstr & MI,MachineBasicBlock * MBB,unsigned Opcode) const5968*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *SystemZTargetLowering::emitLoadAndTestCmp0(
5969*9880d681SAndroid Build Coastguard Worker     MachineInstr &MI, MachineBasicBlock *MBB, unsigned Opcode) const {
5970*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB->getParent();
5971*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo *MRI = &MF.getRegInfo();
5972*9880d681SAndroid Build Coastguard Worker   const SystemZInstrInfo *TII =
5973*9880d681SAndroid Build Coastguard Worker       static_cast<const SystemZInstrInfo *>(Subtarget.getInstrInfo());
5974*9880d681SAndroid Build Coastguard Worker   DebugLoc DL = MI.getDebugLoc();
5975*9880d681SAndroid Build Coastguard Worker 
5976*9880d681SAndroid Build Coastguard Worker   unsigned SrcReg = MI.getOperand(0).getReg();
5977*9880d681SAndroid Build Coastguard Worker 
5978*9880d681SAndroid Build Coastguard Worker   // Create new virtual register of the same class as source.
5979*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *RC = MRI->getRegClass(SrcReg);
5980*9880d681SAndroid Build Coastguard Worker   unsigned DstReg = MRI->createVirtualRegister(RC);
5981*9880d681SAndroid Build Coastguard Worker 
5982*9880d681SAndroid Build Coastguard Worker   // Replace pseudo with a normal load-and-test that models the def as
5983*9880d681SAndroid Build Coastguard Worker   // well.
5984*9880d681SAndroid Build Coastguard Worker   BuildMI(*MBB, MI, DL, TII->get(Opcode), DstReg)
5985*9880d681SAndroid Build Coastguard Worker     .addReg(SrcReg);
5986*9880d681SAndroid Build Coastguard Worker   MI.eraseFromParent();
5987*9880d681SAndroid Build Coastguard Worker 
5988*9880d681SAndroid Build Coastguard Worker   return MBB;
5989*9880d681SAndroid Build Coastguard Worker }
5990*9880d681SAndroid Build Coastguard Worker 
EmitInstrWithCustomInserter(MachineInstr & MI,MachineBasicBlock * MBB) const5991*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *SystemZTargetLowering::EmitInstrWithCustomInserter(
5992*9880d681SAndroid Build Coastguard Worker     MachineInstr &MI, MachineBasicBlock *MBB) const {
5993*9880d681SAndroid Build Coastguard Worker   switch (MI.getOpcode()) {
5994*9880d681SAndroid Build Coastguard Worker   case SystemZ::Select32Mux:
5995*9880d681SAndroid Build Coastguard Worker   case SystemZ::Select32:
5996*9880d681SAndroid Build Coastguard Worker   case SystemZ::SelectF32:
5997*9880d681SAndroid Build Coastguard Worker   case SystemZ::Select64:
5998*9880d681SAndroid Build Coastguard Worker   case SystemZ::SelectF64:
5999*9880d681SAndroid Build Coastguard Worker   case SystemZ::SelectF128:
6000*9880d681SAndroid Build Coastguard Worker     return emitSelect(MI, MBB);
6001*9880d681SAndroid Build Coastguard Worker 
6002*9880d681SAndroid Build Coastguard Worker   case SystemZ::CondStore8Mux:
6003*9880d681SAndroid Build Coastguard Worker     return emitCondStore(MI, MBB, SystemZ::STCMux, 0, false);
6004*9880d681SAndroid Build Coastguard Worker   case SystemZ::CondStore8MuxInv:
6005*9880d681SAndroid Build Coastguard Worker     return emitCondStore(MI, MBB, SystemZ::STCMux, 0, true);
6006*9880d681SAndroid Build Coastguard Worker   case SystemZ::CondStore16Mux:
6007*9880d681SAndroid Build Coastguard Worker     return emitCondStore(MI, MBB, SystemZ::STHMux, 0, false);
6008*9880d681SAndroid Build Coastguard Worker   case SystemZ::CondStore16MuxInv:
6009*9880d681SAndroid Build Coastguard Worker     return emitCondStore(MI, MBB, SystemZ::STHMux, 0, true);
6010*9880d681SAndroid Build Coastguard Worker   case SystemZ::CondStore8:
6011*9880d681SAndroid Build Coastguard Worker     return emitCondStore(MI, MBB, SystemZ::STC, 0, false);
6012*9880d681SAndroid Build Coastguard Worker   case SystemZ::CondStore8Inv:
6013*9880d681SAndroid Build Coastguard Worker     return emitCondStore(MI, MBB, SystemZ::STC, 0, true);
6014*9880d681SAndroid Build Coastguard Worker   case SystemZ::CondStore16:
6015*9880d681SAndroid Build Coastguard Worker     return emitCondStore(MI, MBB, SystemZ::STH, 0, false);
6016*9880d681SAndroid Build Coastguard Worker   case SystemZ::CondStore16Inv:
6017*9880d681SAndroid Build Coastguard Worker     return emitCondStore(MI, MBB, SystemZ::STH, 0, true);
6018*9880d681SAndroid Build Coastguard Worker   case SystemZ::CondStore32:
6019*9880d681SAndroid Build Coastguard Worker     return emitCondStore(MI, MBB, SystemZ::ST, SystemZ::STOC, false);
6020*9880d681SAndroid Build Coastguard Worker   case SystemZ::CondStore32Inv:
6021*9880d681SAndroid Build Coastguard Worker     return emitCondStore(MI, MBB, SystemZ::ST, SystemZ::STOC, true);
6022*9880d681SAndroid Build Coastguard Worker   case SystemZ::CondStore64:
6023*9880d681SAndroid Build Coastguard Worker     return emitCondStore(MI, MBB, SystemZ::STG, SystemZ::STOCG, false);
6024*9880d681SAndroid Build Coastguard Worker   case SystemZ::CondStore64Inv:
6025*9880d681SAndroid Build Coastguard Worker     return emitCondStore(MI, MBB, SystemZ::STG, SystemZ::STOCG, true);
6026*9880d681SAndroid Build Coastguard Worker   case SystemZ::CondStoreF32:
6027*9880d681SAndroid Build Coastguard Worker     return emitCondStore(MI, MBB, SystemZ::STE, 0, false);
6028*9880d681SAndroid Build Coastguard Worker   case SystemZ::CondStoreF32Inv:
6029*9880d681SAndroid Build Coastguard Worker     return emitCondStore(MI, MBB, SystemZ::STE, 0, true);
6030*9880d681SAndroid Build Coastguard Worker   case SystemZ::CondStoreF64:
6031*9880d681SAndroid Build Coastguard Worker     return emitCondStore(MI, MBB, SystemZ::STD, 0, false);
6032*9880d681SAndroid Build Coastguard Worker   case SystemZ::CondStoreF64Inv:
6033*9880d681SAndroid Build Coastguard Worker     return emitCondStore(MI, MBB, SystemZ::STD, 0, true);
6034*9880d681SAndroid Build Coastguard Worker 
6035*9880d681SAndroid Build Coastguard Worker   case SystemZ::AEXT128_64:
6036*9880d681SAndroid Build Coastguard Worker     return emitExt128(MI, MBB, false, SystemZ::subreg_l64);
6037*9880d681SAndroid Build Coastguard Worker   case SystemZ::ZEXT128_32:
6038*9880d681SAndroid Build Coastguard Worker     return emitExt128(MI, MBB, true, SystemZ::subreg_l32);
6039*9880d681SAndroid Build Coastguard Worker   case SystemZ::ZEXT128_64:
6040*9880d681SAndroid Build Coastguard Worker     return emitExt128(MI, MBB, true, SystemZ::subreg_l64);
6041*9880d681SAndroid Build Coastguard Worker 
6042*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_SWAPW:
6043*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, 0, 0);
6044*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_SWAP_32:
6045*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, 0, 32);
6046*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_SWAP_64:
6047*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, 0, 64);
6048*9880d681SAndroid Build Coastguard Worker 
6049*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOADW_AR:
6050*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::AR, 0);
6051*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOADW_AFI:
6052*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::AFI, 0);
6053*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_AR:
6054*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::AR, 32);
6055*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_AHI:
6056*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::AHI, 32);
6057*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_AFI:
6058*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::AFI, 32);
6059*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_AGR:
6060*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::AGR, 64);
6061*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_AGHI:
6062*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::AGHI, 64);
6063*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_AGFI:
6064*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::AGFI, 64);
6065*9880d681SAndroid Build Coastguard Worker 
6066*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOADW_SR:
6067*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::SR, 0);
6068*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_SR:
6069*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::SR, 32);
6070*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_SGR:
6071*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::SGR, 64);
6072*9880d681SAndroid Build Coastguard Worker 
6073*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOADW_NR:
6074*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NR, 0);
6075*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOADW_NILH:
6076*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH, 0);
6077*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NR:
6078*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NR, 32);
6079*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NILL:
6080*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NILL, 32);
6081*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NILH:
6082*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH, 32);
6083*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NILF:
6084*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NILF, 32);
6085*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NGR:
6086*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NGR, 64);
6087*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NILL64:
6088*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NILL64, 64);
6089*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NILH64:
6090*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH64, 64);
6091*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NIHL64:
6092*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHL64, 64);
6093*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NIHH64:
6094*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHH64, 64);
6095*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NILF64:
6096*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NILF64, 64);
6097*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NIHF64:
6098*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHF64, 64);
6099*9880d681SAndroid Build Coastguard Worker 
6100*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOADW_OR:
6101*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::OR, 0);
6102*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOADW_OILH:
6103*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::OILH, 0);
6104*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_OR:
6105*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::OR, 32);
6106*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_OILL:
6107*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::OILL, 32);
6108*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_OILH:
6109*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::OILH, 32);
6110*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_OILF:
6111*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::OILF, 32);
6112*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_OGR:
6113*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::OGR, 64);
6114*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_OILL64:
6115*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::OILL64, 64);
6116*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_OILH64:
6117*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::OILH64, 64);
6118*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_OIHL64:
6119*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::OIHL64, 64);
6120*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_OIHH64:
6121*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::OIHH64, 64);
6122*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_OILF64:
6123*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::OILF64, 64);
6124*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_OIHF64:
6125*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::OIHF64, 64);
6126*9880d681SAndroid Build Coastguard Worker 
6127*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOADW_XR:
6128*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::XR, 0);
6129*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOADW_XILF:
6130*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::XILF, 0);
6131*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_XR:
6132*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::XR, 32);
6133*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_XILF:
6134*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::XILF, 32);
6135*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_XGR:
6136*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::XGR, 64);
6137*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_XILF64:
6138*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::XILF64, 64);
6139*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_XIHF64:
6140*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::XIHF64, 64);
6141*9880d681SAndroid Build Coastguard Worker 
6142*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOADW_NRi:
6143*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NR, 0, true);
6144*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOADW_NILHi:
6145*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH, 0, true);
6146*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NRi:
6147*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NR, 32, true);
6148*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NILLi:
6149*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NILL, 32, true);
6150*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NILHi:
6151*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH, 32, true);
6152*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NILFi:
6153*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NILF, 32, true);
6154*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NGRi:
6155*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NGR, 64, true);
6156*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NILL64i:
6157*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NILL64, 64, true);
6158*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NILH64i:
6159*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH64, 64, true);
6160*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NIHL64i:
6161*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHL64, 64, true);
6162*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NIHH64i:
6163*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHH64, 64, true);
6164*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NILF64i:
6165*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NILF64, 64, true);
6166*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_NIHF64i:
6167*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHF64, 64, true);
6168*9880d681SAndroid Build Coastguard Worker 
6169*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOADW_MIN:
6170*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR,
6171*9880d681SAndroid Build Coastguard Worker                                 SystemZ::CCMASK_CMP_LE, 0);
6172*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_MIN_32:
6173*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR,
6174*9880d681SAndroid Build Coastguard Worker                                 SystemZ::CCMASK_CMP_LE, 32);
6175*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_MIN_64:
6176*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadMinMax(MI, MBB, SystemZ::CGR,
6177*9880d681SAndroid Build Coastguard Worker                                 SystemZ::CCMASK_CMP_LE, 64);
6178*9880d681SAndroid Build Coastguard Worker 
6179*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOADW_MAX:
6180*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR,
6181*9880d681SAndroid Build Coastguard Worker                                 SystemZ::CCMASK_CMP_GE, 0);
6182*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_MAX_32:
6183*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR,
6184*9880d681SAndroid Build Coastguard Worker                                 SystemZ::CCMASK_CMP_GE, 32);
6185*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_MAX_64:
6186*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadMinMax(MI, MBB, SystemZ::CGR,
6187*9880d681SAndroid Build Coastguard Worker                                 SystemZ::CCMASK_CMP_GE, 64);
6188*9880d681SAndroid Build Coastguard Worker 
6189*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOADW_UMIN:
6190*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR,
6191*9880d681SAndroid Build Coastguard Worker                                 SystemZ::CCMASK_CMP_LE, 0);
6192*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_UMIN_32:
6193*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR,
6194*9880d681SAndroid Build Coastguard Worker                                 SystemZ::CCMASK_CMP_LE, 32);
6195*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_UMIN_64:
6196*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLGR,
6197*9880d681SAndroid Build Coastguard Worker                                 SystemZ::CCMASK_CMP_LE, 64);
6198*9880d681SAndroid Build Coastguard Worker 
6199*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOADW_UMAX:
6200*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR,
6201*9880d681SAndroid Build Coastguard Worker                                 SystemZ::CCMASK_CMP_GE, 0);
6202*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_UMAX_32:
6203*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR,
6204*9880d681SAndroid Build Coastguard Worker                                 SystemZ::CCMASK_CMP_GE, 32);
6205*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_LOAD_UMAX_64:
6206*9880d681SAndroid Build Coastguard Worker     return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLGR,
6207*9880d681SAndroid Build Coastguard Worker                                 SystemZ::CCMASK_CMP_GE, 64);
6208*9880d681SAndroid Build Coastguard Worker 
6209*9880d681SAndroid Build Coastguard Worker   case SystemZ::ATOMIC_CMP_SWAPW:
6210*9880d681SAndroid Build Coastguard Worker     return emitAtomicCmpSwapW(MI, MBB);
6211*9880d681SAndroid Build Coastguard Worker   case SystemZ::MVCSequence:
6212*9880d681SAndroid Build Coastguard Worker   case SystemZ::MVCLoop:
6213*9880d681SAndroid Build Coastguard Worker     return emitMemMemWrapper(MI, MBB, SystemZ::MVC);
6214*9880d681SAndroid Build Coastguard Worker   case SystemZ::NCSequence:
6215*9880d681SAndroid Build Coastguard Worker   case SystemZ::NCLoop:
6216*9880d681SAndroid Build Coastguard Worker     return emitMemMemWrapper(MI, MBB, SystemZ::NC);
6217*9880d681SAndroid Build Coastguard Worker   case SystemZ::OCSequence:
6218*9880d681SAndroid Build Coastguard Worker   case SystemZ::OCLoop:
6219*9880d681SAndroid Build Coastguard Worker     return emitMemMemWrapper(MI, MBB, SystemZ::OC);
6220*9880d681SAndroid Build Coastguard Worker   case SystemZ::XCSequence:
6221*9880d681SAndroid Build Coastguard Worker   case SystemZ::XCLoop:
6222*9880d681SAndroid Build Coastguard Worker     return emitMemMemWrapper(MI, MBB, SystemZ::XC);
6223*9880d681SAndroid Build Coastguard Worker   case SystemZ::CLCSequence:
6224*9880d681SAndroid Build Coastguard Worker   case SystemZ::CLCLoop:
6225*9880d681SAndroid Build Coastguard Worker     return emitMemMemWrapper(MI, MBB, SystemZ::CLC);
6226*9880d681SAndroid Build Coastguard Worker   case SystemZ::CLSTLoop:
6227*9880d681SAndroid Build Coastguard Worker     return emitStringWrapper(MI, MBB, SystemZ::CLST);
6228*9880d681SAndroid Build Coastguard Worker   case SystemZ::MVSTLoop:
6229*9880d681SAndroid Build Coastguard Worker     return emitStringWrapper(MI, MBB, SystemZ::MVST);
6230*9880d681SAndroid Build Coastguard Worker   case SystemZ::SRSTLoop:
6231*9880d681SAndroid Build Coastguard Worker     return emitStringWrapper(MI, MBB, SystemZ::SRST);
6232*9880d681SAndroid Build Coastguard Worker   case SystemZ::TBEGIN:
6233*9880d681SAndroid Build Coastguard Worker     return emitTransactionBegin(MI, MBB, SystemZ::TBEGIN, false);
6234*9880d681SAndroid Build Coastguard Worker   case SystemZ::TBEGIN_nofloat:
6235*9880d681SAndroid Build Coastguard Worker     return emitTransactionBegin(MI, MBB, SystemZ::TBEGIN, true);
6236*9880d681SAndroid Build Coastguard Worker   case SystemZ::TBEGINC:
6237*9880d681SAndroid Build Coastguard Worker     return emitTransactionBegin(MI, MBB, SystemZ::TBEGINC, true);
6238*9880d681SAndroid Build Coastguard Worker   case SystemZ::LTEBRCompare_VecPseudo:
6239*9880d681SAndroid Build Coastguard Worker     return emitLoadAndTestCmp0(MI, MBB, SystemZ::LTEBR);
6240*9880d681SAndroid Build Coastguard Worker   case SystemZ::LTDBRCompare_VecPseudo:
6241*9880d681SAndroid Build Coastguard Worker     return emitLoadAndTestCmp0(MI, MBB, SystemZ::LTDBR);
6242*9880d681SAndroid Build Coastguard Worker   case SystemZ::LTXBRCompare_VecPseudo:
6243*9880d681SAndroid Build Coastguard Worker     return emitLoadAndTestCmp0(MI, MBB, SystemZ::LTXBR);
6244*9880d681SAndroid Build Coastguard Worker 
6245*9880d681SAndroid Build Coastguard Worker   default:
6246*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Unexpected instr type to insert");
6247*9880d681SAndroid Build Coastguard Worker   }
6248*9880d681SAndroid Build Coastguard Worker }
6249