#ifndef ARMISELLOWERING_H
#define ARMISELLOWERING_H
#include "ARMSubtarget.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include <vector>
namespace llvm {
class ARMConstantPoolValue;
namespace ARMISD {
enum NodeType {
FIRST_NUMBER = ISD::BUILTIN_OP_END,
Wrapper, WrapperJT,
CALL, CALL_PRED, CALL_NOLINK, tCALL, BRCOND, BR_JT, BR2_JT, RET_FLAG,
PIC_ADD,
CMP, CMPZ, CMPFP, CMPFPw0, FMSTAT, CMOV, CNEG,
RBIT,
FTOSI, FTOUI, SITOF, UITOF, F16_TO_F32, F32_TO_F16,
SRL_FLAG, SRA_FLAG, RRX,
VMOVRRD, VMOVDRR,
EH_SJLJ_SETJMP, EH_SJLJ_LONGJMP,
THREAD_POINTER,
DYN_ALLOC,
MEMBARRIER, SYNCBARRIER,
VCEQ, VCGE, VCGEU, VCGT, VCGTU, VTST,
VSHL, VSHRs, VSHRu, VSHLLs, VSHLLu, VSHLLi, VSHRN,
VRSHRs, VRSHRu, VRSHRN,
VQSHLs, VQSHLu, VQSHLsu, VQSHRNs, VQSHRNu, VQSHRNsu,
VQRSHRNs, VQRSHRNu, VQRSHRNsu,
VSLI, VSRI,
VGETLANEu, VGETLANEs,
VDUP,
VDUPLANE,
VEXT, VREV64, VREV32, VREV16, VZIP, VUZP, VTRN,
FMAX,
FMIN
};
}
namespace ARM {
SDValue getVMOVImm(SDNode *N, unsigned ByteSize, SelectionDAG &DAG);
int getVFPf32Imm(const APFloat &FPImm);
int getVFPf64Imm(const APFloat &FPImm);
}
class ARMTargetLowering : public TargetLowering {
int VarArgsFrameIndex; public:
explicit ARMTargetLowering(TargetMachine &TM);
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG);
virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,
SelectionDAG &DAG);
virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
virtual const char *getTargetNodeName(unsigned Opcode) const;
virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
MachineBasicBlock *MBB,
DenseMap<MachineBasicBlock*, MachineBasicBlock*>*) const;
virtual bool allowsUnalignedMemoryAccesses(EVT VT) const;
virtual bool isLegalAddressingMode(const AddrMode &AM, const Type *Ty)const;
bool isLegalT2ScaledAddressingMode(const AddrMode &AM, EVT VT) const;
virtual bool isLegalICmpImmediate(int64_t Imm) const;
virtual bool getPreIndexedAddressParts(SDNode *N, SDValue &Base,
SDValue &Offset,
ISD::MemIndexedMode &AM,
SelectionDAG &DAG) const;
virtual bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
SDValue &Base, SDValue &Offset,
ISD::MemIndexedMode &AM,
SelectionDAG &DAG) const;
virtual void computeMaskedBitsForTargetNode(const SDValue Op,
const APInt &Mask,
APInt &KnownZero,
APInt &KnownOne,
const SelectionDAG &DAG,
unsigned Depth) const;
ConstraintType getConstraintType(const std::string &Constraint) const;
std::pair<unsigned, const TargetRegisterClass*>
getRegForInlineAsmConstraint(const std::string &Constraint,
EVT VT) const;
std::vector<unsigned>
getRegClassForInlineAsmConstraint(const std::string &Constraint,
EVT VT) const;
virtual void LowerAsmOperandForConstraint(SDValue Op,
char ConstraintLetter,
bool hasMemory,
std::vector<SDValue> &Ops,
SelectionDAG &DAG) const;
virtual const ARMSubtarget* getSubtarget() {
return Subtarget;
}
virtual unsigned getFunctionAlignment(const Function *F) const;
bool isShuffleMaskLegal(const SmallVectorImpl<int> &M, EVT VT) const;
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const;
private:
const ARMSubtarget *Subtarget;
unsigned ARMPCLabelIndex;
void addTypeForNEON(EVT VT, EVT PromotedLdStVT, EVT PromotedBitwiseVT);
void addDRTypeForNEON(EVT VT);
void addQRTypeForNEON(EVT VT);
typedef SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPassVector;
void PassF64ArgInRegs(DebugLoc dl, SelectionDAG &DAG,
SDValue Chain, SDValue &Arg,
RegsToPassVector &RegsToPass,
CCValAssign &VA, CCValAssign &NextVA,
SDValue &StackPtr,
SmallVector<SDValue, 8> &MemOpChains,
ISD::ArgFlagsTy Flags);
SDValue GetF64FormalArgument(CCValAssign &VA, CCValAssign &NextVA,
SDValue &Root, SelectionDAG &DAG, DebugLoc dl);
CCAssignFn *CCAssignFnForNode(CallingConv::ID CC, bool Return, bool isVarArg) const;
SDValue LowerMemOpCallTo(SDValue Chain, SDValue StackPtr, SDValue Arg,
DebugLoc dl, SelectionDAG &DAG,
const CCValAssign &VA,
ISD::ArgFlagsTy Flags);
SDValue LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
const ARMSubtarget *Subtarget);
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG);
SDValue LowerGlobalAddressDarwin(SDValue Op, SelectionDAG &DAG);
SDValue LowerGlobalAddressELF(SDValue Op, SelectionDAG &DAG);
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG);
SDValue LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
SelectionDAG &DAG);
SDValue LowerToTLSExecModels(GlobalAddressSDNode *GA,
SelectionDAG &DAG);
SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG);
SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG);
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG);
SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG);
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG);
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG);
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG);
SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG);
SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG);
SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain,
SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
bool isVolatile, bool AlwaysInline,
const Value *DstSV, uint64_t DstSVOff,
const Value *SrcSV, uint64_t SrcSVOff);
SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals);
virtual SDValue
LowerFormalArguments(SDValue Chain,
CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals);
virtual SDValue
LowerCall(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
bool &isTailCall,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals);
virtual SDValue
LowerReturn(SDValue Chain,
CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
DebugLoc dl, SelectionDAG &DAG);
SDValue getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
SDValue &ARMCC, SelectionDAG &DAG, DebugLoc dl);
MachineBasicBlock *EmitAtomicCmpSwap(MachineInstr *MI,
MachineBasicBlock *BB,
unsigned Size) const;
MachineBasicBlock *EmitAtomicBinary(MachineInstr *MI,
MachineBasicBlock *BB,
unsigned Size,
unsigned BinOpcode) const;
};
}
#endif // ARMISELLOWERING_H