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