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" 19263508Sdim#include "llvm/CodeGen/MachineBasicBlock.h" 20251607Sdim#include "llvm/CodeGen/SelectionDAG.h" 21251607Sdim#include "llvm/Target/TargetLowering.h" 22251607Sdim 23251607Sdimnamespace llvm { 24251607Sdimnamespace SystemZISD { 25251607Sdim enum { 26251607Sdim FIRST_NUMBER = ISD::BUILTIN_OP_END, 27251607Sdim 28251607Sdim // Return with a flag operand. Operand 0 is the chain operand. 29251607Sdim RET_FLAG, 30251607Sdim 31251607Sdim // Calls a function. Operand 0 is the chain operand and operand 1 32251607Sdim // is the target address. The arguments start at operand 2. 33251607Sdim // There is an optional glue operand at the end. 34251607Sdim CALL, 35263508Sdim SIBCALL, 36251607Sdim 37251607Sdim // Wraps a TargetGlobalAddress that should be loaded using PC-relative 38251607Sdim // accesses (LARL). Operand 0 is the address. 39251607Sdim PCREL_WRAPPER, 40251607Sdim 41263508Sdim // Used in cases where an offset is applied to a TargetGlobalAddress. 42263508Sdim // Operand 0 is the full TargetGlobalAddress and operand 1 is a 43263508Sdim // PCREL_WRAPPER for an anchor point. This is used so that we can 44263508Sdim // cheaply refer to either the full address or the anchor point 45263508Sdim // as a register base. 46263508Sdim PCREL_OFFSET, 47251607Sdim 48263508Sdim // Integer comparisons. There are three operands: the two values 49263508Sdim // to compare, and an integer of type SystemZICMP. 50263508Sdim ICMP, 51251607Sdim 52263508Sdim // Floating-point comparisons. The two operands are the values to compare. 53263508Sdim FCMP, 54263508Sdim 55263508Sdim // Test under mask. The first operand is ANDed with the second operand 56263508Sdim // and the condition codes are set on the result. The third operand is 57263508Sdim // a boolean that is true if the condition codes need to distinguish 58263508Sdim // between CCMASK_TM_MIXED_MSB_0 and CCMASK_TM_MIXED_MSB_1 (which the 59263508Sdim // register forms do but the memory forms don't). 60263508Sdim TM, 61263508Sdim 62251607Sdim // Branches if a condition is true. Operand 0 is the chain operand; 63251607Sdim // operand 1 is the 4-bit condition-code mask, with bit N in 64251607Sdim // big-endian order meaning "branch if CC=N"; operand 2 is the 65251607Sdim // target block and operand 3 is the flag operand. 66251607Sdim BR_CCMASK, 67251607Sdim 68251607Sdim // Selects between operand 0 and operand 1. Operand 2 is the 69251607Sdim // mask of condition-code values for which operand 0 should be 70251607Sdim // chosen over operand 1; it has the same form as BR_CCMASK. 71251607Sdim // Operand 3 is the flag operand. 72251607Sdim SELECT_CCMASK, 73251607Sdim 74251607Sdim // Evaluates to the gap between the stack pointer and the 75251607Sdim // base of the dynamically-allocatable area. 76251607Sdim ADJDYNALLOC, 77251607Sdim 78251607Sdim // Extracts the value of a 32-bit access register. Operand 0 is 79251607Sdim // the number of the register. 80251607Sdim EXTRACT_ACCESS, 81251607Sdim 82251607Sdim // Wrappers around the ISD opcodes of the same name. The output and 83251607Sdim // first input operands are GR128s. The trailing numbers are the 84251607Sdim // widths of the second operand in bits. 85251607Sdim UMUL_LOHI64, 86263508Sdim SDIVREM32, 87251607Sdim SDIVREM64, 88251607Sdim UDIVREM32, 89251607Sdim UDIVREM64, 90251607Sdim 91263508Sdim // Use a series of MVCs to copy bytes from one memory location to another. 92263508Sdim // The operands are: 93263508Sdim // - the target address 94263508Sdim // - the source address 95263508Sdim // - the constant length 96263508Sdim // 97263508Sdim // This isn't a memory opcode because we'd need to attach two 98263508Sdim // MachineMemOperands rather than one. 99263508Sdim MVC, 100263508Sdim 101263508Sdim // Like MVC, but implemented as a loop that handles X*256 bytes 102263508Sdim // followed by straight-line code to handle the rest (if any). 103263508Sdim // The value of X is passed as an additional operand. 104263508Sdim MVC_LOOP, 105263508Sdim 106263508Sdim // Similar to MVC and MVC_LOOP, but for logic operations (AND, OR, XOR). 107263508Sdim NC, 108263508Sdim NC_LOOP, 109263508Sdim OC, 110263508Sdim OC_LOOP, 111263508Sdim XC, 112263508Sdim XC_LOOP, 113263508Sdim 114263508Sdim // Use CLC to compare two blocks of memory, with the same comments 115263508Sdim // as for MVC and MVC_LOOP. 116263508Sdim CLC, 117263508Sdim CLC_LOOP, 118263508Sdim 119263508Sdim // Use an MVST-based sequence to implement stpcpy(). 120263508Sdim STPCPY, 121263508Sdim 122263508Sdim // Use a CLST-based sequence to implement strcmp(). The two input operands 123263508Sdim // are the addresses of the strings to compare. 124263508Sdim STRCMP, 125263508Sdim 126263508Sdim // Use an SRST-based sequence to search a block of memory. The first 127263508Sdim // operand is the end address, the second is the start, and the third 128263508Sdim // is the character to search for. CC is set to 1 on success and 2 129263508Sdim // on failure. 130263508Sdim SEARCH_STRING, 131263508Sdim 132263508Sdim // Store the CC value in bits 29 and 28 of an integer. 133263508Sdim IPM, 134263508Sdim 135251607Sdim // Wrappers around the inner loop of an 8- or 16-bit ATOMIC_SWAP or 136251607Sdim // ATOMIC_LOAD_<op>. 137251607Sdim // 138251607Sdim // Operand 0: the address of the containing 32-bit-aligned field 139251607Sdim // Operand 1: the second operand of <op>, in the high bits of an i32 140251607Sdim // for everything except ATOMIC_SWAPW 141251607Sdim // Operand 2: how many bits to rotate the i32 left to bring the first 142251607Sdim // operand into the high bits 143251607Sdim // Operand 3: the negative of operand 2, for rotating the other way 144251607Sdim // Operand 4: the width of the field in bits (8 or 16) 145251607Sdim ATOMIC_SWAPW = ISD::FIRST_TARGET_MEMORY_OPCODE, 146251607Sdim ATOMIC_LOADW_ADD, 147251607Sdim ATOMIC_LOADW_SUB, 148251607Sdim ATOMIC_LOADW_AND, 149251607Sdim ATOMIC_LOADW_OR, 150251607Sdim ATOMIC_LOADW_XOR, 151251607Sdim ATOMIC_LOADW_NAND, 152251607Sdim ATOMIC_LOADW_MIN, 153251607Sdim ATOMIC_LOADW_MAX, 154251607Sdim ATOMIC_LOADW_UMIN, 155251607Sdim ATOMIC_LOADW_UMAX, 156251607Sdim 157251607Sdim // A wrapper around the inner loop of an ATOMIC_CMP_SWAP. 158251607Sdim // 159251607Sdim // Operand 0: the address of the containing 32-bit-aligned field 160251607Sdim // Operand 1: the compare value, in the low bits of an i32 161251607Sdim // Operand 2: the swap value, in the low bits of an i32 162251607Sdim // Operand 3: how many bits to rotate the i32 left to bring the first 163251607Sdim // operand into the high bits 164251607Sdim // Operand 4: the negative of operand 2, for rotating the other way 165251607Sdim // Operand 5: the width of the field in bits (8 or 16) 166263508Sdim ATOMIC_CMP_SWAPW, 167263508Sdim 168263508Sdim // Prefetch from the second operand using the 4-bit control code in 169263508Sdim // the first operand. The code is 1 for a load prefetch and 2 for 170263508Sdim // a store prefetch. 171263508Sdim PREFETCH 172251607Sdim }; 173263508Sdim 174263508Sdim // Return true if OPCODE is some kind of PC-relative address. 175263508Sdim inline bool isPCREL(unsigned Opcode) { 176263508Sdim return Opcode == PCREL_WRAPPER || Opcode == PCREL_OFFSET; 177263508Sdim } 178251607Sdim} 179251607Sdim 180263508Sdimnamespace SystemZICMP { 181263508Sdim // Describes whether an integer comparison needs to be signed or unsigned, 182263508Sdim // or whether either type is OK. 183263508Sdim enum { 184263508Sdim Any, 185263508Sdim UnsignedOnly, 186263508Sdim SignedOnly 187263508Sdim }; 188263508Sdim} 189263508Sdim 190251607Sdimclass SystemZSubtarget; 191251607Sdimclass SystemZTargetMachine; 192251607Sdim 193251607Sdimclass SystemZTargetLowering : public TargetLowering { 194251607Sdimpublic: 195251607Sdim explicit SystemZTargetLowering(SystemZTargetMachine &TM); 196251607Sdim 197251607Sdim // Override TargetLowering. 198251607Sdim virtual MVT getScalarShiftAmountTy(EVT LHSTy) const LLVM_OVERRIDE { 199251607Sdim return MVT::i32; 200251607Sdim } 201263508Sdim virtual EVT getSetCCResultType(LLVMContext &, EVT) const LLVM_OVERRIDE; 202263508Sdim virtual bool isFMAFasterThanFMulAndFAdd(EVT VT) const LLVM_OVERRIDE; 203263508Sdim virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const LLVM_OVERRIDE; 204263508Sdim virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const 205263508Sdim LLVM_OVERRIDE; 206263508Sdim virtual bool allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const 207263508Sdim LLVM_OVERRIDE; 208263508Sdim virtual bool isTruncateFree(Type *, Type *) const LLVM_OVERRIDE; 209263508Sdim virtual bool isTruncateFree(EVT, EVT) const LLVM_OVERRIDE; 210251607Sdim virtual const char *getTargetNodeName(unsigned Opcode) const LLVM_OVERRIDE; 211251607Sdim virtual std::pair<unsigned, const TargetRegisterClass *> 212251607Sdim getRegForInlineAsmConstraint(const std::string &Constraint, 213263508Sdim MVT VT) const LLVM_OVERRIDE; 214251607Sdim virtual TargetLowering::ConstraintType 215251607Sdim getConstraintType(const std::string &Constraint) const LLVM_OVERRIDE; 216251607Sdim virtual TargetLowering::ConstraintWeight 217251607Sdim getSingleConstraintMatchWeight(AsmOperandInfo &info, 218251607Sdim const char *constraint) const LLVM_OVERRIDE; 219251607Sdim virtual void 220251607Sdim LowerAsmOperandForConstraint(SDValue Op, 221251607Sdim std::string &Constraint, 222251607Sdim std::vector<SDValue> &Ops, 223251607Sdim SelectionDAG &DAG) const LLVM_OVERRIDE; 224251607Sdim virtual MachineBasicBlock * 225251607Sdim EmitInstrWithCustomInserter(MachineInstr *MI, 226251607Sdim MachineBasicBlock *BB) const LLVM_OVERRIDE; 227251607Sdim virtual SDValue LowerOperation(SDValue Op, 228251607Sdim SelectionDAG &DAG) const LLVM_OVERRIDE; 229263508Sdim virtual bool allowTruncateForTailCall(Type *, Type *) const LLVM_OVERRIDE; 230263508Sdim virtual bool mayBeEmittedAsTailCall(CallInst *CI) const LLVM_OVERRIDE; 231251607Sdim virtual SDValue 232251607Sdim LowerFormalArguments(SDValue Chain, 233251607Sdim CallingConv::ID CallConv, bool isVarArg, 234251607Sdim const SmallVectorImpl<ISD::InputArg> &Ins, 235263508Sdim SDLoc DL, SelectionDAG &DAG, 236251607Sdim SmallVectorImpl<SDValue> &InVals) const LLVM_OVERRIDE; 237251607Sdim virtual SDValue 238251607Sdim LowerCall(CallLoweringInfo &CLI, 239251607Sdim SmallVectorImpl<SDValue> &InVals) const LLVM_OVERRIDE; 240251607Sdim 241251607Sdim virtual SDValue 242251607Sdim LowerReturn(SDValue Chain, 243251607Sdim CallingConv::ID CallConv, bool IsVarArg, 244251607Sdim const SmallVectorImpl<ISD::OutputArg> &Outs, 245251607Sdim const SmallVectorImpl<SDValue> &OutVals, 246263508Sdim SDLoc DL, SelectionDAG &DAG) const LLVM_OVERRIDE; 247251607Sdim 248251607Sdimprivate: 249251607Sdim const SystemZSubtarget &Subtarget; 250251607Sdim const SystemZTargetMachine &TM; 251251607Sdim 252251607Sdim // Implement LowerOperation for individual opcodes. 253263508Sdim SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const; 254251607Sdim SDValue lowerBR_CC(SDValue Op, SelectionDAG &DAG) const; 255251607Sdim SDValue lowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; 256251607Sdim SDValue lowerGlobalAddress(GlobalAddressSDNode *Node, 257251607Sdim SelectionDAG &DAG) const; 258251607Sdim SDValue lowerGlobalTLSAddress(GlobalAddressSDNode *Node, 259251607Sdim SelectionDAG &DAG) const; 260251607Sdim SDValue lowerBlockAddress(BlockAddressSDNode *Node, 261251607Sdim SelectionDAG &DAG) const; 262251607Sdim SDValue lowerJumpTable(JumpTableSDNode *JT, SelectionDAG &DAG) const; 263251607Sdim SDValue lowerConstantPool(ConstantPoolSDNode *CP, SelectionDAG &DAG) const; 264251607Sdim SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const; 265251607Sdim SDValue lowerVACOPY(SDValue Op, SelectionDAG &DAG) const; 266251607Sdim SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; 267263508Sdim SDValue lowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const; 268251607Sdim SDValue lowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const; 269251607Sdim SDValue lowerSDIVREM(SDValue Op, SelectionDAG &DAG) const; 270251607Sdim SDValue lowerUDIVREM(SDValue Op, SelectionDAG &DAG) const; 271251607Sdim SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const; 272251607Sdim SDValue lowerOR(SDValue Op, SelectionDAG &DAG) const; 273251607Sdim SDValue lowerATOMIC_LOAD(SDValue Op, SelectionDAG &DAG, 274251607Sdim unsigned Opcode) const; 275251607Sdim SDValue lowerATOMIC_CMP_SWAP(SDValue Op, SelectionDAG &DAG) const; 276251607Sdim SDValue lowerSTACKSAVE(SDValue Op, SelectionDAG &DAG) const; 277251607Sdim SDValue lowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const; 278263508Sdim SDValue lowerPREFETCH(SDValue Op, SelectionDAG &DAG) const; 279251607Sdim 280263508Sdim // If the last instruction before MBBI in MBB was some form of COMPARE, 281263508Sdim // try to replace it with a COMPARE AND BRANCH just before MBBI. 282263508Sdim // CCMask and Target are the BRC-like operands for the branch. 283263508Sdim // Return true if the change was made. 284263508Sdim bool convertPrevCompareToBranch(MachineBasicBlock *MBB, 285263508Sdim MachineBasicBlock::iterator MBBI, 286263508Sdim unsigned CCMask, 287263508Sdim MachineBasicBlock *Target) const; 288263508Sdim 289251607Sdim // Implement EmitInstrWithCustomInserter for individual operation types. 290251607Sdim MachineBasicBlock *emitSelect(MachineInstr *MI, 291251607Sdim MachineBasicBlock *BB) const; 292263508Sdim MachineBasicBlock *emitCondStore(MachineInstr *MI, 293263508Sdim MachineBasicBlock *BB, 294263508Sdim unsigned StoreOpcode, unsigned STOCOpcode, 295263508Sdim bool Invert) const; 296251607Sdim MachineBasicBlock *emitExt128(MachineInstr *MI, 297251607Sdim MachineBasicBlock *MBB, 298251607Sdim bool ClearEven, unsigned SubReg) const; 299251607Sdim MachineBasicBlock *emitAtomicLoadBinary(MachineInstr *MI, 300251607Sdim MachineBasicBlock *BB, 301251607Sdim unsigned BinOpcode, unsigned BitSize, 302251607Sdim bool Invert = false) const; 303251607Sdim MachineBasicBlock *emitAtomicLoadMinMax(MachineInstr *MI, 304251607Sdim MachineBasicBlock *MBB, 305251607Sdim unsigned CompareOpcode, 306251607Sdim unsigned KeepOldMask, 307251607Sdim unsigned BitSize) const; 308251607Sdim MachineBasicBlock *emitAtomicCmpSwapW(MachineInstr *MI, 309251607Sdim MachineBasicBlock *BB) const; 310263508Sdim MachineBasicBlock *emitMemMemWrapper(MachineInstr *MI, 311263508Sdim MachineBasicBlock *BB, 312263508Sdim unsigned Opcode) const; 313263508Sdim MachineBasicBlock *emitStringWrapper(MachineInstr *MI, 314263508Sdim MachineBasicBlock *BB, 315263508Sdim unsigned Opcode) const; 316251607Sdim}; 317251607Sdim} // end namespace llvm 318251607Sdim 319251607Sdim#endif // LLVM_TARGET_SystemZ_ISELLOWERING_H 320