Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp
35271 views
1
//===- XtensaISelDAGToDAG.cpp - A dag to dag inst selector for Xtensa -----===//
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 Xtensa target.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "Xtensa.h"
14
#include "XtensaTargetMachine.h"
15
#include "XtensaUtils.h"
16
#include "llvm/CodeGen/MachineFunction.h"
17
#include "llvm/CodeGen/MachineRegisterInfo.h"
18
#include "llvm/CodeGen/SelectionDAGISel.h"
19
#include "llvm/IR/DiagnosticInfo.h"
20
#include "llvm/Support/Debug.h"
21
#include "llvm/Support/raw_ostream.h"
22
23
using namespace llvm;
24
25
#define DEBUG_TYPE "xtensa-isel"
26
27
namespace {
28
29
class XtensaDAGToDAGISel : public SelectionDAGISel {
30
public:
31
XtensaDAGToDAGISel(XtensaTargetMachine &TM, CodeGenOptLevel OptLevel)
32
: SelectionDAGISel(TM, OptLevel) {}
33
34
void Select(SDNode *Node) override;
35
36
// For load/store instructions generate (base+offset) pair from
37
// memory address. The offset must be a multiple of scale argument.
38
bool selectMemRegAddr(SDValue Addr, SDValue &Base, SDValue &Offset,
39
int Scale) {
40
EVT ValTy = Addr.getValueType();
41
42
// if Address is FI, get the TargetFrameIndex.
43
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
44
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
45
Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), ValTy);
46
47
return true;
48
}
49
50
if (TM.isPositionIndependent()) {
51
DiagnosticInfoUnsupported Diag(CurDAG->getMachineFunction().getFunction(),
52
"PIC relocations are not supported ",
53
Addr.getDebugLoc());
54
CurDAG->getContext()->diagnose(Diag);
55
}
56
57
if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
58
Addr.getOpcode() == ISD::TargetGlobalAddress))
59
return false;
60
61
// Addresses of the form FI+const
62
bool Valid = false;
63
if (CurDAG->isBaseWithConstantOffset(Addr)) {
64
ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));
65
int64_t OffsetVal = CN->getSExtValue();
66
67
Valid = isValidAddrOffset(Scale, OffsetVal);
68
69
if (Valid) {
70
// If the first operand is a FI, get the TargetFI Node
71
if (FrameIndexSDNode *FIN =
72
dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
73
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
74
else
75
Base = Addr.getOperand(0);
76
77
Offset =
78
CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), ValTy);
79
return true;
80
}
81
}
82
83
// Last case
84
Base = Addr;
85
Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), Addr.getValueType());
86
return true;
87
}
88
89
bool selectMemRegAddrISH1(SDValue Addr, SDValue &Base, SDValue &Offset) {
90
return selectMemRegAddr(Addr, Base, Offset, 1);
91
}
92
93
bool selectMemRegAddrISH2(SDValue Addr, SDValue &Base, SDValue &Offset) {
94
return selectMemRegAddr(Addr, Base, Offset, 2);
95
}
96
97
bool selectMemRegAddrISH4(SDValue Addr, SDValue &Base, SDValue &Offset) {
98
return selectMemRegAddr(Addr, Base, Offset, 4);
99
}
100
101
// Include the pieces autogenerated from the target description.
102
#include "XtensaGenDAGISel.inc"
103
}; // namespace
104
105
class XtensaDAGToDAGISelLegacy : public SelectionDAGISelLegacy {
106
public:
107
static char ID;
108
109
XtensaDAGToDAGISelLegacy(XtensaTargetMachine &TM, CodeGenOptLevel OptLevel)
110
: SelectionDAGISelLegacy(
111
ID, std::make_unique<XtensaDAGToDAGISel>(TM, OptLevel)) {}
112
113
StringRef getPassName() const override {
114
return "Xtensa DAG->DAG Pattern Instruction Selection";
115
}
116
};
117
} // end anonymous namespace
118
119
char XtensaDAGToDAGISelLegacy::ID = 0;
120
121
FunctionPass *llvm::createXtensaISelDag(XtensaTargetMachine &TM,
122
CodeGenOptLevel OptLevel) {
123
return new XtensaDAGToDAGISelLegacy(TM, OptLevel);
124
}
125
126
void XtensaDAGToDAGISel::Select(SDNode *Node) {
127
SDLoc DL(Node);
128
129
// If we have a custom node, we already have selected!
130
if (Node->isMachineOpcode()) {
131
Node->setNodeId(-1);
132
return;
133
}
134
135
SelectCode(Node);
136
}
137
138