xref: /freebsd/contrib/llvm-project/llvm/lib/Target/MSP430/MSP430ISelLowering.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
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