SystemZISelLowering.h revision 276479
1234285Sdim//===-- SystemZISelLowering.h - SystemZ DAG lowering interface --*- C++ -*-===//
2234285Sdim//
3234285Sdim//                     The LLVM Compiler Infrastructure
4234285Sdim//
5234285Sdim// This file is distributed under the University of Illinois Open Source
6234285Sdim// License. See LICENSE.TXT for details.
7234285Sdim//
8234285Sdim//===----------------------------------------------------------------------===//
9234285Sdim//
10234285Sdim// This file defines the interfaces that SystemZ uses to lower LLVM code into a
11234285Sdim// selection DAG.
12234285Sdim//
13234285Sdim//===----------------------------------------------------------------------===//
14234285Sdim
15234285Sdim#ifndef LLVM_TARGET_SystemZ_ISELLOWERING_H
16234285Sdim#define LLVM_TARGET_SystemZ_ISELLOWERING_H
17243830Sdim
18234285Sdim#include "SystemZ.h"
19234285Sdim#include "llvm/CodeGen/MachineBasicBlock.h"
20234285Sdim#include "llvm/CodeGen/SelectionDAG.h"
21234285Sdim#include "llvm/Target/TargetLowering.h"
22234285Sdim
23234285Sdimnamespace llvm {
24234285Sdimnamespace SystemZISD {
25234285Sdimenum {
26234285Sdim  FIRST_NUMBER = ISD::BUILTIN_OP_END,
27234285Sdim
28234285Sdim  // Return with a flag operand.  Operand 0 is the chain operand.
29234285Sdim  RET_FLAG,
30234285Sdim
31234285Sdim  // Calls a function.  Operand 0 is the chain operand and operand 1
32234285Sdim  // is the target address.  The arguments start at operand 2.
33234285Sdim  // There is an optional glue operand at the end.
34234285Sdim  CALL,
35234285Sdim  SIBCALL,
36234285Sdim
37234285Sdim  // Wraps a TargetGlobalAddress that should be loaded using PC-relative
38234285Sdim  // accesses (LARL).  Operand 0 is the address.
39234285Sdim  PCREL_WRAPPER,
40234285Sdim
41234285Sdim  // Used in cases where an offset is applied to a TargetGlobalAddress.
42234285Sdim  // Operand 0 is the full TargetGlobalAddress and operand 1 is a
43234285Sdim  // PCREL_WRAPPER for an anchor point.  This is used so that we can
44234285Sdim  // cheaply refer to either the full address or the anchor point
45234285Sdim  // as a register base.
46234285Sdim  PCREL_OFFSET,
47234285Sdim
48234285Sdim  // Integer absolute.
49234285Sdim  IABS,
50234285Sdim
51234285Sdim  // Integer comparisons.  There are three operands: the two values
52234285Sdim  // to compare, and an integer of type SystemZICMP.
53234285Sdim  ICMP,
54234285Sdim
55234285Sdim  // Floating-point comparisons.  The two operands are the values to compare.
56234285Sdim  FCMP,
57234285Sdim
58234285Sdim  // Test under mask.  The first operand is ANDed with the second operand
59234285Sdim  // and the condition codes are set on the result.  The third operand is
60234285Sdim  // a boolean that is true if the condition codes need to distinguish
61234285Sdim  // between CCMASK_TM_MIXED_MSB_0 and CCMASK_TM_MIXED_MSB_1 (which the
62234285Sdim  // register forms do but the memory forms don't).
63234285Sdim  TM,
64234285Sdim
65234285Sdim  // Branches if a condition is true.  Operand 0 is the chain operand;
66234285Sdim  // operand 1 is the 4-bit condition-code mask, with bit N in
67234285Sdim  // big-endian order meaning "branch if CC=N"; operand 2 is the
68234285Sdim  // target block and operand 3 is the flag operand.
69234285Sdim  BR_CCMASK,
70234285Sdim
71234285Sdim  // Selects between operand 0 and operand 1.  Operand 2 is the
72234285Sdim  // mask of condition-code values for which operand 0 should be
73234285Sdim  // chosen over operand 1; it has the same form as BR_CCMASK.
74234285Sdim  // Operand 3 is the flag operand.
75234285Sdim  SELECT_CCMASK,
76234285Sdim
77234285Sdim  // Evaluates to the gap between the stack pointer and the
78234285Sdim  // base of the dynamically-allocatable area.
79234285Sdim  ADJDYNALLOC,
80234285Sdim
81234285Sdim  // Extracts the value of a 32-bit access register.  Operand 0 is
82234285Sdim  // the number of the register.
83234285Sdim  EXTRACT_ACCESS,
84234285Sdim
85234285Sdim  // Wrappers around the ISD opcodes of the same name.  The output and
86234285Sdim  // first input operands are GR128s.  The trailing numbers are the
87234285Sdim  // widths of the second operand in bits.
88234285Sdim  UMUL_LOHI64,
89234285Sdim  SDIVREM32,
90234285Sdim  SDIVREM64,
91234285Sdim  UDIVREM32,
92234285Sdim  UDIVREM64,
93234285Sdim
94234285Sdim  // Use a series of MVCs to copy bytes from one memory location to another.
95234285Sdim  // The operands are:
96234285Sdim  // - the target address
97234285Sdim  // - the source address
98234285Sdim  // - the constant length
99234285Sdim  //
100234285Sdim  // This isn't a memory opcode because we'd need to attach two
101234285Sdim  // MachineMemOperands rather than one.
102234285Sdim  MVC,
103234285Sdim
104234285Sdim  // Like MVC, but implemented as a loop that handles X*256 bytes
105234285Sdim  // followed by straight-line code to handle the rest (if any).
106234285Sdim  // The value of X is passed as an additional operand.
107234285Sdim  MVC_LOOP,
108234285Sdim
109234285Sdim  // Similar to MVC and MVC_LOOP, but for logic operations (AND, OR, XOR).
110234285Sdim  NC,
111234285Sdim  NC_LOOP,
112234285Sdim  OC,
113234285Sdim  OC_LOOP,
114234285Sdim  XC,
115234285Sdim  XC_LOOP,
116234285Sdim
117234285Sdim  // Use CLC to compare two blocks of memory, with the same comments
118234285Sdim  // as for MVC and MVC_LOOP.
119234285Sdim  CLC,
120234285Sdim  CLC_LOOP,
121234285Sdim
122234285Sdim  // Use an MVST-based sequence to implement stpcpy().
123234285Sdim  STPCPY,
124234285Sdim
125234285Sdim  // Use a CLST-based sequence to implement strcmp().  The two input operands
126234285Sdim  // are the addresses of the strings to compare.
127234285Sdim  STRCMP,
128234285Sdim
129234285Sdim  // Use an SRST-based sequence to search a block of memory.  The first
130234285Sdim  // operand is the end address, the second is the start, and the third
131234285Sdim  // is the character to search for.  CC is set to 1 on success and 2
132234285Sdim  // on failure.
133234285Sdim  SEARCH_STRING,
134234285Sdim
135234285Sdim  // Store the CC value in bits 29 and 28 of an integer.
136234285Sdim  IPM,
137234285Sdim
138234285Sdim  // Perform a serialization operation.  (BCR 15,0 or BCR 14,0.)
139234285Sdim  SERIALIZE,
140234285Sdim
141234285Sdim  // Wrappers around the inner loop of an 8- or 16-bit ATOMIC_SWAP or
142234285Sdim  // ATOMIC_LOAD_<op>.
143234285Sdim  //
144234285Sdim  // Operand 0: the address of the containing 32-bit-aligned field
145234285Sdim  // Operand 1: the second operand of <op>, in the high bits of an i32
146234285Sdim  //            for everything except ATOMIC_SWAPW
147234285Sdim  // Operand 2: how many bits to rotate the i32 left to bring the first
148234285Sdim  //            operand into the high bits
149243830Sdim  // Operand 3: the negative of operand 2, for rotating the other way
150234285Sdim  // Operand 4: the width of the field in bits (8 or 16)
151234285Sdim  ATOMIC_SWAPW = ISD::FIRST_TARGET_MEMORY_OPCODE,
152234285Sdim  ATOMIC_LOADW_ADD,
153234285Sdim  ATOMIC_LOADW_SUB,
154234285Sdim  ATOMIC_LOADW_AND,
155234285Sdim  ATOMIC_LOADW_OR,
156234285Sdim  ATOMIC_LOADW_XOR,
157234285Sdim  ATOMIC_LOADW_NAND,
158234285Sdim  ATOMIC_LOADW_MIN,
159234285Sdim  ATOMIC_LOADW_MAX,
160234285Sdim  ATOMIC_LOADW_UMIN,
161243830Sdim  ATOMIC_LOADW_UMAX,
162234285Sdim
163234285Sdim  // A wrapper around the inner loop of an ATOMIC_CMP_SWAP.
164243830Sdim  //
165234285Sdim  // Operand 0: the address of the containing 32-bit-aligned field
166234285Sdim  // Operand 1: the compare value, in the low bits of an i32
167234285Sdim  // Operand 2: the swap value, in the low bits of an i32
168243830Sdim  // Operand 3: how many bits to rotate the i32 left to bring the first
169234285Sdim  //            operand into the high bits
170234285Sdim  // Operand 4: the negative of operand 2, for rotating the other way
171234285Sdim  // Operand 5: the width of the field in bits (8 or 16)
172234285Sdim  ATOMIC_CMP_SWAPW,
173234285Sdim
174234285Sdim  // Prefetch from the second operand using the 4-bit control code in
175234285Sdim  // the first operand.  The code is 1 for a load prefetch and 2 for
176234285Sdim  // a store prefetch.
177234285Sdim  PREFETCH
178234285Sdim};
179234285Sdim
180234285Sdim// Return true if OPCODE is some kind of PC-relative address.
181234285Sdiminline bool isPCREL(unsigned Opcode) {
182234285Sdim  return Opcode == PCREL_WRAPPER || Opcode == PCREL_OFFSET;
183234285Sdim}
184234285Sdim} // end namespace SystemZISD
185234285Sdim
186234285Sdimnamespace SystemZICMP {
187243830Sdim// Describes whether an integer comparison needs to be signed or unsigned,
188234285Sdim// or whether either type is OK.
189234285Sdimenum {
190234285Sdim  Any,
191234285Sdim  UnsignedOnly,
192234285Sdim  SignedOnly
193234285Sdim};
194234285Sdim} // end namespace SystemZICMP
195234285Sdim
196234285Sdimclass SystemZSubtarget;
197234285Sdimclass SystemZTargetMachine;
198
199class SystemZTargetLowering : public TargetLowering {
200public:
201  explicit SystemZTargetLowering(const TargetMachine &TM);
202
203  // Override TargetLowering.
204  MVT getScalarShiftAmountTy(EVT LHSTy) const override {
205    return MVT::i32;
206  }
207  EVT getSetCCResultType(LLVMContext &, EVT) const override;
208  bool isFMAFasterThanFMulAndFAdd(EVT VT) const override;
209  bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
210  bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const override;
211  bool allowsUnalignedMemoryAccesses(EVT VT, unsigned AS,
212                                     bool *Fast) const override;
213  bool isTruncateFree(Type *, Type *) const override;
214  bool isTruncateFree(EVT, EVT) const override;
215  const char *getTargetNodeName(unsigned Opcode) const override;
216  std::pair<unsigned, const TargetRegisterClass *>
217    getRegForInlineAsmConstraint(const std::string &Constraint,
218                                 MVT VT) const override;
219  TargetLowering::ConstraintType
220    getConstraintType(const std::string &Constraint) const override;
221  TargetLowering::ConstraintWeight
222    getSingleConstraintMatchWeight(AsmOperandInfo &info,
223                                   const char *constraint) const override;
224  void LowerAsmOperandForConstraint(SDValue Op,
225                                    std::string &Constraint,
226                                    std::vector<SDValue> &Ops,
227                                    SelectionDAG &DAG) const override;
228  MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
229                                                 MachineBasicBlock *BB) const
230    override;
231  SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
232  bool allowTruncateForTailCall(Type *, Type *) const override;
233  bool mayBeEmittedAsTailCall(CallInst *CI) const override;
234  SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
235                               bool isVarArg,
236                               const SmallVectorImpl<ISD::InputArg> &Ins,
237                               SDLoc DL, SelectionDAG &DAG,
238                               SmallVectorImpl<SDValue> &InVals) const override;
239  SDValue LowerCall(CallLoweringInfo &CLI,
240                    SmallVectorImpl<SDValue> &InVals) const override;
241
242  SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
243                      const SmallVectorImpl<ISD::OutputArg> &Outs,
244                      const SmallVectorImpl<SDValue> &OutVals,
245                      SDLoc DL, SelectionDAG &DAG) const override;
246  SDValue prepareVolatileOrAtomicLoad(SDValue Chain, SDLoc DL,
247                                      SelectionDAG &DAG) const override;
248  SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
249
250private:
251  const SystemZSubtarget &Subtarget;
252
253  // Implement LowerOperation for individual opcodes.
254  SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const;
255  SDValue lowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
256  SDValue lowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
257  SDValue lowerGlobalAddress(GlobalAddressSDNode *Node,
258                             SelectionDAG &DAG) const;
259  SDValue lowerGlobalTLSAddress(GlobalAddressSDNode *Node,
260                                SelectionDAG &DAG) const;
261  SDValue lowerBlockAddress(BlockAddressSDNode *Node,
262                            SelectionDAG &DAG) const;
263  SDValue lowerJumpTable(JumpTableSDNode *JT, SelectionDAG &DAG) const;
264  SDValue lowerConstantPool(ConstantPoolSDNode *CP, SelectionDAG &DAG) const;
265  SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
266  SDValue lowerVACOPY(SDValue Op, SelectionDAG &DAG) const;
267  SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
268  SDValue lowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const;
269  SDValue lowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const;
270  SDValue lowerSDIVREM(SDValue Op, SelectionDAG &DAG) const;
271  SDValue lowerUDIVREM(SDValue Op, SelectionDAG &DAG) const;
272  SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const;
273  SDValue lowerOR(SDValue Op, SelectionDAG &DAG) const;
274  SDValue lowerATOMIC_LOAD(SDValue Op, SelectionDAG &DAG) const;
275  SDValue lowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG) const;
276  SDValue lowerATOMIC_LOAD_OP(SDValue Op, SelectionDAG &DAG,
277                              unsigned Opcode) const;
278  SDValue lowerATOMIC_LOAD_SUB(SDValue Op, SelectionDAG &DAG) const;
279  SDValue lowerATOMIC_CMP_SWAP(SDValue Op, SelectionDAG &DAG) const;
280  SDValue lowerLOAD_SEQUENCE_POINT(SDValue Op, SelectionDAG &DAG) const;
281  SDValue lowerSTACKSAVE(SDValue Op, SelectionDAG &DAG) const;
282  SDValue lowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const;
283  SDValue lowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;
284
285  // If the last instruction before MBBI in MBB was some form of COMPARE,
286  // try to replace it with a COMPARE AND BRANCH just before MBBI.
287  // CCMask and Target are the BRC-like operands for the branch.
288  // Return true if the change was made.
289  bool convertPrevCompareToBranch(MachineBasicBlock *MBB,
290                                  MachineBasicBlock::iterator MBBI,
291                                  unsigned CCMask,
292                                  MachineBasicBlock *Target) const;
293
294  // Implement EmitInstrWithCustomInserter for individual operation types.
295  MachineBasicBlock *emitSelect(MachineInstr *MI,
296                                MachineBasicBlock *BB) const;
297  MachineBasicBlock *emitCondStore(MachineInstr *MI,
298                                   MachineBasicBlock *BB,
299                                   unsigned StoreOpcode, unsigned STOCOpcode,
300                                   bool Invert) const;
301  MachineBasicBlock *emitExt128(MachineInstr *MI,
302                                MachineBasicBlock *MBB,
303                                bool ClearEven, unsigned SubReg) const;
304  MachineBasicBlock *emitAtomicLoadBinary(MachineInstr *MI,
305                                          MachineBasicBlock *BB,
306                                          unsigned BinOpcode, unsigned BitSize,
307                                          bool Invert = false) const;
308  MachineBasicBlock *emitAtomicLoadMinMax(MachineInstr *MI,
309                                          MachineBasicBlock *MBB,
310                                          unsigned CompareOpcode,
311                                          unsigned KeepOldMask,
312                                          unsigned BitSize) const;
313  MachineBasicBlock *emitAtomicCmpSwapW(MachineInstr *MI,
314                                        MachineBasicBlock *BB) const;
315  MachineBasicBlock *emitMemMemWrapper(MachineInstr *MI,
316                                       MachineBasicBlock *BB,
317                                       unsigned Opcode) const;
318  MachineBasicBlock *emitStringWrapper(MachineInstr *MI,
319                                       MachineBasicBlock *BB,
320                                       unsigned Opcode) const;
321};
322} // end namespace llvm
323
324#endif // LLVM_TARGET_SystemZ_ISELLOWERING_H
325