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