//===-- AVRInstrInfo.td - AVR Instruction Formats ----------*- tablegen -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // AVR Instruction Format Definitions. // //===----------------------------------------------------------------------===// // A generic AVR instruction. class AVRInst pattern> : Instruction { let Namespace = "AVR"; dag OutOperandList = outs; dag InOperandList = ins; let AsmString = asmstr; let Pattern = pattern; field bits<32> SoftFail = 0; } /// A 16-bit AVR instruction. class AVRInst16 pattern> : AVRInst { field bits<16> Inst; let Size = 2; } /// a 32-bit AVR instruction. class AVRInst32 pattern> : AVRInst { field bits<32> Inst; let Size = 4; } // A class for pseudo instructions. // Psuedo instructions are not real AVR instructions. The DAG stores // psuedo instructions which are replaced by real AVR instructions by // AVRExpandPseudoInsts.cpp. // // For example, the ADDW (add wide, as in add 16 bit values) instruction // is defined as a pseudo instruction. In AVRExpandPseudoInsts.cpp, // the instruction is then replaced by two add instructions - one for each byte. class Pseudo pattern> : AVRInst16 { let Pattern = pattern; let isPseudo = 1; let isCodeGenOnly = 1; } //===----------------------------------------------------------------------===// // Register / register instruction: <|opcode|ffrd|dddd|rrrr|> // opcode = 4 bits. // f = secondary opcode = 2 bits // d = destination = 5 bits // r = source = 5 bits // (Accepts all registers) //===----------------------------------------------------------------------===// class FRdRr opcode, bits<2> f, dag outs, dag ins, string asmstr, list pattern> : AVRInst16 { bits<5> rd; bits<5> rr; let Inst{15-12} = opcode; let Inst{11-10} = f; let Inst{9} = rr{4}; let Inst{8-4} = rd; let Inst{3-0} = rr{3-0}; } class FTST opcode, bits<2> f, dag outs, dag ins, string asmstr, list pattern> : AVRInst16 { bits<5> rd; let Inst{15-12} = opcode; let Inst{11-10} = f; let Inst{9} = rd{4}; let Inst{8-4} = rd; let Inst{3-0} = rd{3-0}; } //===----------------------------------------------------------------------===// // Instruction of the format ` Z, Rd` // <|1001|001r|rrrr|0ttt> //===----------------------------------------------------------------------===// class FZRd t, dag outs, dag ins, string asmstr, list pattern> : AVRInst16 { bits<5> rd; let Inst{15-12} = 0b1001; let Inst{11-9} = 0b001; let Inst{8} = rd{4}; let Inst{7-4} = rd{3-0}; let Inst{3} = 0; let Inst{2-0} = t; } //===----------------------------------------------------------------------===// // Register / immediate8 instruction: <|opcode|KKKK|dddd|KKKK|> // opcode = 4 bits. // K = constant data = 8 bits // d = destination = 4 bits // (Only accepts r16-r31) //===----------------------------------------------------------------------===// class FRdK opcode, dag outs, dag ins, string asmstr, list pattern> : AVRInst16 { bits<4> rd; bits<8> k; let Inst{15-12} = opcode; let Inst{11-8} = k{7-4}; let Inst{7-4} = rd{3-0}; let Inst{3-0} = k{3-0}; let isAsCheapAsAMove = 1; } //===----------------------------------------------------------------------===// // Register instruction: <|opcode|fffd|dddd|ffff|> // opcode = 4 bits. // f = secondary opcode = 7 bits // d = destination = 5 bits // (Accepts all registers) //===----------------------------------------------------------------------===// class FRd opcode, bits<7> f, dag outs, dag ins, string asmstr, list pattern> : AVRInst16 { bits<5> d; let Inst{15-12} = opcode; let Inst{11-9} = f{6-4}; let Inst{8-4} = d; let Inst{3-0} = f{3-0}; } //===----------------------------------------------------------------------===// // [STD/LDD] P+q, Rr special encoding: <|10q0|qqtr|rrrr|pqqq> // t = type (1 for STD, 0 for LDD) // q = displacement (6 bits) // r = register (5 bits) // p = pointer register (1 bit) [1 for Y, 0 for Z] //===----------------------------------------------------------------------===// class FSTDLDD pattern> : AVRInst16 { bits<7> memri; bits<5> reg; // the GP register let Inst{15-14} = 0b10; let Inst{13} = memri{5}; let Inst{12} = 0; let Inst{11-10} = memri{4-3}; let Inst{9} = type; let Inst{8} = reg{4}; let Inst{7-4} = reg{3-0}; let Inst{3} = memri{6}; let Inst{2-0} = memri{2-0}; } //===---------------------------------------------------------------------===// // An ST/LD instruction. // <|100i|00tr|rrrr|ppaa|> // t = type (1 for store, 0 for load) // a = regular/postinc/predec (reg = 0b00, postinc = 0b01, predec = 0b10) // p = pointer register // r = src/dst register // // Note that the bit labelled 'i' above does not follow a simple pattern, // so there exists a post encoder method to set it manually. //===---------------------------------------------------------------------===// class FSTLD mode, dag outs, dag ins, string asmstr, list pattern> : AVRInst16 { bits<2> ptrreg; bits<5> reg; let Inst{15-13} = 0b100; // This bit varies depending on the arguments and the mode. // We have a post encoder method to set this bit manually. let Inst{12} = 0; let Inst{11-10} = 0b00; let Inst{9} = type; let Inst{8} = reg{4}; let Inst{7-4} = reg{3-0}; let Inst{3-2} = ptrreg{1-0}; let Inst{1-0} = mode{1-0}; let PostEncoderMethod = "loadStorePostEncoder"; } //===---------------------------------------------------------------------===// // Special format for the LPM/ELPM instructions // [E]LPM Rd, Z[+] // <|1001|000d|dddd|01ep> // d = destination register // e = is elpm // p = is postincrement //===---------------------------------------------------------------------===// class FLPMX pattern> : AVRInst16 { bits<5> reg; let Inst{15-12} = 0b1001; let Inst{11-9} = 0b000; let Inst{8} = reg{4}; let Inst{7-4} = reg{3-0}; let Inst{3-2} = 0b01; let Inst{1} = e; let Inst{0} = p; } //===----------------------------------------------------------------------===// // MOVWRdRr special encoding: <|0000|0001|dddd|rrrr|> // d = destination = 4 bits // r = source = 4 bits // (Only accepts even registers) //===----------------------------------------------------------------------===// class FMOVWRdRr pattern> : AVRInst16 { bits<5> d; bits<5> r; let Inst{15-8} = 0b00000001; let Inst{7-4} = d{4-1}; let Inst{3-0} = r{4-1}; } //===----------------------------------------------------------------------===// // MULSrr special encoding: <|0000|0010|dddd|rrrr|> // d = multiplicand = 4 bits // r = multiplier = 4 bits // (Only accepts r16-r31) //===----------------------------------------------------------------------===// class FMUL2RdRr pattern> : AVRInst16 { bits<5> rd; // accept 5 bits but only encode the lower 4 bits<5> rr; // accept 5 bits but only encode the lower 4 let Inst{15-9} = 0b0000001; let Inst{8} = f; let Inst{7-4} = rd{3-0}; let Inst{3-0} = rr{3-0}; } // Special encoding for the FMUL family of instructions. // // <0000|0011|fddd|frrr|> // // ff = 0b01 for FMUL // 0b10 for FMULS // 0b11 for FMULSU // // ddd = destination register // rrr = source register class FFMULRdRr f, dag outs, dag ins, string asmstr, list pattern> : AVRInst16 { bits<3> rd; bits<3> rr; let Inst{15-8} = 0b00000011; let Inst{7} = f{1}; let Inst{6-4} = rd; let Inst{3} = f{0}; let Inst{2-0} = rr; } //===----------------------------------------------------------------------===// // Arithmetic word instructions (ADIW / SBIW): <|1001|011f|kkdd|kkkk|> // f = secondary opcode = 1 bit // k = constant data = 6 bits // d = destination = 4 bits // (Only accepts r25:24 r27:26 r29:28 r31:30) //===----------------------------------------------------------------------===// class FWRdK pattern> : AVRInst16 { bits<5> dst; // accept 5 bits but only encode bits 1 and 2 bits<6> k; let Inst{15-9} = 0b1001011; let Inst{8} = f; let Inst{7-6} = k{5-4}; let Inst{5-4} = dst{2-1}; let Inst{3-0} = k{3-0}; } //===----------------------------------------------------------------------===// // In I/O instruction: <|1011|0AAd|dddd|AAAA|> // A = I/O location address = 6 bits // d = destination = 5 bits // (Accepts all registers) //===----------------------------------------------------------------------===// class FIORdA pattern> : AVRInst16 { bits<5> d; bits<6> A; let Inst{15-11} = 0b10110; let Inst{10-9} = A{5-4}; let Inst{8-4} = d; let Inst{3-0} = A{3-0}; } //===----------------------------------------------------------------------===// // Out I/O instruction: <|1011|1AAr|rrrr|AAAA|> // A = I/O location address = 6 bits // d = destination = 5 bits // (Accepts all registers) //===----------------------------------------------------------------------===// class FIOARr pattern> : AVRInst16 { bits<6> A; bits<5> r; let Inst{15-11} = 0b10111; let Inst{10-9} = A{5-4}; let Inst{8-4} = r; let Inst{3-0} = A{3-0}; } //===----------------------------------------------------------------------===// // I/O bit instruction. // <|1001|10tt|AAAA|Abbb> // t = type (1 for SBI, 0 for CBI) // A = I/O location address (5 bits) // b = bit number //===----------------------------------------------------------------------===// class FIOBIT t, dag outs, dag ins, string asmstr, list pattern> : AVRInst16 { bits<5> A; bits<3> b; let Inst{15-12} = 0b1001; let Inst{11-10} = 0b10; let Inst{9-8} = t; let Inst{7-4} = A{4-1}; let Inst{3} = A{0}; let Inst{2-0} = b{2-0}; } //===----------------------------------------------------------------------===// // BST/BLD instruction. // <|1111|1ttd|dddd|0bbb> // t = type (1 for BST, 0 for BLD) // d = destination register // b = bit //===----------------------------------------------------------------------===// class FRdB t, dag outs, dag ins, string asmstr, list pattern> : AVRInst16 { bits<5> rd; bits<3> b; let Inst{15-12} = 0b1111; let Inst{11} = 0b1; let Inst{10-9} = t; let Inst{8} = rd{4}; let Inst{7-4} = rd{3-0}; let Inst{3} = 0; let Inst{2-0} = b; } // Special encoding for the `DES K` instruction. // // <|1001|0100|KKKK|1011> // // KKKK = 4 bit immediate class FDES pattern> : AVRInst16 { bits<4> k; let Inst{15-12} = 0b1001; let Inst{11-8} = 0b0100; let Inst{7-4} = k; let Inst{3-0} = 0b1011; } //===----------------------------------------------------------------------===// // Conditional Branching instructions: <|1111|0fkk|kkkk|ksss|> // f = secondary opcode = 1 bit // k = constant address = 7 bits // s = bit in status register = 3 bits //===----------------------------------------------------------------------===// class FBRsk s, dag outs, dag ins, string asmstr, list pattern> : AVRInst16 { bits<7> k; let Inst{15-11} = 0b11110; let Inst{10} = f; let Inst{9-3} = k; let Inst{2-0} = s; } //===----------------------------------------------------------------------===// // Special, opcode only instructions: <|opcode|> //===----------------------------------------------------------------------===// class F16 opcode, dag outs, dag ins, string asmstr, list pattern> : AVRInst16 { let Inst = opcode; } class F32 opcode, dag outs, dag ins, string asmstr, list pattern> : AVRInst32 { let Inst = opcode; } //===----------------------------------------------------------------------===// // Branching instructions with immediate12: <|110f|kkkk|kkkk|kkkk|> // f = secondary opcode = 1 bit // k = constant address = 12 bits //===----------------------------------------------------------------------===// class FBRk pattern> : AVRInst16 { bits<12> k; let Inst{15-13} = 0b110; let Inst{12} = f; let Inst{11-0} = k; } //===----------------------------------------------------------------------===// // 32 bits branching instructions: <|1001|010k|kkkk|fffk|kkkk|kkkk|kkkk|kkkk|> // f = secondary opcode = 3 bits // k = constant address = 22 bits //===----------------------------------------------------------------------===// class F32BRk f, dag outs, dag ins, string asmstr, list pattern> : AVRInst32 { bits<22> k; let Inst{31-25} = 0b1001010; let Inst{24-20} = k{21-17}; let Inst{19-17} = f; let Inst{16-0} = k{16-0}; } //===----------------------------------------------------------------------===// // 32 bits direct mem instructions: <|1001|00fd|dddd|0000|kkkk|kkkk|kkkk|kkkk|> // f = secondary opcode = 1 bit // d = destination = 5 bits // k = constant address = 16 bits // (Accepts all registers) //===----------------------------------------------------------------------===// class F32DM pattern> : AVRInst32 { bits<5> rd; bits<16> k; let Inst{31-28} = 0b1001; let Inst{27-26} = 0b00; let Inst{25} = f; let Inst{24} = rd{4}; let Inst{23-20} = rd{3-0}; let Inst{19-16} = 0b0000; let Inst{15-0} = k; } // <|1001|0100|bfff|1000> class FS pattern> : AVRInst16 { bits<3> s; let Inst{15-12} = 0b1001; let Inst{11-8} = 0b0100; let Inst{7} = b; let Inst{6-4} = s; let Inst{3-0} = 0b1000; } // Set/clr bit in status flag instructions/ // s, k // --------------------- // <|1111|0fkk|kkkk|ksss> class FSK pattern> : AVRInst16 { bits<7> k; bits<3> s; let Inst{15-12} = 0b1111; let Inst{11} = 0; let Inst{10} = f; let Inst{9-8} = k{6-5}; let Inst{7-4} = k{4-1}; let Inst{3} = k{0}; let Inst{2-0} = s; } class ExtensionPseudo pattern> : Pseudo { let Defs = [SREG]; } class StorePseudo pattern> : Pseudo { let Defs = [SP]; } class SelectPseudo pattern> : Pseudo { let usesCustomInserter = 1; let Uses = [SREG]; } class ShiftPseudo pattern> : Pseudo { let usesCustomInserter = 1; let Defs = [SREG]; }