SystemZISelLowering.h [plain text]
#ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZISELLOWERING_H
#define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZISELLOWERING_H
#include "SystemZ.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/Target/TargetLowering.h"
namespace llvm {
namespace SystemZISD {
enum {
FIRST_NUMBER = ISD::BUILTIN_OP_END,
RET_FLAG,
CALL,
SIBCALL,
TLS_GDCALL,
TLS_LDCALL,
PCREL_WRAPPER,
PCREL_OFFSET,
IABS,
ICMP,
FCMP,
TM,
BR_CCMASK,
SELECT_CCMASK,
ADJDYNALLOC,
EXTRACT_ACCESS,
UMUL_LOHI64,
SDIVREM32,
SDIVREM64,
UDIVREM32,
UDIVREM64,
MVC,
MVC_LOOP,
NC,
NC_LOOP,
OC,
OC_LOOP,
XC,
XC_LOOP,
CLC,
CLC_LOOP,
STPCPY,
STRCMP,
SEARCH_STRING,
IPM,
SERIALIZE,
ATOMIC_SWAPW = ISD::FIRST_TARGET_MEMORY_OPCODE,
ATOMIC_LOADW_ADD,
ATOMIC_LOADW_SUB,
ATOMIC_LOADW_AND,
ATOMIC_LOADW_OR,
ATOMIC_LOADW_XOR,
ATOMIC_LOADW_NAND,
ATOMIC_LOADW_MIN,
ATOMIC_LOADW_MAX,
ATOMIC_LOADW_UMIN,
ATOMIC_LOADW_UMAX,
ATOMIC_CMP_SWAPW,
PREFETCH
};
inline bool isPCREL(unsigned Opcode) {
return Opcode == PCREL_WRAPPER || Opcode == PCREL_OFFSET;
}
}
namespace SystemZICMP {
enum {
Any,
UnsignedOnly,
SignedOnly
};
}
class SystemZSubtarget;
class SystemZTargetMachine;
class SystemZTargetLowering : public TargetLowering {
public:
explicit SystemZTargetLowering(const TargetMachine &TM,
const SystemZSubtarget &STI);
MVT getScalarShiftAmountTy(EVT LHSTy) const override {
return MVT::i32;
}
EVT getSetCCResultType(LLVMContext &, EVT) const override;
bool isFMAFasterThanFMulAndFAdd(EVT VT) const override;
bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const override;
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS,
unsigned Align,
bool *Fast) const override;
bool isTruncateFree(Type *, Type *) const override;
bool isTruncateFree(EVT, EVT) const override;
const char *getTargetNodeName(unsigned Opcode) const override;
std::pair<unsigned, const TargetRegisterClass *>
getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
const std::string &Constraint,
MVT VT) const override;
TargetLowering::ConstraintType
getConstraintType(const std::string &Constraint) const override;
TargetLowering::ConstraintWeight
getSingleConstraintMatchWeight(AsmOperandInfo &info,
const char *constraint) const override;
void LowerAsmOperandForConstraint(SDValue Op,
std::string &Constraint,
std::vector<SDValue> &Ops,
SelectionDAG &DAG) const override;
MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
MachineBasicBlock *BB) const
override;
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
bool allowTruncateForTailCall(Type *, Type *) const override;
bool mayBeEmittedAsTailCall(CallInst *CI) const override;
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
SDLoc DL, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerCall(CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<SDValue> &OutVals,
SDLoc DL, SelectionDAG &DAG) const override;
SDValue prepareVolatileOrAtomicLoad(SDValue Chain, SDLoc DL,
SelectionDAG &DAG) const override;
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
private:
const SystemZSubtarget &Subtarget;
SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerGlobalAddress(GlobalAddressSDNode *Node,
SelectionDAG &DAG) const;
SDValue lowerTLSGetOffset(GlobalAddressSDNode *Node,
SelectionDAG &DAG, unsigned Opcode,
SDValue GOTOffset) const;
SDValue lowerGlobalTLSAddress(GlobalAddressSDNode *Node,
SelectionDAG &DAG) const;
SDValue lowerBlockAddress(BlockAddressSDNode *Node,
SelectionDAG &DAG) const;
SDValue lowerJumpTable(JumpTableSDNode *JT, SelectionDAG &DAG) const;
SDValue lowerConstantPool(ConstantPoolSDNode *CP, SelectionDAG &DAG) const;
SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerVACOPY(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerSDIVREM(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerUDIVREM(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerOR(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerATOMIC_LOAD(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerATOMIC_LOAD_OP(SDValue Op, SelectionDAG &DAG,
unsigned Opcode) const;
SDValue lowerATOMIC_LOAD_SUB(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerATOMIC_CMP_SWAP(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerLOAD_SEQUENCE_POINT(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerSTACKSAVE(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;
bool convertPrevCompareToBranch(MachineBasicBlock *MBB,
MachineBasicBlock::iterator MBBI,
unsigned CCMask,
MachineBasicBlock *Target) const;
MachineBasicBlock *emitSelect(MachineInstr *MI,
MachineBasicBlock *BB) const;
MachineBasicBlock *emitCondStore(MachineInstr *MI,
MachineBasicBlock *BB,
unsigned StoreOpcode, unsigned STOCOpcode,
bool Invert) const;
MachineBasicBlock *emitExt128(MachineInstr *MI,
MachineBasicBlock *MBB,
bool ClearEven, unsigned SubReg) const;
MachineBasicBlock *emitAtomicLoadBinary(MachineInstr *MI,
MachineBasicBlock *BB,
unsigned BinOpcode, unsigned BitSize,
bool Invert = false) const;
MachineBasicBlock *emitAtomicLoadMinMax(MachineInstr *MI,
MachineBasicBlock *MBB,
unsigned CompareOpcode,
unsigned KeepOldMask,
unsigned BitSize) const;
MachineBasicBlock *emitAtomicCmpSwapW(MachineInstr *MI,
MachineBasicBlock *BB) const;
MachineBasicBlock *emitMemMemWrapper(MachineInstr *MI,
MachineBasicBlock *BB,
unsigned Opcode) const;
MachineBasicBlock *emitStringWrapper(MachineInstr *MI,
MachineBasicBlock *BB,
unsigned Opcode) const;
};
}
#endif