1 //===-- AVRISelLowering.h - AVR DAG Lowering Interface ----------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the interfaces that AVR uses to lower LLVM code into a 11 // selection DAG. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_AVR_ISEL_LOWERING_H 16 #define LLVM_AVR_ISEL_LOWERING_H 17 18 #include "llvm/Target/TargetLowering.h" 19 20 namespace llvm { 21 22 namespace AVRISD { 23 24 /// AVR Specific DAG Nodes 25 enum NodeType { 26 /// Start the numbering where the builtin ops leave off. 27 FIRST_NUMBER = ISD::BUILTIN_OP_END, 28 /// Return from subroutine. 29 RET_FLAG, 30 /// Return from ISR. 31 RETI_FLAG, 32 /// Represents an abstract call instruction, 33 /// which includes a bunch of information. 34 CALL, 35 /// A wrapper node for TargetConstantPool, 36 /// TargetExternalSymbol, and TargetGlobalAddress. 37 WRAPPER, 38 LSL, ///< Logical shift left. 39 LSR, ///< Logical shift right. 40 ASR, ///< Arithmetic shift right. 41 ROR, ///< Bit rotate right. 42 ROL, ///< Bit rotate left. 43 LSLLOOP, ///< A loop of single logical shift left instructions. 44 LSRLOOP, ///< A loop of single logical shift right instructions. 45 ASRLOOP, ///< A loop of single arithmetic shift right instructions. 46 /// AVR conditional branches. Operand 0 is the chain operand, operand 1 47 /// is the block to branch if condition is true, operand 2 is the 48 /// condition code, and operand 3 is the flag operand produced by a CMP 49 /// or TEST instruction. 50 BRCOND, 51 /// Compare instruction. 52 CMP, 53 /// Compare with carry instruction. 54 CMPC, 55 /// Test for zero or minus instruction. 56 TST, 57 /// Operand 0 and operand 1 are selection variable, operand 2 58 /// is condition code and operand 3 is flag operand. 59 SELECT_CC 60 }; 61 62 } // end of namespace AVRISD 63 64 class AVRTargetMachine; 65 66 /// Performs target lowering for the AVR. 67 class AVRTargetLowering : public TargetLowering { 68 public: 69 explicit AVRTargetLowering(AVRTargetMachine &TM); 70 71 public: getScalarShiftAmountTy(const DataLayout &,EVT LHSTy)72 MVT getScalarShiftAmountTy(const DataLayout &, EVT LHSTy) const override { 73 return MVT::i8; 74 } 75 const char *getTargetNodeName(unsigned Opcode) const override; 76 77 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 78 79 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results, 80 SelectionDAG &DAG) const override; 81 82 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, 83 unsigned AS) const override; 84 85 bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, 86 ISD::MemIndexedMode &AM, 87 SelectionDAG &DAG) const override; 88 89 bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, SDValue &Base, 90 SDValue &Offset, ISD::MemIndexedMode &AM, 91 SelectionDAG &DAG) const override; 92 93 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; 94 95 MachineBasicBlock * 96 EmitInstrWithCustomInserter(MachineInstr &MI, 97 MachineBasicBlock *MBB) const override; 98 99 ConstraintType getConstraintType(StringRef Constraint) const override; 100 101 ConstraintWeight 102 getSingleConstraintMatchWeight(AsmOperandInfo &info, 103 const char *constraint) const override; 104 105 std::pair<unsigned, const TargetRegisterClass *> 106 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 107 StringRef Constraint, MVT VT) const override; 108 109 unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const override; 110 111 void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, 112 std::vector<SDValue> &Ops, 113 SelectionDAG &DAG) const override; 114 115 private: 116 SDValue getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, SDValue &AVRcc, 117 SelectionDAG &DAG, SDLoc dl) const; 118 SDValue LowerShifts(SDValue Op, SelectionDAG &DAG) const; 119 SDValue LowerDivRem(SDValue Op, SelectionDAG &DAG) const; 120 SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 121 SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 122 SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const; 123 SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const; 124 SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; 125 SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; 126 SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; 127 128 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 129 const SmallVectorImpl<ISD::OutputArg> &Outs, 130 const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl, 131 SelectionDAG &DAG) const override; 132 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, 133 bool isVarArg, 134 const SmallVectorImpl<ISD::InputArg> &Ins, 135 const SDLoc &dl, SelectionDAG &DAG, 136 SmallVectorImpl<SDValue> &InVals) const override; 137 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, 138 SmallVectorImpl<SDValue> &InVals) const override; 139 SDValue LowerCallResult(SDValue Chain, SDValue InFlag, 140 CallingConv::ID CallConv, bool isVarArg, 141 const SmallVectorImpl<ISD::InputArg> &Ins, 142 const SDLoc &dl, SelectionDAG &DAG, 143 SmallVectorImpl<SDValue> &InVals) const; 144 145 private: 146 MachineBasicBlock *insertShift(MachineInstr *MI, MachineBasicBlock *BB) const; 147 MachineBasicBlock *insertMul(MachineInstr *MI, MachineBasicBlock *BB) const; 148 }; 149 150 } // end namespace llvm 151 152 #endif // LLVM_AVR_ISEL_LOWERING_H 153