1//===-- AVRInstrInfo.td - AVR Instruction Formats ----------*- tablegen -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// AVR Instruction Format Definitions.
10//
11//===----------------------------------------------------------------------===//
12
13// A generic AVR instruction.
14class AVRInst<dag outs, dag ins, string asmstr, list<dag> pattern>
15    : Instruction {
16  let Namespace = "AVR";
17
18  dag OutOperandList = outs;
19  dag InOperandList = ins;
20  let AsmString = asmstr;
21  let Pattern = pattern;
22
23  field bits<32> SoftFail = 0;
24}
25
26/// A 16-bit AVR instruction.
27class AVRInst16<dag outs, dag ins, string asmstr, list<dag> pattern>
28    : AVRInst<outs, ins, asmstr, pattern> {
29  field bits<16> Inst;
30
31  let Size = 2;
32}
33
34/// a 32-bit AVR instruction.
35class AVRInst32<dag outs, dag ins, string asmstr, list<dag> pattern>
36    : AVRInst<outs, ins, asmstr, pattern> {
37  field bits<32> Inst;
38
39  let Size = 4;
40}
41
42// A class for pseudo instructions.
43// Pseudo instructions are not real AVR instructions. The DAG stores
44// pseudo instructions which are replaced by real AVR instructions by
45// AVRExpandPseudoInsts.cpp.
46//
47// For example, the ADDW (add wide, as in add 16 bit values) instruction
48// is defined as a pseudo instruction. In AVRExpandPseudoInsts.cpp,
49// the instruction is then replaced by two add instructions - one for each byte.
50class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
51    : AVRInst16<outs, ins, asmstr, pattern> {
52  let Pattern = pattern;
53
54  let isPseudo = 1;
55  let isCodeGenOnly = 1;
56}
57
58//===----------------------------------------------------------------------===//
59// Register / register instruction: <|opcode|ffrd|dddd|rrrr|>
60// opcode = 4 bits.
61// f = secondary opcode = 2 bits
62// d = destination = 5 bits
63// r = source = 5 bits
64// (Accepts all registers)
65//===----------------------------------------------------------------------===//
66class FRdRr<bits<4> opcode, bits<2> f, dag outs, dag ins, string asmstr,
67            list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern> {
68  bits<5> rd;
69  bits<5> rr;
70
71  let Inst{15 - 12} = opcode;
72  let Inst{11 - 10} = f;
73  let Inst{9} = rr{4};
74  let Inst{8 - 4} = rd;
75  let Inst{3 - 0} = rr{3 - 0};
76}
77
78class FTST<bits<4> opcode, bits<2> f, dag outs, dag ins, string asmstr,
79           list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern> {
80  bits<5> rd;
81
82  let Inst{15 - 12} = opcode;
83  let Inst{11 - 10} = f;
84  let Inst{9} = rd{4};
85  let Inst{8 - 4} = rd;
86  let Inst{3 - 0} = rd{3 - 0};
87}
88
89//===----------------------------------------------------------------------===//
90// Instruction of the format `<mnemonic> Z, Rd`
91// <|1001|001r|rrrr|0ttt>
92//===----------------------------------------------------------------------===//
93class FZRd<bits<3> t, dag outs, dag ins, string asmstr, list<dag> pattern>
94    : AVRInst16<outs, ins, asmstr, pattern> {
95  bits<5> rd;
96
97  let Inst{15 - 12} = 0b1001;
98
99  let Inst{11 - 9} = 0b001;
100  let Inst{8} = rd{4};
101
102  let Inst{7 - 4} = rd{3 - 0};
103
104  let Inst{3} = 0;
105  let Inst{2 - 0} = t;
106}
107
108//===----------------------------------------------------------------------===//
109// Register / immediate8 instruction: <|opcode|KKKK|dddd|KKKK|>
110// opcode = 4 bits.
111// K = constant data = 8 bits
112// d = destination = 4 bits
113// (Only accepts r16-r31)
114//===----------------------------------------------------------------------===//
115class FRdK<bits<4> opcode, dag outs, dag ins, string asmstr, list<dag> pattern>
116    : AVRInst16<outs, ins, asmstr, pattern> {
117  bits<4> rd;
118  bits<8> k;
119
120  let Inst{15 - 12} = opcode;
121  let Inst{11 - 8} = k{7 - 4};
122  let Inst{7 - 4} = rd{3 - 0};
123  let Inst{3 - 0} = k{3 - 0};
124
125  let isAsCheapAsAMove = 1;
126}
127
128//===----------------------------------------------------------------------===//
129// Register instruction: <|opcode|fffd|dddd|ffff|>
130// opcode = 4 bits.
131// f = secondary opcode = 7 bits
132// d = destination = 5 bits
133// (Accepts all registers)
134//===----------------------------------------------------------------------===//
135class FRd<bits<4> opcode, bits<7> f, dag outs, dag ins, string asmstr,
136          list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern> {
137  bits<5> rd;
138
139  let Inst{15 - 12} = opcode;
140  let Inst{11 - 9} = f{6 - 4};
141  let Inst{8 - 4} = rd;
142  let Inst{3 - 0} = f{3 - 0};
143
144  let DecoderMethod = "decodeFRd";
145}
146
147//===----------------------------------------------------------------------===//
148// [STD/LDD] P+q, Rr special encoding: <|10q0|qqtr|rrrr|pqqq>
149// t = type (1 for STD, 0 for LDD)
150// q = displacement (6 bits)
151// r = register (5 bits)
152// p = pointer register (1 bit) [1 for Y, 0 for Z]
153//===----------------------------------------------------------------------===//
154class FSTDLDD<bit type, dag outs, dag ins, string asmstr, list<dag> pattern>
155    : AVRInst16<outs, ins, asmstr, pattern> {
156  bits<7> memri;
157  bits<5> reg; // the GP register
158
159  let Inst{15 - 14} = 0b10;
160  let Inst{13} = memri{5};
161  let Inst{12} = 0;
162
163  let Inst{11 - 10} = memri{4 - 3};
164  let Inst{9} = type;
165  let Inst{8} = reg{4};
166
167  let Inst{7 - 4} = reg{3 - 0};
168
169  let Inst{3} = memri{6};
170  let Inst{2 - 0} = memri{2 - 0};
171}
172
173//===---------------------------------------------------------------------===//
174// An ST/LD instruction.
175// <|100i|00tr|rrrr|ppaa|>
176// t = type (1 for store, 0 for load)
177// a = regular/postinc/predec (reg = 0b00, postinc = 0b01, predec = 0b10)
178// p = pointer register
179// r = src/dst register
180//
181// Note that the bit labelled 'i' above does not follow a simple pattern,
182// so there exists a post encoder method to set it manually. Also a specified
183// decoder method is needed.
184//===---------------------------------------------------------------------===//
185class FSTLD<bit type, bits<2> mode, dag outs, dag ins, string asmstr,
186            list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern> {
187  bits<2> ptrreg;
188  bits<5> reg;
189
190  let Inst{15 - 13} = 0b100;
191  // This bit varies depending on the arguments and the mode.
192  // We have a post encoder method to set this bit manually.
193  let Inst{12} = 0;
194
195  let Inst{11 - 10} = 0b00;
196  let Inst{9} = type;
197  let Inst{8} = reg{4};
198
199  let Inst{7 - 4} = reg{3 - 0};
200
201  let Inst{3 - 2} = ptrreg{1 - 0};
202  let Inst{1 - 0} = mode{1 - 0};
203
204  let DecoderMethod = "decodeLoadStore";
205  let PostEncoderMethod = "loadStorePostEncoder";
206}
207
208//===---------------------------------------------------------------------===//
209// Special format for the LPM/ELPM instructions
210// [E]LPM Rd, Z[+]
211// <|1001|000d|dddd|01ep>
212// d = destination register
213// e = is elpm
214// p = is postincrement
215//===---------------------------------------------------------------------===//
216class FLPMX<bit e, bit p, dag outs, dag ins, string asmstr, list<dag> pattern>
217    : AVRInst16<outs, ins, asmstr, pattern> {
218  bits<5> rd;
219
220  let Inst{15 - 12} = 0b1001;
221
222  let Inst{11 - 9} = 0b000;
223  let Inst{8} = rd{4};
224
225  let Inst{7 - 4} = rd{3 - 0};
226
227  let Inst{3 - 2} = 0b01;
228  let Inst{1} = e;
229  let Inst{0} = p;
230
231  let DecoderMethod = "decodeFLPMX";
232}
233
234//===----------------------------------------------------------------------===//
235// MOVWRdRr special encoding: <|0000|0001|dddd|rrrr|>
236// d = destination = 4 bits
237// r = source = 4 bits
238// (Only accepts even registers)
239//===----------------------------------------------------------------------===//
240class FMOVWRdRr<dag outs, dag ins, string asmstr, list<dag> pattern>
241    : AVRInst16<outs, ins, asmstr, pattern> {
242  bits<5> rd;
243  bits<5> rr;
244
245  let Inst{15 - 8} = 0b00000001;
246  let Inst{7 - 4} = rd{4 - 1};
247  let Inst{3 - 0} = rr{4 - 1};
248
249  let DecoderMethod = "decodeFMOVWRdRr";
250}
251
252//===----------------------------------------------------------------------===//
253// MULSrr special encoding: <|0000|0010|dddd|rrrr|>
254// d = multiplicand = 4 bits
255// r = multiplier = 4 bits
256// (Only accepts r16-r31)
257//===----------------------------------------------------------------------===//
258class FMUL2RdRr<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
259    : AVRInst16<outs, ins, asmstr, pattern> {
260  bits<5> rd; // accept 5 bits but only encode the lower 4
261  bits<5> rr; // accept 5 bits but only encode the lower 4
262
263  let Inst{15 - 9} = 0b0000001;
264  let Inst{8} = f;
265  let Inst{7 - 4} = rd{3 - 0};
266  let Inst{3 - 0} = rr{3 - 0};
267
268  let DecoderMethod = "decodeFMUL2RdRr";
269}
270
271// Special encoding for the FMUL family of instructions.
272//
273// <0000|0011|fddd|frrr|>
274//
275// ff = 0b01 for FMUL
276//      0b10 for FMULS
277//      0b11 for FMULSU
278//
279// ddd = destination register
280// rrr = source register
281class FFMULRdRr<bits<2> f, dag outs, dag ins, string asmstr, list<dag> pattern>
282    : AVRInst16<outs, ins, asmstr, pattern> {
283  bits<3> rd;
284  bits<3> rr;
285
286  let Inst{15 - 8} = 0b00000011;
287  let Inst{7} = f{1};
288  let Inst{6 - 4} = rd;
289  let Inst{3} = f{0};
290  let Inst{2 - 0} = rr;
291
292  let DecoderMethod = "decodeFFMULRdRr";
293}
294
295//===----------------------------------------------------------------------===//
296// Arithmetic word instructions (ADIW / SBIW): <|1001|011f|kkdd|kkkk|>
297// f = secondary opcode = 1 bit
298// k = constant data = 6 bits
299// d = destination = 2 bits
300// (Only accepts r25:24 r27:26 r29:28 r31:30)
301//===----------------------------------------------------------------------===//
302class FWRdK<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
303    : AVRInst16<outs, ins, asmstr, pattern> {
304  bits<5> rd; // accept 5 bits but only encode bits 1 and 2
305  bits<6> k;
306
307  let Inst{15 - 9} = 0b1001011;
308  let Inst{8} = f;
309  let Inst{7 - 6} = k{5 - 4};
310  let Inst{5 - 4} = rd{2 - 1};
311  let Inst{3 - 0} = k{3 - 0};
312
313  let DecoderMethod = "decodeFWRdK";
314}
315
316//===----------------------------------------------------------------------===//
317// In I/O instruction: <|1011|0AAd|dddd|AAAA|>
318// A = I/O location address = 6 bits
319// d = destination = 5 bits
320// (Accepts all registers)
321//===----------------------------------------------------------------------===//
322class FIORdA<dag outs, dag ins, string asmstr, list<dag> pattern>
323    : AVRInst16<outs, ins, asmstr, pattern> {
324  bits<5> rd;
325  bits<6> A;
326
327  let Inst{15 - 11} = 0b10110;
328  let Inst{10 - 9} = A{5 - 4};
329  let Inst{8 - 4} = rd;
330  let Inst{3 - 0} = A{3 - 0};
331
332  let DecoderMethod = "decodeFIORdA";
333}
334
335//===----------------------------------------------------------------------===//
336// Out I/O instruction: <|1011|1AAr|rrrr|AAAA|>
337// A = I/O location address = 6 bits
338// d = destination = 5 bits
339// (Accepts all registers)
340//===----------------------------------------------------------------------===//
341class FIOARr<dag outs, dag ins, string asmstr, list<dag> pattern>
342    : AVRInst16<outs, ins, asmstr, pattern> {
343  bits<6> A;
344  bits<5> rr;
345
346  let Inst{15 - 11} = 0b10111;
347  let Inst{10 - 9} = A{5 - 4};
348  let Inst{8 - 4} = rr;
349  let Inst{3 - 0} = A{3 - 0};
350
351  let DecoderMethod = "decodeFIOARr";
352}
353
354//===----------------------------------------------------------------------===//
355// I/O bit instruction.
356// <|1001|10tt|AAAA|Abbb>
357// t = type (1 for SBI, 0 for CBI)
358// A = I/O location address (5 bits)
359// b = bit number
360//===----------------------------------------------------------------------===//
361class FIOBIT<bits<2> t, dag outs, dag ins, string asmstr, list<dag> pattern>
362    : AVRInst16<outs, ins, asmstr, pattern> {
363  bits<5> addr;
364  bits<3> b;
365
366  let Inst{15 - 12} = 0b1001;
367
368  let Inst{11 - 10} = 0b10;
369  let Inst{9 - 8} = t;
370
371  let Inst{7 - 4} = addr{4 - 1};
372
373  let Inst{3} = addr{0};
374  let Inst{2 - 0} = b{2 - 0};
375
376  let DecoderMethod = "decodeFIOBIT";
377}
378
379//===----------------------------------------------------------------------===//
380// BST/BLD instruction.
381// <|1111|1ttd|dddd|0bbb>
382// t = type (1 for BST, 0 for BLD)
383// d = destination register
384// b = bit
385//===----------------------------------------------------------------------===//
386class FRdB<bits<2> t, dag outs, dag ins, string asmstr, list<dag> pattern>
387    : AVRInst16<outs, ins, asmstr, pattern> {
388  bits<5> rd;
389  bits<3> b;
390
391  let Inst{15 - 12} = 0b1111;
392
393  let Inst{11} = 0b1;
394  let Inst{10 - 9} = t;
395  let Inst{8} = rd{4};
396
397  let Inst{7 - 4} = rd{3 - 0};
398
399  let Inst{3} = 0;
400  let Inst{2 - 0} = b;
401}
402
403// Special encoding for the `DES K` instruction.
404//
405// <|1001|0100|KKKK|1011>
406//
407// KKKK = 4 bit immediate
408class FDES<dag outs, dag ins, string asmstr, list<dag> pattern>
409    : AVRInst16<outs, ins, asmstr, pattern> {
410  bits<4> k;
411
412  let Inst{15 - 12} = 0b1001;
413
414  let Inst{11 - 8} = 0b0100;
415
416  let Inst{7 - 4} = k;
417
418  let Inst{3 - 0} = 0b1011;
419}
420
421//===----------------------------------------------------------------------===//
422// Conditional Branching instructions: <|1111|0fkk|kkkk|ksss|>
423// f = secondary opcode = 1 bit
424// k = constant address = 7 bits
425// s = bit in status register = 3 bits
426//===----------------------------------------------------------------------===//
427class FBRsk<bit f, bits<3> s, dag outs, dag ins, string asmstr,
428            list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern> {
429  bits<7> k;
430
431  let Inst{15 - 11} = 0b11110;
432  let Inst{10} = f;
433  let Inst{9 - 3} = k;
434  let Inst{2 - 0} = s;
435}
436
437//===----------------------------------------------------------------------===//
438// Special, opcode only instructions: <|opcode|>
439//===----------------------------------------------------------------------===//
440
441class F16<bits<16> opcode, dag outs, dag ins, string asmstr, list<dag> pattern>
442    : AVRInst16<outs, ins, asmstr, pattern> {
443  let Inst = opcode;
444}
445
446class F32<bits<32> opcode, dag outs, dag ins, string asmstr, list<dag> pattern>
447    : AVRInst32<outs, ins, asmstr, pattern> {
448  let Inst = opcode;
449}
450
451//===----------------------------------------------------------------------===//
452// Branching instructions with immediate12: <|110f|kkkk|kkkk|kkkk|>
453// f = secondary opcode = 1 bit
454// k = constant address = 12 bits
455//===----------------------------------------------------------------------===//
456class FBRk<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
457    : AVRInst16<outs, ins, asmstr, pattern> {
458  bits<12> k;
459
460  let Inst{15 - 13} = 0b110;
461  let Inst{12} = f;
462  let Inst{11 - 0} = k;
463
464  let DecoderMethod = "decodeFBRk";
465}
466
467//===----------------------------------------------------------------------===//
468// 32 bits branching instructions: <|1001|010k|kkkk|fffk|kkkk|kkkk|kkkk|kkkk|>
469// f = secondary opcode = 3 bits
470// k = constant address = 22 bits
471//===----------------------------------------------------------------------===//
472class F32BRk<bits<3> f, dag outs, dag ins, string asmstr, list<dag> pattern>
473    : AVRInst32<outs, ins, asmstr, pattern> {
474  bits<22> k;
475
476  let Inst{31 - 25} = 0b1001010;
477  let Inst{24 - 20} = k{21 - 17};
478  let Inst{19 - 17} = f;
479  let Inst{16 - 0} = k{16 - 0};
480}
481
482//===----------------------------------------------------------------------===//
483// 32 bits direct mem instructions: <|1001|00fd|dddd|0000|kkkk|kkkk|kkkk|kkkk|>
484// f = secondary opcode = 1 bit
485// d = destination = 5 bits
486// k = constant address = 16 bits
487// (Accepts all registers)
488//===----------------------------------------------------------------------===//
489class F32DM<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
490    : AVRInst32<outs, ins, asmstr, pattern> {
491  bits<5> rd;
492  bits<16> k;
493
494  let Inst{31 - 28} = 0b1001;
495
496  let Inst{27 - 26} = 0b00;
497  let Inst{25} = f;
498  let Inst{24} = rd{4};
499
500  let Inst{23 - 20} = rd{3 - 0};
501
502  let Inst{19 - 16} = 0b0000;
503
504  let Inst{15 - 0} = k;
505}
506
507//===---------------------------------------------------------------------===//
508// Special format for the LDS/STS instructions on AVRTiny.
509// <|1010|ikkk|dddd|kkkk>
510// d = R16 ~ R31
511// i = 0 - lds, 1 - sts
512// k = 7-bit data space address
513//===---------------------------------------------------------------------===//
514class FLDSSTSTINY<bit i, dag outs, dag ins, string asmstr, list<dag> pattern>
515    : AVRInst16<outs, ins, asmstr, pattern> {
516  bits<5> rd;
517  bits<7> k;
518
519  let Inst{15 - 12} = 0b1010;
520
521  let Inst{11} = i;
522
523  let Inst{10 - 8} = k{6 - 4};
524  let Inst{7 - 4} = rd{3 - 0};
525  let Inst{3 - 0} = k{3 - 0};
526
527  let DecoderNamespace = "AVRTiny";
528}
529
530// <|1001|0100|bfff|1000>
531class FS<bit b, dag outs, dag ins, string asmstr, list<dag> pattern>
532    : AVRInst16<outs, ins, asmstr, pattern> {
533  bits<3> s;
534
535  let Inst{15 - 12} = 0b1001;
536
537  let Inst{11 - 8} = 0b0100;
538
539  let Inst{7} = b;
540  let Inst{6 - 4} = s;
541
542  let Inst{3 - 0} = 0b1000;
543}
544
545// Set/clr bit in status flag instructions/
546// <BRBS|BRBC> s, k
547// ---------------------
548// <|1111|0fkk|kkkk|ksss>
549class FSK<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
550    : AVRInst16<outs, ins, asmstr, pattern> {
551  bits<7> k;
552  bits<3> s;
553
554  let Inst{15 - 12} = 0b1111;
555
556  let Inst{11} = 0;
557  let Inst{10} = f;
558  let Inst{9 - 8} = k{6 - 5};
559
560  let Inst{7 - 4} = k{4 - 1};
561
562  let Inst{3} = k{0};
563  let Inst{2 - 0} = s;
564}
565
566class ExtensionPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
567    : Pseudo<outs, ins, asmstr, pattern> {
568  let Defs = [SREG];
569}
570
571class StorePseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
572    : Pseudo<outs, ins, asmstr, pattern> {
573  let Defs = [SP];
574}
575
576class SelectPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
577    : Pseudo<outs, ins, asmstr, pattern> {
578  let usesCustomInserter = 1;
579
580  let Uses = [SREG];
581}
582
583class ShiftPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
584    : Pseudo<outs, ins, asmstr, pattern> {
585  let usesCustomInserter = 1;
586
587  let Defs = [SREG];
588}
589