1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
|
//===-- VEInstrInfo.td - Target Description for VE Target -----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file describes the VE instructions in TableGen format.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Instruction format superclass
//===----------------------------------------------------------------------===//
include "VEInstrFormats.td"
//===----------------------------------------------------------------------===//
// Feature predicates.
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Instruction Pattern Stuff
//===----------------------------------------------------------------------===//
def simm7 : PatLeaf<(imm), [{ return isInt<7>(N->getSExtValue()); }]>;
def simm32 : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;
def uimm6 : PatLeaf<(imm), [{ return isUInt<6>(N->getZExtValue()); }]>;
// ASX format of memory address
def MEMri : Operand<iPTR> {
let PrintMethod = "printMemASXOperand";
let MIOperandInfo = (ops ptr_rc, i64imm);
}
// AS format of memory address
def MEMASri : Operand<iPTR> {
let PrintMethod = "printMemASOperand";
let MIOperandInfo = (ops ptr_rc, i64imm);
}
// Branch targets have OtherVT type.
def brtarget32 : Operand<OtherVT> {
let EncoderMethod = "getBranchTarget32OpValue";
}
def simm7Op64 : Operand<i64> {
let DecoderMethod = "DecodeSIMM7";
}
def simm32Op64 : Operand<i64> {
let DecoderMethod = "DecodeSIMM32";
}
def uimm6Op64 : Operand<i64> {
let DecoderMethod = "DecodeUIMM6";
}
// Operand for printing out a condition code.
let PrintMethod = "printCCOperand" in
def CCOp : Operand<i32>;
// These are target-independent nodes, but have target-specific formats.
def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i64>,
SDTCisVT<1, i64> ]>;
def SDT_SPCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i64>,
SDTCisVT<1, i64> ]>;
def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart,
[SDNPHasChain, SDNPOutGlue]>;
def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
// def SDT_SPCall : SDTypeProfile<0, -1, [SDTCisVT<0, i64>]>;
def retflag : SDNode<"VEISD::RET_FLAG", SDTNone,
[SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
//===----------------------------------------------------------------------===//
// VE Flag Conditions
//===----------------------------------------------------------------------===//
// Note that these values must be kept in sync with the CCOp::CondCode enum
// values.
class CC_VAL<int N> : PatLeaf<(i32 N)>;
def CC_IG : CC_VAL< 0>; // Greater
def CC_IL : CC_VAL< 1>; // Less
def CC_INE : CC_VAL< 2>; // Not Equal
def CC_IEQ : CC_VAL< 3>; // Equal
def CC_IGE : CC_VAL< 4>; // Greater or Equal
def CC_ILE : CC_VAL< 5>; // Less or Equal
def CC_AF : CC_VAL< 6>; // Always false
def CC_G : CC_VAL< 7>; // Greater
def CC_L : CC_VAL< 8>; // Less
def CC_NE : CC_VAL< 9>; // Not Equal
def CC_EQ : CC_VAL<10>; // Equal
def CC_GE : CC_VAL<11>; // Greater or Equal
def CC_LE : CC_VAL<12>; // Less or Equal
def CC_NUM : CC_VAL<13>; // Number
def CC_NAN : CC_VAL<14>; // NaN
def CC_GNAN : CC_VAL<15>; // Greater or NaN
def CC_LNAN : CC_VAL<16>; // Less or NaN
def CC_NENAN : CC_VAL<17>; // Not Equal or NaN
def CC_EQNAN : CC_VAL<18>; // Equal or NaN
def CC_GENAN : CC_VAL<19>; // Greater or Equal or NaN
def CC_LENAN : CC_VAL<20>; // Less or Equal or NaN
def CC_AT : CC_VAL<21>; // Always true
//===----------------------------------------------------------------------===//
// VE Multiclasses for common instruction formats
//===----------------------------------------------------------------------===//
multiclass RMm<string opcStr, bits<8>opc,
RegisterClass RC, ValueType Ty, Operand immOp, Operand immOp2> {
def rri : RM<
opc, (outs RC:$sx), (ins RC:$sy, RC:$sz, immOp2:$imm32),
!strconcat(opcStr, " $sx, ${imm32}($sy, ${sz})")> {
let cy = 1;
let cz = 1;
let hasSideEffects = 0;
}
def zzi : RM<
opc, (outs RC:$sx), (ins immOp2:$imm32),
!strconcat(opcStr, " $sx, $imm32")> {
let cy = 0;
let sy = 0;
let cz = 0;
let sz = 0;
let hasSideEffects = 0;
}
}
// Multiclass for RR type instructions
multiclass RRmrr<string opcStr, bits<8>opc,
RegisterClass RCo, ValueType Tyo,
RegisterClass RCi, ValueType Tyi> {
def rr : RR<opc, (outs RCo:$sx), (ins RCi:$sy, RCi:$sz),
!strconcat(opcStr, " $sx, $sy, $sz")>
{ let cy = 1; let cz = 1; let hasSideEffects = 0; }
}
multiclass RRmri<string opcStr, bits<8>opc,
RegisterClass RCo, ValueType Tyo,
RegisterClass RCi, ValueType Tyi, Operand immOp> {
// VE calculates (OpNode $sy, $sz), but llvm requires to have immediate
// in RHS, so we use following definition.
def ri : RR<opc, (outs RCo:$sx), (ins RCi:$sz, immOp:$sy),
!strconcat(opcStr, " $sx, $sy, $sz")>
{ let cy = 0; let cz = 1; let hasSideEffects = 0; }
}
multiclass RRmiz<string opcStr, bits<8>opc,
RegisterClass RCo, ValueType Tyo,
RegisterClass RCi, ValueType Tyi, Operand immOp> {
def zi : RR<opc, (outs RCo:$sx), (ins immOp:$sy),
!strconcat(opcStr, " $sx, $sy")>
{ let cy = 0; let cz = 0; let sz = 0; let hasSideEffects = 0; }
}
multiclass RRNDmrm<string opcStr, bits<8>opc,
RegisterClass RCo, ValueType Tyo,
RegisterClass RCi, ValueType Tyi, Operand immOp2> {
def rm0 : RR<opc, (outs RCo:$sx), (ins RCi:$sy, immOp2:$sz),
!strconcat(opcStr, " $sx, $sy, (${sz})0")> {
let cy = 1;
let cz = 0;
let sz{6} = 1;
// (guess) tblgen conservatively assumes hasSideEffects when
// it fails to infer from a pattern.
let hasSideEffects = 0;
}
}
// Used by add, mul, div, and similar commutative instructions
// The order of operands are "$sx, $sy, $sz"
multiclass RRm<string opcStr, bits<8>opc,
RegisterClass RC, ValueType Ty, Operand immOp, Operand immOp2> :
RRmrr<opcStr, opc, RC, Ty, RC, Ty>,
RRmri<opcStr, opc, RC, Ty, RC, Ty, immOp>,
RRmiz<opcStr, opc, RC, Ty, RC, Ty, immOp>,
RRNDmrm<opcStr, opc, RC, Ty, RC, Ty, immOp2>;
// Branch multiclass
let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in
multiclass BCRm<string opcStr, string opcStrAt, bits<8> opc,
RegisterClass RC, ValueType Ty, Operand immOp, Operand immOp2> {
def rr : CF<
opc, (outs),
(ins CCOp:$cf, RC:$sy, RC:$sz, brtarget32:$imm32),
!strconcat(opcStr, " $sy, $sz, $imm32")> {
let cy = 1;
let cz = 1;
let hasSideEffects = 0;
}
}
//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
// LEA and LEASL instruction (load 32 bit imm to low or high part)
let cx = 0 in
defm LEA : RMm<"lea", 0x06, I64, i64, simm7Op64, simm32Op64>;
let cx = 1 in
defm LEASL : RMm<"lea.sl", 0x06, I64, i64, simm7Op64, simm32Op64>;
// 5.3.2.2. Fixed-Point Arithmetic Operation Instructions
// ADX instruction
let cx = 0 in
defm ADX : RRm<"adds.l", 0x59, I64, i64, simm7Op64, uimm6Op64>;
// 5.3.2.3. Logical Arithmetic Operation Instructions
let cx = 0 in {
defm AND : RRm<"and", 0x44, I64, i64, simm7Op64, uimm6Op64>;
defm OR : RRm<"or", 0x45, I64, i64, simm7Op64, uimm6Op64>;
}
// Load and Store instructions
// As 1st step, only uses sz and imm32 to represent $addr
let mayLoad = 1, hasSideEffects = 0 in {
let cy = 0, sy = 0, cz = 1 in {
let cx = 0 in
def LDSri : RM<
0x01, (outs I64:$sx), (ins MEMri:$addr),
"ld $sx, $addr">;
}
}
let mayStore = 1, hasSideEffects = 0 in {
let cx = 0, cy = 0, sy = 0, cz = 1 in {
def STSri : RM<
0x11, (outs), (ins MEMri:$addr, I64:$sx),
"st $sx, $addr">;
}
}
// Return instruction is also a special case of jump.
let cx = 0, cx2 = 0, bpf = 0 /* NONE */, cf = 15 /* AT */, cy = 0, sy = 0,
cz = 1, sz = 0x10 /* SX10 */, imm32 = 0, Uses = [SX10],
isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1,
isCodeGenOnly = 1, hasSideEffects = 0 in
def RET : CF<
0x19, (outs), (ins),
"b.l (,%lr)",
[(retflag)]>;
// Branch instruction
let cx = 0, cx2 = 0, bpf = 0 /* NONE */ in
defm BCRL : BCRm<"br${cf}.l", "br.l", 0x18, I64, i64, simm7Op64, uimm6Op64>;
let cx = 0, cy = 0, cz = 1, hasSideEffects = 0 in {
let sy = 3 in
def SHMri : RM<
0x31, (outs), (ins MEMASri:$addr, I64:$sx),
"shm.l $sx, $addr">;
}
let cx = 0, sx = 0, cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 0 in
def MONC : RR<
0x3F, (outs), (ins),
"monc">;
//===----------------------------------------------------------------------===//
// Pseudo Instructions
//===----------------------------------------------------------------------===//
let Defs = [SX11], Uses = [SX11], hasSideEffects = 0 in {
def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i64imm:$amt, i64imm:$amt2),
"# ADJCALLSTACKDOWN $amt, $amt2",
[(callseq_start timm:$amt, timm:$amt2)]>;
def ADJCALLSTACKUP : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2),
"# ADJCALLSTACKUP $amt1",
[(callseq_end timm:$amt1, timm:$amt2)]>;
}
let Defs = [SX8], Uses = [SX8, SX11], hasSideEffects = 0 in
def EXTEND_STACK : Pseudo<(outs), (ins),
"# EXTEND STACK",
[]>;
let hasSideEffects = 0 in
def EXTEND_STACK_GUARD : Pseudo<(outs), (ins),
"# EXTEND STACK GUARD",
[]>;
|