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