xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Xtensa/XtensaInstrInfo.td (revision 700637cbb5e582861067a11aaca4d053546871d2)
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"
17include "XtensaOperators.td"
18
19//===----------------------------------------------------------------------===//
20// Arithmetic & Logical instructions
21//===----------------------------------------------------------------------===//
22
23class ArithLogic_RRR<bits<4> oper2, bits<4> oper1, string instrAsm,
24      SDPatternOperator opNode, bit isComm = 0>
25  : RRR_Inst<0x00, oper1, oper2, (outs AR:$r), (ins AR:$s, AR:$t),
26             instrAsm#"\t$r, $s, $t",
27            [(set AR:$r, (opNode AR:$s, AR:$t))]> {
28  let isCommutable = isComm;
29  let isReMaterializable = 0;
30}
31
32def ADD : ArithLogic_RRR<0x08, 0x00, "add", add, 1>;
33def SUB : ArithLogic_RRR<0x0C, 0x00, "sub", sub>;
34def AND : ArithLogic_RRR<0x01, 0x00, "and", and, 1>;
35def OR  : ArithLogic_RRR<0x02, 0x00, "or", or, 1>;
36def XOR : ArithLogic_RRR<0x03, 0x00, "xor", xor, 1>;
37
38class ADDX<bits<4> oper, string instrAsm, list<dag> pattern>
39  : RRR_Inst<0x00, 0x00, oper, (outs AR:$r), (ins AR:$s, AR:$t),
40             instrAsm#"\t$r, $s, $t", pattern>;
41
42def ADDX2 : ADDX<0x09, "addx2", [(set AR:$r, (add AR:$t, (shl AR:$s, (i32 1))))]>;
43def ADDX4 : ADDX<0x0A, "addx4", [(set AR:$r, (add AR:$t, (shl AR:$s, (i32 2))))]>;
44def ADDX8 : ADDX<0x0B, "addx8", [(set AR:$r, (add AR:$t, (shl AR:$s, (i32 3))))]>;
45
46class SUBX<bits<4> oper, string instrAsm, list<dag> pattern>
47  : RRR_Inst<0x00, 0x00, oper, (outs AR:$r), (ins AR:$s, AR:$t),
48             instrAsm#"\t$r, $s, $t", pattern>;
49
50def SUBX2 : SUBX<0x0D, "subx2", [(set AR:$r, (sub (shl AR:$s, (i32 1)), AR:$t))]>;
51def SUBX4 : SUBX<0x0E, "subx4", [(set AR:$r, (sub (shl AR:$s, (i32 2)), AR:$t))]>;
52def SUBX8 : SUBX<0x0F, "subx8", [(set AR:$r, (sub (shl AR:$s, (i32 3)), AR:$t))]>;
53
54def ABS : RRR_Inst<0x00, 0x00, 0x06, (outs AR:$r), (ins AR:$t),
55                  "abs\t$r, $t", []> {
56  let s = 0x1;
57}
58
59def ADDI : RRI8_Inst<0x02, (outs AR:$t), (ins AR:$s, imm8:$imm8),
60                    "addi\t$t, $s, $imm8",
61                    [(set AR:$t, (add AR:$s, imm8:$imm8))]> {
62  let r = 0x0C;
63}
64
65def ADDMI : RRI8_Inst<0x02, (outs AR:$t), (ins AR:$s, imm8_sh8:$imm_sh8),
66                     "addmi\t$t, $s, $imm_sh8",
67                     [(set AR:$t, (add AR:$s, imm8_sh8:$imm_sh8))]> {
68  bits<16> imm_sh8;
69
70  let r = 0x0D;
71  let imm8 = imm_sh8{15-8};
72}
73
74def NEG : RRR_Inst<0x00, 0x00, 0x06, (outs AR:$r), (ins AR:$t),
75                  "neg\t$r, $t",
76                  [(set AR:$r, (ineg AR:$t))]> {
77  let s = 0x00;
78}
79
80//===----------------------------------------------------------------------===//
81// Move instructions
82//===----------------------------------------------------------------------===//
83def MOVI : RRI8_Inst<0x02, (outs AR:$t), (ins imm12m:$imm),
84                    "movi\t$t, $imm",
85                    [(set AR:$t, imm12m:$imm)]> {
86  bits<12> imm;
87
88  let imm8{7-0} = imm{7-0};
89  let s{3-0} = imm{11-8};
90  let r = 0xa;
91}
92
93def MOVEQZ : RRR_Inst<0x00, 0x03, 0x08, (outs AR:$r), (ins AR:$s, AR:$t),
94                     "moveqz\t$r, $s, $t", []>;
95def MOVNEZ : RRR_Inst<0x00, 0x03, 0x09, (outs AR:$r), (ins AR:$s, AR:$t),
96                     "movnez\t$r, $s, $t", []>;
97def MOVLTZ : RRR_Inst<0x00, 0x03, 0x0A, (outs AR:$r), (ins AR:$s, AR:$t),
98                     "movltz\t$r, $s, $t", []>;
99def MOVGEZ : RRR_Inst<0x00, 0x03, 0x0B, (outs AR:$r), (ins AR:$s, AR:$t),
100                     "movgez\t$r, $s, $t", []>;
101
102//===----------------------------------------------------------------------===//
103// Shift instructions
104//===----------------------------------------------------------------------===//
105
106let Uses = [SAR] in {
107  def SLL : RRR_Inst<0x00, 0x01, 0x0A, (outs AR:$r), (ins AR:$s),
108                    "sll\t$r, $s", []> {
109    let t = 0x00;
110  }
111
112  def SRA : RRR_Inst<0x00, 0x01, 0x0B, (outs AR:$r), (ins AR:$t),
113                    "sra\t$r, $t", []> {
114    let s = 0x00;
115  }
116
117  def SRC : RRR_Inst<0x00, 0x01, 0x08, (outs AR:$r), (ins AR:$s, AR:$t),
118                    "src\t$r, $s, $t", []>;
119
120  def SRL : RRR_Inst<0x00, 0x01, 0x09, (outs AR:$r), (ins AR:$t),
121                    "srl\t$r, $t", []> {
122    let s = 0x00;
123  }
124}
125
126let Defs = [SAR] in {
127  def SSL : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins AR:$s),
128                    "ssl\t$s", []> {
129    let r = 0x01;
130    let t = 0x00;
131  }
132
133  def SSR : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins AR:$s),
134                    "ssr\t$s", []> {
135    let r = 0x00;
136    let t = 0x00;
137  }
138}
139
140def EXTUI : RRR_Inst<0x00, 0x04, 0x00, (outs AR:$r), (ins AR:$t, uimm5:$imm1, imm1_16:$imm2),
141                    "extui\t$r, $t, $imm1, $imm2",
142                    [(set AR:$r, (Xtensa_extui AR:$t, uimm5:$imm1, imm1_16:$imm2))]> {
143  bits<5> imm1;
144  bits<4> imm2;
145
146  let s = imm1{3-0};
147  let Inst{16} = imm1{4};
148  let Inst{23-20} = imm2;
149}
150
151def SRAI : RRR_Inst<0x00, 0x01, 0x02, (outs AR:$r), (ins AR:$t, uimm5:$sa),
152                   "srai\t$r, $t, $sa",
153                   [(set AR:$r, (sra AR:$t, uimm5:$sa))]> {
154  bits<5> sa;
155
156  let Inst{20} = sa{4};
157  let s = sa{3-0};
158}
159
160def SRLI : RRR_Inst<0x00, 0x01, 0x04, (outs AR:$r), (ins AR:$t, uimm4:$sa),
161                   "srli\t$r, $t, $sa",
162                   [(set AR:$r, (srl AR:$t, uimm4:$sa))]> {
163  bits<4> sa;
164
165  let s = sa;
166}
167
168def SLLI : RRR_Inst<0x00, 0x01, 0x00, (outs AR:$r), (ins AR:$s, shimm1_31:$sa),
169                   "slli\t$r, $s, $sa",
170                   [(set AR:$r, (shl AR:$s, shimm1_31:$sa))]> {
171  bits<5> sa;
172
173  let Inst{20} = sa{4};
174  let t = sa{3-0};
175}
176
177def SSA8L : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins AR:$s),
178                    "ssa8l\t$s", []> {
179  let r = 0x2;
180  let t = 0x0;
181}
182
183def SSAI : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins uimm5:$imm),
184                   "ssai\t$imm", []> {
185  bits<5> imm;
186
187  let r = 0x04;
188  let s = imm{3-0};
189  let t{3-1} = 0;
190  let t{0} = imm{4};
191}
192
193//===----------------------------------------------------------------------===//
194// Load and store instructions
195//===----------------------------------------------------------------------===//
196
197// Load instructions
198let mayLoad = 1, usesCustomInserter = 1 in {
199
200  class Load_RRI8<bits<4> oper, string instrAsm, SDPatternOperator opNode,
201        ComplexPattern addrOp, Operand memOp>
202	  : RRI8_Inst<0x02, (outs AR:$t), (ins memOp:$addr),
203                instrAsm#"\t$t, $addr",
204               [(set AR:$t, (opNode addrOp:$addr))]> {
205    bits<12> addr;
206
207    let r = oper;
208    let imm8{7-0} = addr{11-4};
209    let s{3-0} = addr{3-0};
210  }
211}
212
213def L8UI  : Load_RRI8<0x00, "l8ui", zextloadi8, addr_ish1, mem8>;
214def L16SI : Load_RRI8<0x09, "l16si", sextloadi16, addr_ish2, mem16>;
215def L16UI : Load_RRI8<0x01, "l16ui", zextloadi16, addr_ish2, mem16>;
216def L32I  : Load_RRI8<0x02, "l32i", load, addr_ish4, mem32>;
217
218// Store instructions
219let mayStore = 1, usesCustomInserter = 1 in {
220  class Store_II8<bits<4> oper, string instrAsm, SDPatternOperator opNode,
221        ComplexPattern addrOp, Operand memOp>
222	  : RRI8_Inst<0x02, (outs), (ins AR:$t, memOp:$addr),
223                instrAsm#"\t$t, $addr",
224               [(opNode AR:$t, addrOp:$addr)]> {
225    bits<12> addr;
226
227    let r = oper;
228    let imm8{7-0} = addr{11-4};
229    let s{3-0} = addr{3-0};
230  }
231}
232
233def S8I  : Store_II8<0x04, "s8i", truncstorei8, addr_ish1, mem8>;
234def S16I : Store_II8<0x05, "s16i", truncstorei16, addr_ish2, mem16>;
235def S32I : Store_II8<0x06, "s32i", store, addr_ish4, mem32>;
236
237let AddedComplexity = 10 in
238def L32R : RI16_Inst<0x01, (outs AR:$t), (ins L32Rtarget:$label),
239                    "l32r\t$t, $label", [(set AR:$t, (load (Xtensa_pcrel_wrapper tconstpool:$label)))]> {
240  bits<16> label;
241  let imm16 = label;
242}
243
244// FrameIndexes are legalized when they are operands from load/store
245// instructions. The same not happens for stack address copies, so an
246// add op with mem ComplexPattern is used and the stack address copy
247// can be matched.
248// Setting of attribute mayLoad is trick to process instruction operands
249// in function XtensaRegisterInfo::eliminateFI
250
251let isCodeGenOnly = 1, mayLoad = 1 in {
252
253  def LEA_ADD : RRI8_Inst<0x02, (outs AR:$t), (ins mem32:$addr),
254       "addi\t$t, $addr",
255       [(set AR:$t, addr_ish4:$addr)]> {
256    bits<12> addr;
257
258    let r = 0x0C;
259    let imm8{7-0} = addr{11-4};
260    let s{3-0} = addr{3-0};
261  }
262}
263
264//extending loads
265def : Pat<(i32 (extloadi1  addr_ish1:$addr)), (L8UI addr_ish1:$addr)>;
266def : Pat<(i32 (extloadi8  addr_ish1:$addr)), (L8UI addr_ish1:$addr)>;
267def : Pat<(i32 (extloadi16 addr_ish2:$addr)), (L16UI addr_ish2:$addr)>;
268
269//===----------------------------------------------------------------------===//
270// Conditional branch instructions
271//===----------------------------------------------------------------------===//
272let isBranch = 1, isTerminator = 1 in {
273  class Branch_RR<bits<4> oper, string instrAsm, CondCode CC>
274      : RRI8_Inst<0x07, (outs),
275                 (ins AR:$s, AR:$t, brtarget:$target),
276                  instrAsm#"\t$s, $t, $target",
277                 [(brcc CC, AR:$s, AR:$t,  bb:$target)]> {
278    bits<8> target;
279
280    let r = oper;
281    let imm8 = target;
282  }
283
284  class Branch_RI<bits<4> oper, string instrAsm, CondCode CC>
285      : RRI8_Inst<0x06, (outs),
286                 (ins AR:$s, b4const:$imm, brtarget:$target),
287                  instrAsm#"\t$s, $imm, $target",
288                 [(brcc CC, AR:$s, b4const:$imm,  bb:$target)]> {
289    bits<4> imm;
290    bits<8> target;
291
292    let t = oper;
293    let r = imm;
294    let imm8 = target;
295  }
296
297  class Branch_RIU<bits<4> oper, string instrAsm, CondCode CC>
298    : RRI8_Inst<0x06, (outs),
299               (ins AR:$s, b4constu:$imm, brtarget:$target),
300                instrAsm#"\t$s, $imm, $target",
301               [(brcc CC, AR:$s, b4constu:$imm,  bb:$target)]> {
302    bits<4> imm;
303    bits<8> target;
304
305    let t = oper;
306    let r = imm;
307    let imm8 = target;
308  }
309
310  class Branch_RZ<bits<2> n, bits<2> m, string instrAsm, CondCode CC>
311    : BRI12_Inst<0x06, n, m, (outs),
312                (ins AR:$s, brtarget:$target),
313                 instrAsm#"\t$s, $target",
314                [(brcc CC, AR:$s, (i32 0),  bb:$target)]> {
315    bits<12> target;
316
317    let imm12 = target;
318  }
319}
320
321def BEQ   : Branch_RR<0x01, "beq", SETEQ>;
322def BNE   : Branch_RR<0x09, "bne", SETNE>;
323def BGE   : Branch_RR<0x0A, "bge", SETGE>;
324def BLT   : Branch_RR<0x02, "blt", SETLT>;
325def BGEU  : Branch_RR<0x0B, "bgeu", SETUGE>;
326def BLTU  : Branch_RR<0x03, "bltu", SETULT>;
327
328def BEQI  : Branch_RI<0x02, "beqi", SETEQ>;
329def BNEI  : Branch_RI<0x06, "bnei", SETNE>;
330def BGEI  : Branch_RI<0x0E, "bgei", SETGE>;
331def BLTI  : Branch_RI<0x0A, "blti", SETLT>;
332def BGEUI : Branch_RIU<0x0F, "bgeui", SETUGE>;
333def BLTUI : Branch_RIU<0x0B, "bltui", SETULT>;
334
335def BEQZ  : Branch_RZ<0x01, 0x00, "beqz", SETEQ>;
336def BNEZ  : Branch_RZ<0x01, 0x01, "bnez", SETNE>;
337def BGEZ  : Branch_RZ<0x01, 0x03, "bgez", SETGE>;
338def BLTZ  : Branch_RZ<0x01, 0x02, "bltz", SETLT>;
339
340def BALL : RRI8_Inst<0x07, (outs),
341                    (ins AR:$s, AR:$t, brtarget:$target),
342                    "ball\t$s, $t, $target", []> {
343  bits<8> target;
344
345  let r = 0x04;
346  let imm8 = target;
347}
348
349def BANY : RRI8_Inst<0x07, (outs),
350                    (ins AR:$s, AR:$t, brtarget:$target),
351                    "bany\t$s, $t, $target", []> {
352  bits<8> target;
353
354  let r = 0x08;
355  let imm8 = target;
356}
357
358def BBC : RRI8_Inst<0x07, (outs),
359                   (ins AR:$s, AR:$t, brtarget:$target),
360                   "bbc\t$s, $t, $target", []> {
361  bits<8> target;
362
363  let r = 0x05;
364  let imm8 = target;
365}
366
367def BBS : RRI8_Inst<0x07, (outs),
368                   (ins AR:$s, AR:$t, brtarget:$target),
369                   "bbs\t$s, $t, $target", []> {
370  bits<8> target;
371
372  let r = 0x0d;
373  let imm8 = target;
374}
375
376def BNALL : RRI8_Inst<0x07, (outs),
377                    (ins AR:$s, AR:$t, brtarget:$target),
378                    "bnall\t$s, $t, $target", []> {
379  bits<8> target;
380
381  let r = 0x0c;
382  let imm8 = target;
383}
384
385def BNONE : RRI8_Inst<0x07, (outs),
386                     (ins AR:$s, AR:$t, brtarget:$target),
387                     "bnone\t$s, $t, $target", []> {
388  bits<8> target;
389
390  let r = 0x00;
391  let imm8 = target;
392}
393
394def BBCI : RRI8_Inst<0x07, (outs),
395                    (ins AR:$s, uimm5:$imm, brtarget:$target),
396                    "bbci\t$s, $imm, $target", []> {
397  bits<8> target;
398  bits<5> imm;
399
400  let r{3-1} = 0x3;
401  let r{0} = imm{4};
402  let t{3-0} = imm{3-0};
403  let imm8 = target;
404}
405
406def BBSI : RRI8_Inst<0x07, (outs),
407                    (ins AR:$s, uimm5:$imm, brtarget:$target),
408                    "bbsi\t$s, $imm, $target", []> {
409  bits<8> target;
410  bits<5> imm;
411
412  let r{3-1} = 0x7;
413  let r{0} = imm{4};
414  let t{3-0} = imm{3-0};
415  let imm8 = target;
416}
417
418def : Pat<(brcond AR:$s, bb:$target), (BNEZ AR:$s, bb:$target)>;
419//===----------------------------------------------------------------------===//
420// Call and jump instructions
421//===----------------------------------------------------------------------===//
422
423let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
424  def J : CALL_Inst<0x06, (outs), (ins jumptarget:$offset),
425                   "j\t$offset",
426                   [(br bb:$offset)]> {
427    let n = 0x0;
428  }
429
430  def JX : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins AR:$s),
431                     "jx\t$s",
432                     [(brind AR:$s)]> {
433    let m = 0x2;
434    let n = 0x2;
435    let r = 0;
436    let isIndirectBranch = 1;
437  }
438}
439
440let isCall = 1, Defs = [A0] in {
441  def CALL0 : CALL_Inst<0x05, (outs), (ins pcrel32call:$offset),
442                       "call0\t$offset", []> {
443    let n = 0;
444  }
445
446  def CALLX0 : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins AR:$s),
447                         "callx0\t$s", []> {
448    let m = 0x3;
449    let n = 0x0;
450    let r = 0;
451  }
452}
453
454let isReturn = 1, isTerminator = 1,
455    isBarrier = 1, Uses = [A0] in {
456
457  def RET : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins),
458                      "ret", [(Xtensa_ret)]> {
459    let m = 0x2;
460    let n = 0x0;
461    let s = 0;
462    let r = 0;
463  }
464}
465
466// Call patterns
467def : Pat<(Xtensa_call (i32 tglobaladdr:$dst)),
468          (CALL0 tglobaladdr:$dst)>;
469def : Pat<(Xtensa_call (i32 texternalsym:$dst)),
470          (CALL0 texternalsym:$dst)>;
471def : Pat<(Xtensa_call AR:$dst),
472          (CALLX0 AR:$dst)>;
473
474let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1, Size = 3 in {
475  def BR_JT: Pseudo<(outs), (ins AR:$s, i32imm:$jt),
476                    "!br_jt_p, $s, $jt",
477                    [(Xtensa_brjt AR:$s, tjumptable:$jt)]>;
478}
479
480//===----------------------------------------------------------------------===//
481// Mem barrier instructions
482//===----------------------------------------------------------------------===//
483
484def MEMW :  RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
485                    "memw", []> {
486  let r = 0x2;
487  let t = 0x0c;
488  let s = 0x0;
489}
490
491def EXTW : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
492                   "extw", []> {
493  let r = 0x2;
494  let s = 0x0;
495  let t = 0xd;
496  let hasSideEffects = 1;
497}
498
499//===----------------------------------------------------------------------===//
500// Illegal instructions
501//===----------------------------------------------------------------------===//
502
503def ILL : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins),
504                    "ill", []> {
505  let m = 0x0;
506  let n = 0x0;
507  let r = 0;
508  let s = 0;
509}
510
511//===----------------------------------------------------------------------===//
512// Processor control instructions
513//===----------------------------------------------------------------------===//
514
515def DSYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
516                    "dsync", []> {
517  let r = 0x2;
518  let s = 0x0;
519  let t = 0x3;
520  let hasSideEffects = 1;
521}
522
523def ISYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
524                    "isync", []> {
525  let r = 0x2;
526  let s = 0x0;
527  let t = 0x0;
528  let hasSideEffects = 1;
529}
530
531def RSYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
532                    "rsync", []> {
533  let r = 0x2;
534  let s = 0x0;
535  let t = 0x1;
536  let hasSideEffects = 1;
537}
538
539def ESYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
540                    "esync", []> {
541  let r = 0x2;
542  let s = 0x0;
543  let t = 0x2;
544  let hasSideEffects = 1;
545}
546
547def NOP : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
548                  "nop", []> {
549  let r = 0x02;
550  let s = 0x00;
551  let t = 0x0f;
552}
553
554def WSR : RSR_Inst<0x00, 0x03, 0x01, (outs SR:$sr), (ins AR:$t),
555                  "wsr\t$t, $sr", []>;
556
557def RSR : RSR_Inst<0x00, 0x03, 0x00, (outs AR:$t), (ins SR:$sr),
558                  "rsr\t$t, $sr", []>;
559
560def XSR : RSR_Inst<0x00, 0x01, 0x06, (outs AR:$ard, SR:$srd), (ins AR:$t, SR:$sr),
561                  "xsr\t$t, $sr", []> {
562  let Constraints = "$ard = $t, $srd = $sr";
563}
564
565//===----------------------------------------------------------------------===//
566// User Registers read/write instructions
567//===----------------------------------------------------------------------===//
568
569def WUR : RRR_Inst<0x00, 0x03, 0x0F, (outs UR:$ur), (ins AR:$t),
570                  "wur\t$t, $ur", []> {
571  bits<8> ur;
572
573  let r = ur{7-4};
574  let s = ur{3-0};
575}
576
577def RUR : RRR_Inst<0x00, 0x03, 0x0E, (outs AR:$r), (ins UR:$ur),
578                  "rur\t$r, $ur", [(set AR:$r, (Xtensa_rur UR:$ur))]> {
579  bits<8> ur;
580
581  let s = ur{7-4};
582  let t = ur{3-0};
583}
584
585//===----------------------------------------------------------------------===//
586// Stack allocation
587//===----------------------------------------------------------------------===//
588
589// ADJCALLSTACKDOWN/UP implicitly use/def SP because they may be expanded into
590// a stack adjustment and the codegen must know that they may modify the stack
591// pointer before prolog-epilog rewriting occurs.
592let Defs = [SP], Uses = [SP] in {
593  def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
594                               "#ADJCALLSTACKDOWN",
595                               [(Xtensa_callseq_start timm:$amt1, timm:$amt2)]>;
596  def ADJCALLSTACKUP   : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
597                               "#ADJCALLSTACKUP",
598                               [(Xtensa_callseq_end timm:$amt1, timm:$amt2)]>;
599}
600
601//===----------------------------------------------------------------------===//
602// Generic select instruction
603//===----------------------------------------------------------------------===//
604let usesCustomInserter = 1 in {
605  def SELECT : Pseudo<(outs AR:$dst), (ins AR:$lhs, AR:$rhs, AR:$t, AR:$f, i32imm:$cond),
606                     "!select $dst, $lhs, $rhs, $t, $f, $cond",
607                     [(set i32:$dst, (Xtensa_select_cc i32:$lhs, i32:$rhs, i32:$t, i32:$f, imm:$cond))]>;
608}
609
610//===----------------------------------------------------------------------===//
611// Code Density instructions
612//===----------------------------------------------------------------------===//
613
614class ArithLogic_RRRN<bits<4> oper0, string instrAsm,
615      SDPatternOperator opNode, bit isComm = 0>
616  : RRRN_Inst<oper0, (outs AR:$r), (ins AR:$s, AR:$t),
617              instrAsm#"\t$r, $s, $t",
618             [(set AR:$r, (opNode AR:$s, AR:$t))]>, Requires<[HasDensity]> {
619  let isCommutable = isComm;
620  let isReMaterializable = 0;
621}
622
623def ADD_N : ArithLogic_RRRN<0x0a, "add.n", add, 1>;
624
625def ADDI_N : RRRN_Inst<0x0B, (outs AR:$r), (ins AR:$s, imm1n_15:$imm),
626                      "addi.n\t$r, $s, $imm",
627                      [(set AR:$r, (add AR:$s, imm1n_15:$imm))]>, Requires<[HasDensity]> {
628  bits<4> imm;
629
630  let t = imm;
631}
632
633// Conditional branch instructions.
634let isBranch = 1, isTerminator = 1 in {
635  def BEQZ_N : RI6_Inst<0xC, 0x1, 0x0, (outs), (ins AR:$s, brtarget:$target),
636                       "beqz.n\t$s, $target", []>, Requires<[HasDensity]> {
637    bits<6> target;
638
639    let imm6 = target;
640  }
641
642  def BNEZ_N : RI6_Inst<0xC, 0x1, 0x1, (outs), (ins AR:$s, brtarget:$target),
643                       "bnez.n\t$s, $target", []>, Requires<[HasDensity]> {
644    bits<6> target;
645
646    let imm6 = target;
647  }
648}
649
650def ILL_N : RRRN_Inst<0x0D, (outs), (ins),
651                     "ill.n", []>, Requires<[HasDensity]> {
652  let r = 0xF;
653  let s = 0x0;
654  let t = 0x6;
655}
656
657def MOV_N : RRRN_Inst<0x0D, (outs AR:$t), (ins AR:$s),
658                     "mov.n\t$t, $s", []>, Requires<[HasDensity]> {
659  let r = 0;
660}
661
662def : InstAlias<"mov\t $t, $s", (OR AR:$t, AR:$s, AR:$s)>;
663
664def MOVI_N : RI7_Inst<0xc, 0x0, (outs AR:$s), (ins imm32n_95:$imm7),
665                     "movi.n\t$s, $imm7",
666                     [(set AR:$s, imm32n_95:$imm7)]>, Requires<[HasDensity]>;
667
668def : InstAlias<"_movi.n\t$s, $imm7", (MOVI_N AR:$s, imm32n_95:$imm7)>;
669
670def NOP_N : RRRN_Inst<0x0D, (outs), (ins),
671                     "nop.n", []>, Requires<[HasDensity]> {
672  let r = 0xF;
673  let s = 0x0;
674  let t = 0x3;
675}
676
677// Load instruction
678let mayLoad = 1, usesCustomInserter = 1 in {
679  def L32I_N : RRRN_Inst<0x8, (outs AR:$t), (ins mem32n:$addr),
680                        "l32i.n\t$t, $addr", []>, Requires<[HasDensity]> {
681    bits<8> addr;
682
683    let r{3-0} = addr{7-4};
684    let s{3-0} = addr{3-0};
685  }
686}
687
688// Store instruction
689let mayStore = 1, usesCustomInserter = 1 in {
690  def S32I_N : RRRN_Inst<0x9, (outs), (ins  AR:$t, mem32n:$addr),
691                        "s32i.n\t$t, $addr", []>, Requires<[HasDensity]> {
692    bits<8> addr;
693
694    let r{3-0} = addr{7-4};
695    let s{3-0} = addr{3-0};
696  }
697}
698
699//Return instruction
700let isReturn = 1, isTerminator = 1,
701    isBarrier = 1, Uses = [A0] in {
702  def RET_N : RRRN_Inst<0x0D, (outs), (ins),
703                       "ret.n", [(Xtensa_ret)]>,
704                       Requires<[HasDensity]> {
705    let r = 0x0F;
706    let s = 0;
707    let t = 0;
708  }
709}
710
711//===----------------------------------------------------------------------===//
712// Windowed instructions
713//===----------------------------------------------------------------------===//
714
715def ENTRY : BRI12_Inst<0x06, 0x3, 0x0, (outs), (ins AR:$s, entry_imm12:$imm),
716                     "entry\t$s, $imm", []>, Requires<[HasWindowed]> {
717  bits<15> imm;
718
719  let imm12{11-0} = imm{14-3};
720  let Defs = [SP];
721}
722
723let isCall = 1, Defs = [A0] in {
724  foreach i = {1,2,3} in {
725    defvar I = !mul(4, i);
726
727    def CALL#I# : CALL_Inst<0x05, (outs), (ins pcrel32call:$offset),
728                           "call"#I#"\t$offset", []>, Requires<[HasWindowed]> {
729      let n = i;
730    }
731
732    def CALLX#I# : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins AR:$s),
733                             "callx"#I#"\t$s", []>, Requires<[HasWindowed]> {
734      let m = 0x3;
735      let n = i;
736      let r = 0;
737    }
738  }
739}
740
741// Windowed call patterns. Currently rotation
742// window by 8 is implemented.
743def : Pat<(Xtensa_callw8 (i32 tglobaladdr:$dst)),
744          (CALL8 tglobaladdr:$dst)>;
745def : Pat<(Xtensa_callw8 (i32 texternalsym:$dst)),
746          (CALL8 texternalsym:$dst)>;
747def : Pat<(Xtensa_callw8 AR:$dst),
748          (CALLX8 AR:$dst)>;
749
750def MOVSP : RRR_Inst<0x00, 0x00, 0x00, (outs AR:$t), (ins AR:$s),
751                    "movsp\t$t, $s", []>, Requires<[HasWindowed]> {
752  let r = 0x01;
753}
754
755// Use this pseudo operation instead of getCopyToReg function to
756// update SP register.
757let usesCustomInserter = 1, Defs = [SP], Predicates = [HasWindowed] in {
758  def MOVSP_P : Pseudo<(outs), (ins AR:$s),
759                      "!movsp_p\tsp, $s", [(Xtensa_movsp AR:$s)]>;
760}
761
762let isReturn = 1, isTerminator = 1,
763    isBarrier = 1, Uses = [A0] in {
764  def RETW_N : RRRN_Inst<0x0D, (outs), (ins),
765                        "retw.n", [(Xtensa_retw)]>,
766                        Requires<[HasWindowed, HasDensity]> {
767    let r = 0x0F;
768    let s = 0;
769    let t = 1;
770  }
771
772  def RETW : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins),
773                       "retw", [(Xtensa_retw)]>,
774                       Requires<[HasWindowed]> {
775    let m = 0x2;
776    let n = 0x1;
777    let s = 0;
778    let r = 0;
779  }
780}
781
782def : InstAlias<"_retw", (RETW)>;
783def : InstAlias<"_retw.n", (RETW_N)>;
784
785def S32E : RRI4_Inst<0x00, 0x09, (outs), (ins AR:$t, AR:$s, imm64n_4n:$imm),
786                    "s32e\t$t, $s, $imm", []>, Requires<[HasWindowed]> {
787  bits<6> imm;
788
789  let r = imm{5-2};
790  let imm4 = 0x4;
791  let mayStore = 1;
792}
793
794def L32E : RRI4_Inst<0x00, 0x09, (outs), (ins AR:$t, AR:$s, imm64n_4n:$imm),
795                    "l32e\t$t, $s, $imm", []>, Requires<[HasWindowed]> {
796  bits<6> imm;
797
798  let r = imm{5-2};
799  let imm4 = 0x0;
800  let mayLoad = 1;
801}
802
803def RFWU : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
804                   "rfwu", []>, Requires<[HasWindowed]> {
805  bits<4> imm;
806
807  let r = 0x3;
808  let s = 0x5;
809  let t = 0x0;
810}
811
812def RFWO : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
813                   "rfwo", []>, Requires<[HasWindowed]> {
814  bits<4> imm;
815
816  let r = 0x3;
817  let s = 0x4;
818  let t = 0x0;
819}
820
821def ROTW : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins imm8n_7:$imm),
822                   "rotw\t$imm", []>, Requires<[HasWindowed]> {
823  bits<4> imm;
824
825  let r = 0x8;
826  let s = 0x0;
827  let t = imm{3-0};
828}
829
830//===----------------------------------------------------------------------===//
831// Boolean Instructions
832//===----------------------------------------------------------------------===//
833
834def ALL4 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s),
835                   "all4\t$t, $s", []>, Requires<[HasBoolean]> {
836  let r = 0x9;
837}
838
839def ALL8 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s),
840                   "all8\t$t, $s", []>, Requires<[HasBoolean]> {
841  let r = 0xB;
842}
843
844def ANDB : RRR_Inst<0x00, 0x02, 0x00, (outs BR:$r), (ins BR:$s, BR:$t),
845                   "andb\t$r, $s, $t", []>, Requires<[HasBoolean]>;
846def ANDBC : RRR_Inst<0x00, 0x02, 0x01, (outs BR:$r), (ins BR:$s, BR:$t),
847                    "andbc\t$r, $s, $t", []>, Requires<[HasBoolean]>;
848def ORB : RRR_Inst<0x00, 0x02, 0x02, (outs BR:$r), (ins BR:$s, BR:$t),
849                  "orb\t$r, $s, $t", []>, Requires<[HasBoolean]>;
850def ORBC : RRR_Inst<0x00, 0x02, 0x03, (outs BR:$r), (ins BR:$s, BR:$t),
851                   "orbc\t$r, $s, $t", []>, Requires<[HasBoolean]>;
852def XORB : RRR_Inst<0x00, 0x02, 0x04, (outs BR:$r), (ins BR:$s, BR:$t),
853                   "xorb\t$r, $s, $t", []>, Requires<[HasBoolean]>;
854
855def ANY4 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s),
856                   "any4\t$t, $s", []>, Requires<[HasBoolean]> {
857  let r = 0x8;
858}
859
860def ANY8 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s),
861                   "any8\t$t, $s", []>, Requires<[HasBoolean]> {
862  let r = 0xA;
863}
864
865let isBranch = 1, isTerminator = 1, Predicates = [HasBoolean] in {
866  def BT : RRI8_Inst<0x06, (outs), (ins BR:$b, brtarget:$target),
867                    "bt\t$b, $target", []> {
868    bits<8> target;
869    bits<4> b;
870
871    let r = 0x1;
872    let s = b;
873    let t = 0x7;
874    let imm8 = target;
875  }
876
877  def BF : RRI8_Inst<0x06, (outs), (ins BR:$b, brtarget:$target),
878                    "bf\t$b, $target", []> {
879    bits<8> target;
880    bits<4> b;
881
882    let r = 0x0;
883    let s = b;
884    let t = 0x7;
885    let imm8 = target;
886  }
887}
888
889def : InstAlias<"_BT\t$b, $target", (BT BR:$b, brtarget:$target)>;
890def : InstAlias<"_BF\t$b, $target", (BF BR:$b, brtarget:$target)>;
891
892let Constraints = "$dr = $r,@earlyclobber $dr" in {
893  def MOVF : RRR_Inst<0x00, 0x03, 0x0C, (outs AR:$dr), (ins AR:$r, AR:$s, BR:$t),
894                   "movf\t$r, $s, $t", []>, Requires<[HasBoolean]>;
895
896  def MOVT : RRR_Inst<0x00, 0x03, 0x0D, (outs AR:$dr), (ins AR:$r, AR:$s, BR:$t),
897                   "movt\t$r, $s, $t", []>, Requires<[HasBoolean]>;
898}
899
900//===----------------------------------------------------------------------===//
901// SEXT Instruction
902//===----------------------------------------------------------------------===//
903
904def SEXT : RRR_Inst<0x00, 0x03, 0x02, (outs AR:$r), (ins AR:$s, imm7_22:$imm),
905                   "sext\t$r, $s, $imm", []>, Requires<[HasSEXT]> {
906  bits<4> imm;
907
908  let t = imm;
909}
910
911def : Pat<(i32 (sext_inreg AR:$s, i8)), (SEXT AR:$s, (i32 7))>;
912def : Pat<(i32 (sext_inreg AR:$s, i16)), (SEXT AR:$s, (i32 15))>;
913
914//===----------------------------------------------------------------------===//
915// CLAMPS Instruction
916//===----------------------------------------------------------------------===//
917
918def CLAMPS : RRR_Inst<0x00, 0x03, 0x03, (outs AR:$r), (ins AR:$s, imm7_22:$imm),
919                   "clamps\t$r, $s, $imm", []>, Requires<[HasCLAMPS]> {
920  bits<4> imm;
921
922  let t = imm;
923}
924
925//===----------------------------------------------------------------------===//
926// NSA Instructions
927//===----------------------------------------------------------------------===//
928
929def NSA : RRR_Inst<0x00, 0x00, 0x04, (outs AR:$t), (ins AR:$s),
930                  "nsa\t$t, $s", []>, Requires<[HasNSA]> {
931  let r = 0xE;
932}
933
934def NSAU : RRR_Inst<0x00, 0x00, 0x04, (outs AR:$t), (ins AR:$s),
935                   "nsau\t$t, $s",
936                   [(set AR:$t, (ctlz AR:$s))]>, Requires<[HasNSA]> {
937  let r = 0xF;
938}
939
940//===----------------------------------------------------------------------===//
941// MINMAX Instructions
942//===----------------------------------------------------------------------===//
943
944let Predicates = [HasMINMAX] in {
945  def MIN   : ArithLogic_RRR<0x04, 0x03, "min", smin, 1>;
946  def MAX   : ArithLogic_RRR<0x05, 0x03, "max", smax, 1>;
947  def MINU  : ArithLogic_RRR<0x06, 0x03, "minu", umin, 1>;
948  def MAXU  : ArithLogic_RRR<0x07, 0x03, "maxu", umax, 1>;
949}
950
951//===----------------------------------------------------------------------===//
952// Loop Instructions
953//===----------------------------------------------------------------------===//
954
955def LOOP : RRI8_Inst<0x06, (outs), (ins AR:$s, ltarget:$target),
956                    "loop\t$s, $target", []>, Requires<[HasLoop]> {
957  bits<8> target;
958
959  let r = 0x08;
960  let t = 0x07;
961  let imm8 = target;
962}
963
964def : InstAlias<"_loop\t$s, $target", (LOOP AR:$s, ltarget:$target)>;
965
966def LOOPGTZ : RRI8_Inst<0x06, (outs), (ins AR:$s, ltarget:$target),
967                       "loopgtz\t$s, $target", []>, Requires<[HasLoop]> {
968  bits<8> target;
969
970  let r = 0x0A;
971  let t = 0x07;
972  let imm8 = target;
973}
974
975def : InstAlias<"_loopgtz\t$s, $target", (LOOPGTZ AR:$s, ltarget:$target)>;
976
977def LOOPNEZ : RRI8_Inst<0x06, (outs), (ins AR:$s, ltarget:$target),
978                       "loopnez\t$s, $target", []>, Requires<[HasLoop]> {
979  bits<8> target;
980
981  let r = 0x09;
982  let t = 0x07;
983  let imm8 = target;
984}
985
986def : InstAlias<"_loopnez\t$s, $target", (LOOPNEZ AR:$s, ltarget:$target)>;
987
988//===----------------------------------------------------------------------===//
989// Mul16 Instructions
990//===----------------------------------------------------------------------===//
991
992let Predicates = [HasMul16] in {
993  def MUL16S : RRR_Inst<0x00, 0x01, 0x0D, (outs AR:$r), (ins AR:$s, AR:$t),
994                       "mul16s\t$r, $s, $t", []>;
995  def MUL16U : RRR_Inst<0x00, 0x01, 0x0C, (outs AR:$r), (ins AR:$s, AR:$t),
996                       "mul16u\t$r, $s, $t", []>;
997}
998
999//===----------------------------------------------------------------------===//
1000// Mul32 Instructions
1001//===----------------------------------------------------------------------===//
1002
1003def MULL  : ArithLogic_RRR<0x08, 0x02, "mull", mul, 1>, Requires<[HasMul32]>;
1004def MULUH : ArithLogic_RRR<0x0A, 0x02, "muluh", mulhu, 1>, Requires<[HasMul32High]>;
1005def MULSH : ArithLogic_RRR<0x0B, 0x02, "mulsh", mulhs, 1>, Requires<[HasMul32High]>;
1006
1007//===----------------------------------------------------------------------===//
1008// Div32 Instructions
1009//===----------------------------------------------------------------------===//
1010
1011let Predicates = [HasDiv32] in {
1012  def QUOS : ArithLogic_RRR<0x0D, 0x02, "quos", sdiv>;
1013  def QUOU : ArithLogic_RRR<0x0C, 0x02, "quou", udiv>;
1014  def REMS : ArithLogic_RRR<0x0F, 0x02, "rems", srem>;
1015  def REMU : ArithLogic_RRR<0x0E, 0x02, "remu", urem>;
1016}
1017
1018//===----------------------------------------------------------------------===//
1019// Floating-Point Instructions
1020//===----------------------------------------------------------------------===//
1021
1022class FPArith_RRR<bits<4> oper2, bits<4> oper1, string instrAsm,
1023                 SDPatternOperator opNode, bit isComm = 0>
1024  : RRR_Inst<0x00, oper1, oper2, (outs FPR:$r), (ins FPR:$s, FPR:$t),
1025             instrAsm#"\t$r, $s, $t",
1026            [(set FPR:$r, (opNode FPR:$s, FPR:$t))]> {
1027  let isCommutable = isComm;
1028  let isReMaterializable = 0;
1029  let Predicates = [HasSingleFloat];
1030}
1031
1032def ADD_S : FPArith_RRR<0x00, 0x0A, "add.s", fadd, 1>;
1033def SUB_S : FPArith_RRR<0x01, 0x0A, "sub.s", fsub>;
1034def MUL_S : FPArith_RRR<0x02, 0x0A, "mul.s", fmul, 1>;
1035
1036// FP load instructions
1037let mayLoad = 1, usesCustomInserter = 1, Predicates = [HasSingleFloat] in {
1038  def LSI : RRI8_Inst<0x03, (outs FPR:$t), (ins mem32:$addr),
1039                     "lsi\t$t, $addr", []> {
1040    bits<12> addr;
1041
1042    let r = 0x00;
1043    let imm8{7-0} = addr{11-4};
1044    let s{3-0} = addr{3-0};
1045  }
1046
1047  def LSIP : RRI8_Inst<0x03, (outs FPR:$t), (ins mem32:$addr),
1048                      "lsip\t$t, $addr", []> {
1049    bits<12> addr;
1050
1051    let r = 0x08;
1052    let imm8{7-0} = addr{11-4};
1053    let s{3-0} = addr{3-0};
1054  }
1055
1056  def LSX : RRR_Inst<0x00, 0x08, 0x00, (outs), (ins FPR:$r, AR:$s, AR:$t),
1057                    "lsx\t$r, $s, $t", []>;
1058
1059  def LSXP : RRR_Inst<0x00, 0x08, 0x01, (outs), (ins FPR:$r, AR:$s, AR:$t),
1060                     "lsxp\t$r, $s, $t", []>;
1061}
1062
1063def : Pat<(f32 (load addr_ish4:$addr)), (f32 (LSI mem32:$addr))>;
1064
1065// FP store instructions
1066let mayStore = 1, usesCustomInserter = 1, Predicates = [HasSingleFloat] in {
1067  def SSI : RRI8_Inst<0x03, (outs), (ins FPR:$t, mem32:$addr),
1068                     "ssi\t$t, $addr", []> {
1069    bits<12> addr;
1070
1071    let r = 0x04;
1072    let imm8{7-0} = addr{11-4};
1073    let s{3-0} = addr{3-0};
1074  }
1075
1076  def SSIP : RRI8_Inst<0x03, (outs), (ins FPR:$t, mem32:$addr),
1077                      "ssip\t$t, $addr", []> {
1078    bits<12> addr;
1079
1080    let r = 0x0C;
1081    let imm8{7-0} = addr{11-4};
1082    let s{3-0} = addr{3-0};
1083  }
1084
1085  def SSX: RRR_Inst<0x00, 0x08, 0x04, (outs), (ins FPR:$r, AR:$s, AR:$t),
1086                   "ssx\t$r, $s, $t", []>;
1087
1088  def SSXP: RRR_Inst<0x00, 0x08, 0x05, (outs), (ins FPR:$r, AR:$s, AR:$t),
1089                    "ssxp\t$r, $s, $t", []>;
1090}
1091
1092def : Pat<(store FPR:$t, addr_ish4:$addr), (SSI FPR:$t, mem32:$addr)>;
1093
1094// FP compare instructions
1095let isCompare = 1, Predicates = [HasSingleFloat] in {
1096  class FCompare <bits<4> oper2, bits<4> oper1, string instrAsm,
1097                 SDPatternOperator opNode, bit isComm = 0>
1098    : RRR_Inst<0x00, oper1, oper2, (outs BR:$r), (ins FPR:$s, FPR:$t),
1099               instrAsm#"\t$r, $s, $t",
1100              [(set BR:$r, (opNode FPR:$s, FPR:$t))]> {
1101    let isCommutable = isComm;
1102    let isReMaterializable = 0;
1103    let Predicates = [HasSingleFloat];
1104  }
1105}
1106
1107def OEQ_S :  FCompare<0x02, 0x0b, "oeq.s", Xtensa_cmpoeq, 1>;
1108def OLT_S :  FCompare<0x04, 0x0b, "olt.s", Xtensa_cmpolt, 0>;
1109def OLE_S :  FCompare<0x06, 0x0b, "ole.s", Xtensa_cmpole, 0>;
1110
1111def UEQ_S :  FCompare<0x03, 0x0b, "ueq.s", Xtensa_cmpueq, 1>;
1112def ULT_S :  FCompare<0x05, 0x0b, "ult.s", Xtensa_cmpult, 0>;
1113def ULE_S :  FCompare<0x07, 0x0b, "ule.s", Xtensa_cmpule, 0>;
1114def UN_S  :  FCompare<0x01, 0x0b, "un.s",  Xtensa_cmpuo, 1>;
1115
1116def ABS_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s),
1117                    "abs.s\t$r, $s",
1118                    [(set FPR:$r, (fabs FPR:$s))]>, Requires<[HasSingleFloat]> {
1119  let t = 0x01;
1120}
1121
1122def : Pat<(fabs FPR:$s), (ABS_S $s)>;
1123
1124def ADDEXP_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s),
1125                       "addexp.s\t$r, $s", []>, Requires<[HasSingleFloat]> {
1126  let t = 0x0E;
1127}
1128
1129def ADDEXPM_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s),
1130                        "addexpm.s\t$r, $s", []>, Requires<[HasSingleFloat]> {
1131  let t = 0x0F;
1132}
1133
1134def CEIL_S : RRR_Inst<0x00, 0x0A, 0x0B, (outs AR:$r), (ins FPR:$s, uimm4:$imm),
1135                     "ceil.s\t$r, $s, $imm", []>, Requires<[HasSingleFloat]> {
1136  bits<4> imm;
1137
1138  let t = imm;
1139}
1140
1141def CONST_S : RRR_Inst<0x00, 0x0a, 0x0f, (outs FPR:$r), (ins uimm4:$imm),
1142                      "const.s\t$r, $imm", []>, Requires<[HasSingleFloat]> {
1143  bits<4> imm;
1144
1145  let t = 0x03;
1146  let s = imm{3-0};
1147}
1148
1149def DIV0_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s),
1150                     "div0.s\t$r, $s", []>, Requires<[HasSingleFloat]> {
1151  let t = 0x7;
1152}
1153
1154def DIVN_S : RRR_Inst<0x00, 0x0A, 0x07, (outs FPR:$r), (ins FPR:$s, FPR:$t),
1155                     "divn.s\t$r, $s, $t", []>, Requires<[HasSingleFloat]>;
1156
1157def FLOAT_S : RRR_Inst<0x00, 0x0A, 0x0c, (outs FPR:$r), (ins AR:$s, uimm4:$imm),
1158                      "float.s\t$r, $s, $imm", []>, Requires<[HasSingleFloat]> {
1159  bits<4> imm;
1160
1161  let t = imm;
1162}
1163
1164def : Pat<(f32 (sint_to_fp AR:$s)), (FLOAT_S AR:$s, 0)>;
1165
1166def FLOOR_S : RRR_Inst<0x00, 0x0A, 0x0A, (outs AR:$r), (ins FPR:$s, uimm4:$imm),
1167                      "floor.s\t$r, $s, $imm", []>, Requires<[HasSingleFloat]> {
1168  bits<4> imm;
1169
1170  let t = imm;
1171}
1172
1173def MADDN_S : RRR_Inst<0x00, 0x0A, 0x06, (outs FPR:$r), (ins FPR:$s, FPR:$t),
1174                      "maddn.s\t$r, $s, $t", []>, Requires<[HasSingleFloat]> {
1175  let isCommutable = 0;
1176}
1177
1178// FP multipy-add
1179def MADD_S : RRR_Inst<0x00, 0x0A, 0x04, (outs FPR:$r), (ins FPR:$a, FPR:$s, FPR:$t),
1180                     "madd.s\t$r, $s, $t",
1181                     [(set FPR:$r, (Xtensa_madd FPR:$a, FPR:$s, FPR:$t))]>,
1182                     Requires<[HasSingleFloat]> {
1183  let isCommutable = 0;
1184  let isReMaterializable = 0;
1185  let Constraints = "$r = $a";
1186}
1187
1188// fmadd: r1 * r2 + r3
1189def : Pat<(fma FPR:$r1, FPR:$r2, FPR:$r3),
1190          (MADD_S $r3, $r1, $r2)>;
1191
1192def MKDADJ_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s),
1193                       "mkdadj.s\t$r, $s", []>, Requires<[HasSingleFloat]> {
1194  let t = 0x0D;
1195}
1196
1197def MKSADJ_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s),
1198                       "mksadj.s\t$r, $s", []>, Requires<[HasSingleFloat]> {
1199  let t = 0x0C;
1200}
1201
1202// FP move instructions
1203def MOV_S : RRR_Inst<0x00, 0x0A, 0x0f, (outs FPR:$r), (ins FPR:$s),
1204                    "mov.s\t$r, $s",
1205                    [(set FPR:$r, (Xtensa_movs FPR:$s))]>, Requires<[HasSingleFloat]> {
1206  let t = 0x00;
1207}
1208
1209def MOVEQZ_S : RRR_Inst<0x00, 0x0B, 0x08, (outs FPR:$r), (ins FPR:$s, AR:$t),
1210                       "moveqz.s\t$r, $s, $t", []>, Requires<[HasSingleFloat]>;
1211
1212def MOVF_S   : RRR_Inst<0x00, 0x0B, 0x0C, (outs FPR:$r), (ins FPR:$s, BR:$t),
1213                       "movf.s\t$r, $s, $t", []>, Requires<[HasBoolean, HasSingleFloat]>;
1214
1215def MOVGEZ_S : RRR_Inst<0x00, 0x0B, 0x0B, (outs FPR:$r), (ins FPR:$s, AR:$t),
1216                       "movgez.s\t$r, $s, $t", []>, Requires<[HasSingleFloat]>;
1217
1218def MOVLTZ_S : RRR_Inst<0x00, 0x0B, 0x0A, (outs FPR:$r), (ins FPR:$s, AR:$t),
1219                       "movltz.s\t$r, $s, $t", []>, Requires<[HasSingleFloat]>;
1220
1221def MOVNEZ_S : RRR_Inst<0x00, 0x0B, 0x09, (outs FPR:$r), (ins FPR:$s, AR:$t),
1222                       "movnez.s\t$r, $s, $t", []>, Requires<[HasSingleFloat]>;
1223
1224def MOVT_S   : RRR_Inst<0x00, 0x0B, 0x0D, (outs FPR:$r), (ins FPR:$s, BR:$t),
1225                       "movt.s\t$r, $s, $t", []>, Requires<[HasBoolean, HasSingleFloat]>;
1226
1227// FP multipy-sub
1228def MSUB_S : RRR_Inst<0x00, 0x0A, 0x05, (outs FPR:$r), (ins FPR:$a, FPR:$s, FPR:$t),
1229                     "msub.s\t$r, $s, $t",
1230                     [(set FPR:$r, (Xtensa_msub FPR:$a, FPR:$s, FPR:$t))]>, Requires<[HasSingleFloat]> {
1231  let isCommutable = 0;
1232  let isReMaterializable = 0;
1233  let Constraints = "$r = $a";
1234}
1235
1236def NEXP01_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s),
1237                       "nexp01.s\t$r, $s", []>, Requires<[HasSingleFloat]> {
1238  let t = 0x0B;
1239}
1240
1241def NEG_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s),
1242                    "neg.s\t$r, $s",
1243                    [(set FPR:$r, (fneg FPR:$s))]>, Requires<[HasSingleFloat]> {
1244  let t = 0x06;
1245}
1246
1247def RECIP0_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s),
1248                       "recip0.s\t$r, $s", []>, Requires<[HasSingleFloat]> {
1249  let t = 0x08;
1250}
1251
1252def RFR : RRR_Inst<0x00, 0x0A, 0x0f, (outs AR:$r), (ins FPR:$s),
1253                  "rfr\t$r, $s",
1254                  [(set AR:$r, (bitconvert FPR:$s))]>, Requires<[HasSingleFloat]> {
1255  let t = 0x04;
1256}
1257
1258def ROUND_S : RRR_Inst<0x00, 0x0A, 0x08, (outs AR:$r), (ins FPR:$s, uimm4:$imm),
1259                      "round.s\t$r, $s, $imm", []>, Requires<[HasSingleFloat]> {
1260  bits<4> imm;
1261
1262  let t = imm;
1263}
1264
1265def RSQRT0_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s),
1266                       "rsqrt0.s\t$r, $s", []>, Requires<[HasSingleFloat]> {
1267  let t = 0x0A;
1268}
1269
1270def SQRT0_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s),
1271                      "sqrt0.s\t$r, $s", []>, Requires<[HasSingleFloat]> {
1272  let t = 0x09;
1273}
1274
1275def TRUNC_S : RRR_Inst<0x00, 0x0A, 0x09, (outs AR:$r), (ins FPR:$s, uimm4:$imm),
1276                      "trunc.s\t$r, $s, $imm", []>, Requires<[HasSingleFloat]>  {
1277  bits<4> imm;
1278
1279  let t = imm;
1280}
1281
1282def : Pat<(i32 (fp_to_sint FPR:$s)), (TRUNC_S FPR:$s, 0)>;
1283
1284def UFLOAT_S : RRR_Inst<0x00, 0x0A, 0x0D, (outs FPR:$r), (ins AR:$s, uimm4:$imm),
1285                       "ufloat.s\t$r, $s, $imm", []>, Requires<[HasSingleFloat]>  {
1286  bits<4> imm;
1287
1288  let t = imm;
1289}
1290
1291def : Pat<(f32 (uint_to_fp AR:$s)), (UFLOAT_S AR:$s, 0)>;
1292
1293def UTRUNC_S : RRR_Inst<0x00, 0x0A, 0x0e, (outs AR:$r), (ins FPR:$s, uimm4:$imm),
1294                       "utrunc.s\t$r, $s, $imm", []>, Requires<[HasSingleFloat]>  {
1295  bits<4> imm;
1296
1297  let t = imm;
1298}
1299
1300def : Pat<(i32 (fp_to_uint FPR:$s)), (UTRUNC_S FPR:$s, 0)>;
1301
1302def WFR : RRR_Inst<0x00, 0x0A, 0x0f, (outs FPR:$r), (ins AR:$s),
1303                  "wfr\t$r, $s",
1304                  [(set FPR:$r, (bitconvert AR:$s))]>, Requires<[HasSingleFloat]>  {
1305  let t = 0x05;
1306}
1307
1308let AddedComplexity = 10 in
1309def : Pat<(f32 (load (Xtensa_pcrel_wrapper tconstpool:$in))),
1310          (WFR (L32R tconstpool:$in))>;
1311
1312//===----------------------------------------------------------------------===//
1313// SelectCC and BranchCC instructions with FP operands
1314//===----------------------------------------------------------------------===//
1315
1316let usesCustomInserter = 1, Predicates = [HasSingleFloat] in {
1317  def SELECT_CC_INT_FP : Pseudo<(outs FPR:$dst), (ins AR:$lhs, AR:$rhs, FPR:$t, FPR:$f, i32imm:$cond),
1318                                "!select_cc_int_fp $dst, $lhs, $rhs, $t, $f, $cond",
1319                                [(set FPR:$dst, (Xtensa_select_cc AR:$lhs, AR:$rhs, FPR:$t, FPR:$f, imm:$cond))]>;
1320  def SELECT_CC_FP_INT : Pseudo<(outs AR:$dst), (ins FPR:$lhs, FPR:$rhs, AR:$t, AR:$f, i32imm:$cond, i32imm:$brkind),
1321                                "!select_cc_fp_int $dst, $lhs, $rhs, $t, $f, $cond, $brkind",
1322                                [(set AR:$dst, (Xtensa_select_cc_fp FPR:$lhs, FPR:$rhs, AR:$t, AR:$f, imm:$cond, imm:$brkind))]>;
1323  def SELECT_CC_FP_FP : Pseudo<(outs FPR:$dst), (ins FPR:$lhs, FPR:$rhs, FPR:$t, FPR:$f, i32imm:$cond, i32imm:$brkind),
1324                               "!select_cc_fp_fp $dst, $lhs, $rhs, $t, $f, $cond, $brkind",
1325                               [(set FPR:$dst, (Xtensa_select_cc_fp FPR:$lhs, FPR:$rhs, FPR:$t, FPR:$f, imm:$cond, imm:$brkind))]>;
1326}
1327
1328let usesCustomInserter = 1, isBranch = 1, isTerminator = 1, isBarrier = 1, Predicates = [HasSingleFloat] in {
1329  def BRCC_FP : Pseudo<(outs), (ins i32imm:$cond, FPR:$lhs, FPR:$rhs, brtarget:$target),
1330                       "!brcc_fp $cond, $lhs, $rhs, $target", []>;
1331}
1332
1333def cond_as_i32imm : SDNodeXForm<cond, [{
1334  return CurDAG->getTargetConstant(N->get(), SDLoc(N), MVT::i32);
1335}]>;
1336
1337def : Pat<(brcc cond:$cond, FPR:$s, FPR:$t,  bb:$target),
1338          (BRCC_FP (cond_as_i32imm $cond), FPR:$s, FPR:$t, bb:$target)>;
1339
1340//===----------------------------------------------------------------------===//
1341// Region Protection feature instructions
1342//===----------------------------------------------------------------------===//
1343
1344let Predicates = [HasRegionProtection] in {
1345  def IDTLB : RRR_Inst<0x00, 0x00, 0x05, (outs), (ins AR:$s),
1346                     "idtlb\t$s", []> {
1347    let r = 0xC;
1348	  let t = 0x0;
1349  }
1350
1351  def IITLB : RRR_Inst<0x00, 0x00, 0x05, (outs), (ins AR:$s),
1352                     "iitlb\t$s", []> {
1353    let r = 0x4;
1354	  let t = 0x0;
1355  }
1356
1357  def PDTLB : RRR_Inst<0x00, 0x00, 0x05, (outs AR:$t), (ins AR:$s),
1358                     "pdtlb\t$t, $s", []> {
1359    let r = 0xD;
1360  }
1361
1362  def PITLB : RRR_Inst<0x00, 0x00, 0x05, (outs AR:$t), (ins AR:$s),
1363                     "pitlb\t$t, $s", []> {
1364    let r = 0x5;
1365  }
1366
1367  def RDTLB0 : RRR_Inst<0x00, 0x00, 0x05, (outs AR:$t), (ins AR:$s),
1368                     "rdtlb0\t$t, $s", []> {
1369    let r = 0xB;
1370  }
1371
1372  def RDTLB1 : RRR_Inst<0x00, 0x00, 0x05, (outs AR:$t), (ins AR:$s),
1373                     "rdtlb1\t$t, $s", []> {
1374    let r = 0xF;
1375  }
1376
1377  def RITLB0 : RRR_Inst<0x00, 0x00, 0x05, (outs AR:$t), (ins AR:$s),
1378                     "ritlb0\t$t, $s", []> {
1379    let r = 0x3;
1380  }
1381
1382  def RITLB1 : RRR_Inst<0x00, 0x00, 0x05, (outs AR:$t), (ins AR:$s),
1383                     "ritlb1\t$t, $s", []> {
1384    let r = 0x7;
1385  }
1386
1387  def WDTLB : RRR_Inst<0x00, 0x00, 0x05, (outs AR:$t), (ins AR:$s),
1388                     "wdtlb\t$t, $s", []> {
1389    let r = 0xE;
1390  }
1391
1392  def WITLB : RRR_Inst<0x00, 0x00, 0x05, (outs AR:$t), (ins AR:$s),
1393                      "witlb\t$t, $s", []> {
1394    let r = 0x6;
1395  }
1396}
1397
1398//===----------------------------------------------------------------------===//
1399// Debug instructions
1400//===----------------------------------------------------------------------===//
1401
1402let isBarrier = 1, isTerminator = 1 in {
1403  def BREAK : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins uimm4:$s, uimm4:$t),
1404                      "break\t$s, $t", []>, Requires<[HasDebug]> {
1405    let r = 0x04;
1406  }
1407
1408  def BREAK_N : RRRN_Inst<0x0C, (outs), (ins uimm4:$imm),
1409                         "break.n\t$imm", []>, Requires<[HasDensity, HasDebug]> {
1410    bits<4> imm;
1411
1412    let r = 0xf;
1413    let s = imm;
1414    let t = 0x2;
1415  }
1416}
1417
1418def : InstAlias<"_break.n\t$imm", (BREAK_N uimm4:$imm)>;
1419
1420def : Pat<(trap), (BREAK (i32 1), (i32 15))>;
1421
1422// Load instruction
1423def LDDR32P : RRR_Inst<0x00, 0x00, 0x00, (outs AR:$s), (ins),
1424                       "lddr32.p\t$s", []>, Requires<[HasDebug]> {
1425  let r = 0x7;
1426  let t = 0xe;
1427  let mayLoad = 1;
1428}
1429
1430// Store instruction
1431def SDDR32P : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins AR:$s),
1432                       "sddr32.p\t$s", []>, Requires<[HasDebug]> {
1433  let r = 0x7;
1434  let t = 0xf;
1435  let mayStore = 1;
1436}
1437
1438//===----------------------------------------------------------------------===//
1439// Exception feature instructions
1440//===----------------------------------------------------------------------===//
1441
1442def EXCW : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
1443                   "excw", []>, Requires<[HasException]> {
1444  let r = 0x2;
1445  let s = 0x0;
1446  let t = 0x8;
1447}
1448
1449def RFDE : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
1450                   "rfde", []>, Requires<[HasException]> {
1451  let r = 0x3;
1452  let s = 0x2;
1453  let t = 0x0;
1454}
1455
1456
1457def RFE : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
1458                  "rfe", []>, Requires<[HasException]> {
1459  let r = 0x3;
1460  let s = 0x0;
1461  let t = 0x0;
1462}
1463
1464def SYSCALL : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
1465                      "syscall", []>, Requires<[HasException]> {
1466  let r = 0x5;
1467  let s = 0x0;
1468  let t = 0x0;
1469}
1470
1471//===----------------------------------------------------------------------===//
1472// Interrupt feature instructions
1473//===----------------------------------------------------------------------===//
1474
1475def RSIL : RRR_Inst<0x00, 0x00, 0x00, (outs AR:$t), (ins uimm4:$imm),
1476                   "rsil\t$t, $imm", []>, Requires<[HasInterrupt]> {
1477  bits<4> imm;
1478
1479  let r = 0x6;
1480  let s = imm{3-0};
1481}
1482
1483def WAITI : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins uimm4:$imm),
1484                   "waiti\t$imm", []>, Requires<[HasInterrupt]> {
1485  bits<4> imm;
1486
1487  let r = 0x7;
1488  let s = imm{3-0};
1489  let t = 0;
1490}
1491
1492def RFI : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins uimm4:$imm),
1493                  "rfi\t$imm", []>, Requires<[HasHighPriInterrupts]> {
1494  bits<4> imm;
1495
1496  let r = 0x3;
1497  let s = imm{3-0};
1498  let t = 0x1;
1499}
1500
1501//===----------------------------------------------------------------------===//
1502// DSP Instructions
1503//===----------------------------------------------------------------------===//
1504include "XtensaDSPInstrInfo.td"
1505