1 //===-- AVRInstrInfo.td - AVR Instruction Formats ----------*- tablegen -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // AVR Instruction Format Definitions.
11 //===----------------------------------------------------------------------===//
13 // A generic AVR instruction.
14 class AVRInst<dag outs, dag ins, string asmstr, list<dag> pattern> : Instruction
16 let Namespace = "AVR";
18 dag OutOperandList = outs;
19 dag InOperandList = ins;
20 let AsmString = asmstr;
21 let Pattern = pattern;
23 field bits<32> SoftFail = 0;
26 /// A 16-bit AVR instruction.
27 class AVRInst16<dag outs, dag ins, string asmstr, list<dag> pattern>
28 : AVRInst<outs, ins, asmstr, pattern>
35 /// a 32-bit AVR instruction.
36 class AVRInst32<dag outs, dag ins, string asmstr, list<dag> pattern>
37 : AVRInst<outs, ins, asmstr, pattern>
44 // A class for pseudo instructions.
45 // Psuedo instructions are not real AVR instructions. The DAG stores
46 // psuedo instructions which are replaced by real AVR instructions by
47 // AVRExpandPseudoInsts.cpp.
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.
52 class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
53 : AVRInst16<outs, ins, asmstr, pattern>
55 let Pattern = pattern;
58 let isCodeGenOnly = 1;
61 //===----------------------------------------------------------------------===//
62 // Register / register instruction: <|opcode|ffrd|dddd|rrrr|>
64 // f = secondary opcode = 2 bits
65 // d = destination = 5 bits
66 // r = source = 5 bits
67 // (Accepts all registers)
68 //===----------------------------------------------------------------------===//
69 class FRdRr<bits<4> opcode, bits<2> f, dag outs, dag ins, string asmstr,
70 list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern>
75 let Inst{15-12} = opcode;
79 let Inst{3-0} = rr{3-0};
82 class FTST<bits<4> opcode, bits<2> f, dag outs, dag ins, string asmstr,
83 list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern>
87 let Inst{15-12} = opcode;
91 let Inst{3-0} = rd{3-0};
94 //===----------------------------------------------------------------------===//
95 // Instruction of the format `<mnemonic> Z, Rd`
96 // <|1001|001r|rrrr|0ttt>
97 //===----------------------------------------------------------------------===//
98 class FZRd<bits<3> t, dag outs, dag ins, string asmstr, list<dag> pattern>
99 : AVRInst16<outs, ins, asmstr, pattern>
103 let Inst{15-12} = 0b1001;
105 let Inst{11-9} = 0b001;
108 let Inst{7-4} = rd{3-0};
114 //===----------------------------------------------------------------------===//
115 // Register / immediate8 instruction: <|opcode|KKKK|dddd|KKKK|>
117 // K = constant data = 8 bits
118 // d = destination = 4 bits
119 // (Only accepts r16-r31)
120 //===----------------------------------------------------------------------===//
121 class FRdK<bits<4> opcode, dag outs, dag ins, string asmstr, list<dag> pattern>
122 : AVRInst16<outs, ins, asmstr, pattern>
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};
132 let isAsCheapAsAMove = 1;
135 //===----------------------------------------------------------------------===//
136 // Register instruction: <|opcode|fffd|dddd|ffff|>
138 // f = secondary opcode = 7 bits
139 // d = destination = 5 bits
140 // (Accepts all registers)
141 //===----------------------------------------------------------------------===//
142 class FRd<bits<4> opcode, bits<7> f, dag outs, dag ins, string asmstr,
143 list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern>
147 let Inst{15-12} = opcode;
148 let Inst{11-9} = f{6-4};
150 let Inst{3-0} = f{3-0};
153 //===----------------------------------------------------------------------===//
154 // [STD/LDD] P+q, Rr special encoding: <|10q0|qqtr|rrrr|pqqq>
155 // t = type (1 for STD, 0 for LDD)
156 // q = displacement (6 bits)
157 // r = register (5 bits)
158 // p = pointer register (1 bit) [1 for Y, 0 for Z]
159 //===----------------------------------------------------------------------===//
160 class FSTDLDD<bit type, dag outs, dag ins, string asmstr, list<dag> pattern>
161 : AVRInst16<outs, ins, asmstr, pattern>
164 bits<5> reg; // the GP register
166 let Inst{15-14} = 0b10;
167 let Inst{13} = memri{5};
170 let Inst{11-10} = memri{4-3};
172 let Inst{8} = reg{4};
174 let Inst{7-4} = reg{3-0};
176 let Inst{3} = memri{6};
177 let Inst{2-0} = memri{2-0};
180 //===---------------------------------------------------------------------===//
181 // An ST/LD instruction.
182 // <|100i|00tr|rrrr|ppaa|>
183 // t = type (1 for store, 0 for load)
184 // a = regular/postinc/predec (reg = 0b00, postinc = 0b01, predec = 0b10)
185 // p = pointer register
186 // r = src/dst register
188 // Note that the bit labelled 'i' above does not follow a simple pattern,
189 // so there exists a post encoder method to set it manually.
190 //===---------------------------------------------------------------------===//
191 class FSTLD<bit type, bits<2> mode, dag outs, dag ins,
192 string asmstr, list<dag> pattern>
193 : AVRInst16<outs, ins, asmstr, pattern>
198 let Inst{15-13} = 0b100;
199 // This bit varies depending on the arguments and the mode.
200 // We have a post encoder method to set this bit manually.
203 let Inst{11-10} = 0b00;
205 let Inst{8} = reg{4};
207 let Inst{7-4} = reg{3-0};
209 let Inst{3-2} = ptrreg{1-0};
210 let Inst{1-0} = mode{1-0};
212 let PostEncoderMethod = "loadStorePostEncoder";
215 //===---------------------------------------------------------------------===//
216 // Special format for the LPM/ELPM instructions
218 // <|1001|000d|dddd|01ep>
219 // d = destination register
221 // p = is postincrement
222 //===---------------------------------------------------------------------===//
223 class FLPMX<bit e, bit p, dag outs, dag ins, string asmstr, list<dag> pattern>
224 : AVRInst16<outs, ins, asmstr, pattern>
228 let Inst{15-12} = 0b1001;
230 let Inst{11-9} = 0b000;
231 let Inst{8} = reg{4};
233 let Inst{7-4} = reg{3-0};
235 let Inst{3-2} = 0b01;
240 //===----------------------------------------------------------------------===//
241 // MOVWRdRr special encoding: <|0000|0001|dddd|rrrr|>
242 // d = destination = 4 bits
243 // r = source = 4 bits
244 // (Only accepts even registers)
245 //===----------------------------------------------------------------------===//
246 class FMOVWRdRr<dag outs, dag ins, string asmstr, list<dag> pattern>
247 : AVRInst16<outs, ins, asmstr, pattern>
252 let Inst{15-8} = 0b00000001;
253 let Inst{7-4} = d{4-1};
254 let Inst{3-0} = r{4-1};
257 //===----------------------------------------------------------------------===//
258 // MULSrr special encoding: <|0000|0010|dddd|rrrr|>
259 // d = multiplicand = 4 bits
260 // r = multiplier = 4 bits
261 // (Only accepts r16-r31)
262 //===----------------------------------------------------------------------===//
263 class FMUL2RdRr<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
264 : AVRInst16<outs, ins, asmstr, pattern>
266 bits<5> rd; // accept 5 bits but only encode the lower 4
267 bits<5> rr; // accept 5 bits but only encode the lower 4
269 let Inst{15-9} = 0b0000001;
271 let Inst{7-4} = rd{3-0};
272 let Inst{3-0} = rr{3-0};
275 // Special encoding for the FMUL family of instructions.
277 // <0000|0011|fddd|frrr|>
279 // ff = 0b01 for FMUL
283 // ddd = destination register
284 // rrr = source register
285 class FFMULRdRr<bits<2> f, dag outs, dag ins, string asmstr, list<dag> pattern>
286 : AVRInst16<outs, ins, asmstr, pattern>
291 let Inst{15-8} = 0b00000011;
299 //===----------------------------------------------------------------------===//
300 // Arithmetic word instructions (ADIW / SBIW): <|1001|011f|kkdd|kkkk|>
301 // f = secondary opcode = 1 bit
302 // k = constant data = 6 bits
303 // d = destination = 4 bits
304 // (Only accepts r25:24 r27:26 r29:28 r31:30)
305 //===----------------------------------------------------------------------===//
306 class FWRdK<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
307 : AVRInst16<outs, ins, asmstr, pattern>
309 bits<5> dst; // accept 5 bits but only encode bits 1 and 2
312 let Inst{15-9} = 0b1001011;
314 let Inst{7-6} = k{5-4};
315 let Inst{5-4} = dst{2-1};
316 let Inst{3-0} = k{3-0};
319 //===----------------------------------------------------------------------===//
320 // In I/O instruction: <|1011|0AAd|dddd|AAAA|>
321 // A = I/O location address = 6 bits
322 // d = destination = 5 bits
323 // (Accepts all registers)
324 //===----------------------------------------------------------------------===//
325 class FIORdA<dag outs, dag ins, string asmstr, list<dag> pattern>
326 : AVRInst16<outs, ins, asmstr, pattern>
331 let Inst{15-11} = 0b10110;
332 let Inst{10-9} = A{5-4};
334 let Inst{3-0} = A{3-0};
337 //===----------------------------------------------------------------------===//
338 // Out I/O instruction: <|1011|1AAr|rrrr|AAAA|>
339 // A = I/O location address = 6 bits
340 // d = destination = 5 bits
341 // (Accepts all registers)
342 //===----------------------------------------------------------------------===//
343 class FIOARr<dag outs, dag ins, string asmstr, list<dag> pattern>
344 : AVRInst16<outs, ins, asmstr, pattern>
349 let Inst{15-11} = 0b10111;
350 let Inst{10-9} = A{5-4};
352 let Inst{3-0} = A{3-0};
355 //===----------------------------------------------------------------------===//
356 // I/O bit instruction.
357 // <|1001|10tt|AAAA|Abbb>
358 // t = type (1 for SBI, 0 for CBI)
359 // A = I/O location address (5 bits)
361 //===----------------------------------------------------------------------===//
362 class FIOBIT<bits<2> t, dag outs, dag ins, string asmstr, list<dag> pattern>
363 : AVRInst16<outs, ins, asmstr, pattern>
368 let Inst{15-12} = 0b1001;
370 let Inst{11-10} = 0b10;
373 let Inst{7-4} = A{4-1};
376 let Inst{2-0} = b{2-0};
379 //===----------------------------------------------------------------------===//
380 // BST/BLD instruction.
381 // <|1111|1ttd|dddd|0bbb>
382 // t = type (1 for BST, 0 for BLD)
383 // d = destination register
385 //===----------------------------------------------------------------------===//
386 class FRdB<bits<2> t, dag outs, dag ins, string asmstr, list<dag> pattern>
387 : AVRInst16<outs, ins, asmstr, pattern>
392 let Inst{15-12} = 0b1111;
398 let Inst{7-4} = rd{3-0};
404 // Special encoding for the `DES K` instruction.
406 // <|1001|0100|KKKK|1011>
408 // KKKK = 4 bit immediate
409 class FDES<dag outs, dag ins, string asmstr, list<dag> pattern>
410 : AVRInst16<outs, ins, asmstr, pattern>
414 let Inst{15-12} = 0b1001;
416 let Inst{11-8} = 0b0100;
420 let Inst{3-0} = 0b1011;
423 //===----------------------------------------------------------------------===//
424 // Conditional Branching instructions: <|1111|0fkk|kkkk|ksss|>
425 // f = secondary opcode = 1 bit
426 // k = constant address = 7 bits
427 // s = bit in status register = 3 bits
428 //===----------------------------------------------------------------------===//
429 class FBRsk<bit f, bits<3> s, dag outs, dag ins, string asmstr, list<dag> pattern>
430 : AVRInst16<outs, ins, asmstr, pattern>
434 let Inst{15-11} = 0b11110;
440 //===----------------------------------------------------------------------===//
441 // Special, opcode only instructions: <|opcode|>
442 //===----------------------------------------------------------------------===//
444 class F16<bits<16> opcode, dag outs, dag ins, string asmstr, list<dag> pattern>
445 : AVRInst16<outs, ins, asmstr, pattern>
450 class F32<bits<32> opcode, dag outs, dag ins, string asmstr, list<dag> pattern>
451 : AVRInst32<outs, ins, asmstr, pattern>
456 //===----------------------------------------------------------------------===//
457 // Branching instructions with immediate12: <|110f|kkkk|kkkk|kkkk|>
458 // f = secondary opcode = 1 bit
459 // k = constant address = 12 bits
460 //===----------------------------------------------------------------------===//
461 class FBRk<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
462 : AVRInst16<outs, ins, asmstr, pattern>
466 let Inst{15-13} = 0b110;
471 //===----------------------------------------------------------------------===//
472 // 32 bits branching instructions: <|1001|010k|kkkk|fffk|kkkk|kkkk|kkkk|kkkk|>
473 // f = secondary opcode = 3 bits
474 // k = constant address = 22 bits
475 //===----------------------------------------------------------------------===//
476 class F32BRk<bits<3> f, dag outs, dag ins, string asmstr, list<dag> pattern>
477 : AVRInst32<outs, ins, asmstr, pattern>
481 let Inst{31-25} = 0b1001010;
482 let Inst{24-20} = k{21-17};
484 let Inst{16-0} = k{16-0};
487 //===----------------------------------------------------------------------===//
488 // 32 bits direct mem instructions: <|1001|00fd|dddd|0000|kkkk|kkkk|kkkk|kkkk|>
489 // f = secondary opcode = 1 bit
490 // d = destination = 5 bits
491 // k = constant address = 16 bits
492 // (Accepts all registers)
493 //===----------------------------------------------------------------------===//
494 class F32DM<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
495 : AVRInst32<outs, ins, asmstr, pattern>
500 let Inst{31-28} = 0b1001;
502 let Inst{27-26} = 0b00;
504 let Inst{24} = rd{4};
506 let Inst{23-20} = rd{3-0};
508 let Inst{19-16} = 0b0000;
513 // <|1001|0100|bfff|1000>
514 class FS<bit b, dag outs, dag ins, string asmstr, list<dag> pattern>
515 : AVRInst16<outs, ins, asmstr, pattern>
519 let Inst{15-12} = 0b1001;
521 let Inst{11-8} = 0b0100;
526 let Inst{3-0} = 0b1000;
529 // Set/clr bit in status flag instructions/
531 // ---------------------
532 // <|1111|0fkk|kkkk|ksss>
533 class FSK<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
534 : AVRInst16<outs, ins, asmstr, pattern>
539 let Inst{15-12} = 0b1111;
543 let Inst{9-8} = k{6-5};
545 let Inst{7-4} = k{4-1};
551 class ExtensionPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
552 : Pseudo<outs, ins, asmstr, pattern>
557 class StorePseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
558 : Pseudo<outs, ins, asmstr, pattern>
563 class SelectPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
564 : Pseudo<outs, ins, asmstr, pattern>
566 let usesCustomInserter = 1;
571 class ShiftPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
572 : Pseudo<outs, ins, asmstr, pattern>
574 let usesCustomInserter = 1;