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