LLVM API Documentation

SystemZISelLowering.h
Go to the documentation of this file.
00001 //===-- SystemZISelLowering.h - SystemZ DAG lowering interface --*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the interfaces that SystemZ uses to lower LLVM code into a
00011 // selection DAG.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZISELLOWERING_H
00016 #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZISELLOWERING_H
00017 
00018 #include "SystemZ.h"
00019 #include "llvm/CodeGen/MachineBasicBlock.h"
00020 #include "llvm/CodeGen/SelectionDAG.h"
00021 #include "llvm/Target/TargetLowering.h"
00022 
00023 namespace llvm {
00024 namespace SystemZISD {
00025 enum {
00026   FIRST_NUMBER = ISD::BUILTIN_OP_END,
00027 
00028   // Return with a flag operand.  Operand 0 is the chain operand.
00029   RET_FLAG,
00030 
00031   // Calls a function.  Operand 0 is the chain operand and operand 1
00032   // is the target address.  The arguments start at operand 2.
00033   // There is an optional glue operand at the end.
00034   CALL,
00035   SIBCALL,
00036 
00037   // Wraps a TargetGlobalAddress that should be loaded using PC-relative
00038   // accesses (LARL).  Operand 0 is the address.
00039   PCREL_WRAPPER,
00040 
00041   // Used in cases where an offset is applied to a TargetGlobalAddress.
00042   // Operand 0 is the full TargetGlobalAddress and operand 1 is a
00043   // PCREL_WRAPPER for an anchor point.  This is used so that we can
00044   // cheaply refer to either the full address or the anchor point
00045   // as a register base.
00046   PCREL_OFFSET,
00047 
00048   // Integer absolute.
00049   IABS,
00050 
00051   // Integer comparisons.  There are three operands: the two values
00052   // to compare, and an integer of type SystemZICMP.
00053   ICMP,
00054 
00055   // Floating-point comparisons.  The two operands are the values to compare.
00056   FCMP,
00057 
00058   // Test under mask.  The first operand is ANDed with the second operand
00059   // and the condition codes are set on the result.  The third operand is
00060   // a boolean that is true if the condition codes need to distinguish
00061   // between CCMASK_TM_MIXED_MSB_0 and CCMASK_TM_MIXED_MSB_1 (which the
00062   // register forms do but the memory forms don't).
00063   TM,
00064 
00065   // Branches if a condition is true.  Operand 0 is the chain operand;
00066   // operand 1 is the 4-bit condition-code mask, with bit N in
00067   // big-endian order meaning "branch if CC=N"; operand 2 is the
00068   // target block and operand 3 is the flag operand.
00069   BR_CCMASK,
00070 
00071   // Selects between operand 0 and operand 1.  Operand 2 is the
00072   // mask of condition-code values for which operand 0 should be
00073   // chosen over operand 1; it has the same form as BR_CCMASK.
00074   // Operand 3 is the flag operand.
00075   SELECT_CCMASK,
00076 
00077   // Evaluates to the gap between the stack pointer and the
00078   // base of the dynamically-allocatable area.
00079   ADJDYNALLOC,
00080 
00081   // Extracts the value of a 32-bit access register.  Operand 0 is
00082   // the number of the register.
00083   EXTRACT_ACCESS,
00084 
00085   // Wrappers around the ISD opcodes of the same name.  The output and
00086   // first input operands are GR128s.  The trailing numbers are the
00087   // widths of the second operand in bits.
00088   UMUL_LOHI64,
00089   SDIVREM32,
00090   SDIVREM64,
00091   UDIVREM32,
00092   UDIVREM64,
00093 
00094   // Use a series of MVCs to copy bytes from one memory location to another.
00095   // The operands are:
00096   // - the target address
00097   // - the source address
00098   // - the constant length
00099   //
00100   // This isn't a memory opcode because we'd need to attach two
00101   // MachineMemOperands rather than one.
00102   MVC,
00103 
00104   // Like MVC, but implemented as a loop that handles X*256 bytes
00105   // followed by straight-line code to handle the rest (if any).
00106   // The value of X is passed as an additional operand.
00107   MVC_LOOP,
00108 
00109   // Similar to MVC and MVC_LOOP, but for logic operations (AND, OR, XOR).
00110   NC,
00111   NC_LOOP,
00112   OC,
00113   OC_LOOP,
00114   XC,
00115   XC_LOOP,
00116 
00117   // Use CLC to compare two blocks of memory, with the same comments
00118   // as for MVC and MVC_LOOP.
00119   CLC,
00120   CLC_LOOP,
00121 
00122   // Use an MVST-based sequence to implement stpcpy().
00123   STPCPY,
00124 
00125   // Use a CLST-based sequence to implement strcmp().  The two input operands
00126   // are the addresses of the strings to compare.
00127   STRCMP,
00128 
00129   // Use an SRST-based sequence to search a block of memory.  The first
00130   // operand is the end address, the second is the start, and the third
00131   // is the character to search for.  CC is set to 1 on success and 2
00132   // on failure.
00133   SEARCH_STRING,
00134 
00135   // Store the CC value in bits 29 and 28 of an integer.
00136   IPM,
00137 
00138   // Perform a serialization operation.  (BCR 15,0 or BCR 14,0.)
00139   SERIALIZE,
00140 
00141   // Wrappers around the inner loop of an 8- or 16-bit ATOMIC_SWAP or
00142   // ATOMIC_LOAD_<op>.
00143   //
00144   // Operand 0: the address of the containing 32-bit-aligned field
00145   // Operand 1: the second operand of <op>, in the high bits of an i32
00146   //            for everything except ATOMIC_SWAPW
00147   // Operand 2: how many bits to rotate the i32 left to bring the first
00148   //            operand into the high bits
00149   // Operand 3: the negative of operand 2, for rotating the other way
00150   // Operand 4: the width of the field in bits (8 or 16)
00151   ATOMIC_SWAPW = ISD::FIRST_TARGET_MEMORY_OPCODE,
00152   ATOMIC_LOADW_ADD,
00153   ATOMIC_LOADW_SUB,
00154   ATOMIC_LOADW_AND,
00155   ATOMIC_LOADW_OR,
00156   ATOMIC_LOADW_XOR,
00157   ATOMIC_LOADW_NAND,
00158   ATOMIC_LOADW_MIN,
00159   ATOMIC_LOADW_MAX,
00160   ATOMIC_LOADW_UMIN,
00161   ATOMIC_LOADW_UMAX,
00162 
00163   // A wrapper around the inner loop of an ATOMIC_CMP_SWAP.
00164   //
00165   // Operand 0: the address of the containing 32-bit-aligned field
00166   // Operand 1: the compare value, in the low bits of an i32
00167   // Operand 2: the swap value, in the low bits of an i32
00168   // Operand 3: how many bits to rotate the i32 left to bring the first
00169   //            operand into the high bits
00170   // Operand 4: the negative of operand 2, for rotating the other way
00171   // Operand 5: the width of the field in bits (8 or 16)
00172   ATOMIC_CMP_SWAPW,
00173 
00174   // Prefetch from the second operand using the 4-bit control code in
00175   // the first operand.  The code is 1 for a load prefetch and 2 for
00176   // a store prefetch.
00177   PREFETCH
00178 };
00179 
00180 // Return true if OPCODE is some kind of PC-relative address.
00181 inline bool isPCREL(unsigned Opcode) {
00182   return Opcode == PCREL_WRAPPER || Opcode == PCREL_OFFSET;
00183 }
00184 } // end namespace SystemZISD
00185 
00186 namespace SystemZICMP {
00187 // Describes whether an integer comparison needs to be signed or unsigned,
00188 // or whether either type is OK.
00189 enum {
00190   Any,
00191   UnsignedOnly,
00192   SignedOnly
00193 };
00194 } // end namespace SystemZICMP
00195 
00196 class SystemZSubtarget;
00197 class SystemZTargetMachine;
00198 
00199 class SystemZTargetLowering : public TargetLowering {
00200 public:
00201   explicit SystemZTargetLowering(const TargetMachine &TM);
00202 
00203   // Override TargetLowering.
00204   MVT getScalarShiftAmountTy(EVT LHSTy) const override {
00205     return MVT::i32;
00206   }
00207   EVT getSetCCResultType(LLVMContext &, EVT) const override;
00208   bool isFMAFasterThanFMulAndFAdd(EVT VT) const override;
00209   bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
00210   bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const override;
00211   bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS,
00212                                       unsigned Align,
00213                                       bool *Fast) const override;
00214   bool isTruncateFree(Type *, Type *) const override;
00215   bool isTruncateFree(EVT, EVT) const override;
00216   const char *getTargetNodeName(unsigned Opcode) const override;
00217   std::pair<unsigned, const TargetRegisterClass *>
00218     getRegForInlineAsmConstraint(const std::string &Constraint,
00219                                  MVT VT) const override;
00220   TargetLowering::ConstraintType
00221     getConstraintType(const std::string &Constraint) const override;
00222   TargetLowering::ConstraintWeight
00223     getSingleConstraintMatchWeight(AsmOperandInfo &info,
00224                                    const char *constraint) const override;
00225   void LowerAsmOperandForConstraint(SDValue Op,
00226                                     std::string &Constraint,
00227                                     std::vector<SDValue> &Ops,
00228                                     SelectionDAG &DAG) const override;
00229   MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
00230                                                  MachineBasicBlock *BB) const
00231     override;
00232   SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
00233   bool allowTruncateForTailCall(Type *, Type *) const override;
00234   bool mayBeEmittedAsTailCall(CallInst *CI) const override;
00235   SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
00236                                bool isVarArg,
00237                                const SmallVectorImpl<ISD::InputArg> &Ins,
00238                                SDLoc DL, SelectionDAG &DAG,
00239                                SmallVectorImpl<SDValue> &InVals) const override;
00240   SDValue LowerCall(CallLoweringInfo &CLI,
00241                     SmallVectorImpl<SDValue> &InVals) const override;
00242 
00243   SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
00244                       const SmallVectorImpl<ISD::OutputArg> &Outs,
00245                       const SmallVectorImpl<SDValue> &OutVals,
00246                       SDLoc DL, SelectionDAG &DAG) const override;
00247   SDValue prepareVolatileOrAtomicLoad(SDValue Chain, SDLoc DL,
00248                                       SelectionDAG &DAG) const override;
00249   SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
00250 
00251 private:
00252   const SystemZSubtarget &Subtarget;
00253 
00254   // Implement LowerOperation for individual opcodes.
00255   SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const;
00256   SDValue lowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
00257   SDValue lowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
00258   SDValue lowerGlobalAddress(GlobalAddressSDNode *Node,
00259                              SelectionDAG &DAG) const;
00260   SDValue lowerGlobalTLSAddress(GlobalAddressSDNode *Node,
00261                                 SelectionDAG &DAG) const;
00262   SDValue lowerBlockAddress(BlockAddressSDNode *Node,
00263                             SelectionDAG &DAG) const;
00264   SDValue lowerJumpTable(JumpTableSDNode *JT, SelectionDAG &DAG) const;
00265   SDValue lowerConstantPool(ConstantPoolSDNode *CP, SelectionDAG &DAG) const;
00266   SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
00267   SDValue lowerVACOPY(SDValue Op, SelectionDAG &DAG) const;
00268   SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
00269   SDValue lowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const;
00270   SDValue lowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const;
00271   SDValue lowerSDIVREM(SDValue Op, SelectionDAG &DAG) const;
00272   SDValue lowerUDIVREM(SDValue Op, SelectionDAG &DAG) const;
00273   SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const;
00274   SDValue lowerOR(SDValue Op, SelectionDAG &DAG) const;
00275   SDValue lowerATOMIC_LOAD(SDValue Op, SelectionDAG &DAG) const;
00276   SDValue lowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG) const;
00277   SDValue lowerATOMIC_LOAD_OP(SDValue Op, SelectionDAG &DAG,
00278                               unsigned Opcode) const;
00279   SDValue lowerATOMIC_LOAD_SUB(SDValue Op, SelectionDAG &DAG) const;
00280   SDValue lowerATOMIC_CMP_SWAP(SDValue Op, SelectionDAG &DAG) const;
00281   SDValue lowerLOAD_SEQUENCE_POINT(SDValue Op, SelectionDAG &DAG) const;
00282   SDValue lowerSTACKSAVE(SDValue Op, SelectionDAG &DAG) const;
00283   SDValue lowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const;
00284   SDValue lowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;
00285 
00286   // If the last instruction before MBBI in MBB was some form of COMPARE,
00287   // try to replace it with a COMPARE AND BRANCH just before MBBI.
00288   // CCMask and Target are the BRC-like operands for the branch.
00289   // Return true if the change was made.
00290   bool convertPrevCompareToBranch(MachineBasicBlock *MBB,
00291                                   MachineBasicBlock::iterator MBBI,
00292                                   unsigned CCMask,
00293                                   MachineBasicBlock *Target) const;
00294 
00295   // Implement EmitInstrWithCustomInserter for individual operation types.
00296   MachineBasicBlock *emitSelect(MachineInstr *MI,
00297                                 MachineBasicBlock *BB) const;
00298   MachineBasicBlock *emitCondStore(MachineInstr *MI,
00299                                    MachineBasicBlock *BB,
00300                                    unsigned StoreOpcode, unsigned STOCOpcode,
00301                                    bool Invert) const;
00302   MachineBasicBlock *emitExt128(MachineInstr *MI,
00303                                 MachineBasicBlock *MBB,
00304                                 bool ClearEven, unsigned SubReg) const;
00305   MachineBasicBlock *emitAtomicLoadBinary(MachineInstr *MI,
00306                                           MachineBasicBlock *BB,
00307                                           unsigned BinOpcode, unsigned BitSize,
00308                                           bool Invert = false) const;
00309   MachineBasicBlock *emitAtomicLoadMinMax(MachineInstr *MI,
00310                                           MachineBasicBlock *MBB,
00311                                           unsigned CompareOpcode,
00312                                           unsigned KeepOldMask,
00313                                           unsigned BitSize) const;
00314   MachineBasicBlock *emitAtomicCmpSwapW(MachineInstr *MI,
00315                                         MachineBasicBlock *BB) const;
00316   MachineBasicBlock *emitMemMemWrapper(MachineInstr *MI,
00317                                        MachineBasicBlock *BB,
00318                                        unsigned Opcode) const;
00319   MachineBasicBlock *emitStringWrapper(MachineInstr *MI,
00320                                        MachineBasicBlock *BB,
00321                                        unsigned Opcode) const;
00322 };
00323 } // end namespace llvm
00324 
00325 #endif