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