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