1//===- XtensaInstrInfo.td - Target Description for Xtensa -*- tablegen -*--===// 2// 3// The LLVM Compiler Infrastructure 4// 5// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 6// See https://llvm.org/LICENSE.txt for license information. 7// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 8// 9//===----------------------------------------------------------------------===// 10// 11// This file describes the Xtensa instructions in TableGen format. 12// 13//===----------------------------------------------------------------------===// 14 15include "XtensaInstrFormats.td" 16include "XtensaOperands.td" 17 18//===----------------------------------------------------------------------===// 19// Arithmetic & Logical instructions 20//===----------------------------------------------------------------------===// 21 22class ArithLogic_RRR<bits<4> oper2, bits<4> oper1, string instrAsm, 23 SDPatternOperator opNode, bit isComm = 0> 24 : RRR_Inst<0x00, oper1, oper2, (outs AR:$r), (ins AR:$s, AR:$t), 25 instrAsm#"\t$r, $s, $t", 26 [(set AR:$r, (opNode AR:$s, AR:$t))]> { 27 let isCommutable = isComm; 28 let isReMaterializable = 0; 29} 30 31def ADD : ArithLogic_RRR<0x08, 0x00, "add", add, 1>; 32def SUB : ArithLogic_RRR<0x0C, 0x00, "sub", sub>; 33def AND : ArithLogic_RRR<0x01, 0x00, "and", and, 1>; 34def OR : ArithLogic_RRR<0x02, 0x00, "or", or, 1>; 35def XOR : ArithLogic_RRR<0x03, 0x00, "xor", xor, 1>; 36 37class ADDX<bits<4> oper, string instrAsm, list<dag> pattern> 38 : RRR_Inst<0x00, 0x00, oper, (outs AR:$r), (ins AR:$s, AR:$t), 39 instrAsm#"\t$r, $s, $t", pattern>; 40 41def ADDX2 : ADDX<0x09, "addx2", [(set AR:$r, (add AR:$t, (shl AR:$s, (i32 1))))]>; 42def ADDX4 : ADDX<0x0A, "addx4", [(set AR:$r, (add AR:$t, (shl AR:$s, (i32 2))))]>; 43def ADDX8 : ADDX<0x0B, "addx8", [(set AR:$r, (add AR:$t, (shl AR:$s, (i32 3))))]>; 44 45class SUBX<bits<4> oper, string instrAsm, list<dag> pattern> 46 : RRR_Inst<0x00, 0x00, oper, (outs AR:$r), (ins AR:$s, AR:$t), 47 instrAsm#"\t$r, $s, $t", pattern>; 48 49def SUBX2 : SUBX<0x0D, "subx2", [(set AR:$r, (sub (shl AR:$s, (i32 1)), AR:$t))]>; 50def SUBX4 : SUBX<0x0E, "subx4", [(set AR:$r, (sub (shl AR:$s, (i32 2)), AR:$t))]>; 51def SUBX8 : SUBX<0x0F, "subx8", [(set AR:$r, (sub (shl AR:$s, (i32 3)), AR:$t))]>; 52 53def ABS : RRR_Inst<0x00, 0x00, 0x06, (outs AR:$r), (ins AR:$t), 54 "abs\t$r, $t", []> { 55 let s = 0x1; 56} 57 58def ADDI : RRI8_Inst<0x02, (outs AR:$t), (ins AR:$s, imm8:$imm8), 59 "addi\t$t, $s, $imm8", 60 [(set AR:$t, (add AR:$s, imm8:$imm8))]> { 61 let r = 0x0C; 62} 63 64def ADDMI : RRI8_Inst<0x02, (outs AR:$t), (ins AR:$s, imm8_sh8:$imm_sh8), 65 "addmi\t$t, $s, $imm_sh8", 66 [(set AR:$t, (add AR:$s, imm8_sh8:$imm_sh8))]> { 67 bits<16> imm_sh8; 68 69 let r = 0x0D; 70 let imm8 = imm_sh8{15-8}; 71} 72 73def NEG : RRR_Inst<0x00, 0x00, 0x06, (outs AR:$r), (ins AR:$t), 74 "neg\t$r, $t", 75 [(set AR:$r, (ineg AR:$t))]> { 76 let s = 0x00; 77} 78 79//===----------------------------------------------------------------------===// 80// Move instructions 81//===----------------------------------------------------------------------===// 82def MOVI : RRI8_Inst<0x02, (outs AR:$t), (ins imm12m:$imm), 83 "movi\t$t, $imm", 84 [(set AR:$t, imm12m:$imm)]> { 85 bits<12> imm; 86 87 let imm8{7-0} = imm{7-0}; 88 let s{3-0} = imm{11-8}; 89 let r = 0xa; 90} 91 92def MOVEQZ : RRR_Inst<0x00, 0x03, 0x08, (outs AR:$r), (ins AR:$s, AR:$t), 93 "moveqz\t$r, $s, $t", []>; 94def MOVNEZ : RRR_Inst<0x00, 0x03, 0x09, (outs AR:$r), (ins AR:$s, AR:$t), 95 "movnez\t$r, $s, $t", []>; 96def MOVLTZ : RRR_Inst<0x00, 0x03, 0x0A, (outs AR:$r), (ins AR:$s, AR:$t), 97 "movltz\t$r, $s, $t", []>; 98def MOVGEZ : RRR_Inst<0x00, 0x03, 0x0B, (outs AR:$r), (ins AR:$s, AR:$t), 99 "movgez\t$r, $s, $t", []>; 100 101//===----------------------------------------------------------------------===// 102// Shift instructions 103//===----------------------------------------------------------------------===// 104 105let Uses = [SAR] in { 106 def SLL : RRR_Inst<0x00, 0x01, 0x0A, (outs AR:$r), (ins AR:$s), 107 "sll\t$r, $s", []> { 108 let t = 0x00; 109 } 110 111 def SRA : RRR_Inst<0x00, 0x01, 0x0B, (outs AR:$r), (ins AR:$t), 112 "sra\t$r, $t", []> { 113 let s = 0x00; 114 } 115 116 def SRC : RRR_Inst<0x00, 0x01, 0x08, (outs AR:$r), (ins AR:$s, AR:$t), 117 "src\t$r, $s, $t", []>; 118 119 def SRL : RRR_Inst<0x00, 0x01, 0x09, (outs AR:$r), (ins AR:$t), 120 "srl\t$r, $t", []> { 121 let s = 0x00; 122 } 123} 124 125let Defs = [SAR] in { 126 def SSL : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins AR:$s), 127 "ssl\t$s", []> { 128 let r = 0x01; 129 let t = 0x00; 130 } 131 132 def SSR : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins AR:$s), 133 "ssr\t$s", []> { 134 let r = 0x00; 135 let t = 0x00; 136 } 137} 138 139def EXTUI : RRR_Inst<0x00, 0x04, 0x00, (outs AR:$r), (ins AR:$t, uimm5:$imm1, imm1_16:$imm2), 140 "extui\t$r, $t, $imm1, $imm2", []> { 141 bits<5> imm1; 142 bits<4> imm2; 143 144 let s = imm1{3-0}; 145 let Inst{16} = imm1{4}; 146 let Inst{23-20} = imm2; 147} 148 149def SRAI : RRR_Inst<0x00, 0x01, 0x02, (outs AR:$r), (ins AR:$t, uimm5:$sa), 150 "srai\t$r, $t, $sa", 151 [(set AR:$r, (sra AR:$t, uimm5:$sa))]> { 152 bits<5> sa; 153 154 let Inst{20} = sa{4}; 155 let s = sa{3-0}; 156} 157 158def SRLI : RRR_Inst<0x00, 0x01, 0x04, (outs AR:$r), (ins AR:$t, uimm4:$sa), 159 "srli\t$r, $t, $sa", 160 [(set AR:$r, (srl AR:$t, uimm4:$sa))]> { 161 bits<4> sa; 162 163 let s = sa; 164} 165 166def SLLI : RRR_Inst<0x00, 0x01, 0x00, (outs AR:$r), (ins AR:$s, shimm1_31:$sa), 167 "slli\t$r, $s, $sa", 168 [(set AR:$r, (shl AR:$s, shimm1_31:$sa))]> { 169 bits<5> sa; 170 171 let Inst{20} = sa{4}; 172 let t = sa{3-0}; 173} 174 175def SSA8L : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins AR:$s), 176 "ssa8l\t$s", []> { 177 let r = 0x2; 178 let t = 0x0; 179} 180 181def SSAI : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins uimm5:$imm), 182 "ssai\t$imm", []> { 183 bits<5> imm; 184 185 let r = 0x04; 186 let s = imm{3-0}; 187 let t{3-1} = 0; 188 let t{0} = imm{4}; 189} 190 191//===----------------------------------------------------------------------===// 192// Load and store instructions 193//===----------------------------------------------------------------------===// 194 195// Load instructions 196let mayLoad = 1 in { 197 198 class Load_RRI8<bits<4> oper, string instrAsm, SDPatternOperator opNode, 199 ComplexPattern addrOp, Operand memOp> 200 : RRI8_Inst<0x02, (outs AR:$t), (ins memOp:$addr), 201 instrAsm#"\t$t, $addr", 202 [(set AR:$t, (opNode addrOp:$addr))]> { 203 bits<12> addr; 204 205 let r = oper; 206 let imm8{7-0} = addr{11-4}; 207 let s{3-0} = addr{3-0}; 208 } 209} 210 211def L8UI : Load_RRI8<0x00, "l8ui", zextloadi8, addr_ish1, mem8>; 212def L16SI : Load_RRI8<0x09, "l16si", sextloadi16, addr_ish2, mem16>; 213def L16UI : Load_RRI8<0x01, "l16ui", zextloadi16, addr_ish2, mem16>; 214def L32I : Load_RRI8<0x02, "l32i", load, addr_ish4, mem32>; 215 216// Store instructions 217let mayStore = 1 in { 218 class Store_II8<bits<4> oper, string instrAsm, SDPatternOperator opNode, 219 ComplexPattern addrOp, Operand memOp> 220 : RRI8_Inst<0x02, (outs), (ins AR:$t, memOp:$addr), 221 instrAsm#"\t$t, $addr", 222 [(opNode AR:$t, addrOp:$addr)]> { 223 bits<12> addr; 224 225 let r = oper; 226 let imm8{7-0} = addr{11-4}; 227 let s{3-0} = addr{3-0}; 228 } 229} 230 231def S8I : Store_II8<0x04, "s8i", truncstorei8, addr_ish1, mem8>; 232def S16I : Store_II8<0x05, "s16i", truncstorei16, addr_ish2, mem16>; 233def S32I : Store_II8<0x06, "s32i", store, addr_ish4, mem32>; 234 235def L32R : RI16_Inst<0x01, (outs AR:$t), (ins L32Rtarget:$label), 236 "l32r\t$t, $label", []> { 237 bits<16> label; 238 let imm16 = label; 239} 240 241//===----------------------------------------------------------------------===// 242// Conditional branch instructions 243//===----------------------------------------------------------------------===// 244let isBranch = 1, isTerminator = 1 in { 245 class Branch_RR<bits<4> oper, string instrAsm, CondCode CC> 246 : RRI8_Inst<0x07, (outs), 247 (ins AR:$s, AR:$t, brtarget:$target), 248 instrAsm#"\t$s, $t, $target", 249 [(brcc CC, AR:$s, AR:$t, bb:$target)]> { 250 bits<8> target; 251 252 let r = oper; 253 let imm8 = target; 254 } 255 256 class Branch_RI<bits<4> oper, string instrAsm, CondCode CC> 257 : RRI8_Inst<0x06, (outs), 258 (ins AR:$s, b4const:$imm, brtarget:$target), 259 instrAsm#"\t$s, $imm, $target", 260 [(brcc CC, AR:$s, b4const:$imm, bb:$target)]> { 261 bits<4> imm; 262 bits<8> target; 263 264 let t = oper; 265 let r = imm; 266 let imm8 = target; 267 } 268 269 class Branch_RIU<bits<4> oper, string instrAsm, CondCode CC> 270 : RRI8_Inst<0x06, (outs), 271 (ins AR:$s, b4constu:$imm, brtarget:$target), 272 instrAsm#"\t$s, $imm, $target", 273 [(brcc CC, AR:$s, b4constu:$imm, bb:$target)]> { 274 bits<4> imm; 275 bits<8> target; 276 277 let t = oper; 278 let r = imm; 279 let imm8 = target; 280 } 281 282 class Branch_RZ<bits<2> n, bits<2> m, string instrAsm, CondCode CC> 283 : BRI12_Inst<0x06, n, m, (outs), 284 (ins AR:$s, brtarget:$target), 285 instrAsm#"\t$s, $target", 286 [(brcc CC, AR:$s, (i32 0), bb:$target)]> { 287 bits<12> target; 288 289 let imm12 = target; 290 } 291} 292 293def BEQ : Branch_RR<0x01, "beq", SETEQ>; 294def BNE : Branch_RR<0x09, "bne", SETNE>; 295def BGE : Branch_RR<0x0A, "bge", SETGE>; 296def BLT : Branch_RR<0x02, "blt", SETLT>; 297def BGEU : Branch_RR<0x0B, "bgeu", SETUGE>; 298def BLTU : Branch_RR<0x03, "bltu", SETULT>; 299 300def BEQI : Branch_RI<0x02, "beqi", SETEQ>; 301def BNEI : Branch_RI<0x06, "bnei", SETNE>; 302def BGEI : Branch_RI<0x0E, "bgei", SETGE>; 303def BLTI : Branch_RI<0x0A, "blti", SETLT>; 304def BGEUI : Branch_RIU<0x0F, "bgeui", SETUGE>; 305def BLTUI : Branch_RIU<0x0B, "bltui", SETULT>; 306 307def BEQZ : Branch_RZ<0x01, 0x00, "beqz", SETEQ>; 308def BNEZ : Branch_RZ<0x01, 0x01, "bnez", SETNE>; 309def BGEZ : Branch_RZ<0x01, 0x03, "bgez", SETGE>; 310def BLTZ : Branch_RZ<0x01, 0x02, "bltz", SETLT>; 311 312def BALL : RRI8_Inst<0x07, (outs), 313 (ins AR:$s, AR:$t, brtarget:$target), 314 "ball\t$s, $t, $target", []> { 315 bits<8> target; 316 317 let r = 0x04; 318 let imm8 = target; 319} 320 321def BANY : RRI8_Inst<0x07, (outs), 322 (ins AR:$s, AR:$t, brtarget:$target), 323 "bany\t$s, $t, $target", []> { 324 bits<8> target; 325 326 let r = 0x08; 327 let imm8 = target; 328} 329 330def BBC : RRI8_Inst<0x07, (outs), 331 (ins AR:$s, AR:$t, brtarget:$target), 332 "bbc\t$s, $t, $target", []> { 333 bits<8> target; 334 335 let r = 0x05; 336 let imm8 = target; 337} 338 339def BBS : RRI8_Inst<0x07, (outs), 340 (ins AR:$s, AR:$t, brtarget:$target), 341 "bbs\t$s, $t, $target", []> { 342 bits<8> target; 343 344 let r = 0x0d; 345 let imm8 = target; 346} 347 348def BNALL : RRI8_Inst<0x07, (outs), 349 (ins AR:$s, AR:$t, brtarget:$target), 350 "bnall\t$s, $t, $target", []> { 351 bits<8> target; 352 353 let r = 0x0c; 354 let imm8 = target; 355} 356 357def BNONE : RRI8_Inst<0x07, (outs), 358 (ins AR:$s, AR:$t, brtarget:$target), 359 "bnone\t$s, $t, $target", []> { 360 bits<8> target; 361 362 let r = 0x00; 363 let imm8 = target; 364} 365 366def BBCI : RRI8_Inst<0x07, (outs), 367 (ins AR:$s, uimm5:$imm, brtarget:$target), 368 "bbci\t$s, $imm, $target", []> { 369 bits<8> target; 370 bits<5> imm; 371 372 let r{3-1} = 0x3; 373 let r{0} = imm{4}; 374 let t{3-0} = imm{3-0}; 375 let imm8 = target; 376} 377 378def BBSI : RRI8_Inst<0x07, (outs), 379 (ins AR:$s, uimm5:$imm, brtarget:$target), 380 "bbsi\t$s, $imm, $target", []> { 381 bits<8> target; 382 bits<5> imm; 383 384 let r{3-1} = 0x7; 385 let r{0} = imm{4}; 386 let t{3-0} = imm{3-0}; 387 let imm8 = target; 388} 389 390//===----------------------------------------------------------------------===// 391// Call and jump instructions 392//===----------------------------------------------------------------------===// 393 394let isBranch = 1, isTerminator = 1, isBarrier = 1 in { 395 def J : CALL_Inst<0x06, (outs), (ins jumptarget:$offset), 396 "j\t$offset", 397 [(br bb:$offset)]> { 398 let n = 0x0; 399 } 400 401 def JX : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins AR:$s), 402 "jx\t$s", 403 [(brind AR:$s)]> { 404 let m = 0x2; 405 let n = 0x2; 406 let r = 0; 407 let isIndirectBranch = 1; 408 } 409} 410 411let isCall = 1, Defs = [A0] in { 412 def CALL0 : CALL_Inst<0x05, (outs), (ins pcrel32call:$offset), 413 "call0\t$offset", []> { 414 let n = 0; 415 } 416 417 def CALLX0 : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins AR:$s), 418 "callx0\t$s", []> { 419 let m = 0x3; 420 let n = 0x0; 421 let r = 0; 422 } 423} 424 425let isReturn = 1, isTerminator = 1, 426 isBarrier = 1, Uses = [A0] in { 427 428 def RET : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins), 429 "ret", []> { 430 let m = 0x2; 431 let n = 0x0; 432 let s = 0; 433 let r = 0; 434 } 435} 436 437//===----------------------------------------------------------------------===// 438// Mem barrier instructions 439//===----------------------------------------------------------------------===// 440 441def MEMW : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 442 "memw", []> { 443 let r = 0x2; 444 let t = 0x0c; 445 let s = 0x0; 446} 447 448def EXTW : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 449 "extw", []> { 450 let r = 0x2; 451 let s = 0x0; 452 let t = 0xd; 453 let hasSideEffects = 1; 454} 455 456//===----------------------------------------------------------------------===// 457// Processor control instructions 458//===----------------------------------------------------------------------===// 459 460def DSYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 461 "dsync", []> { 462 let r = 0x2; 463 let s = 0x0; 464 let t = 0x3; 465 let hasSideEffects = 1; 466} 467 468def ISYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 469 "isync", []> { 470 let r = 0x2; 471 let s = 0x0; 472 let t = 0x0; 473 let hasSideEffects = 1; 474} 475 476def RSYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 477 "rsync", []> { 478 let r = 0x2; 479 let s = 0x0; 480 let t = 0x1; 481 let hasSideEffects = 1; 482} 483 484def ESYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 485 "esync", []> { 486 let r = 0x2; 487 let s = 0x0; 488 let t = 0x2; 489 let hasSideEffects = 1; 490} 491 492def NOP : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 493 "nop", []> { 494 let r = 0x02; 495 let s = 0x00; 496 let t = 0x0f; 497} 498 499def WSR : RSR_Inst<0x00, 0x03, 0x01, (outs SR:$sr), (ins AR:$t), 500 "wsr\t$t, $sr", []>; 501 502def RSR : RSR_Inst<0x00, 0x03, 0x00, (outs AR:$t), (ins SR:$sr), 503 "rsr\t$t, $sr", []>; 504 505def XSR : RSR_Inst<0x00, 0x01, 0x06, (outs AR:$ard, SR:$srd), (ins AR:$t, SR:$sr), 506 "xsr\t$t, $sr", []> { 507 let Constraints = "$ard = $t, $srd = $sr"; 508} 509