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> : Instruction 15{ 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{ 30 field bits<16> Inst; 31 32 let Size = 2; 33} 34 35/// a 32-bit AVR instruction. 36class AVRInst32<dag outs, dag ins, string asmstr, list<dag> pattern> 37 : AVRInst<outs, ins, asmstr, pattern> 38{ 39 field bits<32> Inst; 40 41 let Size = 4; 42} 43 44// A class for pseudo instructions. 45// Pseudo instructions are not real AVR instructions. The DAG stores 46// pseudo instructions which are replaced by real AVR instructions by 47// AVRExpandPseudoInsts.cpp. 48// 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. 52class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern> 53 : AVRInst16<outs, ins, asmstr, pattern> 54{ 55 let Pattern = pattern; 56 57 let isPseudo = 1; 58 let isCodeGenOnly = 1; 59} 60 61//===----------------------------------------------------------------------===// 62// Register / register instruction: <|opcode|ffrd|dddd|rrrr|> 63// opcode = 4 bits. 64// f = secondary opcode = 2 bits 65// d = destination = 5 bits 66// r = source = 5 bits 67// (Accepts all registers) 68//===----------------------------------------------------------------------===// 69class FRdRr<bits<4> opcode, bits<2> f, dag outs, dag ins, string asmstr, 70 list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern> 71{ 72 bits<5> rd; 73 bits<5> rr; 74 75 let Inst{15-12} = opcode; 76 let Inst{11-10} = f; 77 let Inst{9} = rr{4}; 78 let Inst{8-4} = rd; 79 let Inst{3-0} = rr{3-0}; 80} 81 82class FTST<bits<4> opcode, bits<2> f, dag outs, dag ins, string asmstr, 83 list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern> 84{ 85 bits<5> rd; 86 87 let Inst{15-12} = opcode; 88 let Inst{11-10} = f; 89 let Inst{9} = rd{4}; 90 let Inst{8-4} = rd; 91 let Inst{3-0} = rd{3-0}; 92} 93 94//===----------------------------------------------------------------------===// 95// Instruction of the format `<mnemonic> Z, Rd` 96// <|1001|001r|rrrr|0ttt> 97//===----------------------------------------------------------------------===// 98class FZRd<bits<3> t, dag outs, dag ins, string asmstr, list<dag> pattern> 99 : AVRInst16<outs, ins, asmstr, pattern> 100{ 101 bits<5> rd; 102 103 let Inst{15-12} = 0b1001; 104 105 let Inst{11-9} = 0b001; 106 let Inst{8} = rd{4}; 107 108 let Inst{7-4} = rd{3-0}; 109 110 let Inst{3} = 0; 111 let Inst{2-0} = t; 112} 113 114//===----------------------------------------------------------------------===// 115// Register / immediate8 instruction: <|opcode|KKKK|dddd|KKKK|> 116// opcode = 4 bits. 117// K = constant data = 8 bits 118// d = destination = 4 bits 119// (Only accepts r16-r31) 120//===----------------------------------------------------------------------===// 121class FRdK<bits<4> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> 122 : AVRInst16<outs, ins, asmstr, pattern> 123{ 124 bits<4> rd; 125 bits<8> k; 126 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}; 131 132 let isAsCheapAsAMove = 1; 133} 134 135//===----------------------------------------------------------------------===// 136// Register instruction: <|opcode|fffd|dddd|ffff|> 137// opcode = 4 bits. 138// f = secondary opcode = 7 bits 139// d = destination = 5 bits 140// (Accepts all registers) 141//===----------------------------------------------------------------------===// 142class FRd<bits<4> opcode, bits<7> f, dag outs, dag ins, string asmstr, 143 list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern> 144{ 145 bits<5> d; 146 147 let Inst{15-12} = opcode; 148 let Inst{11-9} = f{6-4}; 149 let Inst{8-4} = d; 150 let Inst{3-0} = f{3-0}; 151} 152 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//===----------------------------------------------------------------------===// 160class FSTDLDD<bit type, dag outs, dag ins, string asmstr, list<dag> pattern> 161 : AVRInst16<outs, ins, asmstr, pattern> 162{ 163 bits<7> memri; 164 bits<5> reg; // the GP register 165 166 let Inst{15-14} = 0b10; 167 let Inst{13} = memri{5}; 168 let Inst{12} = 0; 169 170 let Inst{11-10} = memri{4-3}; 171 let Inst{9} = type; 172 let Inst{8} = reg{4}; 173 174 let Inst{7-4} = reg{3-0}; 175 176 let Inst{3} = memri{6}; 177 let Inst{2-0} = memri{2-0}; 178} 179 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 187// 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//===---------------------------------------------------------------------===// 191class FSTLD<bit type, bits<2> mode, dag outs, dag ins, 192 string asmstr, list<dag> pattern> 193 : AVRInst16<outs, ins, asmstr, pattern> 194{ 195 bits<2> ptrreg; 196 bits<5> reg; 197 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. 201 let Inst{12} = 0; 202 203 let Inst{11-10} = 0b00; 204 let Inst{9} = type; 205 let Inst{8} = reg{4}; 206 207 let Inst{7-4} = reg{3-0}; 208 209 let Inst{3-2} = ptrreg{1-0}; 210 let Inst{1-0} = mode{1-0}; 211 212 let PostEncoderMethod = "loadStorePostEncoder"; 213} 214 215//===---------------------------------------------------------------------===// 216// Special format for the LPM/ELPM instructions 217// [E]LPM Rd, Z[+] 218// <|1001|000d|dddd|01ep> 219// d = destination register 220// e = is elpm 221// p = is postincrement 222//===---------------------------------------------------------------------===// 223class FLPMX<bit e, bit p, dag outs, dag ins, string asmstr, list<dag> pattern> 224 : AVRInst16<outs, ins, asmstr, pattern> 225{ 226 bits<5> reg; 227 228 let Inst{15-12} = 0b1001; 229 230 let Inst{11-9} = 0b000; 231 let Inst{8} = reg{4}; 232 233 let Inst{7-4} = reg{3-0}; 234 235 let Inst{3-2} = 0b01; 236 let Inst{1} = e; 237 let Inst{0} = p; 238} 239 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//===----------------------------------------------------------------------===// 246class FMOVWRdRr<dag outs, dag ins, string asmstr, list<dag> pattern> 247 : AVRInst16<outs, ins, asmstr, pattern> 248{ 249 bits<5> d; 250 bits<5> r; 251 252 let Inst{15-8} = 0b00000001; 253 let Inst{7-4} = d{4-1}; 254 let Inst{3-0} = r{4-1}; 255} 256 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//===----------------------------------------------------------------------===// 263class FMUL2RdRr<bit f, dag outs, dag ins, string asmstr, list<dag> pattern> 264 : AVRInst16<outs, ins, asmstr, pattern> 265{ 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 268 269 let Inst{15-9} = 0b0000001; 270 let Inst{8} = f; 271 let Inst{7-4} = rd{3-0}; 272 let Inst{3-0} = rr{3-0}; 273} 274 275// Special encoding for the FMUL family of instructions. 276// 277// <0000|0011|fddd|frrr|> 278// 279// ff = 0b01 for FMUL 280// 0b10 for FMULS 281// 0b11 for FMULSU 282// 283// ddd = destination register 284// rrr = source register 285class FFMULRdRr<bits<2> f, dag outs, dag ins, string asmstr, list<dag> pattern> 286 : AVRInst16<outs, ins, asmstr, pattern> 287{ 288 bits<3> rd; 289 bits<3> rr; 290 291 let Inst{15-8} = 0b00000011; 292 let Inst{7} = f{1}; 293 let Inst{6-4} = rd; 294 let Inst{3} = f{0}; 295 let Inst{2-0} = rr; 296} 297 298 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//===----------------------------------------------------------------------===// 306class FWRdK<bit f, dag outs, dag ins, string asmstr, list<dag> pattern> 307 : AVRInst16<outs, ins, asmstr, pattern> 308{ 309 bits<5> dst; // accept 5 bits but only encode bits 1 and 2 310 bits<6> k; 311 312 let Inst{15-9} = 0b1001011; 313 let Inst{8} = f; 314 let Inst{7-6} = k{5-4}; 315 let Inst{5-4} = dst{2-1}; 316 let Inst{3-0} = k{3-0}; 317} 318 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//===----------------------------------------------------------------------===// 325class FIORdA<dag outs, dag ins, string asmstr, list<dag> pattern> 326 : AVRInst16<outs, ins, asmstr, pattern> 327{ 328 bits<5> d; 329 bits<6> A; 330 331 let Inst{15-11} = 0b10110; 332 let Inst{10-9} = A{5-4}; 333 let Inst{8-4} = d; 334 let Inst{3-0} = A{3-0}; 335} 336 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//===----------------------------------------------------------------------===// 343class FIOARr<dag outs, dag ins, string asmstr, list<dag> pattern> 344 : AVRInst16<outs, ins, asmstr, pattern> 345{ 346 bits<6> A; 347 bits<5> r; 348 349 let Inst{15-11} = 0b10111; 350 let Inst{10-9} = A{5-4}; 351 let Inst{8-4} = r; 352 let Inst{3-0} = A{3-0}; 353} 354 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) 360// b = bit number 361//===----------------------------------------------------------------------===// 362class FIOBIT<bits<2> t, dag outs, dag ins, string asmstr, list<dag> pattern> 363 : AVRInst16<outs, ins, asmstr, pattern> 364{ 365 bits<5> A; 366 bits<3> b; 367 368 let Inst{15-12} = 0b1001; 369 370 let Inst{11-10} = 0b10; 371 let Inst{9-8} = t; 372 373 let Inst{7-4} = A{4-1}; 374 375 let Inst{3} = A{0}; 376 let Inst{2-0} = b{2-0}; 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{ 389 bits<5> rd; 390 bits<3> b; 391 392 let Inst{15-12} = 0b1111; 393 394 let Inst{11} = 0b1; 395 let Inst{10-9} = t; 396 let Inst{8} = rd{4}; 397 398 let Inst{7-4} = rd{3-0}; 399 400 let Inst{3} = 0; 401 let Inst{2-0} = b; 402} 403 404// Special encoding for the `DES K` instruction. 405// 406// <|1001|0100|KKKK|1011> 407// 408// KKKK = 4 bit immediate 409class FDES<dag outs, dag ins, string asmstr, list<dag> pattern> 410 : AVRInst16<outs, ins, asmstr, pattern> 411{ 412 bits<4> k; 413 414 let Inst{15-12} = 0b1001; 415 416 let Inst{11-8} = 0b0100; 417 418 let Inst{7-4} = k; 419 420 let Inst{3-0} = 0b1011; 421} 422 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//===----------------------------------------------------------------------===// 429class FBRsk<bit f, bits<3> s, dag outs, dag ins, string asmstr, list<dag> pattern> 430 : AVRInst16<outs, ins, asmstr, pattern> 431{ 432 bits<7> k; 433 434 let Inst{15-11} = 0b11110; 435 let Inst{10} = f; 436 let Inst{9-3} = k; 437 let Inst{2-0} = s; 438} 439 440//===----------------------------------------------------------------------===// 441// Special, opcode only instructions: <|opcode|> 442//===----------------------------------------------------------------------===// 443 444class F16<bits<16> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> 445 : AVRInst16<outs, ins, asmstr, pattern> 446{ 447 let Inst = opcode; 448} 449 450class F32<bits<32> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> 451 : AVRInst32<outs, ins, asmstr, pattern> 452{ 453 let Inst = opcode; 454} 455 456//===----------------------------------------------------------------------===// 457// Branching instructions with immediate12: <|110f|kkkk|kkkk|kkkk|> 458// f = secondary opcode = 1 bit 459// k = constant address = 12 bits 460//===----------------------------------------------------------------------===// 461class FBRk<bit f, dag outs, dag ins, string asmstr, list<dag> pattern> 462 : AVRInst16<outs, ins, asmstr, pattern> 463{ 464 bits<12> k; 465 466 let Inst{15-13} = 0b110; 467 let Inst{12} = f; 468 let Inst{11-0} = k; 469} 470 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//===----------------------------------------------------------------------===// 476class F32BRk<bits<3> f, dag outs, dag ins, string asmstr, list<dag> pattern> 477 : AVRInst32<outs, ins, asmstr, pattern> 478{ 479 bits<22> k; 480 481 let Inst{31-25} = 0b1001010; 482 let Inst{24-20} = k{21-17}; 483 let Inst{19-17} = f; 484 let Inst{16-0} = k{16-0}; 485} 486 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//===----------------------------------------------------------------------===// 494class F32DM<bit f, dag outs, dag ins, string asmstr, list<dag> pattern> 495 : AVRInst32<outs, ins, asmstr, pattern> 496{ 497 bits<5> rd; 498 bits<16> k; 499 500 let Inst{31-28} = 0b1001; 501 502 let Inst{27-26} = 0b00; 503 let Inst{25} = f; 504 let Inst{24} = rd{4}; 505 506 let Inst{23-20} = rd{3-0}; 507 508 let Inst{19-16} = 0b0000; 509 510 let Inst{15-0} = k; 511} 512 513// <|1001|0100|bfff|1000> 514class FS<bit b, dag outs, dag ins, string asmstr, list<dag> pattern> 515 : AVRInst16<outs, ins, asmstr, pattern> 516{ 517 bits<3> s; 518 519 let Inst{15-12} = 0b1001; 520 521 let Inst{11-8} = 0b0100; 522 523 let Inst{7} = b; 524 let Inst{6-4} = s; 525 526 let Inst{3-0} = 0b1000; 527} 528 529// Set/clr bit in status flag instructions/ 530// <BRBS|BRBC> s, k 531// --------------------- 532// <|1111|0fkk|kkkk|ksss> 533class FSK<bit f, dag outs, dag ins, string asmstr, list<dag> pattern> 534 : AVRInst16<outs, ins, asmstr, pattern> 535{ 536 bits<7> k; 537 bits<3> s; 538 539 let Inst{15-12} = 0b1111; 540 541 let Inst{11} = 0; 542 let Inst{10} = f; 543 let Inst{9-8} = k{6-5}; 544 545 let Inst{7-4} = k{4-1}; 546 547 let Inst{3} = k{0}; 548 let Inst{2-0} = s; 549} 550 551class ExtensionPseudo<dag outs, dag ins, string asmstr, list<dag> pattern> 552 : Pseudo<outs, ins, asmstr, pattern> 553{ 554 let Defs = [SREG]; 555} 556 557class StorePseudo<dag outs, dag ins, string asmstr, list<dag> pattern> 558 : Pseudo<outs, ins, asmstr, pattern> 559{ 560 let Defs = [SP]; 561} 562 563class SelectPseudo<dag outs, dag ins, string asmstr, list<dag> pattern> 564 : Pseudo<outs, ins, asmstr, pattern> 565{ 566 let usesCustomInserter = 1; 567 568 let Uses = [SREG]; 569} 570 571class ShiftPseudo<dag outs, dag ins, string asmstr, list<dag> pattern> 572 : Pseudo<outs, ins, asmstr, pattern> 573{ 574 let usesCustomInserter = 1; 575 576 let Defs = [SREG]; 577} 578 579