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