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