10b57cec5SDimitry Andric //===-- MSP430ISelLowering.h - MSP430 DAG Lowering Interface ----*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines the interfaces that MSP430 uses to lower LLVM code into a 100b57cec5SDimitry Andric // selection DAG. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_MSP430_MSP430ISELLOWERING_H 150b57cec5SDimitry Andric #define LLVM_LIB_TARGET_MSP430_MSP430ISELLOWERING_H 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #include "MSP430.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/SelectionDAG.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLowering.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace llvm { 220b57cec5SDimitry Andric namespace MSP430ISD { 230b57cec5SDimitry Andric enum NodeType : unsigned { 240b57cec5SDimitry Andric FIRST_NUMBER = ISD::BUILTIN_OP_END, 250b57cec5SDimitry Andric 26*06c3fb27SDimitry Andric /// Return with a glue operand. Operand 0 is the chain operand. 27*06c3fb27SDimitry Andric RET_GLUE, 280b57cec5SDimitry Andric 29*06c3fb27SDimitry Andric /// Same as RET_GLUE, but used for returning from ISRs. 30*06c3fb27SDimitry Andric RETI_GLUE, 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric /// Y = R{R,L}A X, rotate right (left) arithmetically 330b57cec5SDimitry Andric RRA, RLA, 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric /// Y = RRC X, rotate right via carry 360b57cec5SDimitry Andric RRC, 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric /// Rotate right via carry, carry gets cleared beforehand by clrc 390b57cec5SDimitry Andric RRCL, 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric /// CALL - These operations represent an abstract call 420b57cec5SDimitry Andric /// instruction, which includes a bunch of information. 430b57cec5SDimitry Andric CALL, 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric /// Wrapper - A wrapper node for TargetConstantPool, TargetExternalSymbol, 460b57cec5SDimitry Andric /// and TargetGlobalAddress. 470b57cec5SDimitry Andric Wrapper, 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric /// CMP - Compare instruction. 500b57cec5SDimitry Andric CMP, 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric /// SetCC - Operand 0 is condition code, and operand 1 is the flag 530b57cec5SDimitry Andric /// operand produced by a CMP instruction. 540b57cec5SDimitry Andric SETCC, 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric /// MSP430 conditional branches. Operand 0 is the chain operand, operand 1 570b57cec5SDimitry Andric /// is the block to branch if condition is true, operand 2 is the 580b57cec5SDimitry Andric /// condition code, and operand 3 is the flag operand produced by a CMP 590b57cec5SDimitry Andric /// instruction. 600b57cec5SDimitry Andric BR_CC, 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric /// SELECT_CC - Operand 0 and operand 1 are selection variable, operand 3 630b57cec5SDimitry Andric /// is condition code and operand 4 is flag operand. 640b57cec5SDimitry Andric SELECT_CC, 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric /// DADD - Decimal addition with carry 670b57cec5SDimitry Andric /// TODO Nothing generates a node of this type yet. 680b57cec5SDimitry Andric DADD, 690b57cec5SDimitry Andric }; 700b57cec5SDimitry Andric } 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric class MSP430Subtarget; 730b57cec5SDimitry Andric class MSP430TargetLowering : public TargetLowering { 740b57cec5SDimitry Andric public: 750b57cec5SDimitry Andric explicit MSP430TargetLowering(const TargetMachine &TM, 760b57cec5SDimitry Andric const MSP430Subtarget &STI); 770b57cec5SDimitry Andric getScalarShiftAmountTy(const DataLayout &,EVT)780b57cec5SDimitry Andric MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override { 790b57cec5SDimitry Andric return MVT::i8; 800b57cec5SDimitry Andric } 810b57cec5SDimitry Andric getCmpLibcallReturnType()825ffd83dbSDimitry Andric MVT::SimpleValueType getCmpLibcallReturnType() const override { 835ffd83dbSDimitry Andric return MVT::i16; 845ffd83dbSDimitry Andric } 855ffd83dbSDimitry Andric 860b57cec5SDimitry Andric /// LowerOperation - Provide custom lowering hooks for some operations. 870b57cec5SDimitry Andric SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric /// getTargetNodeName - This method returns the name of a target specific 900b57cec5SDimitry Andric /// DAG node. 910b57cec5SDimitry Andric const char *getTargetNodeName(unsigned Opcode) const override; 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric SDValue LowerShifts(SDValue Op, SelectionDAG &DAG) const; 940b57cec5SDimitry Andric SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 950b57cec5SDimitry Andric SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 960b57cec5SDimitry Andric SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const; 970b57cec5SDimitry Andric SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const; 980b57cec5SDimitry Andric SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; 990b57cec5SDimitry Andric SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; 1000b57cec5SDimitry Andric SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) const; 1010b57cec5SDimitry Andric SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; 1020b57cec5SDimitry Andric SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; 1030b57cec5SDimitry Andric SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; 1040b57cec5SDimitry Andric SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const; 1050b57cec5SDimitry Andric SDValue getReturnAddressFrameIndex(SelectionDAG &DAG) const; 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric TargetLowering::ConstraintType 1080b57cec5SDimitry Andric getConstraintType(StringRef Constraint) const override; 1090b57cec5SDimitry Andric std::pair<unsigned, const TargetRegisterClass *> 1100b57cec5SDimitry Andric getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 1110b57cec5SDimitry Andric StringRef Constraint, MVT VT) const override; 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric /// isTruncateFree - Return true if it's free to truncate a value of type 1140b57cec5SDimitry Andric /// Ty1 to type Ty2. e.g. On msp430 it's free to truncate a i16 value in 1150b57cec5SDimitry Andric /// register R15W to i8 by referencing its sub-register R15B. 1160b57cec5SDimitry Andric bool isTruncateFree(Type *Ty1, Type *Ty2) const override; 1170b57cec5SDimitry Andric bool isTruncateFree(EVT VT1, EVT VT2) const override; 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric /// isZExtFree - Return true if any actual instruction that defines a value 1200b57cec5SDimitry Andric /// of type Ty1 implicit zero-extends the value to Ty2 in the result 1210b57cec5SDimitry Andric /// register. This does not necessarily include registers defined in unknown 1220b57cec5SDimitry Andric /// ways, such as incoming arguments, or copies from unknown virtual 1230b57cec5SDimitry Andric /// registers. Also, if isTruncateFree(Ty2, Ty1) is true, this does not 1240b57cec5SDimitry Andric /// necessarily apply to truncate instructions. e.g. on msp430, all 1250b57cec5SDimitry Andric /// instructions that define 8-bit values implicit zero-extend the result 1260b57cec5SDimitry Andric /// out to 16 bits. 1270b57cec5SDimitry Andric bool isZExtFree(Type *Ty1, Type *Ty2) const override; 1280b57cec5SDimitry Andric bool isZExtFree(EVT VT1, EVT VT2) const override; 1290b57cec5SDimitry Andric 130480093f4SDimitry Andric bool isLegalICmpImmediate(int64_t) const override; 131480093f4SDimitry Andric bool shouldAvoidTransformToShift(EVT VT, unsigned Amount) const override; 1328bcb0991SDimitry Andric 1330b57cec5SDimitry Andric MachineBasicBlock * 1340b57cec5SDimitry Andric EmitInstrWithCustomInserter(MachineInstr &MI, 1350b57cec5SDimitry Andric MachineBasicBlock *BB) const override; 1360b57cec5SDimitry Andric MachineBasicBlock *EmitShiftInstr(MachineInstr &MI, 1370b57cec5SDimitry Andric MachineBasicBlock *BB) const; 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric private: 1400b57cec5SDimitry Andric SDValue LowerCCCCallTo(SDValue Chain, SDValue Callee, 1410b57cec5SDimitry Andric CallingConv::ID CallConv, bool isVarArg, 1420b57cec5SDimitry Andric bool isTailCall, 1430b57cec5SDimitry Andric const SmallVectorImpl<ISD::OutputArg> &Outs, 1440b57cec5SDimitry Andric const SmallVectorImpl<SDValue> &OutVals, 1450b57cec5SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, 1460b57cec5SDimitry Andric const SDLoc &dl, SelectionDAG &DAG, 1470b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals) const; 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric SDValue LowerCCCArguments(SDValue Chain, CallingConv::ID CallConv, 1500b57cec5SDimitry Andric bool isVarArg, 1510b57cec5SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, 1520b57cec5SDimitry Andric const SDLoc &dl, SelectionDAG &DAG, 1530b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals) const; 1540b57cec5SDimitry Andric 155*06c3fb27SDimitry Andric SDValue LowerCallResult(SDValue Chain, SDValue InGlue, 1560b57cec5SDimitry Andric CallingConv::ID CallConv, bool isVarArg, 1570b57cec5SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, 1580b57cec5SDimitry Andric const SDLoc &dl, SelectionDAG &DAG, 1590b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals) const; 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric SDValue 1620b57cec5SDimitry Andric LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 1630b57cec5SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, 1640b57cec5SDimitry Andric const SDLoc &dl, SelectionDAG &DAG, 1650b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals) const override; 1660b57cec5SDimitry Andric SDValue 1670b57cec5SDimitry Andric LowerCall(TargetLowering::CallLoweringInfo &CLI, 1680b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals) const override; 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric bool CanLowerReturn(CallingConv::ID CallConv, 1710b57cec5SDimitry Andric MachineFunction &MF, 1720b57cec5SDimitry Andric bool IsVarArg, 1730b57cec5SDimitry Andric const SmallVectorImpl<ISD::OutputArg> &Outs, 1740b57cec5SDimitry Andric LLVMContext &Context) const override; 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 1770b57cec5SDimitry Andric const SmallVectorImpl<ISD::OutputArg> &Outs, 1780b57cec5SDimitry Andric const SmallVectorImpl<SDValue> &OutVals, 1790b57cec5SDimitry Andric const SDLoc &dl, SelectionDAG &DAG) const override; 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, 1820b57cec5SDimitry Andric SDValue &Base, 1830b57cec5SDimitry Andric SDValue &Offset, 1840b57cec5SDimitry Andric ISD::MemIndexedMode &AM, 1850b57cec5SDimitry Andric SelectionDAG &DAG) const override; 1860b57cec5SDimitry Andric }; 1870b57cec5SDimitry Andric } // namespace llvm 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric #endif 190