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