109467b48Spatrick //===-- AVRISelLowering.h - AVR DAG Lowering Interface ----------*- C++ -*-===// 209467b48Spatrick // 309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information. 509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 609467b48Spatrick // 709467b48Spatrick //===----------------------------------------------------------------------===// 809467b48Spatrick // 909467b48Spatrick // This file defines the interfaces that AVR uses to lower LLVM code into a 1009467b48Spatrick // selection DAG. 1109467b48Spatrick // 1209467b48Spatrick //===----------------------------------------------------------------------===// 1309467b48Spatrick 1409467b48Spatrick #ifndef LLVM_AVR_ISEL_LOWERING_H 1509467b48Spatrick #define LLVM_AVR_ISEL_LOWERING_H 1609467b48Spatrick 1709467b48Spatrick #include "llvm/CodeGen/CallingConvLower.h" 1809467b48Spatrick #include "llvm/CodeGen/TargetLowering.h" 1909467b48Spatrick 2009467b48Spatrick namespace llvm { 2109467b48Spatrick 2209467b48Spatrick namespace AVRISD { 2309467b48Spatrick 2409467b48Spatrick /// AVR Specific DAG Nodes 2509467b48Spatrick enum NodeType { 2609467b48Spatrick /// Start the numbering where the builtin ops leave off. 2709467b48Spatrick FIRST_NUMBER = ISD::BUILTIN_OP_END, 2809467b48Spatrick /// Return from subroutine. 2909467b48Spatrick RET_FLAG, 3009467b48Spatrick /// Return from ISR. 3109467b48Spatrick RETI_FLAG, 3209467b48Spatrick /// Represents an abstract call instruction, 3309467b48Spatrick /// which includes a bunch of information. 3409467b48Spatrick CALL, 3509467b48Spatrick /// A wrapper node for TargetConstantPool, 3609467b48Spatrick /// TargetExternalSymbol, and TargetGlobalAddress. 3709467b48Spatrick WRAPPER, 3809467b48Spatrick LSL, ///< Logical shift left. 3973471bf0Spatrick LSLBN, ///< Byte logical shift left N bits. 4073471bf0Spatrick LSLWN, ///< Word logical shift left N bits. 41*d415bd75Srobert LSLHI, ///< Higher 8-bit of word logical shift left. 42*d415bd75Srobert LSLW, ///< Wide logical shift left. 4309467b48Spatrick LSR, ///< Logical shift right. 4473471bf0Spatrick LSRBN, ///< Byte logical shift right N bits. 4573471bf0Spatrick LSRWN, ///< Word logical shift right N bits. 46*d415bd75Srobert LSRLO, ///< Lower 8-bit of word logical shift right. 47*d415bd75Srobert LSRW, ///< Wide logical shift right. 4809467b48Spatrick ASR, ///< Arithmetic shift right. 4973471bf0Spatrick ASRBN, ///< Byte arithmetic shift right N bits. 5073471bf0Spatrick ASRWN, ///< Word arithmetic shift right N bits. 51*d415bd75Srobert ASRLO, ///< Lower 8-bit of word arithmetic shift right. 52*d415bd75Srobert ASRW, ///< Wide arithmetic shift right. 5309467b48Spatrick ROR, ///< Bit rotate right. 5409467b48Spatrick ROL, ///< Bit rotate left. 5509467b48Spatrick LSLLOOP, ///< A loop of single logical shift left instructions. 5609467b48Spatrick LSRLOOP, ///< A loop of single logical shift right instructions. 5709467b48Spatrick ROLLOOP, ///< A loop of single left bit rotate instructions. 5809467b48Spatrick RORLOOP, ///< A loop of single right bit rotate instructions. 5909467b48Spatrick ASRLOOP, ///< A loop of single arithmetic shift right instructions. 6009467b48Spatrick /// AVR conditional branches. Operand 0 is the chain operand, operand 1 6109467b48Spatrick /// is the block to branch if condition is true, operand 2 is the 6209467b48Spatrick /// condition code, and operand 3 is the flag operand produced by a CMP 6309467b48Spatrick /// or TEST instruction. 6409467b48Spatrick BRCOND, 6509467b48Spatrick /// Compare instruction. 6609467b48Spatrick CMP, 6709467b48Spatrick /// Compare with carry instruction. 6809467b48Spatrick CMPC, 6909467b48Spatrick /// Test for zero or minus instruction. 7009467b48Spatrick TST, 7173471bf0Spatrick /// Swap Rd[7:4] <-> Rd[3:0]. 7273471bf0Spatrick SWAP, 7309467b48Spatrick /// Operand 0 and operand 1 are selection variable, operand 2 7409467b48Spatrick /// is condition code and operand 3 is flag operand. 7509467b48Spatrick SELECT_CC 7609467b48Spatrick }; 7709467b48Spatrick 7809467b48Spatrick } // end of namespace AVRISD 7909467b48Spatrick 8009467b48Spatrick class AVRSubtarget; 8109467b48Spatrick class AVRTargetMachine; 8209467b48Spatrick 8309467b48Spatrick /// Performs target lowering for the AVR. 8409467b48Spatrick class AVRTargetLowering : public TargetLowering { 8509467b48Spatrick public: 8609467b48Spatrick explicit AVRTargetLowering(const AVRTargetMachine &TM, 8709467b48Spatrick const AVRSubtarget &STI); 8809467b48Spatrick 8909467b48Spatrick public: getScalarShiftAmountTy(const DataLayout &,EVT LHSTy)9009467b48Spatrick MVT getScalarShiftAmountTy(const DataLayout &, EVT LHSTy) const override { 9109467b48Spatrick return MVT::i8; 9209467b48Spatrick } 9309467b48Spatrick getCmpLibcallReturnType()9409467b48Spatrick MVT::SimpleValueType getCmpLibcallReturnType() const override { 9509467b48Spatrick return MVT::i8; 9609467b48Spatrick } 9709467b48Spatrick 9809467b48Spatrick const char *getTargetNodeName(unsigned Opcode) const override; 9909467b48Spatrick 10009467b48Spatrick SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 10109467b48Spatrick 10209467b48Spatrick void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results, 10309467b48Spatrick SelectionDAG &DAG) const override; 10409467b48Spatrick 10509467b48Spatrick bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, 10609467b48Spatrick unsigned AS, 10709467b48Spatrick Instruction *I = nullptr) const override; 10809467b48Spatrick 10909467b48Spatrick bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, 11009467b48Spatrick ISD::MemIndexedMode &AM, 11109467b48Spatrick SelectionDAG &DAG) const override; 11209467b48Spatrick 11309467b48Spatrick bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, SDValue &Base, 11409467b48Spatrick SDValue &Offset, ISD::MemIndexedMode &AM, 11509467b48Spatrick SelectionDAG &DAG) const override; 11609467b48Spatrick 11709467b48Spatrick bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; 11809467b48Spatrick 11909467b48Spatrick EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, 12009467b48Spatrick EVT VT) const override; 12109467b48Spatrick 12209467b48Spatrick MachineBasicBlock * 12309467b48Spatrick EmitInstrWithCustomInserter(MachineInstr &MI, 12409467b48Spatrick MachineBasicBlock *MBB) const override; 12509467b48Spatrick 12609467b48Spatrick ConstraintType getConstraintType(StringRef Constraint) const override; 12709467b48Spatrick 12809467b48Spatrick ConstraintWeight 12909467b48Spatrick getSingleConstraintMatchWeight(AsmOperandInfo &info, 13009467b48Spatrick const char *constraint) const override; 13109467b48Spatrick 13209467b48Spatrick std::pair<unsigned, const TargetRegisterClass *> 13309467b48Spatrick getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 13409467b48Spatrick StringRef Constraint, MVT VT) const override; 13509467b48Spatrick 13609467b48Spatrick unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const override; 13709467b48Spatrick 13809467b48Spatrick void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, 13909467b48Spatrick std::vector<SDValue> &Ops, 14009467b48Spatrick SelectionDAG &DAG) const override; 14109467b48Spatrick 14209467b48Spatrick Register getRegisterByName(const char *RegName, LLT VT, 14309467b48Spatrick const MachineFunction &MF) const override; 14409467b48Spatrick shouldSplitFunctionArgumentsAsLittleEndian(const DataLayout & DL)145*d415bd75Srobert bool shouldSplitFunctionArgumentsAsLittleEndian( 146*d415bd75Srobert const DataLayout &DL) const override { 14709467b48Spatrick return false; 14809467b48Spatrick } 14909467b48Spatrick 150*d415bd75Srobert ShiftLegalizationStrategy preferredShiftLegalizationStrategy(SelectionDAG & DAG,SDNode * N,unsigned ExpansionFactor)151*d415bd75Srobert preferredShiftLegalizationStrategy(SelectionDAG &DAG, SDNode *N, 152*d415bd75Srobert unsigned ExpansionFactor) const override { 153*d415bd75Srobert return ShiftLegalizationStrategy::LowerToLibcall; 154*d415bd75Srobert } 155*d415bd75Srobert 15609467b48Spatrick private: 15709467b48Spatrick SDValue getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, SDValue &AVRcc, 15809467b48Spatrick SelectionDAG &DAG, SDLoc dl) const; 15973471bf0Spatrick SDValue getAVRCmp(SDValue LHS, SDValue RHS, SelectionDAG &DAG, 16073471bf0Spatrick SDLoc dl) const; 16109467b48Spatrick SDValue LowerShifts(SDValue Op, SelectionDAG &DAG) const; 16209467b48Spatrick SDValue LowerDivRem(SDValue Op, SelectionDAG &DAG) const; 16309467b48Spatrick SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 16409467b48Spatrick SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 16509467b48Spatrick SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const; 16609467b48Spatrick SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const; 16709467b48Spatrick SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; 16809467b48Spatrick SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; 16909467b48Spatrick SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; 17009467b48Spatrick 171097a140dSpatrick bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 172097a140dSpatrick bool isVarArg, 17309467b48Spatrick const SmallVectorImpl<ISD::OutputArg> &Outs, 17409467b48Spatrick LLVMContext &Context) const override; 17509467b48Spatrick 17609467b48Spatrick SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 17709467b48Spatrick const SmallVectorImpl<ISD::OutputArg> &Outs, 17809467b48Spatrick const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl, 17909467b48Spatrick SelectionDAG &DAG) const override; 18009467b48Spatrick SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, 18109467b48Spatrick bool isVarArg, 18209467b48Spatrick const SmallVectorImpl<ISD::InputArg> &Ins, 18309467b48Spatrick const SDLoc &dl, SelectionDAG &DAG, 18409467b48Spatrick SmallVectorImpl<SDValue> &InVals) const override; 18509467b48Spatrick SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, 18609467b48Spatrick SmallVectorImpl<SDValue> &InVals) const override; 18709467b48Spatrick SDValue LowerCallResult(SDValue Chain, SDValue InFlag, 18809467b48Spatrick CallingConv::ID CallConv, bool isVarArg, 18909467b48Spatrick const SmallVectorImpl<ISD::InputArg> &Ins, 19009467b48Spatrick const SDLoc &dl, SelectionDAG &DAG, 19109467b48Spatrick SmallVectorImpl<SDValue> &InVals) const; 19209467b48Spatrick 19309467b48Spatrick protected: 19409467b48Spatrick const AVRSubtarget &Subtarget; 19509467b48Spatrick 19609467b48Spatrick private: 19709467b48Spatrick MachineBasicBlock *insertShift(MachineInstr &MI, MachineBasicBlock *BB) const; 198*d415bd75Srobert MachineBasicBlock *insertWideShift(MachineInstr &MI, 199*d415bd75Srobert MachineBasicBlock *BB) const; 20009467b48Spatrick MachineBasicBlock *insertMul(MachineInstr &MI, MachineBasicBlock *BB) const; 201*d415bd75Srobert MachineBasicBlock *insertCopyZero(MachineInstr &MI, 202*d415bd75Srobert MachineBasicBlock *BB) const; 203*d415bd75Srobert MachineBasicBlock *insertAtomicArithmeticOp(MachineInstr &MI, 204*d415bd75Srobert MachineBasicBlock *BB, 205*d415bd75Srobert unsigned Opcode, int Width) const; 20609467b48Spatrick }; 20709467b48Spatrick 20809467b48Spatrick } // end namespace llvm 20909467b48Spatrick 21009467b48Spatrick #endif // LLVM_AVR_ISEL_LOWERING_H 211