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