Home | History | Annotate | Download | only in AVR
      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.
     15 class 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.
     26 class 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.
     35 class 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.
     51 class 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 //===----------------------------------------------------------------------===//
     68 class 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 
     81 class 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 //===----------------------------------------------------------------------===//
     97 class 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 //===----------------------------------------------------------------------===//
    120 class 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 //===----------------------------------------------------------------------===//
    141 class 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 //===----------------------------------------------------------------------===//
    159 class 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 //===---------------------------------------------------------------------===//
    190 class 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 //===---------------------------------------------------------------------===//
    222 class 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 //===----------------------------------------------------------------------===//
    245 class 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 //===----------------------------------------------------------------------===//
    262 class 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
    284 class 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 //===----------------------------------------------------------------------===//
    305 class 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 //===----------------------------------------------------------------------===//
    324 class 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 //===----------------------------------------------------------------------===//
    342 class 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 //===----------------------------------------------------------------------===//
    361 class 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 //===----------------------------------------------------------------------===//
    385 class 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
    408 class 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 //===----------------------------------------------------------------------===//
    428 class 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 
    443 class 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 
    449 class 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 //===----------------------------------------------------------------------===//
    460 class 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 //===----------------------------------------------------------------------===//
    475 class 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 //===----------------------------------------------------------------------===//
    493 class 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>
    513 class 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>
    532 class 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 
    550 class ExtensionPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
    551   : Pseudo<outs, ins, asmstr, pattern>
    552 {
    553   let Defs = [SREG];
    554 }
    555 
    556 class StorePseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
    557   : Pseudo<outs, ins, asmstr, pattern>
    558 {
    559   let Defs = [SP];
    560 }
    561 
    562 class 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 
    570 class 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