1//===- LanaiInstrFormats.td - Lanai 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 9class InstLanai<dag outs, dag ins, string asmstr, list<dag> pattern> 10 : Instruction { 11 field bits<32> Inst; 12 field bits<32> SoftFail = 0; 13 let Size = 4; 14 15 let Namespace = "Lanai"; 16 let DecoderNamespace = "Lanai"; 17 18 bits<4> Opcode; 19 let Inst{31 - 28} = Opcode; 20 21 dag OutOperandList = outs; 22 dag InOperandList = ins; 23 let AsmString = asmstr; 24 let Pattern = pattern; 25} 26 27//------------------------------------------------------------------------------ 28// Register Immediate (RI) 29//------------------------------------------------------------------------------ 30// Encoding: 31// ----------------------------------------------------------------- 32// |0.A.A.A| . . . . | . . . . |F.H| . . . . . . . . . . . . . . . | 33// ----------------------------------------------------------------- 34// opcode Rd Rs1 constant (16) 35// 36// Action: 37// Rd <- Rs1 op constant 38// 39// Except for shift instructions, `H' determines whether the constant 40// is in the high (1) or low (0) word. The other halfword is 0x0000, 41// except for the `AND' instruction (`AAA' = 100), for which the other 42// halfword is 0xFFFF, and shifts (`AAA' = 111), for which the constant is 43// sign extended. 44// 45// `F' determines whether the instruction modifies (1) or does not 46// modify (0) the program flags. 47// 48// `AAA' specifies the operation: `add' (000), `addc' (001), `sub' 49// (010), `subb' (011), `and' (100), `or' (101), `xor' (110), or `shift' 50// (111). For the shift, `H' specifies a logical (0) or arithmetic (1) 51// shift. The amount and direction of the shift are determined by the 52// sign extended constant interpreted as a two's complement number. The 53// shift operation is defined only for the range of: 54// 31 ... 0 -1 ... -31 55// \ / \ / 56// left right 57// shift shift 58// 59// If and only if the `F' bit is 1, RI instructions modify the 60// condition bits, `Z' (Zero), `N' (Negative), `V' (oVerflow), and `C' 61// (Carry), according to the result. If the flags are updated, they are 62// updated as follows: 63// `Z' 64// is set if the result is zero and cleared otherwise. 65// 66// `N' 67// is set to the most significant bit of the result. 68// 69// `V' 70// For arithmetic instructions (`add', `addc', `sub', `subb') `V' is 71// set if the sign (most significant) bits of the input operands are 72// the same but different from the sign bit of the result and cleared 73// otherwise. For other RI instructions, `V' is cleared. 74// 75// `C' 76// For arithmetic instructions, `C' is set/cleared if there is/is_not 77// a carry generated out of the most significant when performing the 78// twos-complement addition (`sub(a,b) == a + ~b + 1', `subb(a,b) == 79// a + ~b + `C''). For left shifts, `C' is set to the least 80// significant bit discarded by the shift operation. For all other 81// operations, `C' is cleared. 82// 83// A Jump is accomplished by `Rd' being `pc', and it has one shadow. 84// 85// The all-0s word is the instruction `R0 <- R0 + 0', which is a no-op. 86class InstRI<bits<3> op, dag outs, dag ins, string asmstr, 87 list<dag> pattern> 88 : InstLanai<outs, ins, asmstr, pattern>, Sched<[WriteALU]> { 89 let Itinerary = IIC_ALU; 90 bits<5> Rd; 91 bits<5> Rs1; 92 bit F; 93 bit H; 94 bits<16> imm16; 95 96 let Opcode{3} = 0; 97 let Opcode{2 - 0} = op; 98 let Inst{27 - 23} = Rd; 99 let Inst{22 - 18} = Rs1; 100 let Inst{17} = F; 101 let Inst{16} = H; 102 let Inst{15 - 0} = imm16; 103} 104 105//------------------------------------------------------------------------------ 106// Register Register (RR) 107//------------------------------------------------------------------------------ 108// Encoding: 109// ----------------------------------------------------------------- 110// |1.1.0.0| . . . . | . . . . |F.I| . . . . |B.B.B|J.J.J.J.J|D.D.D| 111// ----------------------------------------------------------------- 112// opcode Rd Rs1 Rs2 \ operation / 113// 114// Action: 115// `Rd <- Rs1 op Rs2' iff condition DDDI is true. 116// 117// `DDDI' is as described for the BR instruction. 118// 119// `F' determines whether the instruction modifies (1) or does not 120// modify (0) the program flags. 121// 122// `BBB' determines the operation: `add' (000), `addc' (001), `sub' 123// (010), `subb' (011), `and' (100), `or' (101), `xor' (110), or "special" 124// (111). The `JJJJJ' field is irrelevant except for special. 125// 126// `JJJJJ' determines which special operation is performed. `10---' 127// is a logical shift, and `11---' is an arithmetic shift, and ‘00000` is 128// the SELECT operation. The amount and direction of the shift are 129// determined by the contents of `Rs2' interpreted as a two's complement 130// number (in the same way as shifts in the Register-Immediate 131// instructions in *Note RI::). For the SELECT operation, Rd gets Rs1 if 132// condition DDDI is true, Rs2 otherwise. All other `JJJJJ' combinations 133// are reserved for instructions that may be defined in the future. 134// 135// If the `F' bit is 1, RR instructions modify the condition bits, `Z' 136// (Zero), `N' (Negative), `V' (oVerflow), and `C' (Carry), according to 137// the result. All RR instructions modify the `Z', `N', and `V' flags. 138// Except for arithmetic instructions (`add', `addc', `sub', `subb'), `V' 139// is cleared. Only arithmetic instructions and shifts modify `C'. Right 140// shifts clear C. 141// 142// DDDI is as described in the table for the BR instruction and only used for 143// the select instruction. 144// 145// A Jump is accomplished by `Rd' being `pc', and it has one shadow. 146class InstRR<bits<3> op, dag outs, dag ins, string asmstr, 147 list<dag> pattern> 148 : InstLanai<outs, ins, asmstr, pattern>, Sched<[WriteALU]> { 149 let Itinerary = IIC_ALU; 150 bits<5> Rd; 151 bits<5> Rs1; 152 bits<5> Rs2; 153 bit F; 154 bits<4> DDDI; 155 bits<5> JJJJJ; 156 157 let Opcode = 0b1100; 158 let Inst{27 - 23} = Rd; 159 let Inst{22 - 18} = Rs1; 160 let Inst{17} = F; 161 let Inst{16} = DDDI{0}; 162 let Inst{15 - 11} = Rs2; 163 let Inst{10 - 8} = op; 164 let Inst{7 - 3} = JJJJJ; 165 let Inst{2 - 0} = DDDI{3 - 1}; 166} 167 168//------------------------------------------------------------------------------ 169// Register Memory (RM) 170//------------------------------------------------------------------------------ 171// Encoding: 172// ----------------------------------------------------------------- 173// |1.0.0.S| . . . . | . . . . |P.Q| . . . . . . . . . . . . . . . | 174// ----------------------------------------------------------------- 175// opcode Rd Rs1 constant (16) 176// 177// Action: 178// Rd <- Memory(ea) (Load) see below for the 179// Memory(ea) <- Rd (Store) definition of ea. 180// 181// `S' determines whether the instruction is a Load (0) or a Store (1). 182// Loads appear in Rd one cycle after this instruction executes. If the 183// following instruction reads Rd, that instruction will be delayed by 1 184// clock cycle. 185// 186// PQ operation 187// -- ------------------------------------------ 188// 00 ea = Rs1 189// 01 ea = Rs1, Rs1 <- Rs1 + constant 190// 10 ea = Rs1 + constant 191// 11 ea = Rs1 + constant, Rs1 <- Rs1 + constant 192// 193// The constant is sign-extended for this instruction. 194// 195// A Jump is accomplished by `Rd' being `pc', and it has *two* delay slots. 196class InstRM<bit S, dag outs, dag ins, string asmstr, list<dag> pattern> 197 : InstLanai<outs, ins, asmstr, pattern> { 198 bits<5> Rd; 199 bits<5> Rs1; 200 bits<1> P; 201 bits<1> Q; 202 bits<16> imm16; 203 // Dummy variables to allow multiclass definition of RM and RRM 204 bits<2> YL; 205 bit E; 206 207 let Opcode{3 - 1} = 0b100; 208 let Opcode{0} = S; 209 let Inst{27 - 23} = Rd; 210 let Inst{22 - 18} = Rs1; 211 let Inst{17} = P; 212 let Inst{16} = Q; 213 let Inst{15 - 0} = imm16; 214 215 let PostEncoderMethod = "adjustPqBitsRmAndRrm"; 216} 217 218//------------------------------------------------------------------------------ 219// Register Register Memory (RRM) 220//------------------------------------------------------------------------------ 221// Encoding: 222// ----------------------------------------------------------------- 223// |1.0.1.S| . . . . | . . . . |P.Q| . . . . |B.B.B|J.J.J.J.J|Y.L.E| 224// ----------------------------------------------------------------- 225// opcode Rd Rs1 Rs2 \ operation / 226// 227// Action: 228// Rd <- Memory(ea) (Load) see below for the 229// Memory(ea) <- Rd (Store) definition of ea. 230// 231// The RRM instruction is identical to the RM (*note RM::.) instruction 232// except that: 233// 234// 1. `Rs1 + constant' is replaced with `Rs1 op Rs2', where `op' is 235// determined in the same way as in the RR instruction (*note RR::.) 236// and 237// 238// 2. part-word memory accesses are allowed as specified below. 239// 240// If `BBB' != 111 (i.e.: For all but shift operations): 241// If `YLE' = 01- => fuLl-word memory access 242// If `YLE' = 00- => half-word memory access 243// If `YLE' = 10- => bYte memory access 244// If `YLE' = --1 => loads are zEro extended 245// If `YLE' = --0 => loads are sign extended 246// 247// If `BBB' = 111 (For shift operations): 248// fullword memory access are performed. 249// 250// All part-word loads write the least significant part of the 251// destination register with the higher-order bits zero- or sign-extended. 252// All part-word stores store the least significant part-word of the 253// source register in the destination memory location. 254// 255// A Jump is accomplished by `Rd' being `pc', and it has *two* delay slots. 256class InstRRM<bit S, dag outs, dag ins, string asmstr, 257 list<dag> pattern> 258 : InstLanai<outs, ins, asmstr, pattern> { 259 bits<5> Rd; 260 bits<5> Rs1; 261 bits<5> Rs2; 262 bits<1> P; 263 bits<1> Q; 264 bits<3> BBB; 265 bits<5> JJJJJ; 266 bits<2> YL; 267 bit E; 268 269 let Opcode{3 - 1} = 0b101; 270 let Opcode{0} = S; 271 let Inst{27 - 23} = Rd; 272 let Inst{22 - 18} = Rs1; 273 let Inst{17} = P; 274 let Inst{16} = Q; 275 let Inst{15 - 11} = Rs2; 276 let Inst{10 - 8} = BBB; 277 let Inst{7 - 3} = JJJJJ; 278 let Inst{2 - 1} = YL; 279 let Inst{0} = E; 280 281 let PostEncoderMethod = "adjustPqBitsRmAndRrm"; 282} 283 284//------------------------------------------------------------------------------ 285// Conditional Branch (BR) 286//------------------------------------------------------------------------------ 287// Encoding: 288// ----------------------------------------------------------------- 289// |1.1.1.0|D.D.D| . . . . . . . . . . . . . . . . . . . . . . |0.I| 290// ----------------------------------------------------------------- 291// opcode condition constant (23) 292// 293// Action: 294// if (condition) { `pc' <- 4*(zero-extended constant) } 295// 296// The BR instruction is an absolute branch. 297// The constant is scaled as shown by its position in the instruction word such 298// that it specifies word-aligned addresses in the range [0,2^25-4] 299// 300// The `DDDI' field selects the condition that causes the branch to be taken. 301// (the `I' (Invert sense) bit inverts the sense of the condition): 302// 303// DDDI logical function [code, used for...] 304// ---- -------------------------------------- ------------------------ 305// 0000 1 [T, true] 306// 0001 0 [F, false] 307// 0010 C AND Z' [HI, high] 308// 0011 C' OR Z [LS, low or same] 309// 0100 C' [CC, carry cleared] 310// 0101 C [CS, carry set] 311// 0110 Z' [NE, not equal] 312// 0111 Z [EQ, equal] 313// 1000 V' [VC, oVerflow cleared] 314// 1001 V [VS, oVerflow set] 315// 1010 N' [PL, plus] 316// 1011 N [MI, minus] 317// 1100 (N AND V) OR (N' AND V') [GE, greater than or equal] 318// 1101 (N AND V') OR (N' AND V) [LT, less than] 319// 1110 (N AND V AND Z') OR (N' AND V' AND Z') [GT, greater than] 320// 1111 (Z) OR (N AND V') OR (N' AND V) [LE, less than or equal] 321// 322// If the branch is not taken, the BR instruction is a no-op. If the branch is 323// taken, the processor starts executing instructions at the branch target 324// address *after* the processor has executed one more instruction. That is, 325// the branch has one “branch delay slot”. Be very careful if you find yourself 326// wanting to put a branch in a branch delays slot! 327class InstBR<dag outs, dag ins, string asmstr, list<dag> pattern> 328 : InstLanai<outs, ins, asmstr, pattern> { 329 let Itinerary = IIC_ALU; 330 bits<25> addr; 331 bits<4> DDDI; 332 333 let Opcode = 0b1110; 334 let Inst{27 - 25} = DDDI{3 - 1}; 335 let Inst{24 - 0} = addr; 336 // These instructions overwrite the last two address bits (which are assumed 337 // and ensured to be 0). 338 let Inst{1} = 0; 339 let Inst{0} = DDDI{0}; 340} 341 342//------------------------------------------------------------------------------ 343// Conditional Branch Relative (BRR) 344//------------------------------------------------------------------------------ 345// Encoding: 346// ----------------------------------------------------------------- 347// |1.1.1.0|D.D.D|1|-| . . . . |-.-| . . . . . . . . . . . . . |1.I| 348// ----------------------------------------------------------------- 349// opcode condition Rs1 constant (14) 350// Action: 351// if (condition) { ‘pc’ <- Rs1 + 4*sign-extended constant) } 352// 353// BRR behaves like BR, except the branch target address is a 16-bit PC relative 354// offset. 355class InstBRR<dag outs, dag ins, string asmstr, list<dag> pattern> 356 : InstLanai<outs, ins, asmstr, pattern> { 357 bits<4> DDDI; 358 bits<5> Rs1; 359 bits<16> imm16; 360 361 let Opcode = 0b1110; 362 let Inst{27 - 25} = DDDI{3 - 1}; 363 let Inst{24} = 1; 364 let Inst{22 - 18} = Rs1; 365 let Inst{17 - 16} = 0; 366 let Inst{15 - 0} = imm16; 367 // Overwrite last two bits which have to be zero 368 let Inst{1} = 1; 369 let Inst{0} = DDDI{0}; 370 371 // Set don't cares to zero 372 let Inst{23} = 0; 373} 374 375//------------------------------------------------------------------------------ 376// Conditional Set (SCC) 377//------------------------------------------------------------------------------ 378// Encoding: 379// ----------------------------------------------------------------- 380// |1.1.1.0|D.D.D|0.-| . . . . |-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-|1.I| 381// ----------------------------------------------------------------- 382// opcode condition Rs1 383// 384// Action: 385// Rs1 <- logical function result 386// 387// SCC sets dst_reg to the boolean result of computing the logical function 388// specified by DDDI, as described in the table for the BR instruction. 389class InstSCC<dag outs, dag ins, string asmstr, 390 list<dag> pattern> 391 : InstLanai<outs, ins, asmstr, pattern> { 392 let Itinerary = IIC_ALU; 393 bits<5> Rs1; // dst_reg in documentation 394 bits<4> DDDI; 395 396 let Opcode = 0b1110; 397 let Inst{27 - 25} = DDDI{3 - 1}; 398 let Inst{24} = 0; 399 let Inst{22 - 18} = Rs1; 400 let Inst{1} = 1; 401 let Inst{0} = DDDI{0}; 402 403 // Set don't cares to zero 404 let Inst{23} = 0; 405 let Inst{17 - 2} = 0; 406} 407 408//------------------------------------------------------------------------------ 409// Special Load/Store (SLS) 410//------------------------------------------------------------------------------ 411// 412// Encoding: 413// ----------------------------------------------------------------- 414// |1.1.1.1| . . . . | . . . . |0.S| . . . . . . . . . . . . . . . | 415// ----------------------------------------------------------------- 416// opcode Rd addr 5msb's address 16 lsb's 417// 418// Action: 419// If S = 0 (LOAD): Rd <- Memory(address); 420// If S = 1 (STORE): Memory(address) <- Rd 421// 422// The timing is the same as for RM (*note RM::.) and RRM (*note 423// RRM::.) instructions. The two low-order bits of the 21-bit address are 424// ignored. The address is zero extended. Fullword memory accesses are 425// performed. 426class InstSLS<bit S, dag outs, dag ins, string asmstr, list<dag> pattern> 427 : InstLanai<outs, ins, asmstr, pattern> { 428 bits<5> Rd; 429 bits<5> msb; 430 bits<16> lsb; 431 432 let Opcode = 0b1111; 433 let Inst{27 - 23} = Rd; 434 let Inst{22 - 18} = msb; 435 let Inst{17} = 0; 436 let Inst{16} = S; 437 let Inst{15 - 0} = lsb; 438} 439 440//------------------------------------------------------------------------------ 441// Special Load Immediate (SLI) 442//------------------------------------------------------------------------------ 443// Encoding: 444// ----------------------------------------------------------------- 445// |1.1.1.1| . . . . | . . . . |1.0| . . . . . . . . . . . . . . . | 446// ----------------------------------------------------------------- 447// opcode Rd const 5msb's constant 16 lsb's 448// 449// Action: 450// Rd <- constant 451// 452// The 21-bit constant is zero-extended. The timing is the same as the 453// RM instruction (*note RM::.). 454class InstSLI<dag outs, dag ins, string asmstr, list<dag> pattern> 455 : InstLanai<outs, ins, asmstr, pattern> { 456 bits<5> Rd; 457 bits<5> msb; 458 bits<16> lsb; 459 460 let Opcode = 0b1111; 461 let Inst{27 - 23} = Rd; 462 let Inst{22 - 18} = msb; 463 let Inst{17} = 1; 464 let Inst{16} = 0; 465 let Inst{15 - 0} = lsb; 466} 467 468//------------------------------------------------------------------------------ 469// Special Part-Word Load/Store (SPLS) 470//------------------------------------------------------------------------------ 471// Encoding: 472// ----------------------------------------------------------------- 473// |1.1.1.1| . . . . | . . . . |1.1.0.Y.S.E.P.Q| . . . . . . . . . | 474// ----------------------------------------------------------------- 475// opcode Rd Rs1 constant (10) 476// 477// Action: 478// If `YS' = 11 (bYte Store): 479// Memory(ea) <- (least significant byte of Rr) 480// If `YS' = 01 (halfword Store): 481// Memory(ea) <- (least significant half-word of Rr) 482// If `YS' = 10 (bYte load): Rr <- Memory(ea) 483// If `YS' = 00 (halfword load): Rr <- Memory(ea) 484// [Note: here ea is determined as in the RM instruction. ] 485// If `SE' = 01 then the value is zEro extended 486// before being loaded into Rd. 487// If `SE' = 00 then the value is sign extended 488// before being loaded into Rd. 489// 490// `P' and `Q' are used to determine `ea' as in the RM instruction. The 491// constant is sign extended. The timing is the same as the RM and RRM 492// instructions. *Note RM:: and *Note RRM::. 493// 494// All part-word loads write the part-word into the least significant 495// part of the destination register, with the higher-order bits zero- or 496// sign-extended. All part-word stores store the least significant 497// part-word of the source register into the destination memory location. 498class InstSPLS<dag outs, dag ins, string asmstr, 499 list<dag> pattern> 500 : InstLanai<outs, ins, asmstr, pattern> { 501 bits<5> Rd; 502 bits<5> Rs1; 503 bits<5> msb; 504 bit Y; 505 bit S; 506 bit E; 507 bits<1> P; 508 bits<1> Q; 509 bits<10> imm10; 510 511 let Opcode = 0b1111; 512 let Inst{27 - 23} = Rd; 513 let Inst{22 - 18} = Rs1; 514 let Inst{17 - 15} = 0b110; 515 let Inst{14} = Y; 516 let Inst{13} = S; 517 let Inst{12} = E; 518 let Inst{11} = P; 519 let Inst{10} = Q; 520 let Inst{9 - 0} = imm10; 521 522 let PostEncoderMethod = "adjustPqBitsSpls"; 523} 524 525//------------------------------------------------------------------------------ 526// Special instructions (popc, leadz, trailz) 527//------------------------------------------------------------------------------ 528// Encoding: 529// ----------------------------------------------------------------- 530// |1.1.0.1| Rd | Rs1 |F.-| . . . . | . . | . . . . | OP | 531// ----------------------------------------------------------------- 532// opcode Rd Rs1 533// Action: 534// Rd <- Perform action encoded in OP on Rs1 535// OP is one of: 536// 0b001 POPC Population count; 537// 0b010 LEADZ Count number of leading zeros; 538// 0b011 TRAILZ Count number of trailing zeros; 539class InstSpecial<bits<3> op, dag outs, dag ins, string asmstr, 540 list<dag> pattern> : InstLanai<outs, ins, asmstr, 541 pattern>, Sched<[WriteALU]> { 542 let Itinerary = IIC_ALU; 543 bit F; 544 bits<5> Rd; 545 bits<5> Rs1; 546 547 let Opcode = 0b1101; 548 let Inst{27 - 23} = Rd; 549 let Inst{22 - 18} = Rs1; 550 let Inst{17} = F; 551 let Inst{16 - 3} = 0; 552 let Inst{2 - 0} = op; 553} 554 555// Pseudo instructions 556class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern> 557 : InstLanai<outs, ins, asmstr, pattern> { 558 let Inst{15 - 0} = 0; 559 let isPseudo = 1; 560} 561