1//=- LoongArchISelDAGToDAG.h - A dag to dag inst selector for LoongArch ---===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines an instruction selector for the LoongArch target.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELDAGTODAG_H
14#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELDAGTODAG_H
15
16#include "LoongArch.h"
17#include "LoongArchSelectionDAGInfo.h"
18#include "LoongArchTargetMachine.h"
19#include "llvm/CodeGen/SelectionDAGISel.h"
20
21// LoongArch-specific code to select LoongArch machine instructions for
22// SelectionDAG operations.
23namespace llvm {
24class LoongArchDAGToDAGISel : public SelectionDAGISel {
25 const LoongArchSubtarget *Subtarget = nullptr;
26
27public:
28 LoongArchDAGToDAGISel() = delete;
29
30 explicit LoongArchDAGToDAGISel(LoongArchTargetMachine &TM,
31 CodeGenOptLevel OptLevel)
32 : SelectionDAGISel(TM, OptLevel) {}
33
34 bool runOnMachineFunction(MachineFunction &MF) override {
35 Subtarget = &MF.getSubtarget<LoongArchSubtarget>();
36 return SelectionDAGISel::runOnMachineFunction(mf&: MF);
37 }
38
39 void Select(SDNode *Node) override;
40
41 bool SelectInlineAsmMemoryOperand(const SDValue &Op,
42 InlineAsm::ConstraintCode ConstraintID,
43 std::vector<SDValue> &OutOps) override;
44
45 bool SelectBaseAddr(SDValue Addr, SDValue &Base);
46 bool SelectAddrConstant(SDValue Addr, SDValue &Base, SDValue &Offset);
47 bool selectNonFIBaseAddr(SDValue Addr, SDValue &Base);
48 bool SelectAddrRegImm12(SDValue Addr, SDValue &Base, SDValue &Offset);
49
50 bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt);
51 bool selectShiftMaskGRLen(SDValue N, SDValue &ShAmt) {
52 return selectShiftMask(N, ShiftWidth: Subtarget->getGRLen(), ShAmt);
53 }
54 bool selectShiftMask32(SDValue N, SDValue &ShAmt) {
55 return selectShiftMask(N, ShiftWidth: 32, ShAmt);
56 }
57
58 bool selectSExti32(SDValue N, SDValue &Val);
59 bool selectZExti32(SDValue N, SDValue &Val);
60
61 bool selectVSplat(SDNode *N, APInt &Imm, unsigned MinSizeInBits) const;
62
63 template <unsigned ImmSize, unsigned EltSize = 0, bool IsSigned = false>
64 bool selectVSplatImm(SDValue N, SDValue &SplatVal);
65 template <unsigned ImmSize>
66 bool selectVSplatImmNeg(SDValue N, SDValue &SplatVal) const;
67 template <unsigned EltSize = 0>
68 bool selectVSplatUimmInvPow2(SDValue N, SDValue &SplatImm) const;
69 template <unsigned EltSize = 0>
70 bool selectVSplatUimmPow2(SDValue N, SDValue &SplatImm) const;
71
72 // Return the LoongArch branch opcode that matches the given DAG integer
73 // condition code. The CondCode must be one of those supported by the
74 // LoongArch ISA (see translateSetCCForBranch).
75 static unsigned getBranchOpcForIntCC(ISD::CondCode CC) {
76 switch (CC) {
77 default:
78 llvm_unreachable("Unsupported CondCode");
79 case ISD::SETEQ:
80 return LoongArch::BEQ;
81 case ISD::SETNE:
82 return LoongArch::BNE;
83 case ISD::SETLT:
84 return LoongArch::BLT;
85 case ISD::SETGE:
86 return LoongArch::BGE;
87 case ISD::SETULT:
88 return LoongArch::BLTU;
89 case ISD::SETUGE:
90 return LoongArch::BGEU;
91 }
92 }
93
94// Include the pieces autogenerated from the target description.
95#include "LoongArchGenDAGISel.inc"
96};
97
98class LoongArchDAGToDAGISelLegacy : public SelectionDAGISelLegacy {
99public:
100 static char ID;
101 explicit LoongArchDAGToDAGISelLegacy(LoongArchTargetMachine &TM,
102 CodeGenOptLevel OptLevel);
103};
104
105} // end namespace llvm
106
107#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELDAGTODAG_H
108