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