SystemZISelLowering.h revision 276479
1251607Sdim//===-- SystemZISelLowering.h - SystemZ DAG lowering interface --*- C++ -*-===//
2251607Sdim//
3251607Sdim//                     The LLVM Compiler Infrastructure
4251607Sdim//
5251607Sdim// This file is distributed under the University of Illinois Open Source
6251607Sdim// License. See LICENSE.TXT for details.
7251607Sdim//
8251607Sdim//===----------------------------------------------------------------------===//
9251607Sdim//
10251607Sdim// This file defines the interfaces that SystemZ uses to lower LLVM code into a
11251607Sdim// selection DAG.
12251607Sdim//
13251607Sdim//===----------------------------------------------------------------------===//
14251607Sdim
15251607Sdim#ifndef LLVM_TARGET_SystemZ_ISELLOWERING_H
16251607Sdim#define LLVM_TARGET_SystemZ_ISELLOWERING_H
17251607Sdim
18251607Sdim#include "SystemZ.h"
19261991Sdim#include "llvm/CodeGen/MachineBasicBlock.h"
20251607Sdim#include "llvm/CodeGen/SelectionDAG.h"
21251607Sdim#include "llvm/Target/TargetLowering.h"
22251607Sdim
23251607Sdimnamespace llvm {
24251607Sdimnamespace SystemZISD {
25276479Sdimenum {
26276479Sdim  FIRST_NUMBER = ISD::BUILTIN_OP_END,
27251607Sdim
28276479Sdim  // Return with a flag operand.  Operand 0 is the chain operand.
29276479Sdim  RET_FLAG,
30251607Sdim
31276479Sdim  // Calls a function.  Operand 0 is the chain operand and operand 1
32276479Sdim  // is the target address.  The arguments start at operand 2.
33276479Sdim  // There is an optional glue operand at the end.
34276479Sdim  CALL,
35276479Sdim  SIBCALL,
36251607Sdim
37276479Sdim  // Wraps a TargetGlobalAddress that should be loaded using PC-relative
38276479Sdim  // accesses (LARL).  Operand 0 is the address.
39276479Sdim  PCREL_WRAPPER,
40251607Sdim
41276479Sdim  // Used in cases where an offset is applied to a TargetGlobalAddress.
42276479Sdim  // Operand 0 is the full TargetGlobalAddress and operand 1 is a
43276479Sdim  // PCREL_WRAPPER for an anchor point.  This is used so that we can
44276479Sdim  // cheaply refer to either the full address or the anchor point
45276479Sdim  // as a register base.
46276479Sdim  PCREL_OFFSET,
47251607Sdim
48276479Sdim  // Integer absolute.
49276479Sdim  IABS,
50251607Sdim
51276479Sdim  // Integer comparisons.  There are three operands: the two values
52276479Sdim  // to compare, and an integer of type SystemZICMP.
53276479Sdim  ICMP,
54261991Sdim
55276479Sdim  // Floating-point comparisons.  The two operands are the values to compare.
56276479Sdim  FCMP,
57261991Sdim
58276479Sdim  // Test under mask.  The first operand is ANDed with the second operand
59276479Sdim  // and the condition codes are set on the result.  The third operand is
60276479Sdim  // a boolean that is true if the condition codes need to distinguish
61276479Sdim  // between CCMASK_TM_MIXED_MSB_0 and CCMASK_TM_MIXED_MSB_1 (which the
62276479Sdim  // register forms do but the memory forms don't).
63276479Sdim  TM,
64251607Sdim
65276479Sdim  // Branches if a condition is true.  Operand 0 is the chain operand;
66276479Sdim  // operand 1 is the 4-bit condition-code mask, with bit N in
67276479Sdim  // big-endian order meaning "branch if CC=N"; operand 2 is the
68276479Sdim  // target block and operand 3 is the flag operand.
69276479Sdim  BR_CCMASK,
70251607Sdim
71276479Sdim  // Selects between operand 0 and operand 1.  Operand 2 is the
72276479Sdim  // mask of condition-code values for which operand 0 should be
73276479Sdim  // chosen over operand 1; it has the same form as BR_CCMASK.
74276479Sdim  // Operand 3 is the flag operand.
75276479Sdim  SELECT_CCMASK,
76251607Sdim
77276479Sdim  // Evaluates to the gap between the stack pointer and the
78276479Sdim  // base of the dynamically-allocatable area.
79276479Sdim  ADJDYNALLOC,
80251607Sdim
81276479Sdim  // Extracts the value of a 32-bit access register.  Operand 0 is
82276479Sdim  // the number of the register.
83276479Sdim  EXTRACT_ACCESS,
84251607Sdim
85276479Sdim  // Wrappers around the ISD opcodes of the same name.  The output and
86276479Sdim  // first input operands are GR128s.  The trailing numbers are the
87276479Sdim  // widths of the second operand in bits.
88276479Sdim  UMUL_LOHI64,
89276479Sdim  SDIVREM32,
90276479Sdim  SDIVREM64,
91276479Sdim  UDIVREM32,
92276479Sdim  UDIVREM64,
93261991Sdim
94276479Sdim  // Use a series of MVCs to copy bytes from one memory location to another.
95276479Sdim  // The operands are:
96276479Sdim  // - the target address
97276479Sdim  // - the source address
98276479Sdim  // - the constant length
99276479Sdim  //
100276479Sdim  // This isn't a memory opcode because we'd need to attach two
101276479Sdim  // MachineMemOperands rather than one.
102276479Sdim  MVC,
103261991Sdim
104276479Sdim  // Like MVC, but implemented as a loop that handles X*256 bytes
105276479Sdim  // followed by straight-line code to handle the rest (if any).
106276479Sdim  // The value of X is passed as an additional operand.
107276479Sdim  MVC_LOOP,
108261991Sdim
109276479Sdim  // Similar to MVC and MVC_LOOP, but for logic operations (AND, OR, XOR).
110276479Sdim  NC,
111276479Sdim  NC_LOOP,
112276479Sdim  OC,
113276479Sdim  OC_LOOP,
114276479Sdim  XC,
115276479Sdim  XC_LOOP,
116261991Sdim
117276479Sdim  // Use CLC to compare two blocks of memory, with the same comments
118276479Sdim  // as for MVC and MVC_LOOP.
119276479Sdim  CLC,
120276479Sdim  CLC_LOOP,
121261991Sdim
122276479Sdim  // Use an MVST-based sequence to implement stpcpy().
123276479Sdim  STPCPY,
124261991Sdim
125276479Sdim  // Use a CLST-based sequence to implement strcmp().  The two input operands
126276479Sdim  // are the addresses of the strings to compare.
127276479Sdim  STRCMP,
128261991Sdim
129276479Sdim  // Use an SRST-based sequence to search a block of memory.  The first
130276479Sdim  // operand is the end address, the second is the start, and the third
131276479Sdim  // is the character to search for.  CC is set to 1 on success and 2
132276479Sdim  // on failure.
133276479Sdim  SEARCH_STRING,
134261991Sdim
135276479Sdim  // Store the CC value in bits 29 and 28 of an integer.
136276479Sdim  IPM,
137251607Sdim
138276479Sdim  // Perform a serialization operation.  (BCR 15,0 or BCR 14,0.)
139276479Sdim  SERIALIZE,
140261991Sdim
141276479Sdim  // Wrappers around the inner loop of an 8- or 16-bit ATOMIC_SWAP or
142276479Sdim  // ATOMIC_LOAD_<op>.
143276479Sdim  //
144276479Sdim  // Operand 0: the address of the containing 32-bit-aligned field
145276479Sdim  // Operand 1: the second operand of <op>, in the high bits of an i32
146276479Sdim  //            for everything except ATOMIC_SWAPW
147276479Sdim  // Operand 2: how many bits to rotate the i32 left to bring the first
148276479Sdim  //            operand into the high bits
149276479Sdim  // Operand 3: the negative of operand 2, for rotating the other way
150276479Sdim  // Operand 4: the width of the field in bits (8 or 16)
151276479Sdim  ATOMIC_SWAPW = ISD::FIRST_TARGET_MEMORY_OPCODE,
152276479Sdim  ATOMIC_LOADW_ADD,
153276479Sdim  ATOMIC_LOADW_SUB,
154276479Sdim  ATOMIC_LOADW_AND,
155276479Sdim  ATOMIC_LOADW_OR,
156276479Sdim  ATOMIC_LOADW_XOR,
157276479Sdim  ATOMIC_LOADW_NAND,
158276479Sdim  ATOMIC_LOADW_MIN,
159276479Sdim  ATOMIC_LOADW_MAX,
160276479Sdim  ATOMIC_LOADW_UMIN,
161276479Sdim  ATOMIC_LOADW_UMAX,
162261991Sdim
163276479Sdim  // A wrapper around the inner loop of an ATOMIC_CMP_SWAP.
164276479Sdim  //
165276479Sdim  // Operand 0: the address of the containing 32-bit-aligned field
166276479Sdim  // Operand 1: the compare value, in the low bits of an i32
167276479Sdim  // Operand 2: the swap value, in the low bits of an i32
168276479Sdim  // Operand 3: how many bits to rotate the i32 left to bring the first
169276479Sdim  //            operand into the high bits
170276479Sdim  // Operand 4: the negative of operand 2, for rotating the other way
171276479Sdim  // Operand 5: the width of the field in bits (8 or 16)
172276479Sdim  ATOMIC_CMP_SWAPW,
173276479Sdim
174276479Sdim  // Prefetch from the second operand using the 4-bit control code in
175276479Sdim  // the first operand.  The code is 1 for a load prefetch and 2 for
176276479Sdim  // a store prefetch.
177276479Sdim  PREFETCH
178276479Sdim};
179276479Sdim
180276479Sdim// Return true if OPCODE is some kind of PC-relative address.
181276479Sdiminline bool isPCREL(unsigned Opcode) {
182276479Sdim  return Opcode == PCREL_WRAPPER || Opcode == PCREL_OFFSET;
183251607Sdim}
184276479Sdim} // end namespace SystemZISD
185251607Sdim
186261991Sdimnamespace SystemZICMP {
187276479Sdim// Describes whether an integer comparison needs to be signed or unsigned,
188276479Sdim// or whether either type is OK.
189276479Sdimenum {
190276479Sdim  Any,
191276479Sdim  UnsignedOnly,
192276479Sdim  SignedOnly
193276479Sdim};
194276479Sdim} // end namespace SystemZICMP
195261991Sdim
196251607Sdimclass SystemZSubtarget;
197251607Sdimclass SystemZTargetMachine;
198251607Sdim
199251607Sdimclass SystemZTargetLowering : public TargetLowering {
200251607Sdimpublic:
201276479Sdim  explicit SystemZTargetLowering(const TargetMachine &TM);
202251607Sdim
203251607Sdim  // Override TargetLowering.
204276479Sdim  MVT getScalarShiftAmountTy(EVT LHSTy) const override {
205251607Sdim    return MVT::i32;
206251607Sdim  }
207276479Sdim  EVT getSetCCResultType(LLVMContext &, EVT) const override;
208276479Sdim  bool isFMAFasterThanFMulAndFAdd(EVT VT) const override;
209276479Sdim  bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
210276479Sdim  bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const override;
211276479Sdim  bool allowsUnalignedMemoryAccesses(EVT VT, unsigned AS,
212276479Sdim                                     bool *Fast) const override;
213276479Sdim  bool isTruncateFree(Type *, Type *) const override;
214276479Sdim  bool isTruncateFree(EVT, EVT) const override;
215276479Sdim  const char *getTargetNodeName(unsigned Opcode) const override;
216276479Sdim  std::pair<unsigned, const TargetRegisterClass *>
217251607Sdim    getRegForInlineAsmConstraint(const std::string &Constraint,
218276479Sdim                                 MVT VT) const override;
219276479Sdim  TargetLowering::ConstraintType
220276479Sdim    getConstraintType(const std::string &Constraint) const override;
221276479Sdim  TargetLowering::ConstraintWeight
222251607Sdim    getSingleConstraintMatchWeight(AsmOperandInfo &info,
223276479Sdim                                   const char *constraint) const override;
224276479Sdim  void LowerAsmOperandForConstraint(SDValue Op,
225276479Sdim                                    std::string &Constraint,
226276479Sdim                                    std::vector<SDValue> &Ops,
227276479Sdim                                    SelectionDAG &DAG) const override;
228276479Sdim  MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
229276479Sdim                                                 MachineBasicBlock *BB) const
230276479Sdim    override;
231276479Sdim  SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
232276479Sdim  bool allowTruncateForTailCall(Type *, Type *) const override;
233276479Sdim  bool mayBeEmittedAsTailCall(CallInst *CI) const override;
234276479Sdim  SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
235276479Sdim                               bool isVarArg,
236276479Sdim                               const SmallVectorImpl<ISD::InputArg> &Ins,
237276479Sdim                               SDLoc DL, SelectionDAG &DAG,
238276479Sdim                               SmallVectorImpl<SDValue> &InVals) const override;
239276479Sdim  SDValue LowerCall(CallLoweringInfo &CLI,
240276479Sdim                    SmallVectorImpl<SDValue> &InVals) const override;
241251607Sdim
242276479Sdim  SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
243276479Sdim                      const SmallVectorImpl<ISD::OutputArg> &Outs,
244276479Sdim                      const SmallVectorImpl<SDValue> &OutVals,
245276479Sdim                      SDLoc DL, SelectionDAG &DAG) const override;
246276479Sdim  SDValue prepareVolatileOrAtomicLoad(SDValue Chain, SDLoc DL,
247276479Sdim                                      SelectionDAG &DAG) const override;
248276479Sdim  SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
249251607Sdim
250251607Sdimprivate:
251251607Sdim  const SystemZSubtarget &Subtarget;
252251607Sdim
253251607Sdim  // Implement LowerOperation for individual opcodes.
254261991Sdim  SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const;
255251607Sdim  SDValue lowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
256251607Sdim  SDValue lowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
257251607Sdim  SDValue lowerGlobalAddress(GlobalAddressSDNode *Node,
258251607Sdim                             SelectionDAG &DAG) const;
259251607Sdim  SDValue lowerGlobalTLSAddress(GlobalAddressSDNode *Node,
260251607Sdim                                SelectionDAG &DAG) const;
261251607Sdim  SDValue lowerBlockAddress(BlockAddressSDNode *Node,
262251607Sdim                            SelectionDAG &DAG) const;
263251607Sdim  SDValue lowerJumpTable(JumpTableSDNode *JT, SelectionDAG &DAG) const;
264251607Sdim  SDValue lowerConstantPool(ConstantPoolSDNode *CP, SelectionDAG &DAG) const;
265251607Sdim  SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
266251607Sdim  SDValue lowerVACOPY(SDValue Op, SelectionDAG &DAG) const;
267251607Sdim  SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
268261991Sdim  SDValue lowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const;
269251607Sdim  SDValue lowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const;
270251607Sdim  SDValue lowerSDIVREM(SDValue Op, SelectionDAG &DAG) const;
271251607Sdim  SDValue lowerUDIVREM(SDValue Op, SelectionDAG &DAG) const;
272251607Sdim  SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const;
273251607Sdim  SDValue lowerOR(SDValue Op, SelectionDAG &DAG) const;
274276479Sdim  SDValue lowerATOMIC_LOAD(SDValue Op, SelectionDAG &DAG) const;
275276479Sdim  SDValue lowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG) const;
276276479Sdim  SDValue lowerATOMIC_LOAD_OP(SDValue Op, SelectionDAG &DAG,
277276479Sdim                              unsigned Opcode) const;
278276479Sdim  SDValue lowerATOMIC_LOAD_SUB(SDValue Op, SelectionDAG &DAG) const;
279251607Sdim  SDValue lowerATOMIC_CMP_SWAP(SDValue Op, SelectionDAG &DAG) const;
280276479Sdim  SDValue lowerLOAD_SEQUENCE_POINT(SDValue Op, SelectionDAG &DAG) const;
281251607Sdim  SDValue lowerSTACKSAVE(SDValue Op, SelectionDAG &DAG) const;
282251607Sdim  SDValue lowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const;
283261991Sdim  SDValue lowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;
284251607Sdim
285261991Sdim  // If the last instruction before MBBI in MBB was some form of COMPARE,
286261991Sdim  // try to replace it with a COMPARE AND BRANCH just before MBBI.
287261991Sdim  // CCMask and Target are the BRC-like operands for the branch.
288261991Sdim  // Return true if the change was made.
289261991Sdim  bool convertPrevCompareToBranch(MachineBasicBlock *MBB,
290261991Sdim                                  MachineBasicBlock::iterator MBBI,
291261991Sdim                                  unsigned CCMask,
292261991Sdim                                  MachineBasicBlock *Target) const;
293261991Sdim
294251607Sdim  // Implement EmitInstrWithCustomInserter for individual operation types.
295251607Sdim  MachineBasicBlock *emitSelect(MachineInstr *MI,
296251607Sdim                                MachineBasicBlock *BB) const;
297261991Sdim  MachineBasicBlock *emitCondStore(MachineInstr *MI,
298261991Sdim                                   MachineBasicBlock *BB,
299261991Sdim                                   unsigned StoreOpcode, unsigned STOCOpcode,
300261991Sdim                                   bool Invert) const;
301251607Sdim  MachineBasicBlock *emitExt128(MachineInstr *MI,
302251607Sdim                                MachineBasicBlock *MBB,
303251607Sdim                                bool ClearEven, unsigned SubReg) const;
304251607Sdim  MachineBasicBlock *emitAtomicLoadBinary(MachineInstr *MI,
305251607Sdim                                          MachineBasicBlock *BB,
306251607Sdim                                          unsigned BinOpcode, unsigned BitSize,
307251607Sdim                                          bool Invert = false) const;
308251607Sdim  MachineBasicBlock *emitAtomicLoadMinMax(MachineInstr *MI,
309251607Sdim                                          MachineBasicBlock *MBB,
310251607Sdim                                          unsigned CompareOpcode,
311251607Sdim                                          unsigned KeepOldMask,
312251607Sdim                                          unsigned BitSize) const;
313251607Sdim  MachineBasicBlock *emitAtomicCmpSwapW(MachineInstr *MI,
314251607Sdim                                        MachineBasicBlock *BB) const;
315261991Sdim  MachineBasicBlock *emitMemMemWrapper(MachineInstr *MI,
316261991Sdim                                       MachineBasicBlock *BB,
317261991Sdim                                       unsigned Opcode) const;
318261991Sdim  MachineBasicBlock *emitStringWrapper(MachineInstr *MI,
319261991Sdim                                       MachineBasicBlock *BB,
320261991Sdim                                       unsigned Opcode) const;
321251607Sdim};
322251607Sdim} // end namespace llvm
323251607Sdim
324251607Sdim#endif // LLVM_TARGET_SystemZ_ISELLOWERING_H
325