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