1;; GCC machine description for Tensilica's Xtensa architecture. 2;; Copyright (C) 2001-2020 Free Software Foundation, Inc. 3;; Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica. 4 5;; This file is part of GCC. 6 7;; GCC is free software; you can redistribute it and/or modify it 8;; under the terms of the GNU General Public License as published by 9;; the Free Software Foundation; either version 3, or (at your option) 10;; any later version. 11 12;; GCC is distributed in the hope that it will be useful, but WITHOUT 13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15;; License for more details. 16 17;; You should have received a copy of the GNU General Public License 18;; along with GCC; see the file COPYING3. If not see 19;; <http://www.gnu.org/licenses/>. 20 21 22(define_constants [ 23 (A0_REG 0) 24 (A1_REG 1) 25 (A7_REG 7) 26 (A8_REG 8) 27 (A9_REG 9) 28 29 (UNSPEC_NOP 2) 30 (UNSPEC_PLT 3) 31 (UNSPEC_RET_ADDR 4) 32 (UNSPEC_TPOFF 5) 33 (UNSPEC_DTPOFF 6) 34 (UNSPEC_TLS_FUNC 7) 35 (UNSPEC_TLS_ARG 8) 36 (UNSPEC_TLS_CALL 9) 37 (UNSPEC_TP 10) 38 (UNSPEC_MEMW 11) 39 (UNSPEC_LSETUP_START 12) 40 (UNSPEC_LSETUP_END 13) 41 (UNSPEC_FRAME_BLOCKAGE 14) 42 43 (UNSPECV_SET_FP 1) 44 (UNSPECV_ENTRY 2) 45 (UNSPECV_S32RI 4) 46 (UNSPECV_S32C1I 5) 47 (UNSPECV_EH_RETURN 6) 48 (UNSPECV_SET_TP 7) 49 (UNSPECV_BLOCKAGE 8) 50]) 51 52;; This code iterator allows signed and unsigned widening multiplications 53;; to use the same template. 54(define_code_iterator any_extend [sign_extend zero_extend]) 55 56;; <u> expands to an empty string when doing a signed operation and 57;; "u" when doing an unsigned operation. 58(define_code_attr u [(sign_extend "") (zero_extend "u")]) 59 60;; <su> is like <u>, but the signed form expands to "s" rather than "". 61(define_code_attr su [(sign_extend "s") (zero_extend "u")]) 62 63;; This code iterator allows four integer min/max operations to be 64;; generated from one template. 65(define_code_iterator any_minmax [smin umin smax umax]) 66 67;; <minmax> expands to the opcode name for any_minmax operations. 68(define_code_attr minmax [(smin "min") (umin "minu") 69 (smax "max") (umax "maxu")]) 70 71;; This code iterator is for floating-point comparisons. 72(define_code_iterator any_scc_sf [eq lt le uneq unlt unle unordered]) 73(define_code_attr scc_sf [(eq "oeq") (lt "olt") (le "ole") 74 (uneq "ueq") (unlt "ult") (unle "ule") 75 (unordered "un")]) 76 77;; This iterator and attribute allow to combine most atomic operations. 78(define_code_iterator ATOMIC [and ior xor plus minus mult]) 79(define_code_attr atomic [(and "and") (ior "ior") (xor "xor") 80 (plus "add") (minus "sub") (mult "nand")]) 81 82;; This mode iterator allows the HI and QI patterns to be defined from 83;; the same template. 84(define_mode_iterator HQI [HI QI]) 85 86 87;; Attributes. 88 89(define_attr "type" 90 "unknown,jump,call,load,store,move,arith,multi,nop,farith,fmadd,fconv,fload,fstore,mul16,mul32,div32,mac16,rsr,wsr,entry,trap" 91 (const_string "unknown")) 92 93(define_attr "mode" 94 "unknown,none,QI,HI,SI,DI,SF,DF,BL" 95 (const_string "unknown")) 96 97(define_attr "length" "" (const_int 1)) 98 99;; Describe a user's asm statement. 100(define_asm_attributes 101 [(set_attr "type" "multi")]) 102 103 104;; Pipeline model. 105 106;; The Xtensa basically has simple 5-stage RISC pipeline. 107;; Most instructions complete in 1 cycle, and it is OK to assume that 108;; everything is fully pipelined. The exceptions have special insn 109;; reservations in the pipeline description below. The Xtensa can 110;; issue one instruction per cycle, so defining CPU units is unnecessary. 111 112(define_insn_reservation "xtensa_any_insn" 1 113 (eq_attr "type" "!load,fload,rsr,mul16,mul32,fmadd,fconv") 114 "nothing") 115 116(define_insn_reservation "xtensa_memory" 2 117 (eq_attr "type" "load,fload") 118 "nothing") 119 120(define_insn_reservation "xtensa_sreg" 2 121 (eq_attr "type" "rsr") 122 "nothing") 123 124(define_insn_reservation "xtensa_mul16" 2 125 (eq_attr "type" "mul16") 126 "nothing") 127 128(define_insn_reservation "xtensa_mul32" 2 129 (eq_attr "type" "mul32") 130 "nothing") 131 132(define_insn_reservation "xtensa_fmadd" 4 133 (eq_attr "type" "fmadd") 134 "nothing") 135 136(define_insn_reservation "xtensa_fconv" 2 137 (eq_attr "type" "fconv") 138 "nothing") 139 140;; Include predicates and constraints. 141 142(include "predicates.md") 143(include "constraints.md") 144 145 146;; Addition. 147 148(define_insn "addsi3" 149 [(set (match_operand:SI 0 "register_operand" "=D,D,a,a,a") 150 (plus:SI (match_operand:SI 1 "register_operand" "%d,d,r,r,r") 151 (match_operand:SI 2 "add_operand" "d,O,r,J,N")))] 152 "" 153 "@ 154 add.n\t%0, %1, %2 155 addi.n\t%0, %1, %d2 156 add\t%0, %1, %2 157 addi\t%0, %1, %d2 158 addmi\t%0, %1, %x2" 159 [(set_attr "type" "arith,arith,arith,arith,arith") 160 (set_attr "mode" "SI") 161 (set_attr "length" "2,2,3,3,3")]) 162 163(define_insn "*addx" 164 [(set (match_operand:SI 0 "register_operand" "=a") 165 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") 166 (match_operand:SI 3 "addsubx_operand" "i")) 167 (match_operand:SI 2 "register_operand" "r")))] 168 "TARGET_ADDX" 169 "addx%3\t%0, %1, %2" 170 [(set_attr "type" "arith") 171 (set_attr "mode" "SI") 172 (set_attr "length" "3")]) 173 174(define_insn "addsf3" 175 [(set (match_operand:SF 0 "register_operand" "=f") 176 (plus:SF (match_operand:SF 1 "register_operand" "%f") 177 (match_operand:SF 2 "register_operand" "f")))] 178 "TARGET_HARD_FLOAT" 179 "add.s\t%0, %1, %2" 180 [(set_attr "type" "fmadd") 181 (set_attr "mode" "SF") 182 (set_attr "length" "3")]) 183 184 185;; Subtraction. 186 187(define_insn "subsi3" 188 [(set (match_operand:SI 0 "register_operand" "=a") 189 (minus:SI (match_operand:SI 1 "register_operand" "r") 190 (match_operand:SI 2 "register_operand" "r")))] 191 "" 192 "sub\t%0, %1, %2" 193 [(set_attr "type" "arith") 194 (set_attr "mode" "SI") 195 (set_attr "length" "3")]) 196 197(define_insn "*subx" 198 [(set (match_operand:SI 0 "register_operand" "=a") 199 (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") 200 (match_operand:SI 3 "addsubx_operand" "i")) 201 (match_operand:SI 2 "register_operand" "r")))] 202 "TARGET_ADDX" 203 "subx%3\t%0, %1, %2" 204 [(set_attr "type" "arith") 205 (set_attr "mode" "SI") 206 (set_attr "length" "3")]) 207 208(define_insn "subsf3" 209 [(set (match_operand:SF 0 "register_operand" "=f") 210 (minus:SF (match_operand:SF 1 "register_operand" "f") 211 (match_operand:SF 2 "register_operand" "f")))] 212 "TARGET_HARD_FLOAT" 213 "sub.s\t%0, %1, %2" 214 [(set_attr "type" "fmadd") 215 (set_attr "mode" "SF") 216 (set_attr "length" "3")]) 217 218 219;; Multiplication. 220 221(define_expand "<u>mulsidi3" 222 [(set (match_operand:DI 0 "register_operand") 223 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand")) 224 (any_extend:DI (match_operand:SI 2 "register_operand"))))] 225 "TARGET_MUL32_HIGH" 226{ 227 rtx temp = gen_reg_rtx (SImode); 228 emit_insn (gen_mulsi3 (temp, operands[1], operands[2])); 229 emit_insn (gen_<u>mulsi3_highpart (gen_highpart (SImode, operands[0]), 230 operands[1], operands[2])); 231 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), temp)); 232 DONE; 233}) 234 235(define_insn "<u>mulsi3_highpart" 236 [(set (match_operand:SI 0 "register_operand" "=a") 237 (truncate:SI 238 (lshiftrt:DI 239 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r")) 240 (any_extend:DI (match_operand:SI 2 "register_operand" "r"))) 241 (const_int 32))))] 242 "TARGET_MUL32_HIGH" 243 "mul<su>h\t%0, %1, %2" 244 [(set_attr "type" "mul32") 245 (set_attr "mode" "SI") 246 (set_attr "length" "3")]) 247 248(define_insn "mulsi3" 249 [(set (match_operand:SI 0 "register_operand" "=a") 250 (mult:SI (match_operand:SI 1 "register_operand" "%r") 251 (match_operand:SI 2 "register_operand" "r")))] 252 "TARGET_MUL32" 253 "mull\t%0, %1, %2" 254 [(set_attr "type" "mul32") 255 (set_attr "mode" "SI") 256 (set_attr "length" "3")]) 257 258(define_insn "mulhisi3" 259 [(set (match_operand:SI 0 "register_operand" "=C,A") 260 (mult:SI (sign_extend:SI 261 (match_operand:HI 1 "register_operand" "%r,r")) 262 (sign_extend:SI 263 (match_operand:HI 2 "register_operand" "r,r"))))] 264 "TARGET_MUL16 || TARGET_MAC16" 265 "@ 266 mul16s\t%0, %1, %2 267 mul.aa.ll\t%1, %2" 268 [(set_attr "type" "mul16,mac16") 269 (set_attr "mode" "SI") 270 (set_attr "length" "3,3")]) 271 272(define_insn "umulhisi3" 273 [(set (match_operand:SI 0 "register_operand" "=C,A") 274 (mult:SI (zero_extend:SI 275 (match_operand:HI 1 "register_operand" "%r,r")) 276 (zero_extend:SI 277 (match_operand:HI 2 "register_operand" "r,r"))))] 278 "TARGET_MUL16 || TARGET_MAC16" 279 "@ 280 mul16u\t%0, %1, %2 281 umul.aa.ll\t%1, %2" 282 [(set_attr "type" "mul16,mac16") 283 (set_attr "mode" "SI") 284 (set_attr "length" "3,3")]) 285 286(define_insn "muladdhisi" 287 [(set (match_operand:SI 0 "register_operand" "=A") 288 (plus:SI (mult:SI (sign_extend:SI 289 (match_operand:HI 1 "register_operand" "%r")) 290 (sign_extend:SI 291 (match_operand:HI 2 "register_operand" "r"))) 292 (match_operand:SI 3 "register_operand" "0")))] 293 "TARGET_MAC16" 294 "mula.aa.ll\t%1, %2" 295 [(set_attr "type" "mac16") 296 (set_attr "mode" "SI") 297 (set_attr "length" "3")]) 298 299(define_insn "mulsubhisi" 300 [(set (match_operand:SI 0 "register_operand" "=A") 301 (minus:SI (match_operand:SI 1 "register_operand" "0") 302 (mult:SI (sign_extend:SI 303 (match_operand:HI 2 "register_operand" "%r")) 304 (sign_extend:SI 305 (match_operand:HI 3 "register_operand" "r")))))] 306 "TARGET_MAC16" 307 "muls.aa.ll\t%2, %3" 308 [(set_attr "type" "mac16") 309 (set_attr "mode" "SI") 310 (set_attr "length" "3")]) 311 312(define_insn "mulsf3" 313 [(set (match_operand:SF 0 "register_operand" "=f") 314 (mult:SF (match_operand:SF 1 "register_operand" "%f") 315 (match_operand:SF 2 "register_operand" "f")))] 316 "TARGET_HARD_FLOAT" 317 "mul.s\t%0, %1, %2" 318 [(set_attr "type" "fmadd") 319 (set_attr "mode" "SF") 320 (set_attr "length" "3")]) 321 322(define_insn "fmasf4" 323 [(set (match_operand:SF 0 "register_operand" "=f") 324 (fma:SF (match_operand:SF 1 "register_operand" "f") 325 (match_operand:SF 2 "register_operand" "f") 326 (match_operand:SF 3 "register_operand" "0")))] 327 "TARGET_HARD_FLOAT" 328 "madd.s\t%0, %1, %2" 329 [(set_attr "type" "fmadd") 330 (set_attr "mode" "SF") 331 (set_attr "length" "3")]) 332 333;; Note that (C - A*B) = (-A*B + C) 334(define_insn "fnmasf4" 335 [(set (match_operand:SF 0 "register_operand" "=f") 336 (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f")) 337 (match_operand:SF 2 "register_operand" "f") 338 (match_operand:SF 3 "register_operand" "0")))] 339 "TARGET_HARD_FLOAT" 340 "msub.s\t%0, %1, %2" 341 [(set_attr "type" "fmadd") 342 (set_attr "mode" "SF") 343 (set_attr "length" "3")]) 344 345 346;; Division. 347 348(define_insn "divsi3" 349 [(set (match_operand:SI 0 "register_operand" "=a") 350 (div:SI (match_operand:SI 1 "register_operand" "r") 351 (match_operand:SI 2 "register_operand" "r")))] 352 "TARGET_DIV32" 353 "quos\t%0, %1, %2" 354 [(set_attr "type" "div32") 355 (set_attr "mode" "SI") 356 (set_attr "length" "3")]) 357 358(define_insn "udivsi3" 359 [(set (match_operand:SI 0 "register_operand" "=a") 360 (udiv:SI (match_operand:SI 1 "register_operand" "r") 361 (match_operand:SI 2 "register_operand" "r")))] 362 "TARGET_DIV32" 363 "quou\t%0, %1, %2" 364 [(set_attr "type" "div32") 365 (set_attr "mode" "SI") 366 (set_attr "length" "3")]) 367 368 369;; Remainders. 370 371(define_insn "modsi3" 372 [(set (match_operand:SI 0 "register_operand" "=a") 373 (mod:SI (match_operand:SI 1 "register_operand" "r") 374 (match_operand:SI 2 "register_operand" "r")))] 375 "TARGET_DIV32" 376 "rems\t%0, %1, %2" 377 [(set_attr "type" "div32") 378 (set_attr "mode" "SI") 379 (set_attr "length" "3")]) 380 381(define_insn "umodsi3" 382 [(set (match_operand:SI 0 "register_operand" "=a") 383 (umod:SI (match_operand:SI 1 "register_operand" "r") 384 (match_operand:SI 2 "register_operand" "r")))] 385 "TARGET_DIV32" 386 "remu\t%0, %1, %2" 387 [(set_attr "type" "div32") 388 (set_attr "mode" "SI") 389 (set_attr "length" "3")]) 390 391 392;; Absolute value. 393 394(define_insn "abssi2" 395 [(set (match_operand:SI 0 "register_operand" "=a") 396 (abs:SI (match_operand:SI 1 "register_operand" "r")))] 397 "TARGET_ABS" 398 "abs\t%0, %1" 399 [(set_attr "type" "arith") 400 (set_attr "mode" "SI") 401 (set_attr "length" "3")]) 402 403(define_insn "abssf2" 404 [(set (match_operand:SF 0 "register_operand" "=f") 405 (abs:SF (match_operand:SF 1 "register_operand" "f")))] 406 "TARGET_HARD_FLOAT" 407 "abs.s\t%0, %1" 408 [(set_attr "type" "farith") 409 (set_attr "mode" "SF") 410 (set_attr "length" "3")]) 411 412 413;; Min and max. 414 415(define_insn "<code>si3" 416 [(set (match_operand:SI 0 "register_operand" "=a") 417 (any_minmax:SI (match_operand:SI 1 "register_operand" "%r") 418 (match_operand:SI 2 "register_operand" "r")))] 419 "TARGET_MINMAX" 420 "<minmax>\t%0, %1, %2" 421 [(set_attr "type" "arith") 422 (set_attr "mode" "SI") 423 (set_attr "length" "3")]) 424 425 426;; Count leading/trailing zeros and find first bit. 427 428(define_insn "clzsi2" 429 [(set (match_operand:SI 0 "register_operand" "=a") 430 (clz:SI (match_operand:SI 1 "register_operand" "r")))] 431 "TARGET_NSA" 432 "nsau\t%0, %1" 433 [(set_attr "type" "arith") 434 (set_attr "mode" "SI") 435 (set_attr "length" "3")]) 436 437(define_expand "ctzsi2" 438 [(set (match_operand:SI 0 "register_operand" "") 439 (ctz:SI (match_operand:SI 1 "register_operand" "")))] 440 "TARGET_NSA" 441{ 442 rtx temp = gen_reg_rtx (SImode); 443 emit_insn (gen_negsi2 (temp, operands[1])); 444 emit_insn (gen_andsi3 (temp, temp, operands[1])); 445 emit_insn (gen_clzsi2 (temp, temp)); 446 emit_insn (gen_negsi2 (temp, temp)); 447 emit_insn (gen_addsi3 (operands[0], temp, GEN_INT (31))); 448 DONE; 449}) 450 451(define_expand "ffssi2" 452 [(set (match_operand:SI 0 "register_operand" "") 453 (ffs:SI (match_operand:SI 1 "register_operand" "")))] 454 "TARGET_NSA" 455{ 456 rtx temp = gen_reg_rtx (SImode); 457 emit_insn (gen_negsi2 (temp, operands[1])); 458 emit_insn (gen_andsi3 (temp, temp, operands[1])); 459 emit_insn (gen_clzsi2 (temp, temp)); 460 emit_insn (gen_negsi2 (temp, temp)); 461 emit_insn (gen_addsi3 (operands[0], temp, GEN_INT (32))); 462 DONE; 463}) 464 465 466;; Negation and one's complement. 467 468(define_insn "negsi2" 469 [(set (match_operand:SI 0 "register_operand" "=a") 470 (neg:SI (match_operand:SI 1 "register_operand" "r")))] 471 "" 472 "neg\t%0, %1" 473 [(set_attr "type" "arith") 474 (set_attr "mode" "SI") 475 (set_attr "length" "3")]) 476 477(define_expand "one_cmplsi2" 478 [(set (match_operand:SI 0 "register_operand" "") 479 (not:SI (match_operand:SI 1 "register_operand" "")))] 480 "" 481{ 482 rtx temp = gen_reg_rtx (SImode); 483 emit_insn (gen_movsi (temp, constm1_rtx)); 484 emit_insn (gen_xorsi3 (operands[0], temp, operands[1])); 485 DONE; 486}) 487 488(define_insn "negsf2" 489 [(set (match_operand:SF 0 "register_operand" "=f") 490 (neg:SF (match_operand:SF 1 "register_operand" "f")))] 491 "TARGET_HARD_FLOAT" 492 "neg.s\t%0, %1" 493 [(set_attr "type" "farith") 494 (set_attr "mode" "SF") 495 (set_attr "length" "3")]) 496 497 498;; Logical instructions. 499 500(define_insn "andsi3" 501 [(set (match_operand:SI 0 "register_operand" "=a,a") 502 (and:SI (match_operand:SI 1 "register_operand" "%r,r") 503 (match_operand:SI 2 "mask_operand" "P,r")))] 504 "" 505 "@ 506 extui\t%0, %1, 0, %K2 507 and\t%0, %1, %2" 508 [(set_attr "type" "arith,arith") 509 (set_attr "mode" "SI") 510 (set_attr "length" "3,3")]) 511 512(define_insn "iorsi3" 513 [(set (match_operand:SI 0 "register_operand" "=a") 514 (ior:SI (match_operand:SI 1 "register_operand" "%r") 515 (match_operand:SI 2 "register_operand" "r")))] 516 "" 517 "or\t%0, %1, %2" 518 [(set_attr "type" "arith") 519 (set_attr "mode" "SI") 520 (set_attr "length" "3")]) 521 522(define_insn "xorsi3" 523 [(set (match_operand:SI 0 "register_operand" "=a") 524 (xor:SI (match_operand:SI 1 "register_operand" "%r") 525 (match_operand:SI 2 "register_operand" "r")))] 526 "" 527 "xor\t%0, %1, %2" 528 [(set_attr "type" "arith") 529 (set_attr "mode" "SI") 530 (set_attr "length" "3")]) 531 532 533;; Zero-extend instructions. 534 535(define_insn "zero_extendhisi2" 536 [(set (match_operand:SI 0 "register_operand" "=a,a") 537 (zero_extend:SI (match_operand:HI 1 "nonimmed_operand" "r,U")))] 538 "" 539 "@ 540 extui\t%0, %1, 0, 16 541 %v1l16ui\t%0, %1" 542 [(set_attr "type" "arith,load") 543 (set_attr "mode" "SI") 544 (set_attr "length" "3,3")]) 545 546(define_insn "zero_extendqisi2" 547 [(set (match_operand:SI 0 "register_operand" "=a,a") 548 (zero_extend:SI (match_operand:QI 1 "nonimmed_operand" "r,U")))] 549 "" 550 "@ 551 extui\t%0, %1, 0, 8 552 %v1l8ui\t%0, %1" 553 [(set_attr "type" "arith,load") 554 (set_attr "mode" "SI") 555 (set_attr "length" "3,3")]) 556 557 558;; Sign-extend instructions. 559 560(define_expand "extendhisi2" 561 [(set (match_operand:SI 0 "register_operand" "") 562 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] 563 "" 564{ 565 if (sext_operand (operands[1], HImode)) 566 emit_insn (gen_extendhisi2_internal (operands[0], operands[1])); 567 else 568 xtensa_extend_reg (operands[0], operands[1]); 569 DONE; 570}) 571 572(define_insn "extendhisi2_internal" 573 [(set (match_operand:SI 0 "register_operand" "=B,a") 574 (sign_extend:SI (match_operand:HI 1 "sext_operand" "r,U")))] 575 "" 576 "@ 577 sext\t%0, %1, 15 578 %v1l16si\t%0, %1" 579 [(set_attr "type" "arith,load") 580 (set_attr "mode" "SI") 581 (set_attr "length" "3,3")]) 582 583(define_expand "extendqisi2" 584 [(set (match_operand:SI 0 "register_operand" "") 585 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))] 586 "" 587{ 588 if (TARGET_SEXT) 589 emit_insn (gen_extendqisi2_internal (operands[0], operands[1])); 590 else 591 xtensa_extend_reg (operands[0], operands[1]); 592 DONE; 593}) 594 595(define_insn "extendqisi2_internal" 596 [(set (match_operand:SI 0 "register_operand" "=B") 597 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))] 598 "TARGET_SEXT" 599 "sext\t%0, %1, 7" 600 [(set_attr "type" "arith") 601 (set_attr "mode" "SI") 602 (set_attr "length" "3")]) 603 604 605;; Field extract instructions. 606 607(define_expand "extv" 608 [(set (match_operand:SI 0 "register_operand" "") 609 (sign_extract:SI (match_operand:SI 1 "register_operand" "") 610 (match_operand:SI 2 "const_int_operand" "") 611 (match_operand:SI 3 "const_int_operand" "")))] 612 "TARGET_SEXT" 613{ 614 if (!sext_fldsz_operand (operands[2], SImode)) 615 FAIL; 616 617 /* We could expand to a right shift followed by SEXT but that's 618 no better than the standard left and right shift sequence. */ 619 if (!lsbitnum_operand (operands[3], SImode)) 620 FAIL; 621 622 emit_insn (gen_extv_internal (operands[0], operands[1], 623 operands[2], operands[3])); 624 DONE; 625}) 626 627(define_insn "extv_internal" 628 [(set (match_operand:SI 0 "register_operand" "=a") 629 (sign_extract:SI (match_operand:SI 1 "register_operand" "r") 630 (match_operand:SI 2 "sext_fldsz_operand" "i") 631 (match_operand:SI 3 "lsbitnum_operand" "i")))] 632 "TARGET_SEXT" 633{ 634 int fldsz = INTVAL (operands[2]); 635 operands[2] = GEN_INT (fldsz - 1); 636 return "sext\t%0, %1, %2"; 637} 638 [(set_attr "type" "arith") 639 (set_attr "mode" "SI") 640 (set_attr "length" "3")]) 641 642(define_expand "extzv" 643 [(set (match_operand:SI 0 "register_operand" "") 644 (zero_extract:SI (match_operand:SI 1 "register_operand" "") 645 (match_operand:SI 2 "const_int_operand" "") 646 (match_operand:SI 3 "const_int_operand" "")))] 647 "" 648{ 649 if (!extui_fldsz_operand (operands[2], SImode)) 650 FAIL; 651 emit_insn (gen_extzv_internal (operands[0], operands[1], 652 operands[2], operands[3])); 653 DONE; 654}) 655 656(define_insn "extzv_internal" 657 [(set (match_operand:SI 0 "register_operand" "=a") 658 (zero_extract:SI (match_operand:SI 1 "register_operand" "r") 659 (match_operand:SI 2 "extui_fldsz_operand" "i") 660 (match_operand:SI 3 "const_int_operand" "i")))] 661 "" 662{ 663 int shift; 664 if (BITS_BIG_ENDIAN) 665 shift = (32 - (INTVAL (operands[2]) + INTVAL (operands[3]))) & 0x1f; 666 else 667 shift = INTVAL (operands[3]) & 0x1f; 668 operands[3] = GEN_INT (shift); 669 return "extui\t%0, %1, %3, %2"; 670} 671 [(set_attr "type" "arith") 672 (set_attr "mode" "SI") 673 (set_attr "length" "3")]) 674 675 676;; Conversions. 677 678(define_insn "fix_truncsfsi2" 679 [(set (match_operand:SI 0 "register_operand" "=a") 680 (fix:SI (match_operand:SF 1 "register_operand" "f")))] 681 "TARGET_HARD_FLOAT" 682 "trunc.s\t%0, %1, 0" 683 [(set_attr "type" "fconv") 684 (set_attr "mode" "SF") 685 (set_attr "length" "3")]) 686 687(define_insn "fixuns_truncsfsi2" 688 [(set (match_operand:SI 0 "register_operand" "=a") 689 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "f")))] 690 "TARGET_HARD_FLOAT" 691 "utrunc.s\t%0, %1, 0" 692 [(set_attr "type" "fconv") 693 (set_attr "mode" "SF") 694 (set_attr "length" "3")]) 695 696(define_insn "floatsisf2" 697 [(set (match_operand:SF 0 "register_operand" "=f") 698 (float:SF (match_operand:SI 1 "register_operand" "a")))] 699 "TARGET_HARD_FLOAT" 700 "float.s\t%0, %1, 0" 701 [(set_attr "type" "fconv") 702 (set_attr "mode" "SF") 703 (set_attr "length" "3")]) 704 705(define_insn "floatunssisf2" 706 [(set (match_operand:SF 0 "register_operand" "=f") 707 (unsigned_float:SF (match_operand:SI 1 "register_operand" "a")))] 708 "TARGET_HARD_FLOAT" 709 "ufloat.s\t%0, %1, 0" 710 [(set_attr "type" "fconv") 711 (set_attr "mode" "SF") 712 (set_attr "length" "3")]) 713 714 715;; Data movement instructions. 716 717;; 64-bit Integer moves 718 719(define_expand "movdi" 720 [(set (match_operand:DI 0 "nonimmed_operand" "") 721 (match_operand:DI 1 "general_operand" ""))] 722 "" 723{ 724 if (CONSTANT_P (operands[1]) && !TARGET_CONST16) 725 operands[1] = force_const_mem (DImode, operands[1]); 726 727 if (!register_operand (operands[0], DImode) 728 && !register_operand (operands[1], DImode)) 729 operands[1] = force_reg (DImode, operands[1]); 730 731 operands[1] = xtensa_copy_incoming_a7 (operands[1]); 732}) 733 734(define_insn_and_split "movdi_internal" 735 [(set (match_operand:DI 0 "nonimmed_operand" "=a,W,a,a,U") 736 (match_operand:DI 1 "move_operand" "r,i,T,U,r"))] 737 "register_operand (operands[0], DImode) 738 || register_operand (operands[1], DImode)" 739 "#" 740 "reload_completed" 741 [(set (match_dup 0) (match_dup 2)) 742 (set (match_dup 1) (match_dup 3))] 743{ 744 xtensa_split_operand_pair (operands, SImode); 745 if (reg_overlap_mentioned_p (operands[0], operands[3])) 746 { 747 rtx tmp; 748 tmp = operands[0], operands[0] = operands[1], operands[1] = tmp; 749 tmp = operands[2], operands[2] = operands[3], operands[3] = tmp; 750 } 751}) 752 753;; 32-bit Integer moves 754 755(define_expand "movsi" 756 [(set (match_operand:SI 0 "nonimmed_operand" "") 757 (match_operand:SI 1 "general_operand" ""))] 758 "" 759{ 760 if (xtensa_emit_move_sequence (operands, SImode)) 761 DONE; 762}) 763 764(define_insn "movsi_internal" 765 [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,a,W,a,a,U,*a,*A") 766 (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,Y,i,T,U,r,*A,*r"))] 767 "xtensa_valid_move (SImode, operands)" 768 "@ 769 movi.n\t%0, %x1 770 mov.n\t%0, %1 771 mov.n\t%0, %1 772 %v1l32i.n\t%0, %1 773 %v0s32i.n\t%1, %0 774 %v0s32i.n\t%1, %0 775 mov\t%0, %1 776 movsp\t%0, %1 777 movi\t%0, %x1 778 movi\t%0, %1 779 const16\t%0, %t1\;const16\t%0, %b1 780 %v1l32r\t%0, %1 781 %v1l32i\t%0, %1 782 %v0s32i\t%1, %0 783 rsr\t%0, ACCLO 784 wsr\t%1, ACCLO" 785 [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,move,load,load,store,rsr,wsr") 786 (set_attr "mode" "SI") 787 (set_attr "length" "2,2,2,2,2,2,3,3,3,3,6,3,3,3,3,3")]) 788 789;; 16-bit Integer moves 790 791(define_expand "movhi" 792 [(set (match_operand:HI 0 "nonimmed_operand" "") 793 (match_operand:HI 1 "general_operand" ""))] 794 "" 795{ 796 if (xtensa_emit_move_sequence (operands, HImode)) 797 DONE; 798}) 799 800(define_insn "movhi_internal" 801 [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,a,U,*a,*A") 802 (match_operand:HI 1 "move_operand" "M,d,r,I,Y,U,r,*A,*r"))] 803 "xtensa_valid_move (HImode, operands)" 804 "@ 805 movi.n\t%0, %x1 806 mov.n\t%0, %1 807 mov\t%0, %1 808 movi\t%0, %x1 809 movi\t%0, %1 810 %v1l16ui\t%0, %1 811 %v0s16i\t%1, %0 812 rsr\t%0, ACCLO 813 wsr\t%1, ACCLO" 814 [(set_attr "type" "move,move,move,move,move,load,store,rsr,wsr") 815 (set_attr "mode" "HI") 816 (set_attr "length" "2,2,3,3,3,3,3,3,3")]) 817 818;; 8-bit Integer moves 819 820(define_expand "movqi" 821 [(set (match_operand:QI 0 "nonimmed_operand" "") 822 (match_operand:QI 1 "general_operand" ""))] 823 "" 824{ 825 if (xtensa_emit_move_sequence (operands, QImode)) 826 DONE; 827}) 828 829(define_insn "movqi_internal" 830 [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A") 831 (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))] 832 "xtensa_valid_move (QImode, operands)" 833 "@ 834 movi.n\t%0, %x1 835 mov.n\t%0, %1 836 mov\t%0, %1 837 movi\t%0, %x1 838 %v1l8ui\t%0, %1 839 %v0s8i\t%1, %0 840 rsr\t%0, ACCLO 841 wsr\t%1, ACCLO" 842 [(set_attr "type" "move,move,move,move,load,store,rsr,wsr") 843 (set_attr "mode" "QI") 844 (set_attr "length" "2,2,3,3,3,3,3,3")]) 845 846;; Sub-word reloads from the constant pool. 847 848(define_expand "reload<mode>_literal" 849 [(parallel [(match_operand:HQI 0 "register_operand" "=r") 850 (match_operand:HQI 1 "constantpool_operand" "") 851 (match_operand:SI 2 "register_operand" "=&r")])] 852 "" 853{ 854 rtx lit, scratch; 855 unsigned word_off, byte_off; 856 857 if (MEM_P (operands[1])) 858 { 859 lit = operands[1]; 860 word_off = 0; 861 byte_off = 0; 862 } 863 else 864 { 865 gcc_assert (GET_CODE (operands[1]) == SUBREG); 866 lit = SUBREG_REG (operands[1]); 867 word_off = SUBREG_BYTE (operands[1]) & ~(UNITS_PER_WORD - 1); 868 byte_off = SUBREG_BYTE (operands[1]) - word_off; 869 } 870 871 lit = adjust_address (lit, SImode, word_off); 872 scratch = operands[2]; 873 emit_insn (gen_movsi (scratch, lit)); 874 emit_insn (gen_mov<mode> (operands[0], 875 gen_rtx_SUBREG (<MODE>mode, scratch, byte_off))); 876 877 DONE; 878}) 879 880;; 32-bit floating point moves 881 882(define_expand "movsf" 883 [(set (match_operand:SF 0 "nonimmed_operand" "") 884 (match_operand:SF 1 "general_operand" ""))] 885 "" 886{ 887 if (!TARGET_CONST16 && !TARGET_AUTO_LITPOOLS && CONSTANT_P (operands[1])) 888 operands[1] = force_const_mem (SFmode, operands[1]); 889 890 if ((!register_operand (operands[0], SFmode) 891 && !register_operand (operands[1], SFmode)) 892 || (FP_REG_P (xt_true_regnum (operands[0])) 893 && !(reload_in_progress | reload_completed) 894 && (constantpool_mem_p (operands[1]) 895 || CONSTANT_P (operands[1])))) 896 operands[1] = force_reg (SFmode, operands[1]); 897 898 operands[1] = xtensa_copy_incoming_a7 (operands[1]); 899}) 900 901(define_insn "movsf_internal" 902 [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,a,W,a,a,U") 903 (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,Y,iF,T,U,r"))] 904 "((register_operand (operands[0], SFmode) 905 || register_operand (operands[1], SFmode)) 906 && !(FP_REG_P (xt_true_regnum (operands[0])) 907 && (constantpool_mem_p (operands[1]) || CONSTANT_P (operands[1]))))" 908 "@ 909 mov.s\t%0, %1 910 %v1lsi\t%0, %1 911 %v0ssi\t%1, %0 912 mov.n\t%0, %1 913 %v1l32i.n\t%0, %1 914 %v0s32i.n\t%1, %0 915 mov\t%0, %1 916 wfr\t%0, %1 917 rfr\t%0, %1 918 movi\t%0, %y1 919 const16\t%0, %t1\;const16\t%0, %b1 920 %v1l32r\t%0, %1 921 %v1l32i\t%0, %1 922 %v0s32i\t%1, %0" 923 [(set_attr "type" "farith,fload,fstore,move,load,store,move,farith,farith,move,move,load,load,store") 924 (set_attr "mode" "SF") 925 (set_attr "length" "3,3,3,2,2,2,3,3,3,3,6,3,3,3")]) 926 927(define_insn "*lsiu" 928 [(set (match_operand:SF 0 "register_operand" "=f") 929 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "+a") 930 (match_operand:SI 2 "fpmem_offset_operand" "i")))) 931 (set (match_dup 1) 932 (plus:SI (match_dup 1) (match_dup 2)))] 933 "TARGET_HARD_FLOAT && !TARGET_HARD_FLOAT_POSTINC" 934{ 935 if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn))) 936 output_asm_insn ("memw", operands); 937 return "lsiu\t%0, %1, %2"; 938} 939 [(set_attr "type" "fload") 940 (set_attr "mode" "SF") 941 (set_attr "length" "3")]) 942 943(define_insn "*ssiu" 944 [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a") 945 (match_operand:SI 1 "fpmem_offset_operand" "i"))) 946 (match_operand:SF 2 "register_operand" "f")) 947 (set (match_dup 0) 948 (plus:SI (match_dup 0) (match_dup 1)))] 949 "TARGET_HARD_FLOAT && !TARGET_HARD_FLOAT_POSTINC" 950{ 951 if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn))) 952 output_asm_insn ("memw", operands); 953 return "ssiu\t%2, %0, %1"; 954} 955 [(set_attr "type" "fstore") 956 (set_attr "mode" "SF") 957 (set_attr "length" "3")]) 958 959(define_insn "*lsip" 960 [(set (match_operand:SF 0 "register_operand" "=f") 961 (mem:SF (match_operand:SI 1 "register_operand" "+a"))) 962 (set (match_dup 1) 963 (plus:SI (match_dup 1) 964 (match_operand:SI 2 "fpmem_offset_operand" "i")))] 965 "TARGET_HARD_FLOAT && TARGET_HARD_FLOAT_POSTINC" 966{ 967 if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn))) 968 output_asm_insn ("memw", operands); 969 return "lsip\t%0, %1, %2"; 970} 971 [(set_attr "type" "fload") 972 (set_attr "mode" "SF") 973 (set_attr "length" "3")]) 974 975(define_insn "*ssip" 976 [(set (mem:SF (match_operand:SI 0 "register_operand" "+a")) 977 (match_operand:SF 1 "register_operand" "f")) 978 (set (match_dup 0) 979 (plus:SI (match_dup 0) 980 (match_operand:SI 2 "fpmem_offset_operand" "i")))] 981 "TARGET_HARD_FLOAT && TARGET_HARD_FLOAT_POSTINC" 982{ 983 if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn))) 984 output_asm_insn ("memw", operands); 985 return "ssip\t%1, %0, %2"; 986} 987 [(set_attr "type" "fstore") 988 (set_attr "mode" "SF") 989 (set_attr "length" "3")]) 990 991;; 64-bit floating point moves 992 993(define_expand "movdf" 994 [(set (match_operand:DF 0 "nonimmed_operand" "") 995 (match_operand:DF 1 "general_operand" ""))] 996 "" 997{ 998 if (CONSTANT_P (operands[1]) && !TARGET_CONST16 && !TARGET_AUTO_LITPOOLS) 999 operands[1] = force_const_mem (DFmode, operands[1]); 1000 1001 if (!register_operand (operands[0], DFmode) 1002 && !register_operand (operands[1], DFmode)) 1003 operands[1] = force_reg (DFmode, operands[1]); 1004 1005 operands[1] = xtensa_copy_incoming_a7 (operands[1]); 1006}) 1007 1008(define_insn_and_split "movdf_internal" 1009 [(set (match_operand:DF 0 "nonimmed_operand" "=a,a,W,a,a,U") 1010 (match_operand:DF 1 "move_operand" "r,Y,iF,T,U,r"))] 1011 "register_operand (operands[0], DFmode) 1012 || register_operand (operands[1], DFmode)" 1013 "#" 1014 "reload_completed" 1015 [(set (match_dup 0) (match_dup 2)) 1016 (set (match_dup 1) (match_dup 3))] 1017{ 1018 xtensa_split_operand_pair (operands, SFmode); 1019 if (reg_overlap_mentioned_p (operands[0], operands[3])) 1020 { 1021 rtx tmp; 1022 tmp = operands[0], operands[0] = operands[1], operands[1] = tmp; 1023 tmp = operands[2], operands[2] = operands[3], operands[3] = tmp; 1024 } 1025}) 1026 1027;; Block moves 1028 1029(define_expand "cpymemsi" 1030 [(parallel [(set (match_operand:BLK 0 "" "") 1031 (match_operand:BLK 1 "" "")) 1032 (use (match_operand:SI 2 "arith_operand" "")) 1033 (use (match_operand:SI 3 "const_int_operand" ""))])] 1034 "" 1035{ 1036 if (!xtensa_expand_block_move (operands)) 1037 FAIL; 1038 DONE; 1039}) 1040 1041 1042;; Shift instructions. 1043 1044(define_expand "ashlsi3" 1045 [(set (match_operand:SI 0 "register_operand" "") 1046 (ashift:SI (match_operand:SI 1 "register_operand" "") 1047 (match_operand:SI 2 "arith_operand" "")))] 1048 "" 1049{ 1050 operands[1] = xtensa_copy_incoming_a7 (operands[1]); 1051}) 1052 1053(define_insn "ashlsi3_internal" 1054 [(set (match_operand:SI 0 "register_operand" "=a,a") 1055 (ashift:SI (match_operand:SI 1 "register_operand" "r,r") 1056 (match_operand:SI 2 "arith_operand" "J,r")))] 1057 "" 1058 "@ 1059 slli\t%0, %1, %R2 1060 ssl\t%2\;sll\t%0, %1" 1061 [(set_attr "type" "arith,arith") 1062 (set_attr "mode" "SI") 1063 (set_attr "length" "3,6")]) 1064 1065(define_insn "ashrsi3" 1066 [(set (match_operand:SI 0 "register_operand" "=a,a") 1067 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r") 1068 (match_operand:SI 2 "arith_operand" "J,r")))] 1069 "" 1070 "@ 1071 srai\t%0, %1, %R2 1072 ssr\t%2\;sra\t%0, %1" 1073 [(set_attr "type" "arith,arith") 1074 (set_attr "mode" "SI") 1075 (set_attr "length" "3,6")]) 1076 1077(define_insn "lshrsi3" 1078 [(set (match_operand:SI 0 "register_operand" "=a,a") 1079 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r") 1080 (match_operand:SI 2 "arith_operand" "J,r")))] 1081 "" 1082{ 1083 if (which_alternative == 0) 1084 { 1085 if ((INTVAL (operands[2]) & 0x1f) < 16) 1086 return "srli\t%0, %1, %R2"; 1087 else 1088 return "extui\t%0, %1, %R2, %L2"; 1089 } 1090 return "ssr\t%2\;srl\t%0, %1"; 1091} 1092 [(set_attr "type" "arith,arith") 1093 (set_attr "mode" "SI") 1094 (set_attr "length" "3,6")]) 1095 1096(define_insn "rotlsi3" 1097 [(set (match_operand:SI 0 "register_operand" "=a,a") 1098 (rotate:SI (match_operand:SI 1 "register_operand" "r,r") 1099 (match_operand:SI 2 "arith_operand" "J,r")))] 1100 "" 1101 "@ 1102 ssai\t%L2\;src\t%0, %1, %1 1103 ssl\t%2\;src\t%0, %1, %1" 1104 [(set_attr "type" "multi,multi") 1105 (set_attr "mode" "SI") 1106 (set_attr "length" "6,6")]) 1107 1108(define_insn "rotrsi3" 1109 [(set (match_operand:SI 0 "register_operand" "=a,a") 1110 (rotatert:SI (match_operand:SI 1 "register_operand" "r,r") 1111 (match_operand:SI 2 "arith_operand" "J,r")))] 1112 "" 1113 "@ 1114 ssai\t%R2\;src\t%0, %1, %1 1115 ssr\t%2\;src\t%0, %1, %1" 1116 [(set_attr "type" "multi,multi") 1117 (set_attr "mode" "SI") 1118 (set_attr "length" "6,6")]) 1119 1120 1121;; Comparisons. 1122 1123;; Conditional branches. 1124 1125(define_expand "cbranchsi4" 1126 [(match_operator 0 "comparison_operator" 1127 [(match_operand:SI 1 "register_operand") 1128 (match_operand:SI 2 "nonmemory_operand")]) 1129 (match_operand 3 "")] 1130 "" 1131{ 1132 xtensa_expand_conditional_branch (operands, SImode); 1133 DONE; 1134}) 1135 1136(define_expand "cbranchsf4" 1137 [(match_operator 0 "comparison_operator" 1138 [(match_operand:SF 1 "register_operand") 1139 (match_operand:SF 2 "register_operand")]) 1140 (match_operand 3 "")] 1141 "TARGET_HARD_FLOAT" 1142{ 1143 xtensa_expand_conditional_branch (operands, SFmode); 1144 DONE; 1145}) 1146 1147;; Branch patterns for standard integer comparisons 1148 1149(define_insn "*btrue" 1150 [(set (pc) 1151 (if_then_else (match_operator 3 "branch_operator" 1152 [(match_operand:SI 0 "register_operand" "r,r") 1153 (match_operand:SI 1 "branch_operand" "K,r")]) 1154 (label_ref (match_operand 2 "" "")) 1155 (pc)))] 1156 "" 1157{ 1158 return xtensa_emit_branch (false, which_alternative == 0, operands); 1159} 1160 [(set_attr "type" "jump,jump") 1161 (set_attr "mode" "none") 1162 (set_attr "length" "3,3")]) 1163 1164(define_insn "*bfalse" 1165 [(set (pc) 1166 (if_then_else (match_operator 3 "branch_operator" 1167 [(match_operand:SI 0 "register_operand" "r,r") 1168 (match_operand:SI 1 "branch_operand" "K,r")]) 1169 (pc) 1170 (label_ref (match_operand 2 "" ""))))] 1171 "" 1172{ 1173 return xtensa_emit_branch (true, which_alternative == 0, operands); 1174} 1175 [(set_attr "type" "jump,jump") 1176 (set_attr "mode" "none") 1177 (set_attr "length" "3,3")]) 1178 1179(define_insn "*ubtrue" 1180 [(set (pc) 1181 (if_then_else (match_operator 3 "ubranch_operator" 1182 [(match_operand:SI 0 "register_operand" "r,r") 1183 (match_operand:SI 1 "ubranch_operand" "L,r")]) 1184 (label_ref (match_operand 2 "" "")) 1185 (pc)))] 1186 "" 1187{ 1188 return xtensa_emit_branch (false, which_alternative == 0, operands); 1189} 1190 [(set_attr "type" "jump,jump") 1191 (set_attr "mode" "none") 1192 (set_attr "length" "3,3")]) 1193 1194(define_insn "*ubfalse" 1195 [(set (pc) 1196 (if_then_else (match_operator 3 "ubranch_operator" 1197 [(match_operand:SI 0 "register_operand" "r,r") 1198 (match_operand:SI 1 "ubranch_operand" "L,r")]) 1199 (pc) 1200 (label_ref (match_operand 2 "" ""))))] 1201 "" 1202{ 1203 return xtensa_emit_branch (true, which_alternative == 0, operands); 1204} 1205 [(set_attr "type" "jump,jump") 1206 (set_attr "mode" "none") 1207 (set_attr "length" "3,3")]) 1208 1209;; Branch patterns for bit testing 1210 1211(define_insn "*bittrue" 1212 [(set (pc) 1213 (if_then_else (match_operator 3 "boolean_operator" 1214 [(zero_extract:SI 1215 (match_operand:SI 0 "register_operand" "r,r") 1216 (const_int 1) 1217 (match_operand:SI 1 "arith_operand" "J,r")) 1218 (const_int 0)]) 1219 (label_ref (match_operand 2 "" "")) 1220 (pc)))] 1221 "" 1222{ 1223 return xtensa_emit_bit_branch (false, which_alternative == 0, operands); 1224} 1225 [(set_attr "type" "jump") 1226 (set_attr "mode" "none") 1227 (set_attr "length" "3")]) 1228 1229(define_insn "*bitfalse" 1230 [(set (pc) 1231 (if_then_else (match_operator 3 "boolean_operator" 1232 [(zero_extract:SI 1233 (match_operand:SI 0 "register_operand" "r,r") 1234 (const_int 1) 1235 (match_operand:SI 1 "arith_operand" "J,r")) 1236 (const_int 0)]) 1237 (pc) 1238 (label_ref (match_operand 2 "" ""))))] 1239 "" 1240{ 1241 return xtensa_emit_bit_branch (true, which_alternative == 0, operands); 1242} 1243 [(set_attr "type" "jump") 1244 (set_attr "mode" "none") 1245 (set_attr "length" "3")]) 1246 1247(define_insn "*masktrue" 1248 [(set (pc) 1249 (if_then_else (match_operator 3 "boolean_operator" 1250 [(and:SI (match_operand:SI 0 "register_operand" "r") 1251 (match_operand:SI 1 "register_operand" "r")) 1252 (const_int 0)]) 1253 (label_ref (match_operand 2 "" "")) 1254 (pc)))] 1255 "" 1256{ 1257 switch (GET_CODE (operands[3])) 1258 { 1259 case EQ: return "bnone\t%0, %1, %2"; 1260 case NE: return "bany\t%0, %1, %2"; 1261 default: gcc_unreachable (); 1262 } 1263} 1264 [(set_attr "type" "jump") 1265 (set_attr "mode" "none") 1266 (set_attr "length" "3")]) 1267 1268(define_insn "*maskfalse" 1269 [(set (pc) 1270 (if_then_else (match_operator 3 "boolean_operator" 1271 [(and:SI (match_operand:SI 0 "register_operand" "r") 1272 (match_operand:SI 1 "register_operand" "r")) 1273 (const_int 0)]) 1274 (pc) 1275 (label_ref (match_operand 2 "" ""))))] 1276 "" 1277{ 1278 switch (GET_CODE (operands[3])) 1279 { 1280 case EQ: return "bany\t%0, %1, %2"; 1281 case NE: return "bnone\t%0, %1, %2"; 1282 default: gcc_unreachable (); 1283 } 1284} 1285 [(set_attr "type" "jump") 1286 (set_attr "mode" "none") 1287 (set_attr "length" "3")]) 1288 1289 1290;; Zero-overhead looping support. 1291 1292;; Define the loop insns used by bct optimization to represent the 1293;; start and end of a zero-overhead loop. This start template generates 1294;; the loop insn; the end template doesn't generate any instructions since 1295;; loop end is handled in hardware. 1296 1297(define_insn "zero_cost_loop_start" 1298 [(set (pc) 1299 (if_then_else (ne (match_operand:SI 2 "register_operand" "0") 1300 (const_int 1)) 1301 (label_ref (match_operand 1 "" "")) 1302 (pc))) 1303 (set (match_operand:SI 0 "register_operand" "=a") 1304 (plus (match_dup 0) 1305 (const_int -1))) 1306 (unspec [(const_int 0)] UNSPEC_LSETUP_START)] 1307 "TARGET_LOOPS && optimize" 1308 "loop\t%0, %l1_LEND" 1309 [(set_attr "type" "jump") 1310 (set_attr "mode" "none") 1311 (set_attr "length" "3")]) 1312 1313(define_insn "zero_cost_loop_end" 1314 [(set (pc) 1315 (if_then_else (ne (match_operand:SI 2 "nonimmediate_operand" "0,0") 1316 (const_int 1)) 1317 (label_ref (match_operand 1 "" "")) 1318 (pc))) 1319 (set (match_operand:SI 0 "nonimmediate_operand" "=a,m") 1320 (plus (match_dup 0) 1321 (const_int -1))) 1322 (unspec [(const_int 0)] UNSPEC_LSETUP_END) 1323 (clobber (match_scratch:SI 3 "=X,&r"))] 1324 "TARGET_LOOPS && optimize" 1325 "#" 1326 [(set_attr "type" "jump") 1327 (set_attr "mode" "none") 1328 (set_attr "length" "0")]) 1329 1330(define_insn "loop_end" 1331 [(set (pc) 1332 (if_then_else (ne (match_operand:SI 2 "register_operand" "0") 1333 (const_int 1)) 1334 (label_ref (match_operand 1 "" "")) 1335 (pc))) 1336 (set (match_operand:SI 0 "register_operand" "=a") 1337 (plus (match_dup 0) 1338 (const_int -1))) 1339 (unspec [(const_int 0)] UNSPEC_LSETUP_END)] 1340 "TARGET_LOOPS && optimize" 1341{ 1342 xtensa_emit_loop_end (insn, operands); 1343 return ""; 1344} 1345 [(set_attr "type" "jump") 1346 (set_attr "mode" "none") 1347 (set_attr "length" "0")]) 1348 1349(define_split 1350 [(set (pc) 1351 (if_then_else (ne (match_operand:SI 0 "nonimmediate_operand" "") 1352 (const_int 1)) 1353 (label_ref (match_operand 1 "" "")) 1354 (pc))) 1355 (set (match_operand:SI 2 "nonimmediate_operand" "") 1356 (plus:SI (match_dup 0) 1357 (const_int -1))) 1358 (unspec [(const_int 0)] UNSPEC_LSETUP_END) 1359 (clobber (match_scratch 3))] 1360 "TARGET_LOOPS && optimize && reload_completed" 1361 [(const_int 0)] 1362{ 1363 if (!REG_P (operands[0])) 1364 { 1365 rtx test; 1366 1367 /* Fallback into a normal conditional branch insn. */ 1368 emit_move_insn (operands[3], operands[0]); 1369 emit_insn (gen_addsi3 (operands[3], operands[3], constm1_rtx)); 1370 emit_move_insn (operands[0], operands[3]); 1371 test = gen_rtx_NE (VOIDmode, operands[3], const0_rtx); 1372 emit_jump_insn (gen_cbranchsi4 (test, operands[3], 1373 const0_rtx, operands[1])); 1374 } 1375 else 1376 { 1377 emit_jump_insn (gen_loop_end (operands[0], operands[1], operands[2])); 1378 } 1379 1380 DONE; 1381}) 1382 1383; operand 0 is the loop count pseudo register 1384; operand 1 is the label to jump to at the top of the loop 1385(define_expand "doloop_end" 1386 [(parallel [(set (pc) (if_then_else 1387 (ne (match_operand:SI 0 "" "") 1388 (const_int 1)) 1389 (label_ref (match_operand 1 "" "")) 1390 (pc))) 1391 (set (match_dup 0) 1392 (plus:SI (match_dup 0) 1393 (const_int -1))) 1394 (unspec [(const_int 0)] UNSPEC_LSETUP_END) 1395 (clobber (match_dup 2))])] ; match_scratch 1396 "TARGET_LOOPS && optimize" 1397{ 1398 /* The loop optimizer doesn't check the predicates... */ 1399 if (GET_MODE (operands[0]) != SImode) 1400 FAIL; 1401 operands[2] = gen_rtx_SCRATCH (SImode); 1402}) 1403 1404 1405;; Setting a register from a comparison. 1406 1407(define_expand "cstoresi4" 1408 [(match_operand:SI 0 "register_operand") 1409 (match_operator 1 "xtensa_cstoresi_operator" 1410 [(match_operand:SI 2 "register_operand") 1411 (match_operand:SI 3 "nonmemory_operand")])] 1412 "" 1413{ 1414 if (!xtensa_expand_scc (operands, SImode)) 1415 FAIL; 1416 DONE; 1417}) 1418 1419(define_expand "cstoresf4" 1420 [(match_operand:SI 0 "register_operand") 1421 (match_operator:SI 1 "comparison_operator" 1422 [(match_operand:SF 2 "register_operand") 1423 (match_operand:SF 3 "register_operand")])] 1424 "TARGET_HARD_FLOAT" 1425{ 1426 if (!xtensa_expand_scc (operands, SFmode)) 1427 FAIL; 1428 DONE; 1429}) 1430 1431 1432 1433;; Conditional moves. 1434 1435(define_expand "movsicc" 1436 [(set (match_operand:SI 0 "register_operand" "") 1437 (if_then_else:SI (match_operand 1 "comparison_operator" "") 1438 (match_operand:SI 2 "register_operand" "") 1439 (match_operand:SI 3 "register_operand" "")))] 1440 "" 1441{ 1442 if (!xtensa_expand_conditional_move (operands, 0)) 1443 FAIL; 1444 DONE; 1445}) 1446 1447(define_expand "movsfcc" 1448 [(set (match_operand:SF 0 "register_operand" "") 1449 (if_then_else:SF (match_operand 1 "comparison_operator" "") 1450 (match_operand:SF 2 "register_operand" "") 1451 (match_operand:SF 3 "register_operand" "")))] 1452 "" 1453{ 1454 if (!xtensa_expand_conditional_move (operands, 1)) 1455 FAIL; 1456 DONE; 1457}) 1458 1459(define_insn "movsicc_internal0" 1460 [(set (match_operand:SI 0 "register_operand" "=a,a") 1461 (if_then_else:SI (match_operator 4 "branch_operator" 1462 [(match_operand:SI 1 "register_operand" "r,r") 1463 (const_int 0)]) 1464 (match_operand:SI 2 "register_operand" "r,0") 1465 (match_operand:SI 3 "register_operand" "0,r")))] 1466 "" 1467{ 1468 return xtensa_emit_movcc (which_alternative == 1, false, false, operands); 1469} 1470 [(set_attr "type" "move,move") 1471 (set_attr "mode" "SI") 1472 (set_attr "length" "3,3")]) 1473 1474(define_insn "movsicc_internal1" 1475 [(set (match_operand:SI 0 "register_operand" "=a,a") 1476 (if_then_else:SI (match_operator 4 "boolean_operator" 1477 [(match_operand:CC 1 "register_operand" "b,b") 1478 (const_int 0)]) 1479 (match_operand:SI 2 "register_operand" "r,0") 1480 (match_operand:SI 3 "register_operand" "0,r")))] 1481 "TARGET_BOOLEANS" 1482{ 1483 return xtensa_emit_movcc (which_alternative == 1, false, true, operands); 1484} 1485 [(set_attr "type" "move,move") 1486 (set_attr "mode" "SI") 1487 (set_attr "length" "3,3")]) 1488 1489(define_insn "movsfcc_internal0" 1490 [(set (match_operand:SF 0 "register_operand" "=a,a,f,f") 1491 (if_then_else:SF (match_operator 4 "branch_operator" 1492 [(match_operand:SI 1 "register_operand" "r,r,r,r") 1493 (const_int 0)]) 1494 (match_operand:SF 2 "register_operand" "r,0,f,0") 1495 (match_operand:SF 3 "register_operand" "0,r,0,f")))] 1496 "" 1497{ 1498 return xtensa_emit_movcc ((which_alternative & 1) == 1, 1499 which_alternative >= 2, false, operands); 1500} 1501 [(set_attr "type" "move,move,move,move") 1502 (set_attr "mode" "SF") 1503 (set_attr "length" "3,3,3,3")]) 1504 1505(define_insn "movsfcc_internal1" 1506 [(set (match_operand:SF 0 "register_operand" "=a,a,f,f") 1507 (if_then_else:SF (match_operator 4 "boolean_operator" 1508 [(match_operand:CC 1 "register_operand" "b,b,b,b") 1509 (const_int 0)]) 1510 (match_operand:SF 2 "register_operand" "r,0,f,0") 1511 (match_operand:SF 3 "register_operand" "0,r,0,f")))] 1512 "TARGET_BOOLEANS" 1513{ 1514 return xtensa_emit_movcc ((which_alternative & 1) == 1, 1515 which_alternative >= 2, true, operands); 1516} 1517 [(set_attr "type" "move,move,move,move") 1518 (set_attr "mode" "SF") 1519 (set_attr "length" "3,3,3,3")]) 1520 1521 1522;; Floating-point comparisons. 1523 1524(define_insn "s<code>_sf" 1525 [(set (match_operand:CC 0 "register_operand" "=b") 1526 (any_scc_sf:CC (match_operand:SF 1 "register_operand" "f") 1527 (match_operand:SF 2 "register_operand" "f")))] 1528 "TARGET_HARD_FLOAT" 1529 "<scc_sf>.s\t%0, %1, %2" 1530 [(set_attr "type" "farith") 1531 (set_attr "mode" "BL") 1532 (set_attr "length" "3")]) 1533 1534 1535;; Unconditional branches. 1536 1537(define_insn "jump" 1538 [(set (pc) 1539 (label_ref (match_operand 0 "" "")))] 1540 "" 1541 "j\t%l0" 1542 [(set_attr "type" "jump") 1543 (set_attr "mode" "none") 1544 (set_attr "length" "3")]) 1545 1546(define_expand "indirect_jump" 1547 [(set (pc) 1548 (match_operand 0 "register_operand" ""))] 1549 "" 1550{ 1551 rtx dest = operands[0]; 1552 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode) 1553 operands[0] = copy_to_mode_reg (Pmode, dest); 1554 1555 emit_jump_insn (gen_indirect_jump_internal (dest)); 1556 DONE; 1557}) 1558 1559(define_insn "indirect_jump_internal" 1560 [(set (pc) (match_operand:SI 0 "register_operand" "r"))] 1561 "" 1562 "jx\t%0" 1563 [(set_attr "type" "jump") 1564 (set_attr "mode" "none") 1565 (set_attr "length" "3")]) 1566 1567 1568(define_expand "tablejump" 1569 [(use (match_operand:SI 0 "register_operand" "")) 1570 (use (label_ref (match_operand 1 "" "")))] 1571 "" 1572{ 1573 rtx target = operands[0]; 1574 if (flag_pic) 1575 { 1576 /* For PIC, the table entry is relative to the start of the table. */ 1577 rtx label = gen_reg_rtx (SImode); 1578 target = gen_reg_rtx (SImode); 1579 emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1])); 1580 emit_insn (gen_addsi3 (target, operands[0], label)); 1581 } 1582 emit_jump_insn (gen_tablejump_internal (target, operands[1])); 1583 DONE; 1584}) 1585 1586(define_insn "tablejump_internal" 1587 [(set (pc) 1588 (match_operand:SI 0 "register_operand" "r")) 1589 (use (label_ref (match_operand 1 "" "")))] 1590 "" 1591 "jx\t%0" 1592 [(set_attr "type" "jump") 1593 (set_attr "mode" "none") 1594 (set_attr "length" "3")]) 1595 1596 1597;; Function calls. 1598 1599(define_expand "sym_PLT" 1600 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))] 1601 "" 1602 "") 1603 1604(define_expand "call" 1605 [(call (match_operand 0 "memory_operand" "") 1606 (match_operand 1 "" ""))] 1607 "" 1608{ 1609 rtx addr = XEXP (operands[0], 0); 1610 if (flag_pic && GET_CODE (addr) == SYMBOL_REF 1611 && (!SYMBOL_REF_LOCAL_P (addr) || SYMBOL_REF_EXTERNAL_P (addr))) 1612 addr = gen_sym_PLT (addr); 1613 if (!call_insn_operand (addr, VOIDmode)) 1614 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr); 1615}) 1616 1617(define_insn "call_internal" 1618 [(call (mem (match_operand:SI 0 "call_insn_operand" "nir")) 1619 (match_operand 1 "" "i"))] 1620 "" 1621{ 1622 return xtensa_emit_call (0, operands); 1623} 1624 [(set_attr "type" "call") 1625 (set_attr "mode" "none") 1626 (set_attr "length" "3")]) 1627 1628(define_expand "call_value" 1629 [(set (match_operand 0 "register_operand" "") 1630 (call (match_operand 1 "memory_operand" "") 1631 (match_operand 2 "" "")))] 1632 "" 1633{ 1634 rtx addr = XEXP (operands[1], 0); 1635 if (flag_pic && GET_CODE (addr) == SYMBOL_REF 1636 && (!SYMBOL_REF_LOCAL_P (addr) || SYMBOL_REF_EXTERNAL_P (addr))) 1637 addr = gen_sym_PLT (addr); 1638 if (!call_insn_operand (addr, VOIDmode)) 1639 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr); 1640}) 1641 1642(define_insn "call_value_internal" 1643 [(set (match_operand 0 "register_operand" "=a") 1644 (call (mem (match_operand:SI 1 "call_insn_operand" "nir")) 1645 (match_operand 2 "" "i")))] 1646 "" 1647{ 1648 return xtensa_emit_call (1, operands); 1649} 1650 [(set_attr "type" "call") 1651 (set_attr "mode" "none") 1652 (set_attr "length" "3")]) 1653 1654(define_insn "entry" 1655 [(set (reg:SI A1_REG) 1656 (unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "i")] 1657 UNSPECV_ENTRY))] 1658 "" 1659 "entry\tsp, %0" 1660 [(set_attr "type" "entry") 1661 (set_attr "mode" "SI") 1662 (set_attr "length" "3")]) 1663 1664(define_insn "return" 1665 [(return) 1666 (use (reg:SI A0_REG))] 1667 "xtensa_use_return_instruction_p ()" 1668{ 1669 return TARGET_WINDOWED_ABI ? 1670 (TARGET_DENSITY ? "retw.n" : "retw") : 1671 (TARGET_DENSITY ? "ret.n" : "ret"); 1672} 1673 [(set_attr "type" "jump") 1674 (set_attr "mode" "none") 1675 (set_attr "length" "2")]) 1676 1677 1678;; Miscellaneous instructions. 1679 1680;; In windowed ABI stack pointer adjustment must happen before any access 1681;; to the space allocated on stack is allowed, otherwise register spill 1682;; area may be clobbered. That's what frame blockage is supposed to enforce. 1683 1684(define_expand "allocate_stack" 1685 [(set (match_operand 0 "nonimmed_operand") 1686 (minus (reg A1_REG) (match_operand 1 "add_operand"))) 1687 (set (reg A1_REG) 1688 (minus (reg A1_REG) (match_dup 1)))] 1689 "TARGET_WINDOWED_ABI" 1690{ 1691 if (CONST_INT_P (operands[1])) 1692 { 1693 rtx neg_op0 = GEN_INT (-INTVAL (operands[1])); 1694 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, neg_op0)); 1695 } 1696 else 1697 { 1698 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, 1699 operands[1])); 1700 } 1701 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 1702 emit_insn (gen_frame_blockage ()); 1703 DONE; 1704}) 1705 1706(define_expand "prologue" 1707 [(const_int 0)] 1708 "" 1709{ 1710 xtensa_expand_prologue (); 1711 DONE; 1712}) 1713 1714(define_expand "epilogue" 1715 [(return)] 1716 "" 1717{ 1718 xtensa_expand_epilogue (); 1719 DONE; 1720}) 1721 1722(define_insn "nop" 1723 [(const_int 0)] 1724 "" 1725{ 1726 return (TARGET_DENSITY ? "nop.n" : "nop"); 1727} 1728 [(set_attr "type" "nop") 1729 (set_attr "mode" "none") 1730 (set_attr "length" "3")]) 1731 1732(define_expand "nonlocal_goto" 1733 [(match_operand:SI 0 "general_operand" "") 1734 (match_operand:SI 1 "general_operand" "") 1735 (match_operand:SI 2 "general_operand" "") 1736 (match_operand:SI 3 "" "")] 1737 "TARGET_WINDOWED_ABI" 1738{ 1739 xtensa_expand_nonlocal_goto (operands); 1740 DONE; 1741}) 1742 1743;; Stuff an address into the return address register along with the window 1744;; size in the high bits. Because we don't have the window size of the 1745;; previous frame, assume the function called out with a CALL8 since that 1746;; is what compilers always use. Note: __builtin_frob_return_addr has 1747;; already been applied to the handler, but the generic version doesn't 1748;; allow us to frob it quite enough, so we just frob here. 1749 1750(define_expand "eh_return" 1751 [(use (match_operand 0 "general_operand"))] 1752 "" 1753{ 1754 if (TARGET_WINDOWED_ABI) 1755 emit_insn (gen_eh_set_a0_windowed (operands[0])); 1756 else 1757 emit_insn (gen_eh_set_a0_call0 (operands[0])); 1758 DONE; 1759}) 1760 1761(define_insn_and_split "eh_set_a0_windowed" 1762 [(set (reg:SI A0_REG) 1763 (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] 1764 UNSPECV_EH_RETURN)) 1765 (clobber (match_scratch:SI 1 "=r"))] 1766 "" 1767 "#" 1768 "reload_completed" 1769 [(set (match_dup 1) (ashift:SI (match_dup 0) (const_int 2))) 1770 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 2))) 1771 (set (reg:SI A0_REG) (rotatert:SI (match_dup 1) (const_int 2)))] 1772 "") 1773 1774(define_insn_and_split "eh_set_a0_call0" 1775 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] 1776 UNSPECV_EH_RETURN) 1777 (clobber (match_scratch:SI 1 "=r"))] 1778 "" 1779 "#" 1780 "reload_completed" 1781 [(const_int 0)] 1782{ 1783 xtensa_set_return_address (operands[0], operands[1]); 1784 DONE; 1785}) 1786 1787;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 1788;; all of memory. This blocks insns from being moved across this point. 1789 1790(define_insn "blockage" 1791 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 1792 "" 1793 "" 1794 [(set_attr "length" "0") 1795 (set_attr "type" "nop")]) 1796 1797;; Do not schedule instructions accessing memory before this point. 1798 1799(define_expand "frame_blockage" 1800 [(set (match_dup 0) 1801 (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))] 1802 "" 1803{ 1804 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 1805 MEM_VOLATILE_P (operands[0]) = 1; 1806 operands[1] = stack_pointer_rtx; 1807}) 1808 1809(define_insn "*frame_blockage" 1810 [(set (match_operand:BLK 0 "" "") 1811 (unspec:BLK [(match_operand:SI 1 "" "")] UNSPEC_FRAME_BLOCKAGE))] 1812 "" 1813 "" 1814 [(set_attr "length" "0")]) 1815 1816(define_insn "trap" 1817 [(trap_if (const_int 1) (const_int 0))] 1818 "" 1819{ 1820 if (TARGET_DEBUG) 1821 return "break\t1, 15"; 1822 else 1823 return (TARGET_DENSITY ? "ill.n" : "ill"); 1824} 1825 [(set_attr "type" "trap") 1826 (set_attr "mode" "none") 1827 (set_attr "length" "3")]) 1828 1829;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't 1830;; know if a frame pointer is required until the reload pass, and 1831;; because there may be an incoming argument value in the hard frame 1832;; pointer register (a7). If there is an incoming argument in that 1833;; register, the "set_frame_ptr" insn gets inserted immediately after 1834;; the insn that copies the incoming argument to a pseudo or to the 1835;; stack. This serves several purposes here: (1) it keeps the 1836;; optimizer from copy-propagating or scheduling the use of a7 as an 1837;; incoming argument away from the beginning of the function; (2) we 1838;; can use a post-reload splitter to expand away the insn if a frame 1839;; pointer is not required, so that the post-reload scheduler can do 1840;; the right thing; and (3) it makes it easy for the prologue expander 1841;; to search for this insn to determine whether it should add a new insn 1842;; to set up the frame pointer. 1843 1844(define_insn "set_frame_ptr" 1845 [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))] 1846 "" 1847{ 1848 if (frame_pointer_needed) 1849 return "mov\ta7, sp"; 1850 return ""; 1851} 1852 [(set_attr "type" "move") 1853 (set_attr "mode" "SI") 1854 (set_attr "length" "3")]) 1855 1856;; Post-reload splitter to remove fp assignment when it's not needed. 1857(define_split 1858 [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))] 1859 "reload_completed && !frame_pointer_needed" 1860 [(unspec [(const_int 0)] UNSPEC_NOP)] 1861 "") 1862 1863;; The preceding splitter needs something to split the insn into; 1864;; things start breaking if the result is just a "use" so instead we 1865;; generate the following insn. 1866(define_insn "*unspec_nop" 1867 [(unspec [(const_int 0)] UNSPEC_NOP)] 1868 "" 1869 "" 1870 [(set_attr "type" "nop") 1871 (set_attr "mode" "none") 1872 (set_attr "length" "0")]) 1873 1874 1875;; TLS support 1876 1877(define_expand "sym_TPOFF" 1878 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_TPOFF))] 1879 "" 1880 "") 1881 1882(define_expand "sym_DTPOFF" 1883 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_DTPOFF))] 1884 "" 1885 "") 1886 1887(define_insn "get_thread_pointersi" 1888 [(set (match_operand:SI 0 "register_operand" "=a") 1889 (unspec:SI [(const_int 0)] UNSPEC_TP))] 1890 "TARGET_THREADPTR" 1891 "rur\t%0, THREADPTR" 1892 [(set_attr "type" "rsr") 1893 (set_attr "mode" "SI") 1894 (set_attr "length" "3")]) 1895 1896(define_insn "set_thread_pointersi" 1897 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] 1898 UNSPECV_SET_TP)] 1899 "TARGET_THREADPTR" 1900 "wur\t%0, THREADPTR" 1901 [(set_attr "type" "wsr") 1902 (set_attr "mode" "SI") 1903 (set_attr "length" "3")]) 1904 1905(define_insn "tls_func" 1906 [(set (match_operand:SI 0 "register_operand" "=a") 1907 (unspec:SI [(match_operand:SI 1 "tls_symbol_operand" "")] 1908 UNSPEC_TLS_FUNC))] 1909 "TARGET_THREADPTR && HAVE_AS_TLS" 1910 "movi\t%0, %1@TLSFUNC" 1911 [(set_attr "type" "load") 1912 (set_attr "mode" "SI") 1913 (set_attr "length" "3")]) 1914 1915(define_insn "tls_arg" 1916 [(set (match_operand:SI 0 "register_operand" "=a") 1917 (unspec:SI [(match_operand:SI 1 "tls_symbol_operand" "")] 1918 UNSPEC_TLS_ARG))] 1919 "TARGET_THREADPTR && HAVE_AS_TLS" 1920 "movi\t%0, %1@TLSARG" 1921 [(set_attr "type" "load") 1922 (set_attr "mode" "SI") 1923 (set_attr "length" "3")]) 1924 1925(define_insn "tls_call" 1926 [(set (match_operand:SI 0 "register_operand" "=a") 1927 (call (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r") 1928 (match_operand:SI 2 "tls_symbol_operand" "")] 1929 UNSPEC_TLS_CALL)) 1930 (match_operand 3 "" "i")))] 1931 "TARGET_THREADPTR && HAVE_AS_TLS" 1932{ 1933 if (TARGET_WINDOWED_ABI) 1934 return "callx8.tls %1, %2@TLSCALL"; 1935 else 1936 return "callx0.tls %1, %2@TLSCALL"; 1937} 1938 [(set_attr "type" "call") 1939 (set_attr "mode" "none") 1940 (set_attr "length" "3")]) 1941 1942 1943;; Instructions for the Xtensa "boolean" option. 1944 1945(define_insn "*booltrue" 1946 [(set (pc) 1947 (if_then_else (match_operator 2 "boolean_operator" 1948 [(match_operand:CC 0 "register_operand" "b") 1949 (const_int 0)]) 1950 (label_ref (match_operand 1 "" "")) 1951 (pc)))] 1952 "TARGET_BOOLEANS" 1953{ 1954 if (GET_CODE (operands[2]) == EQ) 1955 return "bf\t%0, %1"; 1956 else 1957 return "bt\t%0, %1"; 1958} 1959 [(set_attr "type" "jump") 1960 (set_attr "mode" "none") 1961 (set_attr "length" "3")]) 1962 1963(define_insn "*boolfalse" 1964 [(set (pc) 1965 (if_then_else (match_operator 2 "boolean_operator" 1966 [(match_operand:CC 0 "register_operand" "b") 1967 (const_int 0)]) 1968 (pc) 1969 (label_ref (match_operand 1 "" ""))))] 1970 "TARGET_BOOLEANS" 1971{ 1972 if (GET_CODE (operands[2]) == EQ) 1973 return "bt\t%0, %1"; 1974 else 1975 return "bf\t%0, %1"; 1976} 1977 [(set_attr "type" "jump") 1978 (set_attr "mode" "none") 1979 (set_attr "length" "3")]) 1980 1981 1982;; Atomic operations 1983 1984(define_expand "memory_barrier" 1985 [(set (match_dup 0) 1986 (unspec:BLK [(match_dup 0)] UNSPEC_MEMW))] 1987 "" 1988{ 1989 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 1990 MEM_VOLATILE_P (operands[0]) = 1; 1991}) 1992 1993(define_insn "*memory_barrier" 1994 [(set (match_operand:BLK 0 "" "") 1995 (unspec:BLK [(match_dup 0)] UNSPEC_MEMW))] 1996 "" 1997 "memw" 1998 [(set_attr "type" "unknown") 1999 (set_attr "mode" "none") 2000 (set_attr "length" "3")]) 2001 2002;; sync_lock_release is only implemented for SImode. 2003;; For other modes, just use the default of a store with a memory_barrier. 2004(define_insn "sync_lock_releasesi" 2005 [(set (match_operand:SI 0 "mem_operand" "=U") 2006 (unspec_volatile:SI 2007 [(match_operand:SI 1 "register_operand" "r")] 2008 UNSPECV_S32RI))] 2009 "TARGET_RELEASE_SYNC" 2010 "s32ri\t%1, %0" 2011 [(set_attr "type" "store") 2012 (set_attr "mode" "SI") 2013 (set_attr "length" "3")]) 2014 2015(define_insn "sync_compare_and_swapsi" 2016 [(parallel 2017 [(set (match_operand:SI 0 "register_operand" "=a") 2018 (match_operand:SI 1 "mem_operand" "+U")) 2019 (set (match_dup 1) 2020 (unspec_volatile:SI 2021 [(match_dup 1) 2022 (match_operand:SI 2 "register_operand" "r") 2023 (match_operand:SI 3 "register_operand" "0")] 2024 UNSPECV_S32C1I))])] 2025 "TARGET_S32C1I" 2026 "wsr\t%2, SCOMPARE1\;s32c1i\t%3, %1" 2027 [(set_attr "type" "multi") 2028 (set_attr "mode" "SI") 2029 (set_attr "length" "6")]) 2030 2031(define_expand "sync_compare_and_swap<mode>" 2032 [(parallel 2033 [(set (match_operand:HQI 0 "register_operand" "") 2034 (match_operand:HQI 1 "mem_operand" "")) 2035 (set (match_dup 1) 2036 (unspec_volatile:HQI 2037 [(match_dup 1) 2038 (match_operand:HQI 2 "register_operand" "") 2039 (match_operand:HQI 3 "register_operand" "")] 2040 UNSPECV_S32C1I))])] 2041 "TARGET_S32C1I" 2042{ 2043 xtensa_expand_compare_and_swap (operands[0], operands[1], 2044 operands[2], operands[3]); 2045 DONE; 2046}) 2047 2048(define_expand "sync_lock_test_and_set<mode>" 2049 [(match_operand:HQI 0 "register_operand") 2050 (match_operand:HQI 1 "memory_operand") 2051 (match_operand:HQI 2 "register_operand")] 2052 "TARGET_S32C1I" 2053{ 2054 xtensa_expand_atomic (SET, operands[0], operands[1], operands[2], false); 2055 DONE; 2056}) 2057 2058(define_expand "sync_<atomic><mode>" 2059 [(set (match_operand:HQI 0 "memory_operand") 2060 (ATOMIC:HQI (match_dup 0) 2061 (match_operand:HQI 1 "register_operand")))] 2062 "TARGET_S32C1I" 2063{ 2064 xtensa_expand_atomic (<CODE>, NULL_RTX, operands[0], operands[1], false); 2065 DONE; 2066}) 2067 2068(define_expand "sync_old_<atomic><mode>" 2069 [(set (match_operand:HQI 0 "register_operand") 2070 (match_operand:HQI 1 "memory_operand")) 2071 (set (match_dup 1) 2072 (ATOMIC:HQI (match_dup 1) 2073 (match_operand:HQI 2 "register_operand")))] 2074 "TARGET_S32C1I" 2075{ 2076 xtensa_expand_atomic (<CODE>, operands[0], operands[1], operands[2], false); 2077 DONE; 2078}) 2079 2080(define_expand "sync_new_<atomic><mode>" 2081 [(set (match_operand:HQI 0 "register_operand") 2082 (ATOMIC:HQI (match_operand:HQI 1 "memory_operand") 2083 (match_operand:HQI 2 "register_operand"))) 2084 (set (match_dup 1) (ATOMIC:HQI (match_dup 1) (match_dup 2)))] 2085 "TARGET_S32C1I" 2086{ 2087 xtensa_expand_atomic (<CODE>, operands[0], operands[1], operands[2], true); 2088 DONE; 2089}) 2090