1//===- XtensaInstrInfo.td - Target Description for Xtensa -*- tablegen -*--===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6// See https://llvm.org/LICENSE.txt for license information.
7// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8//
9//===----------------------------------------------------------------------===//
10//
11// This file describes the Xtensa instructions in TableGen format.
12//
13//===----------------------------------------------------------------------===//
14
15include "XtensaInstrFormats.td"
16include "XtensaOperands.td"
17
18//===----------------------------------------------------------------------===//
19// Arithmetic & Logical instructions
20//===----------------------------------------------------------------------===//
21
22class ArithLogic_RRR<bits<4> oper2, bits<4> oper1, string instrAsm,
23      SDPatternOperator opNode, bit isComm = 0>
24  : RRR_Inst<0x00, oper1, oper2, (outs AR:$r), (ins AR:$s, AR:$t),
25             instrAsm#"\t$r, $s, $t",
26            [(set AR:$r, (opNode AR:$s, AR:$t))]> {
27  let isCommutable = isComm;
28  let isReMaterializable = 0;
29}
30
31def ADD : ArithLogic_RRR<0x08, 0x00, "add", add, 1>;
32def SUB : ArithLogic_RRR<0x0C, 0x00, "sub", sub>;
33def AND : ArithLogic_RRR<0x01, 0x00, "and", and, 1>;
34def OR  : ArithLogic_RRR<0x02, 0x00, "or", or, 1>;
35def XOR : ArithLogic_RRR<0x03, 0x00, "xor", xor, 1>;
36
37class ADDX<bits<4> oper, string instrAsm, list<dag> pattern>
38  : RRR_Inst<0x00, 0x00, oper, (outs AR:$r), (ins AR:$s, AR:$t),
39             instrAsm#"\t$r, $s, $t", pattern>;
40
41def ADDX2 : ADDX<0x09, "addx2", [(set AR:$r, (add AR:$t, (shl AR:$s, (i32 1))))]>;
42def ADDX4 : ADDX<0x0A, "addx4", [(set AR:$r, (add AR:$t, (shl AR:$s, (i32 2))))]>;
43def ADDX8 : ADDX<0x0B, "addx8", [(set AR:$r, (add AR:$t, (shl AR:$s, (i32 3))))]>;
44
45class SUBX<bits<4> oper, string instrAsm, list<dag> pattern>
46  : RRR_Inst<0x00, 0x00, oper, (outs AR:$r), (ins AR:$s, AR:$t),
47             instrAsm#"\t$r, $s, $t", pattern>;
48
49def SUBX2 : SUBX<0x0D, "subx2", [(set AR:$r, (sub (shl AR:$s, (i32 1)), AR:$t))]>;
50def SUBX4 : SUBX<0x0E, "subx4", [(set AR:$r, (sub (shl AR:$s, (i32 2)), AR:$t))]>;
51def SUBX8 : SUBX<0x0F, "subx8", [(set AR:$r, (sub (shl AR:$s, (i32 3)), AR:$t))]>;
52
53def ABS : RRR_Inst<0x00, 0x00, 0x06, (outs AR:$r), (ins AR:$t),
54                  "abs\t$r, $t", []> {
55  let s = 0x1;
56}
57
58def ADDI : RRI8_Inst<0x02, (outs AR:$t), (ins AR:$s, imm8:$imm8),
59                    "addi\t$t, $s, $imm8",
60                    [(set AR:$t, (add AR:$s, imm8:$imm8))]> {
61  let r = 0x0C;
62}
63
64def ADDMI : RRI8_Inst<0x02, (outs AR:$t), (ins AR:$s, imm8_sh8:$imm_sh8),
65                     "addmi\t$t, $s, $imm_sh8",
66                     [(set AR:$t, (add AR:$s, imm8_sh8:$imm_sh8))]> {
67  bits<16> imm_sh8;
68
69  let r = 0x0D;
70  let imm8 = imm_sh8{15-8};
71}
72
73def NEG : RRR_Inst<0x00, 0x00, 0x06, (outs AR:$r), (ins AR:$t),
74                  "neg\t$r, $t",
75                  [(set AR:$r, (ineg AR:$t))]> {
76  let s = 0x00;
77}
78
79//===----------------------------------------------------------------------===//
80// Move instructions
81//===----------------------------------------------------------------------===//
82def MOVI : RRI8_Inst<0x02, (outs AR:$t), (ins imm12m:$imm),
83                    "movi\t$t, $imm",
84                    [(set AR:$t, imm12m:$imm)]> {
85  bits<12> imm;
86
87  let imm8{7-0} = imm{7-0};
88  let s{3-0} = imm{11-8};
89  let r = 0xa;
90}
91
92def MOVEQZ : RRR_Inst<0x00, 0x03, 0x08, (outs AR:$r), (ins AR:$s, AR:$t),
93                     "moveqz\t$r, $s, $t", []>;
94def MOVNEZ : RRR_Inst<0x00, 0x03, 0x09, (outs AR:$r), (ins AR:$s, AR:$t),
95                     "movnez\t$r, $s, $t", []>;
96def MOVLTZ : RRR_Inst<0x00, 0x03, 0x0A, (outs AR:$r), (ins AR:$s, AR:$t),
97                     "movltz\t$r, $s, $t", []>;
98def MOVGEZ : RRR_Inst<0x00, 0x03, 0x0B, (outs AR:$r), (ins AR:$s, AR:$t),
99                     "movgez\t$r, $s, $t", []>;
100
101//===----------------------------------------------------------------------===//
102// Shift instructions
103//===----------------------------------------------------------------------===//
104
105let Uses = [SAR] in {
106  def SLL : RRR_Inst<0x00, 0x01, 0x0A, (outs AR:$r), (ins AR:$s),
107                    "sll\t$r, $s", []> {
108    let t = 0x00;
109  }
110
111  def SRA : RRR_Inst<0x00, 0x01, 0x0B, (outs AR:$r), (ins AR:$t),
112                    "sra\t$r, $t", []> {
113    let s = 0x00;
114  }
115
116  def SRC : RRR_Inst<0x00, 0x01, 0x08, (outs AR:$r), (ins AR:$s, AR:$t),
117                    "src\t$r, $s, $t", []>;
118
119  def SRL : RRR_Inst<0x00, 0x01, 0x09, (outs AR:$r), (ins AR:$t),
120                    "srl\t$r, $t", []> {
121    let s = 0x00;
122  }
123}
124
125let Defs = [SAR] in {
126  def SSL : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins AR:$s),
127                    "ssl\t$s", []> {
128    let r = 0x01;
129    let t = 0x00;
130  }
131
132  def SSR : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins AR:$s),
133                    "ssr\t$s", []> {
134    let r = 0x00;
135    let t = 0x00;
136  }
137}
138
139def EXTUI : RRR_Inst<0x00, 0x04, 0x00, (outs AR:$r), (ins AR:$t, uimm5:$imm1, imm1_16:$imm2),
140                    "extui\t$r, $t, $imm1, $imm2", []> {
141  bits<5> imm1;
142  bits<4> imm2;
143
144  let s = imm1{3-0};
145  let Inst{16} = imm1{4};
146  let Inst{23-20} = imm2;
147}
148
149def SRAI : RRR_Inst<0x00, 0x01, 0x02, (outs AR:$r), (ins AR:$t, uimm5:$sa),
150                   "srai\t$r, $t, $sa",
151                   [(set AR:$r, (sra AR:$t, uimm5:$sa))]> {
152  bits<5> sa;
153
154  let Inst{20} = sa{4};
155  let s = sa{3-0};
156}
157
158def SRLI : RRR_Inst<0x00, 0x01, 0x04, (outs AR:$r), (ins AR:$t, uimm4:$sa),
159                   "srli\t$r, $t, $sa",
160                   [(set AR:$r, (srl AR:$t, uimm4:$sa))]> {
161  bits<4> sa;
162
163  let s = sa;
164}
165
166def SLLI : RRR_Inst<0x00, 0x01, 0x00, (outs AR:$r), (ins AR:$s, shimm1_31:$sa),
167                   "slli\t$r, $s, $sa",
168                   [(set AR:$r, (shl AR:$s, shimm1_31:$sa))]> {
169  bits<5> sa;
170
171  let Inst{20} = sa{4};
172  let t = sa{3-0};
173}
174
175def SSA8L : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins AR:$s),
176                    "ssa8l\t$s", []> {
177  let r = 0x2;
178  let t = 0x0;
179}
180
181def SSAI : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins uimm5:$imm),
182                   "ssai\t$imm", []> {
183  bits<5> imm;
184
185  let r = 0x04;
186  let s = imm{3-0};
187  let t{3-1} = 0;
188  let t{0} = imm{4};
189}
190
191//===----------------------------------------------------------------------===//
192// Load and store instructions
193//===----------------------------------------------------------------------===//
194
195// Load instructions
196let mayLoad = 1 in {
197
198  class Load_RRI8<bits<4> oper, string instrAsm, SDPatternOperator opNode,
199        ComplexPattern addrOp, Operand memOp>
200	  : RRI8_Inst<0x02, (outs AR:$t), (ins memOp:$addr),
201                instrAsm#"\t$t, $addr",
202               [(set AR:$t, (opNode addrOp:$addr))]> {
203    bits<12> addr;
204
205    let r = oper;
206    let imm8{7-0} = addr{11-4};
207    let s{3-0} = addr{3-0};
208  }
209}
210
211def L8UI  : Load_RRI8<0x00, "l8ui", zextloadi8, addr_ish1, mem8>;
212def L16SI : Load_RRI8<0x09, "l16si", sextloadi16, addr_ish2, mem16>;
213def L16UI : Load_RRI8<0x01, "l16ui", zextloadi16, addr_ish2, mem16>;
214def L32I  : Load_RRI8<0x02, "l32i", load, addr_ish4, mem32>;
215
216// Store instructions
217let mayStore = 1 in {
218  class Store_II8<bits<4> oper, string instrAsm, SDPatternOperator opNode,
219        ComplexPattern addrOp, Operand memOp>
220	  : RRI8_Inst<0x02, (outs), (ins AR:$t, memOp:$addr),
221                instrAsm#"\t$t, $addr",
222               [(opNode AR:$t, addrOp:$addr)]> {
223    bits<12> addr;
224
225    let r = oper;
226    let imm8{7-0} = addr{11-4};
227    let s{3-0} = addr{3-0};
228  }
229}
230
231def S8I  : Store_II8<0x04, "s8i", truncstorei8, addr_ish1, mem8>;
232def S16I : Store_II8<0x05, "s16i", truncstorei16, addr_ish2, mem16>;
233def S32I : Store_II8<0x06, "s32i", store, addr_ish4, mem32>;
234
235def L32R : RI16_Inst<0x01, (outs AR:$t), (ins L32Rtarget:$label),
236                    "l32r\t$t, $label", []> {
237  bits<16> label;
238  let imm16 = label;
239}
240
241//===----------------------------------------------------------------------===//
242// Conditional branch instructions
243//===----------------------------------------------------------------------===//
244let isBranch = 1, isTerminator = 1 in {
245  class Branch_RR<bits<4> oper, string instrAsm, CondCode CC>
246      : RRI8_Inst<0x07, (outs),
247                 (ins AR:$s, AR:$t, brtarget:$target),
248                  instrAsm#"\t$s, $t, $target",
249                 [(brcc CC, AR:$s, AR:$t,  bb:$target)]> {
250    bits<8> target;
251
252    let r = oper;
253    let imm8 = target;
254  }
255
256  class Branch_RI<bits<4> oper, string instrAsm, CondCode CC>
257      : RRI8_Inst<0x06, (outs),
258                 (ins AR:$s, b4const:$imm, brtarget:$target),
259                  instrAsm#"\t$s, $imm, $target",
260                 [(brcc CC, AR:$s, b4const:$imm,  bb:$target)]> {
261    bits<4> imm;
262    bits<8> target;
263
264    let t = oper;
265    let r = imm;
266    let imm8 = target;
267  }
268
269  class Branch_RIU<bits<4> oper, string instrAsm, CondCode CC>
270    : RRI8_Inst<0x06, (outs),
271               (ins AR:$s, b4constu:$imm, brtarget:$target),
272                instrAsm#"\t$s, $imm, $target",
273               [(brcc CC, AR:$s, b4constu:$imm,  bb:$target)]> {
274    bits<4> imm;
275    bits<8> target;
276
277    let t = oper;
278    let r = imm;
279    let imm8 = target;
280  }
281
282  class Branch_RZ<bits<2> n, bits<2> m, string instrAsm, CondCode CC>
283    : BRI12_Inst<0x06, n, m, (outs),
284                (ins AR:$s, brtarget:$target),
285                 instrAsm#"\t$s, $target",
286                [(brcc CC, AR:$s, (i32 0),  bb:$target)]> {
287    bits<12> target;
288
289    let imm12 = target;
290  }
291}
292
293def BEQ   : Branch_RR<0x01, "beq", SETEQ>;
294def BNE   : Branch_RR<0x09, "bne", SETNE>;
295def BGE   : Branch_RR<0x0A, "bge", SETGE>;
296def BLT   : Branch_RR<0x02, "blt", SETLT>;
297def BGEU  : Branch_RR<0x0B, "bgeu", SETUGE>;
298def BLTU  : Branch_RR<0x03, "bltu", SETULT>;
299
300def BEQI  : Branch_RI<0x02, "beqi", SETEQ>;
301def BNEI  : Branch_RI<0x06, "bnei", SETNE>;
302def BGEI  : Branch_RI<0x0E, "bgei", SETGE>;
303def BLTI  : Branch_RI<0x0A, "blti", SETLT>;
304def BGEUI : Branch_RIU<0x0F, "bgeui", SETUGE>;
305def BLTUI : Branch_RIU<0x0B, "bltui", SETULT>;
306
307def BEQZ  : Branch_RZ<0x01, 0x00, "beqz", SETEQ>;
308def BNEZ  : Branch_RZ<0x01, 0x01, "bnez", SETNE>;
309def BGEZ  : Branch_RZ<0x01, 0x03, "bgez", SETGE>;
310def BLTZ  : Branch_RZ<0x01, 0x02, "bltz", SETLT>;
311
312def BALL : RRI8_Inst<0x07, (outs),
313                    (ins AR:$s, AR:$t, brtarget:$target),
314                    "ball\t$s, $t, $target", []> {
315  bits<8> target;
316
317  let r = 0x04;
318  let imm8 = target;
319}
320
321def BANY : RRI8_Inst<0x07, (outs),
322                    (ins AR:$s, AR:$t, brtarget:$target),
323                    "bany\t$s, $t, $target", []> {
324  bits<8> target;
325
326  let r = 0x08;
327  let imm8 = target;
328}
329
330def BBC : RRI8_Inst<0x07, (outs),
331                   (ins AR:$s, AR:$t, brtarget:$target),
332                   "bbc\t$s, $t, $target", []> {
333  bits<8> target;
334
335  let r = 0x05;
336  let imm8 = target;
337}
338
339def BBS : RRI8_Inst<0x07, (outs),
340                   (ins AR:$s, AR:$t, brtarget:$target),
341                   "bbs\t$s, $t, $target", []> {
342  bits<8> target;
343
344  let r = 0x0d;
345  let imm8 = target;
346}
347
348def BNALL : RRI8_Inst<0x07, (outs),
349                    (ins AR:$s, AR:$t, brtarget:$target),
350                    "bnall\t$s, $t, $target", []> {
351  bits<8> target;
352
353  let r = 0x0c;
354  let imm8 = target;
355}
356
357def BNONE : RRI8_Inst<0x07, (outs),
358                     (ins AR:$s, AR:$t, brtarget:$target),
359                     "bnone\t$s, $t, $target", []> {
360  bits<8> target;
361
362  let r = 0x00;
363  let imm8 = target;
364}
365
366def BBCI : RRI8_Inst<0x07, (outs),
367                    (ins AR:$s, uimm5:$imm, brtarget:$target),
368                    "bbci\t$s, $imm, $target", []> {
369  bits<8> target;
370  bits<5> imm;
371
372  let r{3-1} = 0x3;
373  let r{0} = imm{4};
374  let t{3-0} = imm{3-0};
375  let imm8 = target;
376}
377
378def BBSI : RRI8_Inst<0x07, (outs),
379                    (ins AR:$s, uimm5:$imm, brtarget:$target),
380                    "bbsi\t$s, $imm, $target", []> {
381  bits<8> target;
382  bits<5> imm;
383
384  let r{3-1} = 0x7;
385  let r{0} = imm{4};
386  let t{3-0} = imm{3-0};
387  let imm8 = target;
388}
389
390//===----------------------------------------------------------------------===//
391// Call and jump instructions
392//===----------------------------------------------------------------------===//
393
394let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
395  def J : CALL_Inst<0x06, (outs), (ins jumptarget:$offset),
396                   "j\t$offset",
397                   [(br bb:$offset)]> {
398    let n = 0x0;
399  }
400
401  def JX : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins AR:$s),
402                     "jx\t$s",
403                     [(brind AR:$s)]> {
404    let m = 0x2;
405    let n = 0x2;
406    let r = 0;
407    let isIndirectBranch = 1;
408  }
409}
410
411let isCall = 1, Defs = [A0] in {
412  def CALL0 : CALL_Inst<0x05, (outs), (ins pcrel32call:$offset),
413                       "call0\t$offset", []> {
414    let n = 0;
415  }
416
417  def CALLX0 : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins AR:$s),
418                         "callx0\t$s", []> {
419    let m = 0x3;
420    let n = 0x0;
421    let r = 0;
422  }
423}
424
425let isReturn = 1, isTerminator = 1,
426    isBarrier = 1, Uses = [A0] in {
427
428  def RET : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins),
429                      "ret", []> {
430    let m = 0x2;
431    let n = 0x0;
432    let s = 0;
433    let r = 0;
434  }
435}
436
437//===----------------------------------------------------------------------===//
438// Mem barrier instructions
439//===----------------------------------------------------------------------===//
440
441def MEMW :  RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
442                    "memw", []> {
443  let r = 0x2;
444  let t = 0x0c;
445  let s = 0x0;
446}
447
448def EXTW : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
449                   "extw", []> {
450  let r = 0x2;
451  let s = 0x0;
452  let t = 0xd;
453  let hasSideEffects = 1;
454}
455
456//===----------------------------------------------------------------------===//
457// Processor control instructions
458//===----------------------------------------------------------------------===//
459
460def DSYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
461                    "dsync", []> {
462  let r = 0x2;
463  let s = 0x0;
464  let t = 0x3;
465  let hasSideEffects = 1;
466}
467
468def ISYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
469                    "isync", []> {
470  let r = 0x2;
471  let s = 0x0;
472  let t = 0x0;
473  let hasSideEffects = 1;
474}
475
476def RSYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
477                    "rsync", []> {
478  let r = 0x2;
479  let s = 0x0;
480  let t = 0x1;
481  let hasSideEffects = 1;
482}
483
484def ESYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
485                    "esync", []> {
486  let r = 0x2;
487  let s = 0x0;
488  let t = 0x2;
489  let hasSideEffects = 1;
490}
491
492def NOP : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
493                  "nop", []> {
494  let r = 0x02;
495  let s = 0x00;
496  let t = 0x0f;
497}
498
499def WSR : RSR_Inst<0x00, 0x03, 0x01, (outs SR:$sr), (ins AR:$t),
500                  "wsr\t$t, $sr", []>;
501
502def RSR : RSR_Inst<0x00, 0x03, 0x00, (outs AR:$t), (ins SR:$sr),
503                  "rsr\t$t, $sr", []>;
504
505def XSR : RSR_Inst<0x00, 0x01, 0x06, (outs AR:$ard, SR:$srd), (ins AR:$t, SR:$sr),
506                  "xsr\t$t, $sr", []> {
507  let Constraints = "$ard = $t, $srd = $sr";
508}
509