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