1234353Sdim//===-- MSP430ISelLowering.h - MSP430 DAG Lowering Interface ----*- C++ -*-===//
2193323Sed//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6193323Sed//
7193323Sed//===----------------------------------------------------------------------===//
8193323Sed//
9193323Sed// This file defines the interfaces that MSP430 uses to lower LLVM code into a
10193323Sed// selection DAG.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14280031Sdim#ifndef LLVM_LIB_TARGET_MSP430_MSP430ISELLOWERING_H
15280031Sdim#define LLVM_LIB_TARGET_MSP430_MSP430ISELLOWERING_H
16193323Sed
17193323Sed#include "MSP430.h"
18193323Sed#include "llvm/CodeGen/SelectionDAG.h"
19327952Sdim#include "llvm/CodeGen/TargetLowering.h"
20193323Sed
21193323Sednamespace llvm {
22193323Sed  namespace MSP430ISD {
23288943Sdim    enum NodeType : unsigned {
24193323Sed      FIRST_NUMBER = ISD::BUILTIN_OP_END,
25193323Sed
26193323Sed      /// Return with a flag operand. Operand 0 is the chain operand.
27193323Sed      RET_FLAG,
28193323Sed
29200581Srdivacky      /// Same as RET_FLAG, but used for returning from ISRs.
30200581Srdivacky      RETI_FLAG,
31200581Srdivacky
32193323Sed      /// Y = R{R,L}A X, rotate right (left) arithmetically
33193323Sed      RRA, RLA,
34193323Sed
35193323Sed      /// Y = RRC X, rotate right via carry
36193323Sed      RRC,
37193323Sed
38344779Sdim      /// Rotate right via carry, carry gets cleared beforehand by clrc
39344779Sdim      RRCL,
40344779Sdim
41198090Srdivacky      /// CALL - These operations represent an abstract call
42193323Sed      /// instruction, which includes a bunch of information.
43193323Sed      CALL,
44193323Sed
45193323Sed      /// Wrapper - A wrapper node for TargetConstantPool, TargetExternalSymbol,
46193323Sed      /// and TargetGlobalAddress.
47193323Sed      Wrapper,
48193323Sed
49193323Sed      /// CMP - Compare instruction.
50193323Sed      CMP,
51193323Sed
52200581Srdivacky      /// SetCC - Operand 0 is condition code, and operand 1 is the flag
53193323Sed      /// operand produced by a CMP instruction.
54193323Sed      SETCC,
55193323Sed
56193323Sed      /// MSP430 conditional branches. Operand 0 is the chain operand, operand 1
57193323Sed      /// is the block to branch if condition is true, operand 2 is the
58193323Sed      /// condition code, and operand 3 is the flag operand produced by a CMP
59193323Sed      /// instruction.
60193323Sed      BR_CC,
61193323Sed
62200581Srdivacky      /// SELECT_CC - Operand 0 and operand 1 are selection variable, operand 3
63193323Sed      /// is condition code and operand 4 is flag operand.
64200581Srdivacky      SELECT_CC,
65200581Srdivacky
66344779Sdim      /// DADD - Decimal addition with carry
67344779Sdim      /// TODO Nothing generates a node of this type yet.
68344779Sdim      DADD,
69193323Sed    };
70193323Sed  }
71193323Sed
72288943Sdim  class MSP430Subtarget;
73193323Sed  class MSP430TargetLowering : public TargetLowering {
74193323Sed  public:
75288943Sdim    explicit MSP430TargetLowering(const TargetMachine &TM,
76288943Sdim                                  const MSP430Subtarget &STI);
77193323Sed
78288943Sdim    MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override {
79288943Sdim      return MVT::i8;
80288943Sdim    }
81219077Sdim
82193323Sed    /// LowerOperation - Provide custom lowering hooks for some operations.
83276479Sdim    SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
84193323Sed
85193323Sed    /// getTargetNodeName - This method returns the name of a target specific
86193323Sed    /// DAG node.
87276479Sdim    const char *getTargetNodeName(unsigned Opcode) const override;
88193323Sed
89207618Srdivacky    SDValue LowerShifts(SDValue Op, SelectionDAG &DAG) const;
90207618Srdivacky    SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
91207618Srdivacky    SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
92207618Srdivacky    SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const;
93207618Srdivacky    SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
94207618Srdivacky    SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
95207618Srdivacky    SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
96207618Srdivacky    SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) const;
97207618Srdivacky    SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
98207618Srdivacky    SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
99249423Sdim    SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
100261991Sdim    SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
101207618Srdivacky    SDValue getReturnAddressFrameIndex(SelectionDAG &DAG) const;
102193323Sed
103198090Srdivacky    TargetLowering::ConstraintType
104288943Sdim    getConstraintType(StringRef Constraint) const override;
105288943Sdim    std::pair<unsigned, const TargetRegisterClass *>
106288943Sdim    getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
107288943Sdim                                 StringRef Constraint, MVT VT) const override;
108193323Sed
109202878Srdivacky    /// isTruncateFree - Return true if it's free to truncate a value of type
110202878Srdivacky    /// Ty1 to type Ty2. e.g. On msp430 it's free to truncate a i16 value in
111202878Srdivacky    /// register R15W to i8 by referencing its sub-register R15B.
112276479Sdim    bool isTruncateFree(Type *Ty1, Type *Ty2) const override;
113276479Sdim    bool isTruncateFree(EVT VT1, EVT VT2) const override;
114202878Srdivacky
115202878Srdivacky    /// isZExtFree - Return true if any actual instruction that defines a value
116202878Srdivacky    /// of type Ty1 implicit zero-extends the value to Ty2 in the result
117202878Srdivacky    /// register. This does not necessarily include registers defined in unknown
118202878Srdivacky    /// ways, such as incoming arguments, or copies from unknown virtual
119202878Srdivacky    /// registers. Also, if isTruncateFree(Ty2, Ty1) is true, this does not
120202878Srdivacky    /// necessarily apply to truncate instructions. e.g. on msp430, all
121202878Srdivacky    /// instructions that define 8-bit values implicit zero-extend the result
122202878Srdivacky    /// out to 16 bits.
123276479Sdim    bool isZExtFree(Type *Ty1, Type *Ty2) const override;
124276479Sdim    bool isZExtFree(EVT VT1, EVT VT2) const override;
125276479Sdim    bool isZExtFree(SDValue Val, EVT VT2) const override;
126202878Srdivacky
127360784Sdim    bool isLegalICmpImmediate(int64_t) const override;
128360784Sdim    bool shouldAvoidTransformToShift(EVT VT, unsigned Amount) const override;
129360784Sdim
130309124Sdim    MachineBasicBlock *
131309124Sdim    EmitInstrWithCustomInserter(MachineInstr &MI,
132309124Sdim                                MachineBasicBlock *BB) const override;
133309124Sdim    MachineBasicBlock *EmitShiftInstr(MachineInstr &MI,
134207618Srdivacky                                      MachineBasicBlock *BB) const;
135193323Sed
136193323Sed  private:
137198090Srdivacky    SDValue LowerCCCCallTo(SDValue Chain, SDValue Callee,
138198090Srdivacky                           CallingConv::ID CallConv, bool isVarArg,
139198090Srdivacky                           bool isTailCall,
140198090Srdivacky                           const SmallVectorImpl<ISD::OutputArg> &Outs,
141210299Sed                           const SmallVectorImpl<SDValue> &OutVals,
142198090Srdivacky                           const SmallVectorImpl<ISD::InputArg> &Ins,
143309124Sdim                           const SDLoc &dl, SelectionDAG &DAG,
144207618Srdivacky                           SmallVectorImpl<SDValue> &InVals) const;
145198090Srdivacky
146309124Sdim    SDValue LowerCCCArguments(SDValue Chain, CallingConv::ID CallConv,
147198090Srdivacky                              bool isVarArg,
148198090Srdivacky                              const SmallVectorImpl<ISD::InputArg> &Ins,
149309124Sdim                              const SDLoc &dl, SelectionDAG &DAG,
150207618Srdivacky                              SmallVectorImpl<SDValue> &InVals) const;
151198090Srdivacky
152198090Srdivacky    SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
153198090Srdivacky                            CallingConv::ID CallConv, bool isVarArg,
154198090Srdivacky                            const SmallVectorImpl<ISD::InputArg> &Ins,
155309124Sdim                            const SDLoc &dl, SelectionDAG &DAG,
156207618Srdivacky                            SmallVectorImpl<SDValue> &InVals) const;
157198090Srdivacky
158276479Sdim    SDValue
159309124Sdim    LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
160309124Sdim                         const SmallVectorImpl<ISD::InputArg> &Ins,
161309124Sdim                         const SDLoc &dl, SelectionDAG &DAG,
162309124Sdim                         SmallVectorImpl<SDValue> &InVals) const override;
163276479Sdim    SDValue
164239462Sdim      LowerCall(TargetLowering::CallLoweringInfo &CLI,
165276479Sdim                SmallVectorImpl<SDValue> &InVals) const override;
166198090Srdivacky
167321369Sdim    bool CanLowerReturn(CallingConv::ID CallConv,
168321369Sdim                        MachineFunction &MF,
169321369Sdim                        bool IsVarArg,
170321369Sdim                        const SmallVectorImpl<ISD::OutputArg> &Outs,
171321369Sdim                        LLVMContext &Context) const override;
172321369Sdim
173309124Sdim    SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
174276479Sdim                        const SmallVectorImpl<ISD::OutputArg> &Outs,
175276479Sdim                        const SmallVectorImpl<SDValue> &OutVals,
176309124Sdim                        const SDLoc &dl, SelectionDAG &DAG) const override;
177198090Srdivacky
178276479Sdim    bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
179276479Sdim                                    SDValue &Base,
180276479Sdim                                    SDValue &Offset,
181276479Sdim                                    ISD::MemIndexedMode &AM,
182276479Sdim                                    SelectionDAG &DAG) const override;
183193323Sed  };
184193323Sed} // namespace llvm
185193323Sed
186280031Sdim#endif
187