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" 17include "XtensaOperators.td" 18 19//===----------------------------------------------------------------------===// 20// Arithmetic & Logical instructions 21//===----------------------------------------------------------------------===// 22 23class ArithLogic_RRR<bits<4> oper2, bits<4> oper1, string instrAsm, 24 SDPatternOperator opNode, bit isComm = 0> 25 : RRR_Inst<0x00, oper1, oper2, (outs AR:$r), (ins AR:$s, AR:$t), 26 instrAsm#"\t$r, $s, $t", 27 [(set AR:$r, (opNode AR:$s, AR:$t))]> { 28 let isCommutable = isComm; 29 let isReMaterializable = 0; 30} 31 32def ADD : ArithLogic_RRR<0x08, 0x00, "add", add, 1>; 33def SUB : ArithLogic_RRR<0x0C, 0x00, "sub", sub>; 34def AND : ArithLogic_RRR<0x01, 0x00, "and", and, 1>; 35def OR : ArithLogic_RRR<0x02, 0x00, "or", or, 1>; 36def XOR : ArithLogic_RRR<0x03, 0x00, "xor", xor, 1>; 37 38class ADDX<bits<4> oper, string instrAsm, list<dag> pattern> 39 : RRR_Inst<0x00, 0x00, oper, (outs AR:$r), (ins AR:$s, AR:$t), 40 instrAsm#"\t$r, $s, $t", pattern>; 41 42def ADDX2 : ADDX<0x09, "addx2", [(set AR:$r, (add AR:$t, (shl AR:$s, (i32 1))))]>; 43def ADDX4 : ADDX<0x0A, "addx4", [(set AR:$r, (add AR:$t, (shl AR:$s, (i32 2))))]>; 44def ADDX8 : ADDX<0x0B, "addx8", [(set AR:$r, (add AR:$t, (shl AR:$s, (i32 3))))]>; 45 46class SUBX<bits<4> oper, string instrAsm, list<dag> pattern> 47 : RRR_Inst<0x00, 0x00, oper, (outs AR:$r), (ins AR:$s, AR:$t), 48 instrAsm#"\t$r, $s, $t", pattern>; 49 50def SUBX2 : SUBX<0x0D, "subx2", [(set AR:$r, (sub (shl AR:$s, (i32 1)), AR:$t))]>; 51def SUBX4 : SUBX<0x0E, "subx4", [(set AR:$r, (sub (shl AR:$s, (i32 2)), AR:$t))]>; 52def SUBX8 : SUBX<0x0F, "subx8", [(set AR:$r, (sub (shl AR:$s, (i32 3)), AR:$t))]>; 53 54def ABS : RRR_Inst<0x00, 0x00, 0x06, (outs AR:$r), (ins AR:$t), 55 "abs\t$r, $t", []> { 56 let s = 0x1; 57} 58 59def ADDI : RRI8_Inst<0x02, (outs AR:$t), (ins AR:$s, imm8:$imm8), 60 "addi\t$t, $s, $imm8", 61 [(set AR:$t, (add AR:$s, imm8:$imm8))]> { 62 let r = 0x0C; 63} 64 65def ADDMI : RRI8_Inst<0x02, (outs AR:$t), (ins AR:$s, imm8_sh8:$imm_sh8), 66 "addmi\t$t, $s, $imm_sh8", 67 [(set AR:$t, (add AR:$s, imm8_sh8:$imm_sh8))]> { 68 bits<16> imm_sh8; 69 70 let r = 0x0D; 71 let imm8 = imm_sh8{15-8}; 72} 73 74def NEG : RRR_Inst<0x00, 0x00, 0x06, (outs AR:$r), (ins AR:$t), 75 "neg\t$r, $t", 76 [(set AR:$r, (ineg AR:$t))]> { 77 let s = 0x00; 78} 79 80//===----------------------------------------------------------------------===// 81// Move instructions 82//===----------------------------------------------------------------------===// 83def MOVI : RRI8_Inst<0x02, (outs AR:$t), (ins imm12m:$imm), 84 "movi\t$t, $imm", 85 [(set AR:$t, imm12m:$imm)]> { 86 bits<12> imm; 87 88 let imm8{7-0} = imm{7-0}; 89 let s{3-0} = imm{11-8}; 90 let r = 0xa; 91} 92 93def MOVEQZ : RRR_Inst<0x00, 0x03, 0x08, (outs AR:$r), (ins AR:$s, AR:$t), 94 "moveqz\t$r, $s, $t", []>; 95def MOVNEZ : RRR_Inst<0x00, 0x03, 0x09, (outs AR:$r), (ins AR:$s, AR:$t), 96 "movnez\t$r, $s, $t", []>; 97def MOVLTZ : RRR_Inst<0x00, 0x03, 0x0A, (outs AR:$r), (ins AR:$s, AR:$t), 98 "movltz\t$r, $s, $t", []>; 99def MOVGEZ : RRR_Inst<0x00, 0x03, 0x0B, (outs AR:$r), (ins AR:$s, AR:$t), 100 "movgez\t$r, $s, $t", []>; 101 102//===----------------------------------------------------------------------===// 103// Shift instructions 104//===----------------------------------------------------------------------===// 105 106let Uses = [SAR] in { 107 def SLL : RRR_Inst<0x00, 0x01, 0x0A, (outs AR:$r), (ins AR:$s), 108 "sll\t$r, $s", []> { 109 let t = 0x00; 110 } 111 112 def SRA : RRR_Inst<0x00, 0x01, 0x0B, (outs AR:$r), (ins AR:$t), 113 "sra\t$r, $t", []> { 114 let s = 0x00; 115 } 116 117 def SRC : RRR_Inst<0x00, 0x01, 0x08, (outs AR:$r), (ins AR:$s, AR:$t), 118 "src\t$r, $s, $t", []>; 119 120 def SRL : RRR_Inst<0x00, 0x01, 0x09, (outs AR:$r), (ins AR:$t), 121 "srl\t$r, $t", []> { 122 let s = 0x00; 123 } 124} 125 126let Defs = [SAR] in { 127 def SSL : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins AR:$s), 128 "ssl\t$s", []> { 129 let r = 0x01; 130 let t = 0x00; 131 } 132 133 def SSR : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins AR:$s), 134 "ssr\t$s", []> { 135 let r = 0x00; 136 let t = 0x00; 137 } 138} 139 140def EXTUI : RRR_Inst<0x00, 0x04, 0x00, (outs AR:$r), (ins AR:$t, uimm5:$imm1, imm1_16:$imm2), 141 "extui\t$r, $t, $imm1, $imm2", 142 [(set AR:$r, (Xtensa_extui AR:$t, uimm5:$imm1, imm1_16:$imm2))]> { 143 bits<5> imm1; 144 bits<4> imm2; 145 146 let s = imm1{3-0}; 147 let Inst{16} = imm1{4}; 148 let Inst{23-20} = imm2; 149} 150 151def SRAI : RRR_Inst<0x00, 0x01, 0x02, (outs AR:$r), (ins AR:$t, uimm5:$sa), 152 "srai\t$r, $t, $sa", 153 [(set AR:$r, (sra AR:$t, uimm5:$sa))]> { 154 bits<5> sa; 155 156 let Inst{20} = sa{4}; 157 let s = sa{3-0}; 158} 159 160def SRLI : RRR_Inst<0x00, 0x01, 0x04, (outs AR:$r), (ins AR:$t, uimm4:$sa), 161 "srli\t$r, $t, $sa", 162 [(set AR:$r, (srl AR:$t, uimm4:$sa))]> { 163 bits<4> sa; 164 165 let s = sa; 166} 167 168def SLLI : RRR_Inst<0x00, 0x01, 0x00, (outs AR:$r), (ins AR:$s, shimm1_31:$sa), 169 "slli\t$r, $s, $sa", 170 [(set AR:$r, (shl AR:$s, shimm1_31:$sa))]> { 171 bits<5> sa; 172 173 let Inst{20} = sa{4}; 174 let t = sa{3-0}; 175} 176 177def SSA8L : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins AR:$s), 178 "ssa8l\t$s", []> { 179 let r = 0x2; 180 let t = 0x0; 181} 182 183def SSAI : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins uimm5:$imm), 184 "ssai\t$imm", []> { 185 bits<5> imm; 186 187 let r = 0x04; 188 let s = imm{3-0}; 189 let t{3-1} = 0; 190 let t{0} = imm{4}; 191} 192 193//===----------------------------------------------------------------------===// 194// Load and store instructions 195//===----------------------------------------------------------------------===// 196 197// Load instructions 198let mayLoad = 1, usesCustomInserter = 1 in { 199 200 class Load_RRI8<bits<4> oper, string instrAsm, SDPatternOperator opNode, 201 ComplexPattern addrOp, Operand memOp> 202 : RRI8_Inst<0x02, (outs AR:$t), (ins memOp:$addr), 203 instrAsm#"\t$t, $addr", 204 [(set AR:$t, (opNode addrOp:$addr))]> { 205 bits<12> addr; 206 207 let r = oper; 208 let imm8{7-0} = addr{11-4}; 209 let s{3-0} = addr{3-0}; 210 } 211} 212 213def L8UI : Load_RRI8<0x00, "l8ui", zextloadi8, addr_ish1, mem8>; 214def L16SI : Load_RRI8<0x09, "l16si", sextloadi16, addr_ish2, mem16>; 215def L16UI : Load_RRI8<0x01, "l16ui", zextloadi16, addr_ish2, mem16>; 216def L32I : Load_RRI8<0x02, "l32i", load, addr_ish4, mem32>; 217 218// Store instructions 219let mayStore = 1, usesCustomInserter = 1 in { 220 class Store_II8<bits<4> oper, string instrAsm, SDPatternOperator opNode, 221 ComplexPattern addrOp, Operand memOp> 222 : RRI8_Inst<0x02, (outs), (ins AR:$t, memOp:$addr), 223 instrAsm#"\t$t, $addr", 224 [(opNode AR:$t, addrOp:$addr)]> { 225 bits<12> addr; 226 227 let r = oper; 228 let imm8{7-0} = addr{11-4}; 229 let s{3-0} = addr{3-0}; 230 } 231} 232 233def S8I : Store_II8<0x04, "s8i", truncstorei8, addr_ish1, mem8>; 234def S16I : Store_II8<0x05, "s16i", truncstorei16, addr_ish2, mem16>; 235def S32I : Store_II8<0x06, "s32i", store, addr_ish4, mem32>; 236 237let AddedComplexity = 10 in 238def L32R : RI16_Inst<0x01, (outs AR:$t), (ins L32Rtarget:$label), 239 "l32r\t$t, $label", [(set AR:$t, (load (Xtensa_pcrel_wrapper tconstpool:$label)))]> { 240 bits<16> label; 241 let imm16 = label; 242} 243 244// FrameIndexes are legalized when they are operands from load/store 245// instructions. The same not happens for stack address copies, so an 246// add op with mem ComplexPattern is used and the stack address copy 247// can be matched. 248// Setting of attribute mayLoad is trick to process instruction operands 249// in function XtensaRegisterInfo::eliminateFI 250 251let isCodeGenOnly = 1, mayLoad = 1 in { 252 253 def LEA_ADD : RRI8_Inst<0x02, (outs AR:$t), (ins mem32:$addr), 254 "addi\t$t, $addr", 255 [(set AR:$t, addr_ish4:$addr)]> { 256 bits<12> addr; 257 258 let r = 0x0C; 259 let imm8{7-0} = addr{11-4}; 260 let s{3-0} = addr{3-0}; 261 } 262} 263 264//extending loads 265def : Pat<(i32 (extloadi1 addr_ish1:$addr)), (L8UI addr_ish1:$addr)>; 266def : Pat<(i32 (extloadi8 addr_ish1:$addr)), (L8UI addr_ish1:$addr)>; 267def : Pat<(i32 (extloadi16 addr_ish2:$addr)), (L16UI addr_ish2:$addr)>; 268 269//===----------------------------------------------------------------------===// 270// Conditional branch instructions 271//===----------------------------------------------------------------------===// 272let isBranch = 1, isTerminator = 1 in { 273 class Branch_RR<bits<4> oper, string instrAsm, CondCode CC> 274 : RRI8_Inst<0x07, (outs), 275 (ins AR:$s, AR:$t, brtarget:$target), 276 instrAsm#"\t$s, $t, $target", 277 [(brcc CC, AR:$s, AR:$t, bb:$target)]> { 278 bits<8> target; 279 280 let r = oper; 281 let imm8 = target; 282 } 283 284 class Branch_RI<bits<4> oper, string instrAsm, CondCode CC> 285 : RRI8_Inst<0x06, (outs), 286 (ins AR:$s, b4const:$imm, brtarget:$target), 287 instrAsm#"\t$s, $imm, $target", 288 [(brcc CC, AR:$s, b4const:$imm, bb:$target)]> { 289 bits<4> imm; 290 bits<8> target; 291 292 let t = oper; 293 let r = imm; 294 let imm8 = target; 295 } 296 297 class Branch_RIU<bits<4> oper, string instrAsm, CondCode CC> 298 : RRI8_Inst<0x06, (outs), 299 (ins AR:$s, b4constu:$imm, brtarget:$target), 300 instrAsm#"\t$s, $imm, $target", 301 [(brcc CC, AR:$s, b4constu:$imm, bb:$target)]> { 302 bits<4> imm; 303 bits<8> target; 304 305 let t = oper; 306 let r = imm; 307 let imm8 = target; 308 } 309 310 class Branch_RZ<bits<2> n, bits<2> m, string instrAsm, CondCode CC> 311 : BRI12_Inst<0x06, n, m, (outs), 312 (ins AR:$s, brtarget:$target), 313 instrAsm#"\t$s, $target", 314 [(brcc CC, AR:$s, (i32 0), bb:$target)]> { 315 bits<12> target; 316 317 let imm12 = target; 318 } 319} 320 321def BEQ : Branch_RR<0x01, "beq", SETEQ>; 322def BNE : Branch_RR<0x09, "bne", SETNE>; 323def BGE : Branch_RR<0x0A, "bge", SETGE>; 324def BLT : Branch_RR<0x02, "blt", SETLT>; 325def BGEU : Branch_RR<0x0B, "bgeu", SETUGE>; 326def BLTU : Branch_RR<0x03, "bltu", SETULT>; 327 328def BEQI : Branch_RI<0x02, "beqi", SETEQ>; 329def BNEI : Branch_RI<0x06, "bnei", SETNE>; 330def BGEI : Branch_RI<0x0E, "bgei", SETGE>; 331def BLTI : Branch_RI<0x0A, "blti", SETLT>; 332def BGEUI : Branch_RIU<0x0F, "bgeui", SETUGE>; 333def BLTUI : Branch_RIU<0x0B, "bltui", SETULT>; 334 335def BEQZ : Branch_RZ<0x01, 0x00, "beqz", SETEQ>; 336def BNEZ : Branch_RZ<0x01, 0x01, "bnez", SETNE>; 337def BGEZ : Branch_RZ<0x01, 0x03, "bgez", SETGE>; 338def BLTZ : Branch_RZ<0x01, 0x02, "bltz", SETLT>; 339 340def BALL : RRI8_Inst<0x07, (outs), 341 (ins AR:$s, AR:$t, brtarget:$target), 342 "ball\t$s, $t, $target", []> { 343 bits<8> target; 344 345 let r = 0x04; 346 let imm8 = target; 347} 348 349def BANY : RRI8_Inst<0x07, (outs), 350 (ins AR:$s, AR:$t, brtarget:$target), 351 "bany\t$s, $t, $target", []> { 352 bits<8> target; 353 354 let r = 0x08; 355 let imm8 = target; 356} 357 358def BBC : RRI8_Inst<0x07, (outs), 359 (ins AR:$s, AR:$t, brtarget:$target), 360 "bbc\t$s, $t, $target", []> { 361 bits<8> target; 362 363 let r = 0x05; 364 let imm8 = target; 365} 366 367def BBS : RRI8_Inst<0x07, (outs), 368 (ins AR:$s, AR:$t, brtarget:$target), 369 "bbs\t$s, $t, $target", []> { 370 bits<8> target; 371 372 let r = 0x0d; 373 let imm8 = target; 374} 375 376def BNALL : RRI8_Inst<0x07, (outs), 377 (ins AR:$s, AR:$t, brtarget:$target), 378 "bnall\t$s, $t, $target", []> { 379 bits<8> target; 380 381 let r = 0x0c; 382 let imm8 = target; 383} 384 385def BNONE : RRI8_Inst<0x07, (outs), 386 (ins AR:$s, AR:$t, brtarget:$target), 387 "bnone\t$s, $t, $target", []> { 388 bits<8> target; 389 390 let r = 0x00; 391 let imm8 = target; 392} 393 394def BBCI : RRI8_Inst<0x07, (outs), 395 (ins AR:$s, uimm5:$imm, brtarget:$target), 396 "bbci\t$s, $imm, $target", []> { 397 bits<8> target; 398 bits<5> imm; 399 400 let r{3-1} = 0x3; 401 let r{0} = imm{4}; 402 let t{3-0} = imm{3-0}; 403 let imm8 = target; 404} 405 406def BBSI : RRI8_Inst<0x07, (outs), 407 (ins AR:$s, uimm5:$imm, brtarget:$target), 408 "bbsi\t$s, $imm, $target", []> { 409 bits<8> target; 410 bits<5> imm; 411 412 let r{3-1} = 0x7; 413 let r{0} = imm{4}; 414 let t{3-0} = imm{3-0}; 415 let imm8 = target; 416} 417 418def : Pat<(brcond AR:$s, bb:$target), (BNEZ AR:$s, bb:$target)>; 419//===----------------------------------------------------------------------===// 420// Call and jump instructions 421//===----------------------------------------------------------------------===// 422 423let isBranch = 1, isTerminator = 1, isBarrier = 1 in { 424 def J : CALL_Inst<0x06, (outs), (ins jumptarget:$offset), 425 "j\t$offset", 426 [(br bb:$offset)]> { 427 let n = 0x0; 428 } 429 430 def JX : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins AR:$s), 431 "jx\t$s", 432 [(brind AR:$s)]> { 433 let m = 0x2; 434 let n = 0x2; 435 let r = 0; 436 let isIndirectBranch = 1; 437 } 438} 439 440let isCall = 1, Defs = [A0] in { 441 def CALL0 : CALL_Inst<0x05, (outs), (ins pcrel32call:$offset), 442 "call0\t$offset", []> { 443 let n = 0; 444 } 445 446 def CALLX0 : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins AR:$s), 447 "callx0\t$s", []> { 448 let m = 0x3; 449 let n = 0x0; 450 let r = 0; 451 } 452} 453 454let isReturn = 1, isTerminator = 1, 455 isBarrier = 1, Uses = [A0] in { 456 457 def RET : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins), 458 "ret", [(Xtensa_ret)]> { 459 let m = 0x2; 460 let n = 0x0; 461 let s = 0; 462 let r = 0; 463 } 464} 465 466// Call patterns 467def : Pat<(Xtensa_call (i32 tglobaladdr:$dst)), 468 (CALL0 tglobaladdr:$dst)>; 469def : Pat<(Xtensa_call (i32 texternalsym:$dst)), 470 (CALL0 texternalsym:$dst)>; 471def : Pat<(Xtensa_call AR:$dst), 472 (CALLX0 AR:$dst)>; 473 474let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1, Size = 3 in { 475 def BR_JT: Pseudo<(outs), (ins AR:$s, i32imm:$jt), 476 "!br_jt_p, $s, $jt", 477 [(Xtensa_brjt AR:$s, tjumptable:$jt)]>; 478} 479 480//===----------------------------------------------------------------------===// 481// Mem barrier instructions 482//===----------------------------------------------------------------------===// 483 484def MEMW : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 485 "memw", []> { 486 let r = 0x2; 487 let t = 0x0c; 488 let s = 0x0; 489} 490 491def EXTW : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 492 "extw", []> { 493 let r = 0x2; 494 let s = 0x0; 495 let t = 0xd; 496 let hasSideEffects = 1; 497} 498 499//===----------------------------------------------------------------------===// 500// Illegal instructions 501//===----------------------------------------------------------------------===// 502 503def ILL : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins), 504 "ill", []> { 505 let m = 0x0; 506 let n = 0x0; 507 let r = 0; 508 let s = 0; 509} 510 511//===----------------------------------------------------------------------===// 512// Processor control instructions 513//===----------------------------------------------------------------------===// 514 515def DSYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 516 "dsync", []> { 517 let r = 0x2; 518 let s = 0x0; 519 let t = 0x3; 520 let hasSideEffects = 1; 521} 522 523def ISYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 524 "isync", []> { 525 let r = 0x2; 526 let s = 0x0; 527 let t = 0x0; 528 let hasSideEffects = 1; 529} 530 531def RSYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 532 "rsync", []> { 533 let r = 0x2; 534 let s = 0x0; 535 let t = 0x1; 536 let hasSideEffects = 1; 537} 538 539def ESYNC : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 540 "esync", []> { 541 let r = 0x2; 542 let s = 0x0; 543 let t = 0x2; 544 let hasSideEffects = 1; 545} 546 547def NOP : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 548 "nop", []> { 549 let r = 0x02; 550 let s = 0x00; 551 let t = 0x0f; 552} 553 554def WSR : RSR_Inst<0x00, 0x03, 0x01, (outs SR:$sr), (ins AR:$t), 555 "wsr\t$t, $sr", []>; 556 557def RSR : RSR_Inst<0x00, 0x03, 0x00, (outs AR:$t), (ins SR:$sr), 558 "rsr\t$t, $sr", []>; 559 560def XSR : RSR_Inst<0x00, 0x01, 0x06, (outs AR:$ard, SR:$srd), (ins AR:$t, SR:$sr), 561 "xsr\t$t, $sr", []> { 562 let Constraints = "$ard = $t, $srd = $sr"; 563} 564 565//===----------------------------------------------------------------------===// 566// User Registers read/write instructions 567//===----------------------------------------------------------------------===// 568 569def WUR : RRR_Inst<0x00, 0x03, 0x0F, (outs UR:$ur), (ins AR:$t), 570 "wur\t$t, $ur", []> { 571 bits<8> ur; 572 573 let r = ur{7-4}; 574 let s = ur{3-0}; 575} 576 577def RUR : RRR_Inst<0x00, 0x03, 0x0E, (outs AR:$r), (ins UR:$ur), 578 "rur\t$r, $ur", [(set AR:$r, (Xtensa_rur UR:$ur))]> { 579 bits<8> ur; 580 581 let s = ur{7-4}; 582 let t = ur{3-0}; 583} 584 585//===----------------------------------------------------------------------===// 586// Stack allocation 587//===----------------------------------------------------------------------===// 588 589// ADJCALLSTACKDOWN/UP implicitly use/def SP because they may be expanded into 590// a stack adjustment and the codegen must know that they may modify the stack 591// pointer before prolog-epilog rewriting occurs. 592let Defs = [SP], Uses = [SP] in { 593 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 594 "#ADJCALLSTACKDOWN", 595 [(Xtensa_callseq_start timm:$amt1, timm:$amt2)]>; 596 def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 597 "#ADJCALLSTACKUP", 598 [(Xtensa_callseq_end timm:$amt1, timm:$amt2)]>; 599} 600 601//===----------------------------------------------------------------------===// 602// Generic select instruction 603//===----------------------------------------------------------------------===// 604let usesCustomInserter = 1 in { 605 def SELECT : Pseudo<(outs AR:$dst), (ins AR:$lhs, AR:$rhs, AR:$t, AR:$f, i32imm:$cond), 606 "!select $dst, $lhs, $rhs, $t, $f, $cond", 607 [(set i32:$dst, (Xtensa_select_cc i32:$lhs, i32:$rhs, i32:$t, i32:$f, imm:$cond))]>; 608} 609 610//===----------------------------------------------------------------------===// 611// Code Density instructions 612//===----------------------------------------------------------------------===// 613 614class ArithLogic_RRRN<bits<4> oper0, string instrAsm, 615 SDPatternOperator opNode, bit isComm = 0> 616 : RRRN_Inst<oper0, (outs AR:$r), (ins AR:$s, AR:$t), 617 instrAsm#"\t$r, $s, $t", 618 [(set AR:$r, (opNode AR:$s, AR:$t))]>, Requires<[HasDensity]> { 619 let isCommutable = isComm; 620 let isReMaterializable = 0; 621} 622 623def ADD_N : ArithLogic_RRRN<0x0a, "add.n", add, 1>; 624 625def ADDI_N : RRRN_Inst<0x0B, (outs AR:$r), (ins AR:$s, imm1n_15:$imm), 626 "addi.n\t$r, $s, $imm", 627 [(set AR:$r, (add AR:$s, imm1n_15:$imm))]>, Requires<[HasDensity]> { 628 bits<4> imm; 629 630 let t = imm; 631} 632 633// Conditional branch instructions. 634let isBranch = 1, isTerminator = 1 in { 635 def BEQZ_N : RI6_Inst<0xC, 0x1, 0x0, (outs), (ins AR:$s, brtarget:$target), 636 "beqz.n\t$s, $target", []>, Requires<[HasDensity]> { 637 bits<6> target; 638 639 let imm6 = target; 640 } 641 642 def BNEZ_N : RI6_Inst<0xC, 0x1, 0x1, (outs), (ins AR:$s, brtarget:$target), 643 "bnez.n\t$s, $target", []>, Requires<[HasDensity]> { 644 bits<6> target; 645 646 let imm6 = target; 647 } 648} 649 650def ILL_N : RRRN_Inst<0x0D, (outs), (ins), 651 "ill.n", []>, Requires<[HasDensity]> { 652 let r = 0xF; 653 let s = 0x0; 654 let t = 0x6; 655} 656 657def MOV_N : RRRN_Inst<0x0D, (outs AR:$t), (ins AR:$s), 658 "mov.n\t$t, $s", []>, Requires<[HasDensity]> { 659 let r = 0; 660} 661 662def : InstAlias<"mov\t $t, $s", (OR AR:$t, AR:$s, AR:$s)>; 663 664def MOVI_N : RI7_Inst<0xc, 0x0, (outs AR:$s), (ins imm32n_95:$imm7), 665 "movi.n\t$s, $imm7", 666 [(set AR:$s, imm32n_95:$imm7)]>, Requires<[HasDensity]>; 667 668def : InstAlias<"_movi.n\t$s, $imm7", (MOVI_N AR:$s, imm32n_95:$imm7)>; 669 670def NOP_N : RRRN_Inst<0x0D, (outs), (ins), 671 "nop.n", []>, Requires<[HasDensity]> { 672 let r = 0xF; 673 let s = 0x0; 674 let t = 0x3; 675} 676 677// Load instruction 678let mayLoad = 1, usesCustomInserter = 1 in { 679 def L32I_N : RRRN_Inst<0x8, (outs AR:$t), (ins mem32n:$addr), 680 "l32i.n\t$t, $addr", []>, Requires<[HasDensity]> { 681 bits<8> addr; 682 683 let r{3-0} = addr{7-4}; 684 let s{3-0} = addr{3-0}; 685 } 686} 687 688// Store instruction 689let mayStore = 1, usesCustomInserter = 1 in { 690 def S32I_N : RRRN_Inst<0x9, (outs), (ins AR:$t, mem32n:$addr), 691 "s32i.n\t$t, $addr", []>, Requires<[HasDensity]> { 692 bits<8> addr; 693 694 let r{3-0} = addr{7-4}; 695 let s{3-0} = addr{3-0}; 696 } 697} 698 699//Return instruction 700let isReturn = 1, isTerminator = 1, 701 isBarrier = 1, Uses = [A0] in { 702 def RET_N : RRRN_Inst<0x0D, (outs), (ins), 703 "ret.n", [(Xtensa_ret)]>, 704 Requires<[HasDensity]> { 705 let r = 0x0F; 706 let s = 0; 707 let t = 0; 708 } 709} 710 711//===----------------------------------------------------------------------===// 712// Windowed instructions 713//===----------------------------------------------------------------------===// 714 715def ENTRY : BRI12_Inst<0x06, 0x3, 0x0, (outs), (ins AR:$s, entry_imm12:$imm), 716 "entry\t$s, $imm", []>, Requires<[HasWindowed]> { 717 bits<15> imm; 718 719 let imm12{11-0} = imm{14-3}; 720 let Defs = [SP]; 721} 722 723let isCall = 1, Defs = [A0] in { 724 foreach i = {1,2,3} in { 725 defvar I = !mul(4, i); 726 727 def CALL#I# : CALL_Inst<0x05, (outs), (ins pcrel32call:$offset), 728 "call"#I#"\t$offset", []>, Requires<[HasWindowed]> { 729 let n = i; 730 } 731 732 def CALLX#I# : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins AR:$s), 733 "callx"#I#"\t$s", []>, Requires<[HasWindowed]> { 734 let m = 0x3; 735 let n = i; 736 let r = 0; 737 } 738 } 739} 740 741// Windowed call patterns. Currently rotation 742// window by 8 is implemented. 743def : Pat<(Xtensa_callw8 (i32 tglobaladdr:$dst)), 744 (CALL8 tglobaladdr:$dst)>; 745def : Pat<(Xtensa_callw8 (i32 texternalsym:$dst)), 746 (CALL8 texternalsym:$dst)>; 747def : Pat<(Xtensa_callw8 AR:$dst), 748 (CALLX8 AR:$dst)>; 749 750def MOVSP : RRR_Inst<0x00, 0x00, 0x00, (outs AR:$t), (ins AR:$s), 751 "movsp\t$t, $s", []>, Requires<[HasWindowed]> { 752 let r = 0x01; 753} 754 755// Use this pseudo operation instead of getCopyToReg function to 756// update SP register. 757let usesCustomInserter = 1, Defs = [SP], Predicates = [HasWindowed] in { 758 def MOVSP_P : Pseudo<(outs), (ins AR:$s), 759 "!movsp_p\tsp, $s", [(Xtensa_movsp AR:$s)]>; 760} 761 762let isReturn = 1, isTerminator = 1, 763 isBarrier = 1, Uses = [A0] in { 764 def RETW_N : RRRN_Inst<0x0D, (outs), (ins), 765 "retw.n", [(Xtensa_retw)]>, 766 Requires<[HasWindowed, HasDensity]> { 767 let r = 0x0F; 768 let s = 0; 769 let t = 1; 770 } 771 772 def RETW : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins), 773 "retw", [(Xtensa_retw)]>, 774 Requires<[HasWindowed]> { 775 let m = 0x2; 776 let n = 0x1; 777 let s = 0; 778 let r = 0; 779 } 780} 781 782def : InstAlias<"_retw", (RETW)>; 783def : InstAlias<"_retw.n", (RETW_N)>; 784 785def S32E : RRI4_Inst<0x00, 0x09, (outs), (ins AR:$t, AR:$s, imm64n_4n:$imm), 786 "s32e\t$t, $s, $imm", []>, Requires<[HasWindowed]> { 787 bits<6> imm; 788 789 let r = imm{5-2}; 790 let imm4 = 0x4; 791 let mayStore = 1; 792} 793 794def L32E : RRI4_Inst<0x00, 0x09, (outs), (ins AR:$t, AR:$s, imm64n_4n:$imm), 795 "l32e\t$t, $s, $imm", []>, Requires<[HasWindowed]> { 796 bits<6> imm; 797 798 let r = imm{5-2}; 799 let imm4 = 0x0; 800 let mayLoad = 1; 801} 802 803def RFWU : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 804 "rfwu", []>, Requires<[HasWindowed]> { 805 bits<4> imm; 806 807 let r = 0x3; 808 let s = 0x5; 809 let t = 0x0; 810} 811 812def RFWO : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 813 "rfwo", []>, Requires<[HasWindowed]> { 814 bits<4> imm; 815 816 let r = 0x3; 817 let s = 0x4; 818 let t = 0x0; 819} 820 821def ROTW : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins imm8n_7:$imm), 822 "rotw\t$imm", []>, Requires<[HasWindowed]> { 823 bits<4> imm; 824 825 let r = 0x8; 826 let s = 0x0; 827 let t = imm{3-0}; 828} 829 830//===----------------------------------------------------------------------===// 831// Boolean Instructions 832//===----------------------------------------------------------------------===// 833 834def ALL4 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s), 835 "all4\t$t, $s", []>, Requires<[HasBoolean]> { 836 let r = 0x9; 837} 838 839def ALL8 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s), 840 "all8\t$t, $s", []>, Requires<[HasBoolean]> { 841 let r = 0xB; 842} 843 844def ANDB : RRR_Inst<0x00, 0x02, 0x00, (outs BR:$r), (ins BR:$s, BR:$t), 845 "andb\t$r, $s, $t", []>, Requires<[HasBoolean]>; 846def ANDBC : RRR_Inst<0x00, 0x02, 0x01, (outs BR:$r), (ins BR:$s, BR:$t), 847 "andbc\t$r, $s, $t", []>, Requires<[HasBoolean]>; 848def ORB : RRR_Inst<0x00, 0x02, 0x02, (outs BR:$r), (ins BR:$s, BR:$t), 849 "orb\t$r, $s, $t", []>, Requires<[HasBoolean]>; 850def ORBC : RRR_Inst<0x00, 0x02, 0x03, (outs BR:$r), (ins BR:$s, BR:$t), 851 "orbc\t$r, $s, $t", []>, Requires<[HasBoolean]>; 852def XORB : RRR_Inst<0x00, 0x02, 0x04, (outs BR:$r), (ins BR:$s, BR:$t), 853 "xorb\t$r, $s, $t", []>, Requires<[HasBoolean]>; 854 855def ANY4 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s), 856 "any4\t$t, $s", []>, Requires<[HasBoolean]> { 857 let r = 0x8; 858} 859 860def ANY8 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s), 861 "any8\t$t, $s", []>, Requires<[HasBoolean]> { 862 let r = 0xA; 863} 864 865let isBranch = 1, isTerminator = 1, Predicates = [HasBoolean] in { 866 def BT : RRI8_Inst<0x06, (outs), (ins BR:$b, brtarget:$target), 867 "bt\t$b, $target", []> { 868 bits<8> target; 869 bits<4> b; 870 871 let r = 0x1; 872 let s = b; 873 let t = 0x7; 874 let imm8 = target; 875 } 876 877 def BF : RRI8_Inst<0x06, (outs), (ins BR:$b, brtarget:$target), 878 "bf\t$b, $target", []> { 879 bits<8> target; 880 bits<4> b; 881 882 let r = 0x0; 883 let s = b; 884 let t = 0x7; 885 let imm8 = target; 886 } 887} 888 889def : InstAlias<"_BT\t$b, $target", (BT BR:$b, brtarget:$target)>; 890def : InstAlias<"_BF\t$b, $target", (BF BR:$b, brtarget:$target)>; 891 892let Constraints = "$dr = $r,@earlyclobber $dr" in { 893 def MOVF : RRR_Inst<0x00, 0x03, 0x0C, (outs AR:$dr), (ins AR:$r, AR:$s, BR:$t), 894 "movf\t$r, $s, $t", []>, Requires<[HasBoolean]>; 895 896 def MOVT : RRR_Inst<0x00, 0x03, 0x0D, (outs AR:$dr), (ins AR:$r, AR:$s, BR:$t), 897 "movt\t$r, $s, $t", []>, Requires<[HasBoolean]>; 898} 899 900//===----------------------------------------------------------------------===// 901// SEXT Instruction 902//===----------------------------------------------------------------------===// 903 904def SEXT : RRR_Inst<0x00, 0x03, 0x02, (outs AR:$r), (ins AR:$s, imm7_22:$imm), 905 "sext\t$r, $s, $imm", []>, Requires<[HasSEXT]> { 906 bits<4> imm; 907 908 let t = imm; 909} 910 911def : Pat<(i32 (sext_inreg AR:$s, i8)), (SEXT AR:$s, (i32 7))>; 912def : Pat<(i32 (sext_inreg AR:$s, i16)), (SEXT AR:$s, (i32 15))>; 913 914//===----------------------------------------------------------------------===// 915// CLAMPS Instruction 916//===----------------------------------------------------------------------===// 917 918def CLAMPS : RRR_Inst<0x00, 0x03, 0x03, (outs AR:$r), (ins AR:$s, imm7_22:$imm), 919 "clamps\t$r, $s, $imm", []>, Requires<[HasCLAMPS]> { 920 bits<4> imm; 921 922 let t = imm; 923} 924 925//===----------------------------------------------------------------------===// 926// NSA Instructions 927//===----------------------------------------------------------------------===// 928 929def NSA : RRR_Inst<0x00, 0x00, 0x04, (outs AR:$t), (ins AR:$s), 930 "nsa\t$t, $s", []>, Requires<[HasNSA]> { 931 let r = 0xE; 932} 933 934def NSAU : RRR_Inst<0x00, 0x00, 0x04, (outs AR:$t), (ins AR:$s), 935 "nsau\t$t, $s", 936 [(set AR:$t, (ctlz AR:$s))]>, Requires<[HasNSA]> { 937 let r = 0xF; 938} 939 940//===----------------------------------------------------------------------===// 941// MINMAX Instructions 942//===----------------------------------------------------------------------===// 943 944let Predicates = [HasMINMAX] in { 945 def MIN : ArithLogic_RRR<0x04, 0x03, "min", smin, 1>; 946 def MAX : ArithLogic_RRR<0x05, 0x03, "max", smax, 1>; 947 def MINU : ArithLogic_RRR<0x06, 0x03, "minu", umin, 1>; 948 def MAXU : ArithLogic_RRR<0x07, 0x03, "maxu", umax, 1>; 949} 950 951//===----------------------------------------------------------------------===// 952// Loop Instructions 953//===----------------------------------------------------------------------===// 954 955def LOOP : RRI8_Inst<0x06, (outs), (ins AR:$s, ltarget:$target), 956 "loop\t$s, $target", []>, Requires<[HasLoop]> { 957 bits<8> target; 958 959 let r = 0x08; 960 let t = 0x07; 961 let imm8 = target; 962} 963 964def : InstAlias<"_loop\t$s, $target", (LOOP AR:$s, ltarget:$target)>; 965 966def LOOPGTZ : RRI8_Inst<0x06, (outs), (ins AR:$s, ltarget:$target), 967 "loopgtz\t$s, $target", []>, Requires<[HasLoop]> { 968 bits<8> target; 969 970 let r = 0x0A; 971 let t = 0x07; 972 let imm8 = target; 973} 974 975def : InstAlias<"_loopgtz\t$s, $target", (LOOPGTZ AR:$s, ltarget:$target)>; 976 977def LOOPNEZ : RRI8_Inst<0x06, (outs), (ins AR:$s, ltarget:$target), 978 "loopnez\t$s, $target", []>, Requires<[HasLoop]> { 979 bits<8> target; 980 981 let r = 0x09; 982 let t = 0x07; 983 let imm8 = target; 984} 985 986def : InstAlias<"_loopnez\t$s, $target", (LOOPNEZ AR:$s, ltarget:$target)>; 987 988//===----------------------------------------------------------------------===// 989// Mul16 Instructions 990//===----------------------------------------------------------------------===// 991 992let Predicates = [HasMul16] in { 993 def MUL16S : RRR_Inst<0x00, 0x01, 0x0D, (outs AR:$r), (ins AR:$s, AR:$t), 994 "mul16s\t$r, $s, $t", []>; 995 def MUL16U : RRR_Inst<0x00, 0x01, 0x0C, (outs AR:$r), (ins AR:$s, AR:$t), 996 "mul16u\t$r, $s, $t", []>; 997} 998 999//===----------------------------------------------------------------------===// 1000// Mul32 Instructions 1001//===----------------------------------------------------------------------===// 1002 1003def MULL : ArithLogic_RRR<0x08, 0x02, "mull", mul, 1>, Requires<[HasMul32]>; 1004def MULUH : ArithLogic_RRR<0x0A, 0x02, "muluh", mulhu, 1>, Requires<[HasMul32High]>; 1005def MULSH : ArithLogic_RRR<0x0B, 0x02, "mulsh", mulhs, 1>, Requires<[HasMul32High]>; 1006 1007//===----------------------------------------------------------------------===// 1008// Div32 Instructions 1009//===----------------------------------------------------------------------===// 1010 1011let Predicates = [HasDiv32] in { 1012 def QUOS : ArithLogic_RRR<0x0D, 0x02, "quos", sdiv>; 1013 def QUOU : ArithLogic_RRR<0x0C, 0x02, "quou", udiv>; 1014 def REMS : ArithLogic_RRR<0x0F, 0x02, "rems", srem>; 1015 def REMU : ArithLogic_RRR<0x0E, 0x02, "remu", urem>; 1016} 1017 1018//===----------------------------------------------------------------------===// 1019// Floating-Point Instructions 1020//===----------------------------------------------------------------------===// 1021 1022class FPArith_RRR<bits<4> oper2, bits<4> oper1, string instrAsm, 1023 SDPatternOperator opNode, bit isComm = 0> 1024 : RRR_Inst<0x00, oper1, oper2, (outs FPR:$r), (ins FPR:$s, FPR:$t), 1025 instrAsm#"\t$r, $s, $t", 1026 [(set FPR:$r, (opNode FPR:$s, FPR:$t))]> { 1027 let isCommutable = isComm; 1028 let isReMaterializable = 0; 1029 let Predicates = [HasSingleFloat]; 1030} 1031 1032def ADD_S : FPArith_RRR<0x00, 0x0A, "add.s", fadd, 1>; 1033def SUB_S : FPArith_RRR<0x01, 0x0A, "sub.s", fsub>; 1034def MUL_S : FPArith_RRR<0x02, 0x0A, "mul.s", fmul, 1>; 1035 1036// FP load instructions 1037let mayLoad = 1, usesCustomInserter = 1, Predicates = [HasSingleFloat] in { 1038 def LSI : RRI8_Inst<0x03, (outs FPR:$t), (ins mem32:$addr), 1039 "lsi\t$t, $addr", []> { 1040 bits<12> addr; 1041 1042 let r = 0x00; 1043 let imm8{7-0} = addr{11-4}; 1044 let s{3-0} = addr{3-0}; 1045 } 1046 1047 def LSIP : RRI8_Inst<0x03, (outs FPR:$t), (ins mem32:$addr), 1048 "lsip\t$t, $addr", []> { 1049 bits<12> addr; 1050 1051 let r = 0x08; 1052 let imm8{7-0} = addr{11-4}; 1053 let s{3-0} = addr{3-0}; 1054 } 1055 1056 def LSX : RRR_Inst<0x00, 0x08, 0x00, (outs), (ins FPR:$r, AR:$s, AR:$t), 1057 "lsx\t$r, $s, $t", []>; 1058 1059 def LSXP : RRR_Inst<0x00, 0x08, 0x01, (outs), (ins FPR:$r, AR:$s, AR:$t), 1060 "lsxp\t$r, $s, $t", []>; 1061} 1062 1063def : Pat<(f32 (load addr_ish4:$addr)), (f32 (LSI mem32:$addr))>; 1064 1065// FP store instructions 1066let mayStore = 1, usesCustomInserter = 1, Predicates = [HasSingleFloat] in { 1067 def SSI : RRI8_Inst<0x03, (outs), (ins FPR:$t, mem32:$addr), 1068 "ssi\t$t, $addr", []> { 1069 bits<12> addr; 1070 1071 let r = 0x04; 1072 let imm8{7-0} = addr{11-4}; 1073 let s{3-0} = addr{3-0}; 1074 } 1075 1076 def SSIP : RRI8_Inst<0x03, (outs), (ins FPR:$t, mem32:$addr), 1077 "ssip\t$t, $addr", []> { 1078 bits<12> addr; 1079 1080 let r = 0x0C; 1081 let imm8{7-0} = addr{11-4}; 1082 let s{3-0} = addr{3-0}; 1083 } 1084 1085 def SSX: RRR_Inst<0x00, 0x08, 0x04, (outs), (ins FPR:$r, AR:$s, AR:$t), 1086 "ssx\t$r, $s, $t", []>; 1087 1088 def SSXP: RRR_Inst<0x00, 0x08, 0x05, (outs), (ins FPR:$r, AR:$s, AR:$t), 1089 "ssxp\t$r, $s, $t", []>; 1090} 1091 1092def : Pat<(store FPR:$t, addr_ish4:$addr), (SSI FPR:$t, mem32:$addr)>; 1093 1094// FP compare instructions 1095let isCompare = 1, Predicates = [HasSingleFloat] in { 1096 class FCompare <bits<4> oper2, bits<4> oper1, string instrAsm, 1097 SDPatternOperator opNode, bit isComm = 0> 1098 : RRR_Inst<0x00, oper1, oper2, (outs BR:$r), (ins FPR:$s, FPR:$t), 1099 instrAsm#"\t$r, $s, $t", 1100 [(set BR:$r, (opNode FPR:$s, FPR:$t))]> { 1101 let isCommutable = isComm; 1102 let isReMaterializable = 0; 1103 let Predicates = [HasSingleFloat]; 1104 } 1105} 1106 1107def OEQ_S : FCompare<0x02, 0x0b, "oeq.s", Xtensa_cmpoeq, 1>; 1108def OLT_S : FCompare<0x04, 0x0b, "olt.s", Xtensa_cmpolt, 0>; 1109def OLE_S : FCompare<0x06, 0x0b, "ole.s", Xtensa_cmpole, 0>; 1110 1111def UEQ_S : FCompare<0x03, 0x0b, "ueq.s", Xtensa_cmpueq, 1>; 1112def ULT_S : FCompare<0x05, 0x0b, "ult.s", Xtensa_cmpult, 0>; 1113def ULE_S : FCompare<0x07, 0x0b, "ule.s", Xtensa_cmpule, 0>; 1114def UN_S : FCompare<0x01, 0x0b, "un.s", Xtensa_cmpuo, 1>; 1115 1116def ABS_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s), 1117 "abs.s\t$r, $s", 1118 [(set FPR:$r, (fabs FPR:$s))]>, Requires<[HasSingleFloat]> { 1119 let t = 0x01; 1120} 1121 1122def : Pat<(fabs FPR:$s), (ABS_S $s)>; 1123 1124def ADDEXP_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s), 1125 "addexp.s\t$r, $s", []>, Requires<[HasSingleFloat]> { 1126 let t = 0x0E; 1127} 1128 1129def ADDEXPM_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s), 1130 "addexpm.s\t$r, $s", []>, Requires<[HasSingleFloat]> { 1131 let t = 0x0F; 1132} 1133 1134def CEIL_S : RRR_Inst<0x00, 0x0A, 0x0B, (outs AR:$r), (ins FPR:$s, uimm4:$imm), 1135 "ceil.s\t$r, $s, $imm", []>, Requires<[HasSingleFloat]> { 1136 bits<4> imm; 1137 1138 let t = imm; 1139} 1140 1141def CONST_S : RRR_Inst<0x00, 0x0a, 0x0f, (outs FPR:$r), (ins uimm4:$imm), 1142 "const.s\t$r, $imm", []>, Requires<[HasSingleFloat]> { 1143 bits<4> imm; 1144 1145 let t = 0x03; 1146 let s = imm{3-0}; 1147} 1148 1149def DIV0_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s), 1150 "div0.s\t$r, $s", []>, Requires<[HasSingleFloat]> { 1151 let t = 0x7; 1152} 1153 1154def DIVN_S : RRR_Inst<0x00, 0x0A, 0x07, (outs FPR:$r), (ins FPR:$s, FPR:$t), 1155 "divn.s\t$r, $s, $t", []>, Requires<[HasSingleFloat]>; 1156 1157def FLOAT_S : RRR_Inst<0x00, 0x0A, 0x0c, (outs FPR:$r), (ins AR:$s, uimm4:$imm), 1158 "float.s\t$r, $s, $imm", []>, Requires<[HasSingleFloat]> { 1159 bits<4> imm; 1160 1161 let t = imm; 1162} 1163 1164def : Pat<(f32 (sint_to_fp AR:$s)), (FLOAT_S AR:$s, 0)>; 1165 1166def FLOOR_S : RRR_Inst<0x00, 0x0A, 0x0A, (outs AR:$r), (ins FPR:$s, uimm4:$imm), 1167 "floor.s\t$r, $s, $imm", []>, Requires<[HasSingleFloat]> { 1168 bits<4> imm; 1169 1170 let t = imm; 1171} 1172 1173def MADDN_S : RRR_Inst<0x00, 0x0A, 0x06, (outs FPR:$r), (ins FPR:$s, FPR:$t), 1174 "maddn.s\t$r, $s, $t", []>, Requires<[HasSingleFloat]> { 1175 let isCommutable = 0; 1176} 1177 1178// FP multipy-add 1179def MADD_S : RRR_Inst<0x00, 0x0A, 0x04, (outs FPR:$r), (ins FPR:$a, FPR:$s, FPR:$t), 1180 "madd.s\t$r, $s, $t", 1181 [(set FPR:$r, (Xtensa_madd FPR:$a, FPR:$s, FPR:$t))]>, 1182 Requires<[HasSingleFloat]> { 1183 let isCommutable = 0; 1184 let isReMaterializable = 0; 1185 let Constraints = "$r = $a"; 1186} 1187 1188// fmadd: r1 * r2 + r3 1189def : Pat<(fma FPR:$r1, FPR:$r2, FPR:$r3), 1190 (MADD_S $r3, $r1, $r2)>; 1191 1192def MKDADJ_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s), 1193 "mkdadj.s\t$r, $s", []>, Requires<[HasSingleFloat]> { 1194 let t = 0x0D; 1195} 1196 1197def MKSADJ_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s), 1198 "mksadj.s\t$r, $s", []>, Requires<[HasSingleFloat]> { 1199 let t = 0x0C; 1200} 1201 1202// FP move instructions 1203def MOV_S : RRR_Inst<0x00, 0x0A, 0x0f, (outs FPR:$r), (ins FPR:$s), 1204 "mov.s\t$r, $s", 1205 [(set FPR:$r, (Xtensa_movs FPR:$s))]>, Requires<[HasSingleFloat]> { 1206 let t = 0x00; 1207} 1208 1209def MOVEQZ_S : RRR_Inst<0x00, 0x0B, 0x08, (outs FPR:$r), (ins FPR:$s, AR:$t), 1210 "moveqz.s\t$r, $s, $t", []>, Requires<[HasSingleFloat]>; 1211 1212def MOVF_S : RRR_Inst<0x00, 0x0B, 0x0C, (outs FPR:$r), (ins FPR:$s, BR:$t), 1213 "movf.s\t$r, $s, $t", []>, Requires<[HasBoolean, HasSingleFloat]>; 1214 1215def MOVGEZ_S : RRR_Inst<0x00, 0x0B, 0x0B, (outs FPR:$r), (ins FPR:$s, AR:$t), 1216 "movgez.s\t$r, $s, $t", []>, Requires<[HasSingleFloat]>; 1217 1218def MOVLTZ_S : RRR_Inst<0x00, 0x0B, 0x0A, (outs FPR:$r), (ins FPR:$s, AR:$t), 1219 "movltz.s\t$r, $s, $t", []>, Requires<[HasSingleFloat]>; 1220 1221def MOVNEZ_S : RRR_Inst<0x00, 0x0B, 0x09, (outs FPR:$r), (ins FPR:$s, AR:$t), 1222 "movnez.s\t$r, $s, $t", []>, Requires<[HasSingleFloat]>; 1223 1224def MOVT_S : RRR_Inst<0x00, 0x0B, 0x0D, (outs FPR:$r), (ins FPR:$s, BR:$t), 1225 "movt.s\t$r, $s, $t", []>, Requires<[HasBoolean, HasSingleFloat]>; 1226 1227// FP multipy-sub 1228def MSUB_S : RRR_Inst<0x00, 0x0A, 0x05, (outs FPR:$r), (ins FPR:$a, FPR:$s, FPR:$t), 1229 "msub.s\t$r, $s, $t", 1230 [(set FPR:$r, (Xtensa_msub FPR:$a, FPR:$s, FPR:$t))]>, Requires<[HasSingleFloat]> { 1231 let isCommutable = 0; 1232 let isReMaterializable = 0; 1233 let Constraints = "$r = $a"; 1234} 1235 1236def NEXP01_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s), 1237 "nexp01.s\t$r, $s", []>, Requires<[HasSingleFloat]> { 1238 let t = 0x0B; 1239} 1240 1241def NEG_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s), 1242 "neg.s\t$r, $s", 1243 [(set FPR:$r, (fneg FPR:$s))]>, Requires<[HasSingleFloat]> { 1244 let t = 0x06; 1245} 1246 1247def RECIP0_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s), 1248 "recip0.s\t$r, $s", []>, Requires<[HasSingleFloat]> { 1249 let t = 0x08; 1250} 1251 1252def RFR : RRR_Inst<0x00, 0x0A, 0x0f, (outs AR:$r), (ins FPR:$s), 1253 "rfr\t$r, $s", 1254 [(set AR:$r, (bitconvert FPR:$s))]>, Requires<[HasSingleFloat]> { 1255 let t = 0x04; 1256} 1257 1258def ROUND_S : RRR_Inst<0x00, 0x0A, 0x08, (outs AR:$r), (ins FPR:$s, uimm4:$imm), 1259 "round.s\t$r, $s, $imm", []>, Requires<[HasSingleFloat]> { 1260 bits<4> imm; 1261 1262 let t = imm; 1263} 1264 1265def RSQRT0_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s), 1266 "rsqrt0.s\t$r, $s", []>, Requires<[HasSingleFloat]> { 1267 let t = 0x0A; 1268} 1269 1270def SQRT0_S : RRR_Inst<0x00, 0x0A, 0x0F, (outs FPR:$r), (ins FPR:$s), 1271 "sqrt0.s\t$r, $s", []>, Requires<[HasSingleFloat]> { 1272 let t = 0x09; 1273} 1274 1275def TRUNC_S : RRR_Inst<0x00, 0x0A, 0x09, (outs AR:$r), (ins FPR:$s, uimm4:$imm), 1276 "trunc.s\t$r, $s, $imm", []>, Requires<[HasSingleFloat]> { 1277 bits<4> imm; 1278 1279 let t = imm; 1280} 1281 1282def : Pat<(i32 (fp_to_sint FPR:$s)), (TRUNC_S FPR:$s, 0)>; 1283 1284def UFLOAT_S : RRR_Inst<0x00, 0x0A, 0x0D, (outs FPR:$r), (ins AR:$s, uimm4:$imm), 1285 "ufloat.s\t$r, $s, $imm", []>, Requires<[HasSingleFloat]> { 1286 bits<4> imm; 1287 1288 let t = imm; 1289} 1290 1291def : Pat<(f32 (uint_to_fp AR:$s)), (UFLOAT_S AR:$s, 0)>; 1292 1293def UTRUNC_S : RRR_Inst<0x00, 0x0A, 0x0e, (outs AR:$r), (ins FPR:$s, uimm4:$imm), 1294 "utrunc.s\t$r, $s, $imm", []>, Requires<[HasSingleFloat]> { 1295 bits<4> imm; 1296 1297 let t = imm; 1298} 1299 1300def : Pat<(i32 (fp_to_uint FPR:$s)), (UTRUNC_S FPR:$s, 0)>; 1301 1302def WFR : RRR_Inst<0x00, 0x0A, 0x0f, (outs FPR:$r), (ins AR:$s), 1303 "wfr\t$r, $s", 1304 [(set FPR:$r, (bitconvert AR:$s))]>, Requires<[HasSingleFloat]> { 1305 let t = 0x05; 1306} 1307 1308let AddedComplexity = 10 in 1309def : Pat<(f32 (load (Xtensa_pcrel_wrapper tconstpool:$in))), 1310 (WFR (L32R tconstpool:$in))>; 1311 1312//===----------------------------------------------------------------------===// 1313// SelectCC and BranchCC instructions with FP operands 1314//===----------------------------------------------------------------------===// 1315 1316let usesCustomInserter = 1, Predicates = [HasSingleFloat] in { 1317 def SELECT_CC_INT_FP : Pseudo<(outs FPR:$dst), (ins AR:$lhs, AR:$rhs, FPR:$t, FPR:$f, i32imm:$cond), 1318 "!select_cc_int_fp $dst, $lhs, $rhs, $t, $f, $cond", 1319 [(set FPR:$dst, (Xtensa_select_cc AR:$lhs, AR:$rhs, FPR:$t, FPR:$f, imm:$cond))]>; 1320 def SELECT_CC_FP_INT : Pseudo<(outs AR:$dst), (ins FPR:$lhs, FPR:$rhs, AR:$t, AR:$f, i32imm:$cond, i32imm:$brkind), 1321 "!select_cc_fp_int $dst, $lhs, $rhs, $t, $f, $cond, $brkind", 1322 [(set AR:$dst, (Xtensa_select_cc_fp FPR:$lhs, FPR:$rhs, AR:$t, AR:$f, imm:$cond, imm:$brkind))]>; 1323 def SELECT_CC_FP_FP : Pseudo<(outs FPR:$dst), (ins FPR:$lhs, FPR:$rhs, FPR:$t, FPR:$f, i32imm:$cond, i32imm:$brkind), 1324 "!select_cc_fp_fp $dst, $lhs, $rhs, $t, $f, $cond, $brkind", 1325 [(set FPR:$dst, (Xtensa_select_cc_fp FPR:$lhs, FPR:$rhs, FPR:$t, FPR:$f, imm:$cond, imm:$brkind))]>; 1326} 1327 1328let usesCustomInserter = 1, isBranch = 1, isTerminator = 1, isBarrier = 1, Predicates = [HasSingleFloat] in { 1329 def BRCC_FP : Pseudo<(outs), (ins i32imm:$cond, FPR:$lhs, FPR:$rhs, brtarget:$target), 1330 "!brcc_fp $cond, $lhs, $rhs, $target", []>; 1331} 1332 1333def cond_as_i32imm : SDNodeXForm<cond, [{ 1334 return CurDAG->getTargetConstant(N->get(), SDLoc(N), MVT::i32); 1335}]>; 1336 1337def : Pat<(brcc cond:$cond, FPR:$s, FPR:$t, bb:$target), 1338 (BRCC_FP (cond_as_i32imm $cond), FPR:$s, FPR:$t, bb:$target)>; 1339 1340//===----------------------------------------------------------------------===// 1341// Region Protection feature instructions 1342//===----------------------------------------------------------------------===// 1343 1344let Predicates = [HasRegionProtection] in { 1345 def IDTLB : RRR_Inst<0x00, 0x00, 0x05, (outs), (ins AR:$s), 1346 "idtlb\t$s", []> { 1347 let r = 0xC; 1348 let t = 0x0; 1349 } 1350 1351 def IITLB : RRR_Inst<0x00, 0x00, 0x05, (outs), (ins AR:$s), 1352 "iitlb\t$s", []> { 1353 let r = 0x4; 1354 let t = 0x0; 1355 } 1356 1357 def PDTLB : RRR_Inst<0x00, 0x00, 0x05, (outs AR:$t), (ins AR:$s), 1358 "pdtlb\t$t, $s", []> { 1359 let r = 0xD; 1360 } 1361 1362 def PITLB : RRR_Inst<0x00, 0x00, 0x05, (outs AR:$t), (ins AR:$s), 1363 "pitlb\t$t, $s", []> { 1364 let r = 0x5; 1365 } 1366 1367 def RDTLB0 : RRR_Inst<0x00, 0x00, 0x05, (outs AR:$t), (ins AR:$s), 1368 "rdtlb0\t$t, $s", []> { 1369 let r = 0xB; 1370 } 1371 1372 def RDTLB1 : RRR_Inst<0x00, 0x00, 0x05, (outs AR:$t), (ins AR:$s), 1373 "rdtlb1\t$t, $s", []> { 1374 let r = 0xF; 1375 } 1376 1377 def RITLB0 : RRR_Inst<0x00, 0x00, 0x05, (outs AR:$t), (ins AR:$s), 1378 "ritlb0\t$t, $s", []> { 1379 let r = 0x3; 1380 } 1381 1382 def RITLB1 : RRR_Inst<0x00, 0x00, 0x05, (outs AR:$t), (ins AR:$s), 1383 "ritlb1\t$t, $s", []> { 1384 let r = 0x7; 1385 } 1386 1387 def WDTLB : RRR_Inst<0x00, 0x00, 0x05, (outs AR:$t), (ins AR:$s), 1388 "wdtlb\t$t, $s", []> { 1389 let r = 0xE; 1390 } 1391 1392 def WITLB : RRR_Inst<0x00, 0x00, 0x05, (outs AR:$t), (ins AR:$s), 1393 "witlb\t$t, $s", []> { 1394 let r = 0x6; 1395 } 1396} 1397 1398//===----------------------------------------------------------------------===// 1399// Debug instructions 1400//===----------------------------------------------------------------------===// 1401 1402let isBarrier = 1, isTerminator = 1 in { 1403 def BREAK : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins uimm4:$s, uimm4:$t), 1404 "break\t$s, $t", []>, Requires<[HasDebug]> { 1405 let r = 0x04; 1406 } 1407 1408 def BREAK_N : RRRN_Inst<0x0C, (outs), (ins uimm4:$imm), 1409 "break.n\t$imm", []>, Requires<[HasDensity, HasDebug]> { 1410 bits<4> imm; 1411 1412 let r = 0xf; 1413 let s = imm; 1414 let t = 0x2; 1415 } 1416} 1417 1418def : InstAlias<"_break.n\t$imm", (BREAK_N uimm4:$imm)>; 1419 1420def : Pat<(trap), (BREAK (i32 1), (i32 15))>; 1421 1422// Load instruction 1423def LDDR32P : RRR_Inst<0x00, 0x00, 0x00, (outs AR:$s), (ins), 1424 "lddr32.p\t$s", []>, Requires<[HasDebug]> { 1425 let r = 0x7; 1426 let t = 0xe; 1427 let mayLoad = 1; 1428} 1429 1430// Store instruction 1431def SDDR32P : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins AR:$s), 1432 "sddr32.p\t$s", []>, Requires<[HasDebug]> { 1433 let r = 0x7; 1434 let t = 0xf; 1435 let mayStore = 1; 1436} 1437 1438//===----------------------------------------------------------------------===// 1439// Exception feature instructions 1440//===----------------------------------------------------------------------===// 1441 1442def EXCW : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 1443 "excw", []>, Requires<[HasException]> { 1444 let r = 0x2; 1445 let s = 0x0; 1446 let t = 0x8; 1447} 1448 1449def RFDE : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 1450 "rfde", []>, Requires<[HasException]> { 1451 let r = 0x3; 1452 let s = 0x2; 1453 let t = 0x0; 1454} 1455 1456 1457def RFE : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 1458 "rfe", []>, Requires<[HasException]> { 1459 let r = 0x3; 1460 let s = 0x0; 1461 let t = 0x0; 1462} 1463 1464def SYSCALL : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins), 1465 "syscall", []>, Requires<[HasException]> { 1466 let r = 0x5; 1467 let s = 0x0; 1468 let t = 0x0; 1469} 1470 1471//===----------------------------------------------------------------------===// 1472// Interrupt feature instructions 1473//===----------------------------------------------------------------------===// 1474 1475def RSIL : RRR_Inst<0x00, 0x00, 0x00, (outs AR:$t), (ins uimm4:$imm), 1476 "rsil\t$t, $imm", []>, Requires<[HasInterrupt]> { 1477 bits<4> imm; 1478 1479 let r = 0x6; 1480 let s = imm{3-0}; 1481} 1482 1483def WAITI : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins uimm4:$imm), 1484 "waiti\t$imm", []>, Requires<[HasInterrupt]> { 1485 bits<4> imm; 1486 1487 let r = 0x7; 1488 let s = imm{3-0}; 1489 let t = 0; 1490} 1491 1492def RFI : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins uimm4:$imm), 1493 "rfi\t$imm", []>, Requires<[HasHighPriInterrupts]> { 1494 bits<4> imm; 1495 1496 let r = 0x3; 1497 let s = imm{3-0}; 1498 let t = 0x1; 1499} 1500 1501//===----------------------------------------------------------------------===// 1502// DSP Instructions 1503//===----------------------------------------------------------------------===// 1504include "XtensaDSPInstrInfo.td" 1505