1;; Machine description for RISC-V for GNU compiler. 2;; Copyright (C) 2011-2020 Free Software Foundation, Inc. 3;; Contributed by Andrew Waterman (andrew@sifive.com). 4;; Based on MIPS target for GNU compiler. 5 6;; This file is part of GCC. 7 8;; GCC is free software; you can redistribute it and/or modify 9;; it under the terms of the GNU General Public License as published by 10;; the Free Software Foundation; either version 3, or (at your option) 11;; any later version. 12 13;; GCC is distributed in the hope that it will be useful, 14;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16;; GNU General Public License for more details. 17 18;; You should have received a copy of the GNU General Public License 19;; along with GCC; see the file COPYING3. If not see 20;; <http://www.gnu.org/licenses/>. 21 22(define_c_enum "unspec" [ 23 ;; Override return address for exception handling. 24 UNSPEC_EH_RETURN 25 26 ;; Symbolic accesses. The order of this list must match that of 27 ;; enum riscv_symbol_type in riscv-protos.h. 28 UNSPEC_ADDRESS_FIRST 29 UNSPEC_PCREL 30 UNSPEC_LOAD_GOT 31 UNSPEC_TLS 32 UNSPEC_TLS_LE 33 UNSPEC_TLS_IE 34 UNSPEC_TLS_GD 35 36 ;; High part of PC-relative address. 37 UNSPEC_AUIPC 38 39 ;; Floating-point unspecs. 40 UNSPEC_FLT_QUIET 41 UNSPEC_FLE_QUIET 42 UNSPEC_COPYSIGN 43 UNSPEC_LRINT 44 UNSPEC_LROUND 45 46 ;; Stack tie 47 UNSPEC_TIE 48]) 49 50(define_c_enum "unspecv" [ 51 ;; Register save and restore. 52 UNSPECV_GPR_SAVE 53 UNSPECV_GPR_RESTORE 54 55 ;; Floating-point unspecs. 56 UNSPECV_FRFLAGS 57 UNSPECV_FSFLAGS 58 59 ;; Interrupt handler instructions. 60 UNSPECV_MRET 61 UNSPECV_SRET 62 UNSPECV_URET 63 64 ;; Blockage and synchronization. 65 UNSPECV_BLOCKAGE 66 UNSPECV_FENCE 67 UNSPECV_FENCE_I 68]) 69 70(define_constants 71 [(RETURN_ADDR_REGNUM 1) 72 (GP_REGNUM 3) 73 (T0_REGNUM 5) 74 (T1_REGNUM 6) 75 (S0_REGNUM 8) 76 (S1_REGNUM 9) 77 (S2_REGNUM 18) 78 (S3_REGNUM 19) 79 (S4_REGNUM 20) 80 (S5_REGNUM 21) 81 (S6_REGNUM 22) 82 (S7_REGNUM 23) 83 (S8_REGNUM 24) 84 (S9_REGNUM 25) 85 (S10_REGNUM 26) 86 (S11_REGNUM 27) 87 88 (NORMAL_RETURN 0) 89 (SIBCALL_RETURN 1) 90 (EXCEPTION_RETURN 2) 91]) 92 93(include "predicates.md") 94(include "constraints.md") 95 96;; .................... 97;; 98;; Attributes 99;; 100;; .................... 101 102(define_attr "got" "unset,xgot_high,load" 103 (const_string "unset")) 104 105;; Classification of moves, extensions and truncations. Most values 106;; are as for "type" (see below) but there are also the following 107;; move-specific values: 108;; 109;; andi a single ANDI instruction 110;; shift_shift a shift left followed by a shift right 111;; 112;; This attribute is used to determine the instruction's length and 113;; scheduling type. For doubleword moves, the attribute always describes 114;; the split instructions; in some cases, it is more appropriate for the 115;; scheduling type to be "multi" instead. 116(define_attr "move_type" 117 "unknown,load,fpload,store,fpstore,mtc,mfc,move,fmove, 118 const,logical,arith,andi,shift_shift" 119 (const_string "unknown")) 120 121;; Main data type used by the insn 122(define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF" 123 (const_string "unknown")) 124 125;; True if the main data type is twice the size of a word. 126(define_attr "dword_mode" "no,yes" 127 (cond [(and (eq_attr "mode" "DI,DF") 128 (eq (symbol_ref "TARGET_64BIT") (const_int 0))) 129 (const_string "yes") 130 131 (and (eq_attr "mode" "TI,TF") 132 (ne (symbol_ref "TARGET_64BIT") (const_int 0))) 133 (const_string "yes")] 134 (const_string "no"))) 135 136;; Classification of each insn. 137;; branch conditional branch 138;; jump unconditional jump 139;; call unconditional call 140;; load load instruction(s) 141;; fpload floating point load 142;; store store instruction(s) 143;; fpstore floating point store 144;; mtc transfer to coprocessor 145;; mfc transfer from coprocessor 146;; const load constant 147;; arith integer arithmetic instructions 148;; logical integer logical instructions 149;; shift integer shift instructions 150;; slt set less than instructions 151;; imul integer multiply 152;; idiv integer divide 153;; move integer register move (addi rd, rs1, 0) 154;; fmove floating point register move 155;; fadd floating point add/subtract 156;; fmul floating point multiply 157;; fmadd floating point multiply-add 158;; fdiv floating point divide 159;; fcmp floating point compare 160;; fcvt floating point convert 161;; fsqrt floating point square root 162;; multi multiword sequence (or user asm statements) 163;; nop no operation 164;; ghost an instruction that produces no real code 165(define_attr "type" 166 "unknown,branch,jump,call,load,fpload,store,fpstore, 167 mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul, 168 fmadd,fdiv,fcmp,fcvt,fsqrt,multi,auipc,sfb_alu,nop,ghost" 169 (cond [(eq_attr "got" "load") (const_string "load") 170 171 ;; If a doubleword move uses these expensive instructions, 172 ;; it is usually better to schedule them in the same way 173 ;; as the singleword form, rather than as "multi". 174 (eq_attr "move_type" "load") (const_string "load") 175 (eq_attr "move_type" "fpload") (const_string "fpload") 176 (eq_attr "move_type" "store") (const_string "store") 177 (eq_attr "move_type" "fpstore") (const_string "fpstore") 178 (eq_attr "move_type" "mtc") (const_string "mtc") 179 (eq_attr "move_type" "mfc") (const_string "mfc") 180 181 ;; These types of move are always single insns. 182 (eq_attr "move_type" "fmove") (const_string "fmove") 183 (eq_attr "move_type" "arith") (const_string "arith") 184 (eq_attr "move_type" "logical") (const_string "logical") 185 (eq_attr "move_type" "andi") (const_string "logical") 186 187 ;; These types of move are always split. 188 (eq_attr "move_type" "shift_shift") 189 (const_string "multi") 190 191 ;; These types of move are split for doubleword modes only. 192 (and (eq_attr "move_type" "move,const") 193 (eq_attr "dword_mode" "yes")) 194 (const_string "multi") 195 (eq_attr "move_type" "move") (const_string "move") 196 (eq_attr "move_type" "const") (const_string "const")] 197 (const_string "unknown"))) 198 199;; Length of instruction in bytes. 200(define_attr "length" "" 201 (cond [ 202 ;; Branches further than +/- 4 KiB require two instructions. 203 (eq_attr "type" "branch") 204 (if_then_else (and (le (minus (match_dup 0) (pc)) (const_int 4088)) 205 (le (minus (pc) (match_dup 0)) (const_int 4092))) 206 (const_int 4) 207 (const_int 8)) 208 209 ;; Conservatively assume calls take two instructions (AUIPC + JALR). 210 ;; The linker will opportunistically relax the sequence to JAL. 211 (eq_attr "type" "call") (const_int 8) 212 213 ;; "Ghost" instructions occupy no space. 214 (eq_attr "type" "ghost") (const_int 0) 215 216 (eq_attr "got" "load") (const_int 8) 217 218 (eq_attr "type" "fcmp") (const_int 8) 219 220 ;; SHIFT_SHIFTs are decomposed into two separate instructions. 221 (eq_attr "move_type" "shift_shift") 222 (const_int 8) 223 224 ;; Check for doubleword moves that are decomposed into two 225 ;; instructions. 226 (and (eq_attr "move_type" "mtc,mfc,move") 227 (eq_attr "dword_mode" "yes")) 228 (const_int 8) 229 230 ;; Doubleword CONST{,N} moves are split into two word 231 ;; CONST{,N} moves. 232 (and (eq_attr "move_type" "const") 233 (eq_attr "dword_mode" "yes")) 234 (symbol_ref "riscv_split_const_insns (operands[1]) * 4") 235 236 ;; Otherwise, constants, loads and stores are handled by external 237 ;; routines. 238 (eq_attr "move_type" "load,fpload") 239 (symbol_ref "riscv_load_store_insns (operands[1], insn) * 4") 240 (eq_attr "move_type" "store,fpstore") 241 (symbol_ref "riscv_load_store_insns (operands[0], insn) * 4") 242 ] (const_int 4))) 243 244;; Is copying of this instruction disallowed? 245(define_attr "cannot_copy" "no,yes" (const_string "no")) 246 247;; Microarchitectures we know how to tune for. 248;; Keep this in sync with enum riscv_microarchitecture. 249(define_attr "tune" 250 "generic,sifive_7" 251 (const (symbol_ref "((enum attr_tune) riscv_microarchitecture)"))) 252 253;; Describe a user's asm statement. 254(define_asm_attributes 255 [(set_attr "type" "multi")]) 256 257;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated 258;; from the same template. 259(define_mode_iterator GPR [SI (DI "TARGET_64BIT")]) 260 261;; This mode iterator allows :P to be used for patterns that operate on 262;; pointer-sized quantities. Exactly one of the two alternatives will match. 263(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) 264 265;; Likewise, but for XLEN-sized quantities. 266(define_mode_iterator X [(SI "!TARGET_64BIT") (DI "TARGET_64BIT")]) 267 268;; Branches operate on XLEN-sized quantities, but for RV64 we accept 269;; QImode values so we can force zero-extension. 270(define_mode_iterator BR [(QI "TARGET_64BIT") SI (DI "TARGET_64BIT")]) 271 272;; 32-bit moves for which we provide move patterns. 273(define_mode_iterator MOVE32 [SI]) 274 275;; 64-bit modes for which we provide move patterns. 276(define_mode_iterator MOVE64 [DI DF]) 277 278;; Iterator for sub-32-bit integer modes. 279(define_mode_iterator SHORT [QI HI]) 280 281;; Iterator for HImode constant generation. 282(define_mode_iterator HISI [HI SI]) 283 284;; Iterator for QImode extension patterns. 285(define_mode_iterator SUPERQI [HI SI (DI "TARGET_64BIT")]) 286 287;; Iterator for hardware integer modes narrower than XLEN. 288(define_mode_iterator SUBX [QI HI (SI "TARGET_64BIT")]) 289 290;; Iterator for hardware-supported integer modes. 291(define_mode_iterator ANYI [QI HI SI (DI "TARGET_64BIT")]) 292 293;; Iterator for hardware-supported floating-point modes. 294(define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT") 295 (DF "TARGET_DOUBLE_FLOAT")]) 296 297;; Iterator for floating-point modes that can be loaded into X registers. 298(define_mode_iterator SOFTF [SF (DF "TARGET_64BIT")]) 299 300;; This attribute gives the length suffix for a sign- or zero-extension 301;; instruction. 302(define_mode_attr size [(QI "b") (HI "h")]) 303 304;; Mode attributes for loads. 305(define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (SF "flw") (DF "fld")]) 306 307;; Instruction names for integer loads that aren't explicitly sign or zero 308;; extended. See riscv_output_move and LOAD_EXTEND_OP. 309(define_mode_attr default_load [(QI "lbu") (HI "lhu") (SI "lw") (DI "ld")]) 310 311;; Mode attribute for FP loads into integer registers. 312(define_mode_attr softload [(SF "lw") (DF "ld")]) 313 314;; Instruction names for stores. 315(define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (SF "fsw") (DF "fsd")]) 316 317;; Instruction names for FP stores from integer registers. 318(define_mode_attr softstore [(SF "sw") (DF "sd")]) 319 320;; This attribute gives the best constraint to use for registers of 321;; a given mode. 322(define_mode_attr reg [(SI "d") (DI "d") (CC "d")]) 323 324;; This attribute gives the format suffix for floating-point operations. 325(define_mode_attr fmt [(SF "s") (DF "d")]) 326 327;; This attribute gives the integer suffix for floating-point conversions. 328(define_mode_attr ifmt [(SI "w") (DI "l")]) 329 330;; This attribute gives the format suffix for atomic memory operations. 331(define_mode_attr amo [(SI "w") (DI "d")]) 332 333;; This attribute gives the upper-case mode name for one unit of a 334;; floating-point mode. 335(define_mode_attr UNITMODE [(SF "SF") (DF "DF")]) 336 337;; This attribute gives the integer mode that has half the size of 338;; the controlling mode. 339(define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")]) 340 341;; Iterator and attributes for floating-point rounding instructions. 342(define_int_iterator RINT [UNSPEC_LRINT UNSPEC_LROUND]) 343(define_int_attr rint_pattern [(UNSPEC_LRINT "rint") (UNSPEC_LROUND "round")]) 344(define_int_attr rint_rm [(UNSPEC_LRINT "dyn") (UNSPEC_LROUND "rmm")]) 345 346;; Iterator and attributes for quiet comparisons. 347(define_int_iterator QUIET_COMPARISON [UNSPEC_FLT_QUIET UNSPEC_FLE_QUIET]) 348(define_int_attr quiet_pattern [(UNSPEC_FLT_QUIET "lt") (UNSPEC_FLE_QUIET "le")]) 349 350;; This code iterator allows signed and unsigned widening multiplications 351;; to use the same template. 352(define_code_iterator any_extend [sign_extend zero_extend]) 353 354;; This code iterator allows the two right shift instructions to be 355;; generated from the same template. 356(define_code_iterator any_shiftrt [ashiftrt lshiftrt]) 357 358;; This code iterator allows the three shift instructions to be generated 359;; from the same template. 360(define_code_iterator any_shift [ashift ashiftrt lshiftrt]) 361 362;; This code iterator allows the three bitwise instructions to be generated 363;; from the same template. 364(define_code_iterator any_bitwise [and ior xor]) 365 366;; This code iterator allows unsigned and signed division to be generated 367;; from the same template. 368(define_code_iterator any_div [div udiv mod umod]) 369 370;; This code iterator allows unsigned and signed modulus to be generated 371;; from the same template. 372(define_code_iterator any_mod [mod umod]) 373 374;; These code iterators allow the signed and unsigned scc operations to use 375;; the same template. 376(define_code_iterator any_gt [gt gtu]) 377(define_code_iterator any_ge [ge geu]) 378(define_code_iterator any_lt [lt ltu]) 379(define_code_iterator any_le [le leu]) 380 381;; <u> expands to an empty string when doing a signed operation and 382;; "u" when doing an unsigned operation. 383(define_code_attr u [(sign_extend "") (zero_extend "u") 384 (gt "") (gtu "u") 385 (ge "") (geu "u") 386 (lt "") (ltu "u") 387 (le "") (leu "u")]) 388 389;; <su> is like <u>, but the signed form expands to "s" rather than "". 390(define_code_attr su [(sign_extend "s") (zero_extend "u")]) 391 392;; <optab> expands to the name of the optab for a particular code. 393(define_code_attr optab [(ashift "ashl") 394 (ashiftrt "ashr") 395 (lshiftrt "lshr") 396 (div "div") 397 (mod "mod") 398 (udiv "udiv") 399 (umod "umod") 400 (ge "ge") 401 (le "le") 402 (gt "gt") 403 (lt "lt") 404 (ior "ior") 405 (xor "xor") 406 (and "and") 407 (plus "add") 408 (minus "sub")]) 409 410;; <insn> expands to the name of the insn that implements a particular code. 411(define_code_attr insn [(ashift "sll") 412 (ashiftrt "sra") 413 (lshiftrt "srl") 414 (div "div") 415 (mod "rem") 416 (udiv "divu") 417 (umod "remu") 418 (ior "or") 419 (xor "xor") 420 (and "and") 421 (plus "add") 422 (minus "sub")]) 423 424;; Ghost instructions produce no real code and introduce no hazards. 425;; They exist purely to express an effect on dataflow. 426(define_insn_reservation "ghost" 0 427 (eq_attr "type" "ghost") 428 "nothing") 429 430;; 431;; .................... 432;; 433;; ADDITION 434;; 435;; .................... 436;; 437 438(define_insn "add<mode>3" 439 [(set (match_operand:ANYF 0 "register_operand" "=f") 440 (plus:ANYF (match_operand:ANYF 1 "register_operand" " f") 441 (match_operand:ANYF 2 "register_operand" " f")))] 442 "TARGET_HARD_FLOAT" 443 "fadd.<fmt>\t%0,%1,%2" 444 [(set_attr "type" "fadd") 445 (set_attr "mode" "<UNITMODE>")]) 446 447(define_insn "addsi3" 448 [(set (match_operand:SI 0 "register_operand" "=r,r") 449 (plus:SI (match_operand:SI 1 "register_operand" " r,r") 450 (match_operand:SI 2 "arith_operand" " r,I")))] 451 "" 452 { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; } 453 [(set_attr "type" "arith") 454 (set_attr "mode" "SI")]) 455 456(define_insn "adddi3" 457 [(set (match_operand:DI 0 "register_operand" "=r,r") 458 (plus:DI (match_operand:DI 1 "register_operand" " r,r") 459 (match_operand:DI 2 "arith_operand" " r,I")))] 460 "TARGET_64BIT" 461 "add%i2\t%0,%1,%2" 462 [(set_attr "type" "arith") 463 (set_attr "mode" "DI")]) 464 465(define_insn "*addsi3_extended" 466 [(set (match_operand:DI 0 "register_operand" "=r,r") 467 (sign_extend:DI 468 (plus:SI (match_operand:SI 1 "register_operand" " r,r") 469 (match_operand:SI 2 "arith_operand" " r,I"))))] 470 "TARGET_64BIT" 471 "add%i2w\t%0,%1,%2" 472 [(set_attr "type" "arith") 473 (set_attr "mode" "SI")]) 474 475(define_insn "*addsi3_extended2" 476 [(set (match_operand:DI 0 "register_operand" "=r,r") 477 (sign_extend:DI 478 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" " r,r") 479 (match_operand:DI 2 "arith_operand" " r,I")) 480 0)))] 481 "TARGET_64BIT" 482 "add%i2w\t%0,%1,%2" 483 [(set_attr "type" "arith") 484 (set_attr "mode" "SI")]) 485 486;; 487;; .................... 488;; 489;; SUBTRACTION 490;; 491;; .................... 492;; 493 494(define_insn "sub<mode>3" 495 [(set (match_operand:ANYF 0 "register_operand" "=f") 496 (minus:ANYF (match_operand:ANYF 1 "register_operand" " f") 497 (match_operand:ANYF 2 "register_operand" " f")))] 498 "TARGET_HARD_FLOAT" 499 "fsub.<fmt>\t%0,%1,%2" 500 [(set_attr "type" "fadd") 501 (set_attr "mode" "<UNITMODE>")]) 502 503(define_insn "subdi3" 504 [(set (match_operand:DI 0 "register_operand" "= r") 505 (minus:DI (match_operand:DI 1 "reg_or_0_operand" " rJ") 506 (match_operand:DI 2 "register_operand" " r")))] 507 "TARGET_64BIT" 508 "sub\t%0,%z1,%2" 509 [(set_attr "type" "arith") 510 (set_attr "mode" "DI")]) 511 512(define_insn "subsi3" 513 [(set (match_operand:SI 0 "register_operand" "= r") 514 (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ") 515 (match_operand:SI 2 "register_operand" " r")))] 516 "" 517 { return TARGET_64BIT ? "subw\t%0,%z1,%2" : "sub\t%0,%z1,%2"; } 518 [(set_attr "type" "arith") 519 (set_attr "mode" "SI")]) 520 521(define_insn "*subsi3_extended" 522 [(set (match_operand:DI 0 "register_operand" "= r") 523 (sign_extend:DI 524 (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ") 525 (match_operand:SI 2 "register_operand" " r"))))] 526 "TARGET_64BIT" 527 "subw\t%0,%z1,%2" 528 [(set_attr "type" "arith") 529 (set_attr "mode" "SI")]) 530 531(define_insn "*subsi3_extended2" 532 [(set (match_operand:DI 0 "register_operand" "= r") 533 (sign_extend:DI 534 (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" " rJ") 535 (match_operand:DI 2 "register_operand" " r")) 536 0)))] 537 "TARGET_64BIT" 538 "subw\t%0,%z1,%2" 539 [(set_attr "type" "arith") 540 (set_attr "mode" "SI")]) 541 542(define_insn "negdi2" 543 [(set (match_operand:DI 0 "register_operand" "=r") 544 (neg:DI (match_operand:DI 1 "register_operand" " r")))] 545 "TARGET_64BIT" 546 "neg\t%0,%1" 547 [(set_attr "type" "arith") 548 (set_attr "mode" "DI")]) 549 550(define_insn "negsi2" 551 [(set (match_operand:SI 0 "register_operand" "=r") 552 (neg:SI (match_operand:SI 1 "register_operand" " r")))] 553 "" 554 { return TARGET_64BIT ? "negw\t%0,%1" : "neg\t%0,%1"; } 555 [(set_attr "type" "arith") 556 (set_attr "mode" "SI")]) 557 558(define_insn "*negsi2_extended" 559 [(set (match_operand:DI 0 "register_operand" "=r") 560 (sign_extend:DI 561 (neg:SI (match_operand:SI 1 "register_operand" " r"))))] 562 "TARGET_64BIT" 563 "negw\t%0,%1" 564 [(set_attr "type" "arith") 565 (set_attr "mode" "SI")]) 566 567(define_insn "*negsi2_extended2" 568 [(set (match_operand:DI 0 "register_operand" "=r") 569 (sign_extend:DI 570 (subreg:SI (neg:DI (match_operand:DI 1 "register_operand" " r")) 571 0)))] 572 "TARGET_64BIT" 573 "negw\t%0,%1" 574 [(set_attr "type" "arith") 575 (set_attr "mode" "SI")]) 576 577;; 578;; .................... 579;; 580;; MULTIPLICATION 581;; 582;; .................... 583;; 584 585(define_insn "mul<mode>3" 586 [(set (match_operand:ANYF 0 "register_operand" "=f") 587 (mult:ANYF (match_operand:ANYF 1 "register_operand" " f") 588 (match_operand:ANYF 2 "register_operand" " f")))] 589 "TARGET_HARD_FLOAT" 590 "fmul.<fmt>\t%0,%1,%2" 591 [(set_attr "type" "fmul") 592 (set_attr "mode" "<UNITMODE>")]) 593 594(define_insn "mulsi3" 595 [(set (match_operand:SI 0 "register_operand" "=r") 596 (mult:SI (match_operand:SI 1 "register_operand" " r") 597 (match_operand:SI 2 "register_operand" " r")))] 598 "TARGET_MUL" 599 { return TARGET_64BIT ? "mulw\t%0,%1,%2" : "mul\t%0,%1,%2"; } 600 [(set_attr "type" "imul") 601 (set_attr "mode" "SI")]) 602 603(define_insn "muldi3" 604 [(set (match_operand:DI 0 "register_operand" "=r") 605 (mult:DI (match_operand:DI 1 "register_operand" " r") 606 (match_operand:DI 2 "register_operand" " r")))] 607 "TARGET_MUL && TARGET_64BIT" 608 "mul\t%0,%1,%2" 609 [(set_attr "type" "imul") 610 (set_attr "mode" "DI")]) 611 612(define_insn "*mulsi3_extended" 613 [(set (match_operand:DI 0 "register_operand" "=r") 614 (sign_extend:DI 615 (mult:SI (match_operand:SI 1 "register_operand" " r") 616 (match_operand:SI 2 "register_operand" " r"))))] 617 "TARGET_MUL && TARGET_64BIT" 618 "mulw\t%0,%1,%2" 619 [(set_attr "type" "imul") 620 (set_attr "mode" "SI")]) 621 622(define_insn "*mulsi3_extended2" 623 [(set (match_operand:DI 0 "register_operand" "=r") 624 (sign_extend:DI 625 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" " r") 626 (match_operand:DI 2 "register_operand" " r")) 627 0)))] 628 "TARGET_MUL && TARGET_64BIT" 629 "mulw\t%0,%1,%2" 630 [(set_attr "type" "imul") 631 (set_attr "mode" "SI")]) 632 633;; 634;; ........................ 635;; 636;; MULTIPLICATION HIGH-PART 637;; 638;; ........................ 639;; 640 641 642(define_expand "<u>mulditi3" 643 [(set (match_operand:TI 0 "register_operand") 644 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand")) 645 (any_extend:TI (match_operand:DI 2 "register_operand"))))] 646 "TARGET_MUL && TARGET_64BIT" 647{ 648 rtx low = gen_reg_rtx (DImode); 649 emit_insn (gen_muldi3 (low, operands[1], operands[2])); 650 651 rtx high = gen_reg_rtx (DImode); 652 emit_insn (gen_<u>muldi3_highpart (high, operands[1], operands[2])); 653 654 emit_move_insn (gen_lowpart (DImode, operands[0]), low); 655 emit_move_insn (gen_highpart (DImode, operands[0]), high); 656 DONE; 657}) 658 659(define_insn "<u>muldi3_highpart" 660 [(set (match_operand:DI 0 "register_operand" "=r") 661 (truncate:DI 662 (lshiftrt:TI 663 (mult:TI (any_extend:TI 664 (match_operand:DI 1 "register_operand" " r")) 665 (any_extend:TI 666 (match_operand:DI 2 "register_operand" " r"))) 667 (const_int 64))))] 668 "TARGET_MUL && TARGET_64BIT" 669 "mulh<u>\t%0,%1,%2" 670 [(set_attr "type" "imul") 671 (set_attr "mode" "DI")]) 672 673(define_expand "usmulditi3" 674 [(set (match_operand:TI 0 "register_operand") 675 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand")) 676 (sign_extend:TI (match_operand:DI 2 "register_operand"))))] 677 "TARGET_MUL && TARGET_64BIT" 678{ 679 rtx low = gen_reg_rtx (DImode); 680 emit_insn (gen_muldi3 (low, operands[1], operands[2])); 681 682 rtx high = gen_reg_rtx (DImode); 683 emit_insn (gen_usmuldi3_highpart (high, operands[1], operands[2])); 684 685 emit_move_insn (gen_lowpart (DImode, operands[0]), low); 686 emit_move_insn (gen_highpart (DImode, operands[0]), high); 687 DONE; 688}) 689 690(define_insn "usmuldi3_highpart" 691 [(set (match_operand:DI 0 "register_operand" "=r") 692 (truncate:DI 693 (lshiftrt:TI 694 (mult:TI (zero_extend:TI 695 (match_operand:DI 1 "register_operand" "r")) 696 (sign_extend:TI 697 (match_operand:DI 2 "register_operand" " r"))) 698 (const_int 64))))] 699 "TARGET_MUL && TARGET_64BIT" 700 "mulhsu\t%0,%2,%1" 701 [(set_attr "type" "imul") 702 (set_attr "mode" "DI")]) 703 704(define_expand "<u>mulsidi3" 705 [(set (match_operand:DI 0 "register_operand" "=r") 706 (mult:DI (any_extend:DI 707 (match_operand:SI 1 "register_operand" " r")) 708 (any_extend:DI 709 (match_operand:SI 2 "register_operand" " r"))))] 710 "TARGET_MUL && !TARGET_64BIT" 711{ 712 rtx temp = gen_reg_rtx (SImode); 713 emit_insn (gen_mulsi3 (temp, operands[1], operands[2])); 714 emit_insn (gen_<u>mulsi3_highpart (riscv_subword (operands[0], true), 715 operands[1], operands[2])); 716 emit_insn (gen_movsi (riscv_subword (operands[0], false), temp)); 717 DONE; 718}) 719 720(define_insn "<u>mulsi3_highpart" 721 [(set (match_operand:SI 0 "register_operand" "=r") 722 (truncate:SI 723 (lshiftrt:DI 724 (mult:DI (any_extend:DI 725 (match_operand:SI 1 "register_operand" " r")) 726 (any_extend:DI 727 (match_operand:SI 2 "register_operand" " r"))) 728 (const_int 32))))] 729 "TARGET_MUL && !TARGET_64BIT" 730 "mulh<u>\t%0,%1,%2" 731 [(set_attr "type" "imul") 732 (set_attr "mode" "SI")]) 733 734 735(define_expand "usmulsidi3" 736 [(set (match_operand:DI 0 "register_operand" "=r") 737 (mult:DI (zero_extend:DI 738 (match_operand:SI 1 "register_operand" " r")) 739 (sign_extend:DI 740 (match_operand:SI 2 "register_operand" " r"))))] 741 "TARGET_MUL && !TARGET_64BIT" 742{ 743 rtx temp = gen_reg_rtx (SImode); 744 emit_insn (gen_mulsi3 (temp, operands[1], operands[2])); 745 emit_insn (gen_usmulsi3_highpart (riscv_subword (operands[0], true), 746 operands[1], operands[2])); 747 emit_insn (gen_movsi (riscv_subword (operands[0], false), temp)); 748 DONE; 749}) 750 751(define_insn "usmulsi3_highpart" 752 [(set (match_operand:SI 0 "register_operand" "=r") 753 (truncate:SI 754 (lshiftrt:DI 755 (mult:DI (zero_extend:DI 756 (match_operand:SI 1 "register_operand" " r")) 757 (sign_extend:DI 758 (match_operand:SI 2 "register_operand" " r"))) 759 (const_int 32))))] 760 "TARGET_MUL && !TARGET_64BIT" 761 "mulhsu\t%0,%2,%1" 762 [(set_attr "type" "imul") 763 (set_attr "mode" "SI")]) 764 765;; 766;; .................... 767;; 768;; DIVISION and REMAINDER 769;; 770;; .................... 771;; 772 773(define_insn "<optab>si3" 774 [(set (match_operand:SI 0 "register_operand" "=r") 775 (any_div:SI (match_operand:SI 1 "register_operand" " r") 776 (match_operand:SI 2 "register_operand" " r")))] 777 "TARGET_DIV" 778 { return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2"; } 779 [(set_attr "type" "idiv") 780 (set_attr "mode" "SI")]) 781 782(define_insn "<optab>di3" 783 [(set (match_operand:DI 0 "register_operand" "=r") 784 (any_div:DI (match_operand:DI 1 "register_operand" " r") 785 (match_operand:DI 2 "register_operand" " r")))] 786 "TARGET_DIV && TARGET_64BIT" 787 "<insn>%i2\t%0,%1,%2" 788 [(set_attr "type" "idiv") 789 (set_attr "mode" "DI")]) 790 791(define_insn "*<optab>si3_extended" 792 [(set (match_operand:DI 0 "register_operand" "=r") 793 (sign_extend:DI 794 (any_div:SI (match_operand:SI 1 "register_operand" " r") 795 (match_operand:SI 2 "register_operand" " r"))))] 796 "TARGET_DIV && TARGET_64BIT" 797 "<insn>%i2w\t%0,%1,%2" 798 [(set_attr "type" "idiv") 799 (set_attr "mode" "DI")]) 800 801(define_insn "div<mode>3" 802 [(set (match_operand:ANYF 0 "register_operand" "=f") 803 (div:ANYF (match_operand:ANYF 1 "register_operand" " f") 804 (match_operand:ANYF 2 "register_operand" " f")))] 805 "TARGET_HARD_FLOAT && TARGET_FDIV" 806 "fdiv.<fmt>\t%0,%1,%2" 807 [(set_attr "type" "fdiv") 808 (set_attr "mode" "<UNITMODE>")]) 809 810;; 811;; .................... 812;; 813;; SQUARE ROOT 814;; 815;; .................... 816 817(define_insn "sqrt<mode>2" 818 [(set (match_operand:ANYF 0 "register_operand" "=f") 819 (sqrt:ANYF (match_operand:ANYF 1 "register_operand" " f")))] 820 "TARGET_HARD_FLOAT && TARGET_FDIV" 821{ 822 return "fsqrt.<fmt>\t%0,%1"; 823} 824 [(set_attr "type" "fsqrt") 825 (set_attr "mode" "<UNITMODE>")]) 826 827;; Floating point multiply accumulate instructions. 828 829;; a * b + c 830(define_insn "fma<mode>4" 831 [(set (match_operand:ANYF 0 "register_operand" "=f") 832 (fma:ANYF (match_operand:ANYF 1 "register_operand" " f") 833 (match_operand:ANYF 2 "register_operand" " f") 834 (match_operand:ANYF 3 "register_operand" " f")))] 835 "TARGET_HARD_FLOAT" 836 "fmadd.<fmt>\t%0,%1,%2,%3" 837 [(set_attr "type" "fmadd") 838 (set_attr "mode" "<UNITMODE>")]) 839 840;; a * b - c 841(define_insn "fms<mode>4" 842 [(set (match_operand:ANYF 0 "register_operand" "=f") 843 (fma:ANYF (match_operand:ANYF 1 "register_operand" " f") 844 (match_operand:ANYF 2 "register_operand" " f") 845 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))] 846 "TARGET_HARD_FLOAT" 847 "fmsub.<fmt>\t%0,%1,%2,%3" 848 [(set_attr "type" "fmadd") 849 (set_attr "mode" "<UNITMODE>")]) 850 851;; -a * b - c 852(define_insn "fnms<mode>4" 853 [(set (match_operand:ANYF 0 "register_operand" "=f") 854 (fma:ANYF 855 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f")) 856 (match_operand:ANYF 2 "register_operand" " f") 857 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f"))))] 858 "TARGET_HARD_FLOAT" 859 "fnmadd.<fmt>\t%0,%1,%2,%3" 860 [(set_attr "type" "fmadd") 861 (set_attr "mode" "<UNITMODE>")]) 862 863;; -a * b + c 864(define_insn "fnma<mode>4" 865 [(set (match_operand:ANYF 0 "register_operand" "=f") 866 (fma:ANYF 867 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f")) 868 (match_operand:ANYF 2 "register_operand" " f") 869 (match_operand:ANYF 3 "register_operand" " f")))] 870 "TARGET_HARD_FLOAT" 871 "fnmsub.<fmt>\t%0,%1,%2,%3" 872 [(set_attr "type" "fmadd") 873 (set_attr "mode" "<UNITMODE>")]) 874 875;; -(-a * b - c), modulo signed zeros 876(define_insn "*fma<mode>4" 877 [(set (match_operand:ANYF 0 "register_operand" "=f") 878 (neg:ANYF 879 (fma:ANYF 880 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f")) 881 (match_operand:ANYF 2 "register_operand" " f") 882 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))] 883 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)" 884 "fmadd.<fmt>\t%0,%1,%2,%3" 885 [(set_attr "type" "fmadd") 886 (set_attr "mode" "<UNITMODE>")]) 887 888;; -(-a * b + c), modulo signed zeros 889(define_insn "*fms<mode>4" 890 [(set (match_operand:ANYF 0 "register_operand" "=f") 891 (neg:ANYF 892 (fma:ANYF 893 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f")) 894 (match_operand:ANYF 2 "register_operand" " f") 895 (match_operand:ANYF 3 "register_operand" " f"))))] 896 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)" 897 "fmsub.<fmt>\t%0,%1,%2,%3" 898 [(set_attr "type" "fmadd") 899 (set_attr "mode" "<UNITMODE>")]) 900 901;; -(a * b + c), modulo signed zeros 902(define_insn "*fnms<mode>4" 903 [(set (match_operand:ANYF 0 "register_operand" "=f") 904 (neg:ANYF 905 (fma:ANYF 906 (match_operand:ANYF 1 "register_operand" " f") 907 (match_operand:ANYF 2 "register_operand" " f") 908 (match_operand:ANYF 3 "register_operand" " f"))))] 909 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)" 910 "fnmadd.<fmt>\t%0,%1,%2,%3" 911 [(set_attr "type" "fmadd") 912 (set_attr "mode" "<UNITMODE>")]) 913 914;; -(a * b - c), modulo signed zeros 915(define_insn "*fnma<mode>4" 916 [(set (match_operand:ANYF 0 "register_operand" "=f") 917 (neg:ANYF 918 (fma:ANYF 919 (match_operand:ANYF 1 "register_operand" " f") 920 (match_operand:ANYF 2 "register_operand" " f") 921 (neg:ANYF (match_operand:ANYF 3 "register_operand" " f")))))] 922 "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)" 923 "fnmsub.<fmt>\t%0,%1,%2,%3" 924 [(set_attr "type" "fmadd") 925 (set_attr "mode" "<UNITMODE>")]) 926 927;; 928;; .................... 929;; 930;; SIGN INJECTION 931;; 932;; .................... 933 934(define_insn "abs<mode>2" 935 [(set (match_operand:ANYF 0 "register_operand" "=f") 936 (abs:ANYF (match_operand:ANYF 1 "register_operand" " f")))] 937 "TARGET_HARD_FLOAT" 938 "fabs.<fmt>\t%0,%1" 939 [(set_attr "type" "fmove") 940 (set_attr "mode" "<UNITMODE>")]) 941 942(define_insn "copysign<mode>3" 943 [(set (match_operand:ANYF 0 "register_operand" "=f") 944 (unspec:ANYF [(match_operand:ANYF 1 "register_operand" " f") 945 (match_operand:ANYF 2 "register_operand" " f")] 946 UNSPEC_COPYSIGN))] 947 "TARGET_HARD_FLOAT" 948 "fsgnj.<fmt>\t%0,%1,%2" 949 [(set_attr "type" "fmove") 950 (set_attr "mode" "<UNITMODE>")]) 951 952(define_insn "neg<mode>2" 953 [(set (match_operand:ANYF 0 "register_operand" "=f") 954 (neg:ANYF (match_operand:ANYF 1 "register_operand" " f")))] 955 "TARGET_HARD_FLOAT" 956 "fneg.<fmt>\t%0,%1" 957 [(set_attr "type" "fmove") 958 (set_attr "mode" "<UNITMODE>")]) 959 960;; 961;; .................... 962;; 963;; MIN/MAX 964;; 965;; .................... 966 967(define_insn "smin<mode>3" 968 [(set (match_operand:ANYF 0 "register_operand" "=f") 969 (smin:ANYF (match_operand:ANYF 1 "register_operand" " f") 970 (match_operand:ANYF 2 "register_operand" " f")))] 971 "TARGET_HARD_FLOAT" 972 "fmin.<fmt>\t%0,%1,%2" 973 [(set_attr "type" "fmove") 974 (set_attr "mode" "<UNITMODE>")]) 975 976(define_insn "smax<mode>3" 977 [(set (match_operand:ANYF 0 "register_operand" "=f") 978 (smax:ANYF (match_operand:ANYF 1 "register_operand" " f") 979 (match_operand:ANYF 2 "register_operand" " f")))] 980 "TARGET_HARD_FLOAT" 981 "fmax.<fmt>\t%0,%1,%2" 982 [(set_attr "type" "fmove") 983 (set_attr "mode" "<UNITMODE>")]) 984 985;; 986;; .................... 987;; 988;; LOGICAL 989;; 990;; .................... 991;; 992 993;; For RV64, we don't expose the SImode operations to the rtl expanders, 994;; but SImode versions exist for combine. 995 996(define_insn "<optab><mode>3" 997 [(set (match_operand:X 0 "register_operand" "=r,r") 998 (any_bitwise:X (match_operand:X 1 "register_operand" "%r,r") 999 (match_operand:X 2 "arith_operand" " r,I")))] 1000 "" 1001 "<insn>%i2\t%0,%1,%2" 1002 [(set_attr "type" "logical") 1003 (set_attr "mode" "<MODE>")]) 1004 1005(define_insn "*<optab>si3_internal" 1006 [(set (match_operand:SI 0 "register_operand" "=r,r") 1007 (any_bitwise:SI (match_operand:SI 1 "register_operand" "%r,r") 1008 (match_operand:SI 2 "arith_operand" " r,I")))] 1009 "TARGET_64BIT" 1010 "<insn>%i2\t%0,%1,%2" 1011 [(set_attr "type" "logical") 1012 (set_attr "mode" "SI")]) 1013 1014(define_insn "one_cmpl<mode>2" 1015 [(set (match_operand:X 0 "register_operand" "=r") 1016 (not:X (match_operand:X 1 "register_operand" " r")))] 1017 "" 1018 "not\t%0,%1" 1019 [(set_attr "type" "logical") 1020 (set_attr "mode" "<MODE>")]) 1021 1022(define_insn "*one_cmplsi2_internal" 1023 [(set (match_operand:SI 0 "register_operand" "=r") 1024 (not:SI (match_operand:SI 1 "register_operand" " r")))] 1025 "TARGET_64BIT" 1026 "not\t%0,%1" 1027 [(set_attr "type" "logical") 1028 (set_attr "mode" "SI")]) 1029 1030;; 1031;; .................... 1032;; 1033;; TRUNCATION 1034;; 1035;; .................... 1036 1037(define_insn "truncdfsf2" 1038 [(set (match_operand:SF 0 "register_operand" "=f") 1039 (float_truncate:SF 1040 (match_operand:DF 1 "register_operand" " f")))] 1041 "TARGET_DOUBLE_FLOAT" 1042 "fcvt.s.d\t%0,%1" 1043 [(set_attr "type" "fcvt") 1044 (set_attr "mode" "SF")]) 1045 1046;; 1047;; .................... 1048;; 1049;; ZERO EXTENSION 1050;; 1051;; .................... 1052 1053;; Extension insns. 1054 1055(define_insn_and_split "zero_extendsidi2" 1056 [(set (match_operand:DI 0 "register_operand" "=r,r") 1057 (zero_extend:DI 1058 (match_operand:SI 1 "nonimmediate_operand" " r,m")))] 1059 "TARGET_64BIT" 1060 "@ 1061 # 1062 lwu\t%0,%1" 1063 "&& reload_completed 1064 && REG_P (operands[1]) 1065 && !paradoxical_subreg_p (operands[0])" 1066 [(set (match_dup 0) 1067 (ashift:DI (match_dup 1) (const_int 32))) 1068 (set (match_dup 0) 1069 (lshiftrt:DI (match_dup 0) (const_int 32)))] 1070 { operands[1] = gen_lowpart (DImode, operands[1]); } 1071 [(set_attr "move_type" "shift_shift,load") 1072 (set_attr "mode" "DI")]) 1073 1074(define_insn_and_split "zero_extendhi<GPR:mode>2" 1075 [(set (match_operand:GPR 0 "register_operand" "=r,r") 1076 (zero_extend:GPR 1077 (match_operand:HI 1 "nonimmediate_operand" " r,m")))] 1078 "" 1079 "@ 1080 # 1081 lhu\t%0,%1" 1082 "&& reload_completed 1083 && REG_P (operands[1]) 1084 && !paradoxical_subreg_p (operands[0])" 1085 [(set (match_dup 0) 1086 (ashift:GPR (match_dup 1) (match_dup 2))) 1087 (set (match_dup 0) 1088 (lshiftrt:GPR (match_dup 0) (match_dup 2)))] 1089 { 1090 operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]); 1091 operands[2] = GEN_INT(GET_MODE_BITSIZE(<GPR:MODE>mode) - 16); 1092 } 1093 [(set_attr "move_type" "shift_shift,load") 1094 (set_attr "mode" "<GPR:MODE>")]) 1095 1096(define_insn "zero_extendqi<SUPERQI:mode>2" 1097 [(set (match_operand:SUPERQI 0 "register_operand" "=r,r") 1098 (zero_extend:SUPERQI 1099 (match_operand:QI 1 "nonimmediate_operand" " r,m")))] 1100 "" 1101 "@ 1102 andi\t%0,%1,0xff 1103 lbu\t%0,%1" 1104 [(set_attr "move_type" "andi,load") 1105 (set_attr "mode" "<SUPERQI:MODE>")]) 1106 1107;; 1108;; .................... 1109;; 1110;; SIGN EXTENSION 1111;; 1112;; .................... 1113 1114(define_insn "extendsidi2" 1115 [(set (match_operand:DI 0 "register_operand" "=r,r") 1116 (sign_extend:DI 1117 (match_operand:SI 1 "nonimmediate_operand" " r,m")))] 1118 "TARGET_64BIT" 1119 "@ 1120 sext.w\t%0,%1 1121 lw\t%0,%1" 1122 [(set_attr "move_type" "move,load") 1123 (set_attr "mode" "DI")]) 1124 1125(define_insn_and_split "extend<SHORT:mode><SUPERQI:mode>2" 1126 [(set (match_operand:SUPERQI 0 "register_operand" "=r,r") 1127 (sign_extend:SUPERQI 1128 (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))] 1129 "" 1130 "@ 1131 # 1132 l<SHORT:size>\t%0,%1" 1133 "&& reload_completed 1134 && REG_P (operands[1]) 1135 && !paradoxical_subreg_p (operands[0])" 1136 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2))) 1137 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))] 1138{ 1139 operands[0] = gen_lowpart (SImode, operands[0]); 1140 operands[1] = gen_lowpart (SImode, operands[1]); 1141 operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode) 1142 - GET_MODE_BITSIZE (<SHORT:MODE>mode)); 1143} 1144 [(set_attr "move_type" "shift_shift,load") 1145 (set_attr "mode" "SI")]) 1146 1147(define_insn "extendsfdf2" 1148 [(set (match_operand:DF 0 "register_operand" "=f") 1149 (float_extend:DF 1150 (match_operand:SF 1 "register_operand" " f")))] 1151 "TARGET_DOUBLE_FLOAT" 1152 "fcvt.d.s\t%0,%1" 1153 [(set_attr "type" "fcvt") 1154 (set_attr "mode" "DF")]) 1155 1156;; 1157;; .................... 1158;; 1159;; CONVERSIONS 1160;; 1161;; .................... 1162 1163(define_insn "fix_trunc<ANYF:mode><GPR:mode>2" 1164 [(set (match_operand:GPR 0 "register_operand" "=r") 1165 (fix:GPR 1166 (match_operand:ANYF 1 "register_operand" " f")))] 1167 "TARGET_HARD_FLOAT" 1168 "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,rtz" 1169 [(set_attr "type" "fcvt") 1170 (set_attr "mode" "<ANYF:MODE>")]) 1171 1172(define_insn "fixuns_trunc<ANYF:mode><GPR:mode>2" 1173 [(set (match_operand:GPR 0 "register_operand" "=r") 1174 (unsigned_fix:GPR 1175 (match_operand:ANYF 1 "register_operand" " f")))] 1176 "TARGET_HARD_FLOAT" 1177 "fcvt.<GPR:ifmt>u.<ANYF:fmt> %0,%1,rtz" 1178 [(set_attr "type" "fcvt") 1179 (set_attr "mode" "<ANYF:MODE>")]) 1180 1181(define_insn "float<GPR:mode><ANYF:mode>2" 1182 [(set (match_operand:ANYF 0 "register_operand" "= f") 1183 (float:ANYF 1184 (match_operand:GPR 1 "reg_or_0_operand" " rJ")))] 1185 "TARGET_HARD_FLOAT" 1186 "fcvt.<ANYF:fmt>.<GPR:ifmt>\t%0,%z1" 1187 [(set_attr "type" "fcvt") 1188 (set_attr "mode" "<ANYF:MODE>")]) 1189 1190(define_insn "floatuns<GPR:mode><ANYF:mode>2" 1191 [(set (match_operand:ANYF 0 "register_operand" "= f") 1192 (unsigned_float:ANYF 1193 (match_operand:GPR 1 "reg_or_0_operand" " rJ")))] 1194 "TARGET_HARD_FLOAT" 1195 "fcvt.<ANYF:fmt>.<GPR:ifmt>u\t%0,%z1" 1196 [(set_attr "type" "fcvt") 1197 (set_attr "mode" "<ANYF:MODE>")]) 1198 1199(define_insn "l<rint_pattern><ANYF:mode><GPR:mode>2" 1200 [(set (match_operand:GPR 0 "register_operand" "=r") 1201 (unspec:GPR 1202 [(match_operand:ANYF 1 "register_operand" " f")] 1203 RINT))] 1204 "TARGET_HARD_FLOAT" 1205 "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,<rint_rm>" 1206 [(set_attr "type" "fcvt") 1207 (set_attr "mode" "<ANYF:MODE>")]) 1208 1209;; 1210;; .................... 1211;; 1212;; DATA MOVEMENT 1213;; 1214;; .................... 1215 1216;; Lower-level instructions for loading an address from the GOT. 1217;; We could use MEMs, but an unspec gives more optimization 1218;; opportunities. 1219 1220(define_insn "got_load<mode>" 1221 [(set (match_operand:P 0 "register_operand" "=r") 1222 (unspec:P 1223 [(match_operand:P 1 "symbolic_operand" "")] 1224 UNSPEC_LOAD_GOT))] 1225 "" 1226 "la\t%0,%1" 1227 [(set_attr "got" "load") 1228 (set_attr "mode" "<MODE>")]) 1229 1230(define_insn "tls_add_tp_le<mode>" 1231 [(set (match_operand:P 0 "register_operand" "=r") 1232 (unspec:P 1233 [(match_operand:P 1 "register_operand" "r") 1234 (match_operand:P 2 "register_operand" "r") 1235 (match_operand:P 3 "symbolic_operand" "")] 1236 UNSPEC_TLS_LE))] 1237 "" 1238 "add\t%0,%1,%2,%%tprel_add(%3)" 1239 [(set_attr "type" "arith") 1240 (set_attr "mode" "<MODE>")]) 1241 1242(define_insn "got_load_tls_gd<mode>" 1243 [(set (match_operand:P 0 "register_operand" "=r") 1244 (unspec:P 1245 [(match_operand:P 1 "symbolic_operand" "")] 1246 UNSPEC_TLS_GD))] 1247 "" 1248 "la.tls.gd\t%0,%1" 1249 [(set_attr "got" "load") 1250 (set_attr "mode" "<MODE>")]) 1251 1252(define_insn "got_load_tls_ie<mode>" 1253 [(set (match_operand:P 0 "register_operand" "=r") 1254 (unspec:P 1255 [(match_operand:P 1 "symbolic_operand" "")] 1256 UNSPEC_TLS_IE))] 1257 "" 1258 "la.tls.ie\t%0,%1" 1259 [(set_attr "got" "load") 1260 (set_attr "mode" "<MODE>")]) 1261 1262(define_insn "auipc<mode>" 1263 [(set (match_operand:P 0 "register_operand" "=r") 1264 (unspec:P 1265 [(match_operand:P 1 "symbolic_operand" "") 1266 (match_operand:P 2 "const_int_operand") 1267 (pc)] 1268 UNSPEC_AUIPC))] 1269 "" 1270 ".LA%2: auipc\t%0,%h1" 1271 [(set_attr "type" "auipc") 1272 (set_attr "cannot_copy" "yes")]) 1273 1274;; Instructions for adding the low 12 bits of an address to a register. 1275;; Operand 2 is the address: riscv_print_operand works out which relocation 1276;; should be applied. 1277 1278(define_insn "*low<mode>" 1279 [(set (match_operand:P 0 "register_operand" "=r") 1280 (lo_sum:P (match_operand:P 1 "register_operand" " r") 1281 (match_operand:P 2 "symbolic_operand" "")))] 1282 "" 1283 "addi\t%0,%1,%R2" 1284 [(set_attr "type" "arith") 1285 (set_attr "mode" "<MODE>")]) 1286 1287;; Allow combine to split complex const_int load sequences, using operand 2 1288;; to store the intermediate results. See move_operand for details. 1289(define_split 1290 [(set (match_operand:GPR 0 "register_operand") 1291 (match_operand:GPR 1 "splittable_const_int_operand")) 1292 (clobber (match_operand:GPR 2 "register_operand"))] 1293 "" 1294 [(const_int 0)] 1295{ 1296 riscv_move_integer (operands[2], operands[0], INTVAL (operands[1]), 1297 <GPR:MODE>mode, TRUE); 1298 DONE; 1299}) 1300 1301;; Likewise, for symbolic operands. 1302(define_split 1303 [(set (match_operand:P 0 "register_operand") 1304 (match_operand:P 1)) 1305 (clobber (match_operand:P 2 "register_operand"))] 1306 "riscv_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL, TRUE)" 1307 [(set (match_dup 0) (match_dup 3))] 1308{ 1309 riscv_split_symbol (operands[2], operands[1], 1310 MAX_MACHINE_MODE, &operands[3], TRUE); 1311}) 1312 1313;; 64-bit integer moves 1314 1315(define_expand "movdi" 1316 [(set (match_operand:DI 0 "") 1317 (match_operand:DI 1 ""))] 1318 "" 1319{ 1320 if (riscv_legitimize_move (DImode, operands[0], operands[1])) 1321 DONE; 1322}) 1323 1324(define_insn "*movdi_32bit" 1325 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m, *f,*f,*r,*f,*m") 1326 (match_operand:DI 1 "move_operand" " r,i,m,r,*J*r,*m,*f,*f,*f"))] 1327 "!TARGET_64BIT 1328 && (register_operand (operands[0], DImode) 1329 || reg_or_0_operand (operands[1], DImode))" 1330 { return riscv_output_move (operands[0], operands[1]); } 1331 [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore") 1332 (set_attr "mode" "DI")]) 1333 1334(define_insn "*movdi_64bit" 1335 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, *f,*f,*r,*f,*m") 1336 (match_operand:DI 1 "move_operand" " r,T,m,rJ,*r*J,*m,*f,*f,*f"))] 1337 "TARGET_64BIT 1338 && (register_operand (operands[0], DImode) 1339 || reg_or_0_operand (operands[1], DImode))" 1340 { return riscv_output_move (operands[0], operands[1]); } 1341 [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore") 1342 (set_attr "mode" "DI")]) 1343 1344;; 32-bit Integer moves 1345 1346(define_expand "mov<mode>" 1347 [(set (match_operand:MOVE32 0 "") 1348 (match_operand:MOVE32 1 ""))] 1349 "" 1350{ 1351 if (riscv_legitimize_move (<MODE>mode, operands[0], operands[1])) 1352 DONE; 1353}) 1354 1355(define_insn "*movsi_internal" 1356 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, *f,*f,*r,*m") 1357 (match_operand:SI 1 "move_operand" " r,T,m,rJ,*r*J,*m,*f,*f"))] 1358 "(register_operand (operands[0], SImode) 1359 || reg_or_0_operand (operands[1], SImode))" 1360 { return riscv_output_move (operands[0], operands[1]); } 1361 [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fpstore") 1362 (set_attr "mode" "SI")]) 1363 1364;; 16-bit Integer moves 1365 1366;; Unlike most other insns, the move insns can't be split with 1367;; different predicates, because register spilling and other parts of 1368;; the compiler, have memoized the insn number already. 1369;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND. 1370 1371(define_expand "movhi" 1372 [(set (match_operand:HI 0 "") 1373 (match_operand:HI 1 ""))] 1374 "" 1375{ 1376 if (riscv_legitimize_move (HImode, operands[0], operands[1])) 1377 DONE; 1378}) 1379 1380(define_insn "*movhi_internal" 1381 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r, m, *f,*r") 1382 (match_operand:HI 1 "move_operand" " r,T,m,rJ,*r*J,*f"))] 1383 "(register_operand (operands[0], HImode) 1384 || reg_or_0_operand (operands[1], HImode))" 1385 { return riscv_output_move (operands[0], operands[1]); } 1386 [(set_attr "move_type" "move,const,load,store,mtc,mfc") 1387 (set_attr "mode" "HI")]) 1388 1389;; HImode constant generation; see riscv_move_integer for details. 1390;; si+si->hi without truncation is legal because of 1391;; TARGET_TRULY_NOOP_TRUNCATION. 1392 1393(define_insn "*add<mode>hi3" 1394 [(set (match_operand:HI 0 "register_operand" "=r,r") 1395 (plus:HI (match_operand:HISI 1 "register_operand" " r,r") 1396 (match_operand:HISI 2 "arith_operand" " r,I")))] 1397 "" 1398 { return TARGET_64BIT ? "add%i2w\t%0,%1,%2" : "add%i2\t%0,%1,%2"; } 1399 [(set_attr "type" "arith") 1400 (set_attr "mode" "HI")]) 1401 1402(define_insn "*xor<mode>hi3" 1403 [(set (match_operand:HI 0 "register_operand" "=r,r") 1404 (xor:HI (match_operand:HISI 1 "register_operand" " r,r") 1405 (match_operand:HISI 2 "arith_operand" " r,I")))] 1406 "" 1407 "xor%i2\t%0,%1,%2" 1408 [(set_attr "type" "logical") 1409 (set_attr "mode" "HI")]) 1410 1411;; 8-bit Integer moves 1412 1413(define_expand "movqi" 1414 [(set (match_operand:QI 0 "") 1415 (match_operand:QI 1 ""))] 1416 "" 1417{ 1418 if (riscv_legitimize_move (QImode, operands[0], operands[1])) 1419 DONE; 1420}) 1421 1422(define_insn "*movqi_internal" 1423 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r, m, *f,*r") 1424 (match_operand:QI 1 "move_operand" " r,I,m,rJ,*r*J,*f"))] 1425 "(register_operand (operands[0], QImode) 1426 || reg_or_0_operand (operands[1], QImode))" 1427 { return riscv_output_move (operands[0], operands[1]); } 1428 [(set_attr "move_type" "move,const,load,store,mtc,mfc") 1429 (set_attr "mode" "QI")]) 1430 1431;; 32-bit floating point moves 1432 1433(define_expand "movsf" 1434 [(set (match_operand:SF 0 "") 1435 (match_operand:SF 1 ""))] 1436 "" 1437{ 1438 if (riscv_legitimize_move (SFmode, operands[0], operands[1])) 1439 DONE; 1440}) 1441 1442(define_insn "*movsf_hardfloat" 1443 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r, *r,*r,*m") 1444 (match_operand:SF 1 "move_operand" " f,G,m,f,G,*r,*f,*G*r,*m,*r"))] 1445 "TARGET_HARD_FLOAT 1446 && (register_operand (operands[0], SFmode) 1447 || reg_or_0_operand (operands[1], SFmode))" 1448 { return riscv_output_move (operands[0], operands[1]); } 1449 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") 1450 (set_attr "mode" "SF")]) 1451 1452(define_insn "*movsf_softfloat" 1453 [(set (match_operand:SF 0 "nonimmediate_operand" "= r,r,m") 1454 (match_operand:SF 1 "move_operand" " Gr,m,r"))] 1455 "!TARGET_HARD_FLOAT 1456 && (register_operand (operands[0], SFmode) 1457 || reg_or_0_operand (operands[1], SFmode))" 1458 { return riscv_output_move (operands[0], operands[1]); } 1459 [(set_attr "move_type" "move,load,store") 1460 (set_attr "mode" "SF")]) 1461 1462;; 64-bit floating point moves 1463 1464(define_expand "movdf" 1465 [(set (match_operand:DF 0 "") 1466 (match_operand:DF 1 ""))] 1467 "" 1468{ 1469 if (riscv_legitimize_move (DFmode, operands[0], operands[1])) 1470 DONE; 1471}) 1472 1473;; In RV32, we lack fmv.x.d and fmv.d.x. Go through memory instead. 1474;; (However, we can still use fcvt.d.w to zero a floating-point register.) 1475(define_insn "*movdf_hardfloat_rv32" 1476 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m, *r,*r,*m") 1477 (match_operand:DF 1 "move_operand" " f,G,m,f,G,*r*G,*m,*r"))] 1478 "!TARGET_64BIT && TARGET_DOUBLE_FLOAT 1479 && (register_operand (operands[0], DFmode) 1480 || reg_or_0_operand (operands[1], DFmode))" 1481 { return riscv_output_move (operands[0], operands[1]); } 1482 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,move,load,store") 1483 (set_attr "mode" "DF")]) 1484 1485(define_insn "*movdf_hardfloat_rv64" 1486 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r, *r,*r,*m") 1487 (match_operand:DF 1 "move_operand" " f,G,m,f,G,*r,*f,*r*G,*m,*r"))] 1488 "TARGET_64BIT && TARGET_DOUBLE_FLOAT 1489 && (register_operand (operands[0], DFmode) 1490 || reg_or_0_operand (operands[1], DFmode))" 1491 { return riscv_output_move (operands[0], operands[1]); } 1492 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") 1493 (set_attr "mode" "DF")]) 1494 1495(define_insn "*movdf_softfloat" 1496 [(set (match_operand:DF 0 "nonimmediate_operand" "= r,r, m") 1497 (match_operand:DF 1 "move_operand" " rG,m,rG"))] 1498 "!TARGET_DOUBLE_FLOAT 1499 && (register_operand (operands[0], DFmode) 1500 || reg_or_0_operand (operands[1], DFmode))" 1501 { return riscv_output_move (operands[0], operands[1]); } 1502 [(set_attr "move_type" "move,load,store") 1503 (set_attr "mode" "DF")]) 1504 1505(define_split 1506 [(set (match_operand:MOVE64 0 "nonimmediate_operand") 1507 (match_operand:MOVE64 1 "move_operand"))] 1508 "reload_completed 1509 && riscv_split_64bit_move_p (operands[0], operands[1])" 1510 [(const_int 0)] 1511{ 1512 riscv_split_doubleword_move (operands[0], operands[1]); 1513 DONE; 1514}) 1515 1516(define_expand "cpymemsi" 1517 [(parallel [(set (match_operand:BLK 0 "general_operand") 1518 (match_operand:BLK 1 "general_operand")) 1519 (use (match_operand:SI 2 "")) 1520 (use (match_operand:SI 3 "const_int_operand"))])] 1521 "" 1522{ 1523 if (riscv_expand_block_move (operands[0], operands[1], operands[2])) 1524 DONE; 1525 else 1526 FAIL; 1527}) 1528 1529;; Expand in-line code to clear the instruction cache between operand[0] and 1530;; operand[1]. 1531(define_expand "clear_cache" 1532 [(match_operand 0 "pmode_register_operand") 1533 (match_operand 1 "pmode_register_operand")] 1534 "" 1535{ 1536#ifdef ICACHE_FLUSH_FUNC 1537 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, ICACHE_FLUSH_FUNC), 1538 LCT_NORMAL, VOIDmode, operands[0], Pmode, 1539 operands[1], Pmode, const0_rtx, Pmode); 1540#else 1541 emit_insn (gen_fence_i ()); 1542#endif 1543 DONE; 1544}) 1545 1546(define_insn "fence" 1547 [(unspec_volatile [(const_int 0)] UNSPECV_FENCE)] 1548 "" 1549 "%|fence%-") 1550 1551(define_insn "fence_i" 1552 [(unspec_volatile [(const_int 0)] UNSPECV_FENCE_I)] 1553 "" 1554 "fence.i") 1555 1556;; 1557;; .................... 1558;; 1559;; SHIFTS 1560;; 1561;; .................... 1562 1563;; Use a QImode shift count, to avoid generating sign or zero extend 1564;; instructions for shift counts, and to avoid dropping subregs. 1565;; expand_shift_1 can do this automatically when SHIFT_COUNT_TRUNCATED is 1566;; defined, but use of that is discouraged. 1567 1568(define_insn "<optab>si3" 1569 [(set (match_operand:SI 0 "register_operand" "= r") 1570 (any_shift:SI 1571 (match_operand:SI 1 "register_operand" " r") 1572 (match_operand:QI 2 "arith_operand" " rI")))] 1573 "" 1574{ 1575 if (GET_CODE (operands[2]) == CONST_INT) 1576 operands[2] = GEN_INT (INTVAL (operands[2]) 1577 & (GET_MODE_BITSIZE (SImode) - 1)); 1578 1579 return TARGET_64BIT ? "<insn>%i2w\t%0,%1,%2" : "<insn>%i2\t%0,%1,%2"; 1580} 1581 [(set_attr "type" "shift") 1582 (set_attr "mode" "SI")]) 1583 1584(define_insn_and_split "*<optab>si3_mask" 1585 [(set (match_operand:SI 0 "register_operand" "= r") 1586 (any_shift:SI 1587 (match_operand:SI 1 "register_operand" " r") 1588 (subreg:QI 1589 (and:SI 1590 (match_operand:SI 2 "register_operand" "r") 1591 (match_operand 3 "const_int_operand")) 0)))] 1592 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1)) 1593 == GET_MODE_BITSIZE (SImode)-1" 1594 "#" 1595 "&& 1" 1596 [(set (match_dup 0) 1597 (any_shift:SI (match_dup 1) 1598 (match_dup 2)))] 1599 "operands[2] = gen_lowpart (QImode, operands[2]);" 1600 [(set_attr "type" "shift") 1601 (set_attr "mode" "SI")]) 1602 1603(define_insn_and_split "*<optab>si3_mask_1" 1604 [(set (match_operand:SI 0 "register_operand" "= r") 1605 (any_shift:SI 1606 (match_operand:SI 1 "register_operand" " r") 1607 (subreg:QI 1608 (and:DI 1609 (match_operand:DI 2 "register_operand" "r") 1610 (match_operand 3 "const_int_operand")) 0)))] 1611 "TARGET_64BIT 1612 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1)) 1613 == GET_MODE_BITSIZE (SImode)-1" 1614 "#" 1615 "&& 1" 1616 [(set (match_dup 0) 1617 (any_shift:SI (match_dup 1) 1618 (match_dup 2)))] 1619 "operands[2] = gen_lowpart (QImode, operands[2]);" 1620 [(set_attr "type" "shift") 1621 (set_attr "mode" "SI")]) 1622 1623(define_insn "<optab>di3" 1624 [(set (match_operand:DI 0 "register_operand" "= r") 1625 (any_shift:DI 1626 (match_operand:DI 1 "register_operand" " r") 1627 (match_operand:QI 2 "arith_operand" " rI")))] 1628 "TARGET_64BIT" 1629{ 1630 if (GET_CODE (operands[2]) == CONST_INT) 1631 operands[2] = GEN_INT (INTVAL (operands[2]) 1632 & (GET_MODE_BITSIZE (DImode) - 1)); 1633 1634 return "<insn>%i2\t%0,%1,%2"; 1635} 1636 [(set_attr "type" "shift") 1637 (set_attr "mode" "DI")]) 1638 1639(define_insn_and_split "*<optab>di3_mask" 1640 [(set (match_operand:DI 0 "register_operand" "= r") 1641 (any_shift:DI 1642 (match_operand:DI 1 "register_operand" " r") 1643 (subreg:QI 1644 (and:SI 1645 (match_operand:SI 2 "register_operand" "r") 1646 (match_operand 3 "const_int_operand")) 0)))] 1647 "TARGET_64BIT 1648 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1)) 1649 == GET_MODE_BITSIZE (DImode)-1" 1650 "#" 1651 "&& 1" 1652 [(set (match_dup 0) 1653 (any_shift:DI (match_dup 1) 1654 (match_dup 2)))] 1655 "operands[2] = gen_lowpart (QImode, operands[2]);" 1656 [(set_attr "type" "shift") 1657 (set_attr "mode" "DI")]) 1658 1659(define_insn_and_split "*<optab>di3_mask_1" 1660 [(set (match_operand:DI 0 "register_operand" "= r") 1661 (any_shift:DI 1662 (match_operand:DI 1 "register_operand" " r") 1663 (subreg:QI 1664 (and:DI 1665 (match_operand:DI 2 "register_operand" "r") 1666 (match_operand 3 "const_int_operand")) 0)))] 1667 "TARGET_64BIT 1668 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1)) 1669 == GET_MODE_BITSIZE (DImode)-1" 1670 "#" 1671 "&& 1" 1672 [(set (match_dup 0) 1673 (any_shift:DI (match_dup 1) 1674 (match_dup 2)))] 1675 "operands[2] = gen_lowpart (QImode, operands[2]);" 1676 [(set_attr "type" "shift") 1677 (set_attr "mode" "DI")]) 1678 1679(define_insn "*<optab>si3_extend" 1680 [(set (match_operand:DI 0 "register_operand" "= r") 1681 (sign_extend:DI 1682 (any_shift:SI (match_operand:SI 1 "register_operand" " r") 1683 (match_operand:QI 2 "arith_operand" " rI"))))] 1684 "TARGET_64BIT" 1685{ 1686 if (GET_CODE (operands[2]) == CONST_INT) 1687 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); 1688 1689 return "<insn>%i2w\t%0,%1,%2"; 1690} 1691 [(set_attr "type" "shift") 1692 (set_attr "mode" "SI")]) 1693 1694(define_insn_and_split "*<optab>si3_extend_mask" 1695 [(set (match_operand:DI 0 "register_operand" "= r") 1696 (sign_extend:DI 1697 (any_shift:SI 1698 (match_operand:SI 1 "register_operand" " r") 1699 (subreg:QI 1700 (and:SI 1701 (match_operand:SI 2 "register_operand" " r") 1702 (match_operand 3 "const_int_operand")) 0))))] 1703 "TARGET_64BIT 1704 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1)) 1705 == GET_MODE_BITSIZE (SImode)-1" 1706 "#" 1707 "&& 1" 1708 [(set (match_dup 0) 1709 (sign_extend:DI 1710 (any_shift:SI (match_dup 1) 1711 (match_dup 2))))] 1712 "operands[2] = gen_lowpart (QImode, operands[2]);" 1713 [(set_attr "type" "shift") 1714 (set_attr "mode" "SI")]) 1715 1716(define_insn_and_split "*<optab>si3_extend_mask_1" 1717 [(set (match_operand:DI 0 "register_operand" "= r") 1718 (sign_extend:DI 1719 (any_shift:SI 1720 (match_operand:SI 1 "register_operand" " r") 1721 (subreg:QI 1722 (and:DI 1723 (match_operand:DI 2 "register_operand" " r") 1724 (match_operand 3 "const_int_operand")) 0))))] 1725 "TARGET_64BIT 1726 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1)) 1727 == GET_MODE_BITSIZE (SImode)-1" 1728 "#" 1729 "&& 1" 1730 [(set (match_dup 0) 1731 (sign_extend:DI 1732 (any_shift:SI (match_dup 1) 1733 (match_dup 2))))] 1734 "operands[2] = gen_lowpart (QImode, operands[2]);" 1735 [(set_attr "type" "shift") 1736 (set_attr "mode" "SI")]) 1737 1738;; Non-canonical, but can be formed by ree when combine is not successful at 1739;; producing one of the two canonical patterns below. 1740(define_insn "*lshrsi3_zero_extend_1" 1741 [(set (match_operand:DI 0 "register_operand" "=r") 1742 (zero_extend:DI 1743 (lshiftrt:SI (match_operand:SI 1 "register_operand" " r") 1744 (match_operand 2 "const_int_operand"))))] 1745 "TARGET_64BIT && (INTVAL (operands[2]) & 0x1f) > 0" 1746{ 1747 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); 1748 1749 return "srliw\t%0,%1,%2"; 1750} 1751 [(set_attr "type" "shift") 1752 (set_attr "mode" "SI")]) 1753 1754;; Canonical form for a zero-extend of a logical right shift. 1755(define_insn "*lshrsi3_zero_extend_2" 1756 [(set (match_operand:DI 0 "register_operand" "=r") 1757 (zero_extract:DI (match_operand:DI 1 "register_operand" " r") 1758 (match_operand 2 "const_int_operand") 1759 (match_operand 3 "const_int_operand")))] 1760 "(TARGET_64BIT && (INTVAL (operands[3]) > 0) 1761 && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32))" 1762{ 1763 return "srliw\t%0,%1,%3"; 1764} 1765 [(set_attr "type" "shift") 1766 (set_attr "mode" "SI")]) 1767 1768;; Canonical form for a zero-extend of a logical right shift when the 1769;; shift count is 31. 1770(define_insn "*lshrsi3_zero_extend_3" 1771 [(set (match_operand:DI 0 "register_operand" "=r") 1772 (lt:DI (match_operand:SI 1 "register_operand" " r") 1773 (const_int 0)))] 1774 "TARGET_64BIT" 1775{ 1776 return "srliw\t%0,%1,31"; 1777} 1778 [(set_attr "type" "shift") 1779 (set_attr "mode" "SI")]) 1780 1781;; Handle AND with 2^N-1 for N from 12 to XLEN. This can be split into 1782;; two logical shifts. Otherwise it requires 3 instructions: lui, 1783;; xor/addi/srli, and. 1784 1785;; Generating a temporary for the shift output gives better combiner results; 1786;; and also fixes a problem where op0 could be a paradoxical reg and shifting 1787;; by amounts larger than the size of the SUBREG_REG doesn't work. 1788(define_split 1789 [(set (match_operand:GPR 0 "register_operand") 1790 (and:GPR (match_operand:GPR 1 "register_operand") 1791 (match_operand:GPR 2 "p2m1_shift_operand"))) 1792 (clobber (match_operand:GPR 3 "register_operand"))] 1793 "" 1794 [(set (match_dup 3) 1795 (ashift:GPR (match_dup 1) (match_dup 2))) 1796 (set (match_dup 0) 1797 (lshiftrt:GPR (match_dup 3) (match_dup 2)))] 1798{ 1799 /* Op2 is a VOIDmode constant, so get the mode size from op1. */ 1800 operands[2] = GEN_INT (GET_MODE_BITSIZE (GET_MODE (operands[1])) 1801 - exact_log2 (INTVAL (operands[2]) + 1)); 1802}) 1803 1804;; Handle AND with 0xF...F0...0 where there are 32 to 63 zeros. This can be 1805;; split into two shifts. Otherwise it requires 3 instructions: li, sll, and. 1806(define_split 1807 [(set (match_operand:DI 0 "register_operand") 1808 (and:DI (match_operand:DI 1 "register_operand") 1809 (match_operand:DI 2 "high_mask_shift_operand"))) 1810 (clobber (match_operand:DI 3 "register_operand"))] 1811 "TARGET_64BIT" 1812 [(set (match_dup 3) 1813 (lshiftrt:DI (match_dup 1) (match_dup 2))) 1814 (set (match_dup 0) 1815 (ashift:DI (match_dup 3) (match_dup 2)))] 1816{ 1817 operands[2] = GEN_INT (ctz_hwi (INTVAL (operands[2]))); 1818}) 1819 1820;; 1821;; .................... 1822;; 1823;; CONDITIONAL BRANCHES 1824;; 1825;; .................... 1826 1827;; Conditional branches 1828 1829(define_insn "*branch<mode>" 1830 [(set (pc) 1831 (if_then_else 1832 (match_operator 1 "order_operator" 1833 [(match_operand:X 2 "register_operand" "r") 1834 (match_operand:X 3 "reg_or_0_operand" "rJ")]) 1835 (label_ref (match_operand 0 "" "")) 1836 (pc)))] 1837 "" 1838 "b%C1\t%2,%z3,%0" 1839 [(set_attr "type" "branch") 1840 (set_attr "mode" "none")]) 1841 1842;; Patterns for implementations that optimize short forward branches. 1843 1844(define_expand "mov<mode>cc" 1845 [(set (match_operand:GPR 0 "register_operand") 1846 (if_then_else:GPR (match_operand 1 "comparison_operator") 1847 (match_operand:GPR 2 "register_operand") 1848 (match_operand:GPR 3 "sfb_alu_operand")))] 1849 "TARGET_SFB_ALU" 1850{ 1851 rtx cmp = operands[1]; 1852 /* We only handle word mode integer compares for now. */ 1853 if (GET_MODE (XEXP (cmp, 0)) != word_mode) 1854 FAIL; 1855 riscv_expand_conditional_move (operands[0], operands[2], operands[3], 1856 GET_CODE (cmp), XEXP (cmp, 0), XEXP (cmp, 1)); 1857 DONE; 1858}) 1859 1860(define_insn "*mov<GPR:mode><X:mode>cc" 1861 [(set (match_operand:GPR 0 "register_operand" "=r,r") 1862 (if_then_else:GPR 1863 (match_operator 5 "order_operator" 1864 [(match_operand:X 1 "register_operand" "r,r") 1865 (match_operand:X 2 "reg_or_0_operand" "rJ,rJ")]) 1866 (match_operand:GPR 3 "register_operand" "0,0") 1867 (match_operand:GPR 4 "sfb_alu_operand" "rJ,IL")))] 1868 "TARGET_SFB_ALU" 1869 "@ 1870 b%C5 %1,%z2,1f; mv %0,%z4; 1: # movcc 1871 b%C5 %1,%z2,1f; li %0,%4; 1: # movcc" 1872 [(set_attr "length" "8") 1873 (set_attr "type" "sfb_alu") 1874 (set_attr "mode" "<GPR:MODE>")]) 1875 1876;; Used to implement built-in functions. 1877(define_expand "condjump" 1878 [(set (pc) 1879 (if_then_else (match_operand 0) 1880 (label_ref (match_operand 1)) 1881 (pc)))]) 1882 1883(define_expand "cbranch<mode>4" 1884 [(set (pc) 1885 (if_then_else (match_operator 0 "comparison_operator" 1886 [(match_operand:BR 1 "register_operand") 1887 (match_operand:BR 2 "nonmemory_operand")]) 1888 (label_ref (match_operand 3 "")) 1889 (pc)))] 1890 "" 1891{ 1892 riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]), 1893 operands[1], operands[2]); 1894 DONE; 1895}) 1896 1897(define_expand "cbranch<mode>4" 1898 [(set (pc) 1899 (if_then_else (match_operator 0 "fp_branch_comparison" 1900 [(match_operand:ANYF 1 "register_operand") 1901 (match_operand:ANYF 2 "register_operand")]) 1902 (label_ref (match_operand 3 "")) 1903 (pc)))] 1904 "TARGET_HARD_FLOAT" 1905{ 1906 riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]), 1907 operands[1], operands[2]); 1908 DONE; 1909}) 1910 1911(define_insn_and_split "*branch_on_bit<X:mode>" 1912 [(set (pc) 1913 (if_then_else 1914 (match_operator 0 "equality_operator" 1915 [(zero_extract:X (match_operand:X 2 "register_operand" "r") 1916 (const_int 1) 1917 (match_operand 3 "branch_on_bit_operand")) 1918 (const_int 0)]) 1919 (label_ref (match_operand 1)) 1920 (pc))) 1921 (clobber (match_scratch:X 4 "=&r"))] 1922 "" 1923 "#" 1924 "reload_completed" 1925 [(set (match_dup 4) 1926 (ashift:X (match_dup 2) (match_dup 3))) 1927 (set (pc) 1928 (if_then_else 1929 (match_op_dup 0 [(match_dup 4) (const_int 0)]) 1930 (label_ref (match_operand 1)) 1931 (pc)))] 1932{ 1933 int shift = GET_MODE_BITSIZE (<MODE>mode) - 1 - INTVAL (operands[3]); 1934 operands[3] = GEN_INT (shift); 1935 1936 if (GET_CODE (operands[0]) == EQ) 1937 operands[0] = gen_rtx_GE (<MODE>mode, operands[4], const0_rtx); 1938 else 1939 operands[0] = gen_rtx_LT (<MODE>mode, operands[4], const0_rtx); 1940}) 1941 1942(define_insn_and_split "*branch_on_bit_range<X:mode>" 1943 [(set (pc) 1944 (if_then_else 1945 (match_operator 0 "equality_operator" 1946 [(zero_extract:X (match_operand:X 2 "register_operand" "r") 1947 (match_operand 3 "branch_on_bit_operand") 1948 (const_int 0)) 1949 (const_int 0)]) 1950 (label_ref (match_operand 1)) 1951 (pc))) 1952 (clobber (match_scratch:X 4 "=&r"))] 1953 "" 1954 "#" 1955 "reload_completed" 1956 [(set (match_dup 4) 1957 (ashift:X (match_dup 2) (match_dup 3))) 1958 (set (pc) 1959 (if_then_else 1960 (match_op_dup 0 [(match_dup 4) (const_int 0)]) 1961 (label_ref (match_operand 1)) 1962 (pc)))] 1963{ 1964 operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[3])); 1965}) 1966 1967;; 1968;; .................... 1969;; 1970;; SETTING A REGISTER FROM A COMPARISON 1971;; 1972;; .................... 1973 1974;; Destination is always set in SI mode. 1975 1976(define_expand "cstore<mode>4" 1977 [(set (match_operand:SI 0 "register_operand") 1978 (match_operator:SI 1 "order_operator" 1979 [(match_operand:GPR 2 "register_operand") 1980 (match_operand:GPR 3 "nonmemory_operand")]))] 1981 "" 1982{ 1983 riscv_expand_int_scc (operands[0], GET_CODE (operands[1]), operands[2], 1984 operands[3]); 1985 DONE; 1986}) 1987 1988(define_expand "cstore<mode>4" 1989 [(set (match_operand:SI 0 "register_operand") 1990 (match_operator:SI 1 "fp_scc_comparison" 1991 [(match_operand:ANYF 2 "register_operand") 1992 (match_operand:ANYF 3 "register_operand")]))] 1993 "TARGET_HARD_FLOAT" 1994{ 1995 riscv_expand_float_scc (operands[0], GET_CODE (operands[1]), operands[2], 1996 operands[3]); 1997 DONE; 1998}) 1999 2000(define_insn "*cstore<ANYF:mode><X:mode>4" 2001 [(set (match_operand:X 0 "register_operand" "=r") 2002 (match_operator:X 1 "fp_native_comparison" 2003 [(match_operand:ANYF 2 "register_operand" " f") 2004 (match_operand:ANYF 3 "register_operand" " f")]))] 2005 "TARGET_HARD_FLOAT" 2006 "f%C1.<fmt>\t%0,%2,%3" 2007 [(set_attr "type" "fcmp") 2008 (set_attr "mode" "<UNITMODE>")]) 2009 2010(define_expand "f<quiet_pattern>_quiet<ANYF:mode><X:mode>4" 2011 [(parallel [(set (match_operand:X 0 "register_operand") 2012 (unspec:X 2013 [(match_operand:ANYF 1 "register_operand") 2014 (match_operand:ANYF 2 "register_operand")] 2015 QUIET_COMPARISON)) 2016 (clobber (match_scratch:X 3))])] 2017 "TARGET_HARD_FLOAT") 2018 2019(define_insn "*f<quiet_pattern>_quiet<ANYF:mode><X:mode>4_default" 2020 [(set (match_operand:X 0 "register_operand" "=r") 2021 (unspec:X 2022 [(match_operand:ANYF 1 "register_operand" " f") 2023 (match_operand:ANYF 2 "register_operand" " f")] 2024 QUIET_COMPARISON)) 2025 (clobber (match_scratch:X 3 "=&r"))] 2026 "TARGET_HARD_FLOAT && ! HONOR_SNANS (<ANYF:MODE>mode)" 2027 "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3" 2028 [(set_attr "type" "fcmp") 2029 (set_attr "mode" "<UNITMODE>") 2030 (set (attr "length") (const_int 12))]) 2031 2032(define_insn "*f<quiet_pattern>_quiet<ANYF:mode><X:mode>4_snan" 2033 [(set (match_operand:X 0 "register_operand" "=r") 2034 (unspec:X 2035 [(match_operand:ANYF 1 "register_operand" " f") 2036 (match_operand:ANYF 2 "register_operand" " f")] 2037 QUIET_COMPARISON)) 2038 (clobber (match_scratch:X 3 "=&r"))] 2039 "TARGET_HARD_FLOAT && HONOR_SNANS (<ANYF:MODE>mode)" 2040 "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3\n\tfeq.<fmt>\tzero,%1,%2" 2041 [(set_attr "type" "fcmp") 2042 (set_attr "mode" "<UNITMODE>") 2043 (set (attr "length") (const_int 16))]) 2044 2045(define_insn "*seq_zero_<X:mode><GPR:mode>" 2046 [(set (match_operand:GPR 0 "register_operand" "=r") 2047 (eq:GPR (match_operand:X 1 "register_operand" " r") 2048 (const_int 0)))] 2049 "" 2050 "seqz\t%0,%1" 2051 [(set_attr "type" "slt") 2052 (set_attr "mode" "<X:MODE>")]) 2053 2054(define_insn "*sne_zero_<X:mode><GPR:mode>" 2055 [(set (match_operand:GPR 0 "register_operand" "=r") 2056 (ne:GPR (match_operand:X 1 "register_operand" " r") 2057 (const_int 0)))] 2058 "" 2059 "snez\t%0,%1" 2060 [(set_attr "type" "slt") 2061 (set_attr "mode" "<X:MODE>")]) 2062 2063(define_insn "*sgt<u>_<X:mode><GPR:mode>" 2064 [(set (match_operand:GPR 0 "register_operand" "= r") 2065 (any_gt:GPR (match_operand:X 1 "register_operand" " r") 2066 (match_operand:X 2 "reg_or_0_operand" " rJ")))] 2067 "" 2068 "sgt<u>\t%0,%1,%z2" 2069 [(set_attr "type" "slt") 2070 (set_attr "mode" "<X:MODE>")]) 2071 2072(define_insn "*sge<u>_<X:mode><GPR:mode>" 2073 [(set (match_operand:GPR 0 "register_operand" "=r") 2074 (any_ge:GPR (match_operand:X 1 "register_operand" " r") 2075 (const_int 1)))] 2076 "" 2077 "slt%i2<u>\t%0,zero,%1" 2078 [(set_attr "type" "slt") 2079 (set_attr "mode" "<X:MODE>")]) 2080 2081(define_insn "*slt<u>_<X:mode><GPR:mode>" 2082 [(set (match_operand:GPR 0 "register_operand" "= r") 2083 (any_lt:GPR (match_operand:X 1 "register_operand" " r") 2084 (match_operand:X 2 "arith_operand" " rI")))] 2085 "" 2086 "slt%i2<u>\t%0,%1,%2" 2087 [(set_attr "type" "slt") 2088 (set_attr "mode" "<X:MODE>")]) 2089 2090(define_insn "*sle<u>_<X:mode><GPR:mode>" 2091 [(set (match_operand:GPR 0 "register_operand" "=r") 2092 (any_le:GPR (match_operand:X 1 "register_operand" " r") 2093 (match_operand:X 2 "sle_operand" "")))] 2094 "" 2095{ 2096 operands[2] = GEN_INT (INTVAL (operands[2]) + 1); 2097 return "slt%i2<u>\t%0,%1,%2"; 2098} 2099 [(set_attr "type" "slt") 2100 (set_attr "mode" "<X:MODE>")]) 2101 2102;; 2103;; .................... 2104;; 2105;; UNCONDITIONAL BRANCHES 2106;; 2107;; .................... 2108 2109;; Unconditional branches. 2110 2111(define_insn "jump" 2112 [(set (pc) 2113 (label_ref (match_operand 0 "" "")))] 2114 "" 2115 "j\t%l0" 2116 [(set_attr "type" "jump") 2117 (set_attr "mode" "none")]) 2118 2119(define_expand "indirect_jump" 2120 [(set (pc) (match_operand 0 "register_operand"))] 2121 "" 2122{ 2123 operands[0] = force_reg (Pmode, operands[0]); 2124 if (Pmode == SImode) 2125 emit_jump_insn (gen_indirect_jumpsi (operands[0])); 2126 else 2127 emit_jump_insn (gen_indirect_jumpdi (operands[0])); 2128 DONE; 2129}) 2130 2131(define_insn "indirect_jump<mode>" 2132 [(set (pc) (match_operand:P 0 "register_operand" "l"))] 2133 "" 2134 "jr\t%0" 2135 [(set_attr "type" "jump") 2136 (set_attr "mode" "none")]) 2137 2138(define_expand "tablejump" 2139 [(set (pc) (match_operand 0 "register_operand" "")) 2140 (use (label_ref (match_operand 1 "" "")))] 2141 "" 2142{ 2143 if (CASE_VECTOR_PC_RELATIVE) 2144 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0], 2145 gen_rtx_LABEL_REF (Pmode, operands[1]), 2146 NULL_RTX, 0, OPTAB_DIRECT); 2147 2148 if (CASE_VECTOR_PC_RELATIVE && Pmode == DImode) 2149 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1])); 2150 else 2151 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1])); 2152 DONE; 2153}) 2154 2155(define_insn "tablejump<mode>" 2156 [(set (pc) (match_operand:GPR 0 "register_operand" "l")) 2157 (use (label_ref (match_operand 1 "" "")))] 2158 "" 2159 "jr\t%0" 2160 [(set_attr "type" "jump") 2161 (set_attr "mode" "none")]) 2162 2163;; 2164;; .................... 2165;; 2166;; Function prologue/epilogue 2167;; 2168;; .................... 2169;; 2170 2171(define_expand "prologue" 2172 [(const_int 1)] 2173 "" 2174{ 2175 riscv_expand_prologue (); 2176 DONE; 2177}) 2178 2179;; Block any insns from being moved before this point, since the 2180;; profiling call to mcount can use various registers that aren't 2181;; saved or used to pass arguments. 2182 2183(define_insn "blockage" 2184 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 2185 "" 2186 "" 2187 [(set_attr "type" "ghost") 2188 (set_attr "mode" "none")]) 2189 2190(define_expand "epilogue" 2191 [(const_int 2)] 2192 "" 2193{ 2194 riscv_expand_epilogue (NORMAL_RETURN); 2195 DONE; 2196}) 2197 2198(define_expand "sibcall_epilogue" 2199 [(const_int 2)] 2200 "" 2201{ 2202 riscv_expand_epilogue (SIBCALL_RETURN); 2203 DONE; 2204}) 2205 2206;; Trivial return. Make it look like a normal return insn as that 2207;; allows jump optimizations to work better. 2208 2209(define_expand "return" 2210 [(simple_return)] 2211 "riscv_can_use_return_insn ()" 2212 "") 2213 2214(define_insn "simple_return" 2215 [(simple_return)] 2216 "" 2217{ 2218 return riscv_output_return (); 2219} 2220 [(set_attr "type" "jump") 2221 (set_attr "mode" "none")]) 2222 2223;; Normal return. 2224 2225(define_insn "simple_return_internal" 2226 [(simple_return) 2227 (use (match_operand 0 "pmode_register_operand" ""))] 2228 "" 2229 "jr\t%0" 2230 [(set_attr "type" "jump") 2231 (set_attr "mode" "none")]) 2232 2233;; This is used in compiling the unwind routines. 2234(define_expand "eh_return" 2235 [(use (match_operand 0 "general_operand"))] 2236 "" 2237{ 2238 if (GET_MODE (operands[0]) != word_mode) 2239 operands[0] = convert_to_mode (word_mode, operands[0], 0); 2240 if (TARGET_64BIT) 2241 emit_insn (gen_eh_set_lr_di (operands[0])); 2242 else 2243 emit_insn (gen_eh_set_lr_si (operands[0])); 2244 2245 emit_jump_insn (gen_eh_return_internal ()); 2246 emit_barrier (); 2247 DONE; 2248}) 2249 2250;; Clobber the return address on the stack. We can't expand this 2251;; until we know where it will be put in the stack frame. 2252 2253(define_insn "eh_set_lr_si" 2254 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN) 2255 (clobber (match_scratch:SI 1 "=&r"))] 2256 "! TARGET_64BIT" 2257 "#") 2258 2259(define_insn "eh_set_lr_di" 2260 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN) 2261 (clobber (match_scratch:DI 1 "=&r"))] 2262 "TARGET_64BIT" 2263 "#") 2264 2265(define_split 2266 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN) 2267 (clobber (match_scratch 1))] 2268 "reload_completed" 2269 [(const_int 0)] 2270{ 2271 riscv_set_return_address (operands[0], operands[1]); 2272 DONE; 2273}) 2274 2275(define_insn_and_split "eh_return_internal" 2276 [(eh_return)] 2277 "" 2278 "#" 2279 "epilogue_completed" 2280 [(const_int 0)] 2281 "riscv_expand_epilogue (EXCEPTION_RETURN); DONE;") 2282 2283;; 2284;; .................... 2285;; 2286;; FUNCTION CALLS 2287;; 2288;; .................... 2289 2290(define_expand "sibcall" 2291 [(parallel [(call (match_operand 0 "") 2292 (match_operand 1 "")) 2293 (use (match_operand 2 "")) ;; next_arg_reg 2294 (use (match_operand 3 ""))])] ;; struct_value_size_rtx 2295 "" 2296{ 2297 rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0)); 2298 emit_call_insn (gen_sibcall_internal (target, operands[1])); 2299 DONE; 2300}) 2301 2302(define_insn "sibcall_internal" 2303 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S,U")) 2304 (match_operand 1 "" ""))] 2305 "SIBLING_CALL_P (insn)" 2306 "@ 2307 jr\t%0 2308 tail\t%0 2309 tail\t%0@plt" 2310 [(set_attr "type" "call")]) 2311 2312(define_expand "sibcall_value" 2313 [(parallel [(set (match_operand 0 "") 2314 (call (match_operand 1 "") 2315 (match_operand 2 ""))) 2316 (use (match_operand 3 ""))])] ;; next_arg_reg 2317 "" 2318{ 2319 rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0)); 2320 emit_call_insn (gen_sibcall_value_internal (operands[0], target, operands[2])); 2321 DONE; 2322}) 2323 2324(define_insn "sibcall_value_internal" 2325 [(set (match_operand 0 "" "") 2326 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S,U")) 2327 (match_operand 2 "" "")))] 2328 "SIBLING_CALL_P (insn)" 2329 "@ 2330 jr\t%1 2331 tail\t%1 2332 tail\t%1@plt" 2333 [(set_attr "type" "call")]) 2334 2335(define_expand "call" 2336 [(parallel [(call (match_operand 0 "") 2337 (match_operand 1 "")) 2338 (use (match_operand 2 "")) ;; next_arg_reg 2339 (use (match_operand 3 ""))])] ;; struct_value_size_rtx 2340 "" 2341{ 2342 rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0)); 2343 emit_call_insn (gen_call_internal (target, operands[1])); 2344 DONE; 2345}) 2346 2347(define_insn "call_internal" 2348 [(call (mem:SI (match_operand 0 "call_insn_operand" "l,S,U")) 2349 (match_operand 1 "" "")) 2350 (clobber (reg:SI RETURN_ADDR_REGNUM))] 2351 "" 2352 "@ 2353 jalr\t%0 2354 call\t%0 2355 call\t%0@plt" 2356 [(set_attr "type" "call")]) 2357 2358(define_expand "call_value" 2359 [(parallel [(set (match_operand 0 "") 2360 (call (match_operand 1 "") 2361 (match_operand 2 ""))) 2362 (use (match_operand 3 ""))])] ;; next_arg_reg 2363 "" 2364{ 2365 rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0)); 2366 emit_call_insn (gen_call_value_internal (operands[0], target, operands[2])); 2367 DONE; 2368}) 2369 2370(define_insn "call_value_internal" 2371 [(set (match_operand 0 "" "") 2372 (call (mem:SI (match_operand 1 "call_insn_operand" "l,S,U")) 2373 (match_operand 2 "" ""))) 2374 (clobber (reg:SI RETURN_ADDR_REGNUM))] 2375 "" 2376 "@ 2377 jalr\t%1 2378 call\t%1 2379 call\t%1@plt" 2380 [(set_attr "type" "call")]) 2381 2382;; Call subroutine returning any type. 2383 2384(define_expand "untyped_call" 2385 [(parallel [(call (match_operand 0 "") 2386 (const_int 0)) 2387 (match_operand 1 "") 2388 (match_operand 2 "")])] 2389 "" 2390{ 2391 int i; 2392 2393 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); 2394 2395 for (i = 0; i < XVECLEN (operands[2], 0); i++) 2396 { 2397 rtx set = XVECEXP (operands[2], 0, i); 2398 riscv_emit_move (SET_DEST (set), SET_SRC (set)); 2399 } 2400 2401 emit_insn (gen_blockage ()); 2402 DONE; 2403}) 2404 2405(define_insn "nop" 2406 [(const_int 0)] 2407 "" 2408 "nop" 2409 [(set_attr "type" "nop") 2410 (set_attr "mode" "none")]) 2411 2412(define_insn "trap" 2413 [(trap_if (const_int 1) (const_int 0))] 2414 "" 2415 "ebreak") 2416 2417;; Must use the registers that we save to prevent the rename reg optimization 2418;; pass from using them before the gpr_save pattern when shrink wrapping 2419;; occurs. See bug 95252 for instance. 2420 2421(define_insn "gpr_save" 2422 [(match_parallel 1 "gpr_save_operation" 2423 [(unspec_volatile [(match_operand 0 "const_int_operand")] 2424 UNSPECV_GPR_SAVE)])] 2425 "" 2426 "call\tt0,__riscv_save_%0") 2427 2428(define_insn "gpr_restore" 2429 [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_RESTORE)] 2430 "" 2431 "tail\t__riscv_restore_%0") 2432 2433(define_insn "gpr_restore_return" 2434 [(return) 2435 (use (match_operand 0 "pmode_register_operand" "")) 2436 (const_int 0)] 2437 "" 2438 "") 2439 2440(define_insn "riscv_frflags" 2441 [(set (match_operand:SI 0 "register_operand" "=r") 2442 (unspec_volatile [(const_int 0)] UNSPECV_FRFLAGS))] 2443 "TARGET_HARD_FLOAT" 2444 "frflags\t%0") 2445 2446(define_insn "riscv_fsflags" 2447 [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)] 2448 "TARGET_HARD_FLOAT" 2449 "fsflags\t%0") 2450 2451(define_insn "riscv_mret" 2452 [(return) 2453 (unspec_volatile [(const_int 0)] UNSPECV_MRET)] 2454 "" 2455 "mret") 2456 2457(define_insn "riscv_sret" 2458 [(return) 2459 (unspec_volatile [(const_int 0)] UNSPECV_SRET)] 2460 "" 2461 "sret") 2462 2463(define_insn "riscv_uret" 2464 [(return) 2465 (unspec_volatile [(const_int 0)] UNSPECV_URET)] 2466 "" 2467 "uret") 2468 2469(define_insn "stack_tie<mode>" 2470 [(set (mem:BLK (scratch)) 2471 (unspec:BLK [(match_operand:X 0 "register_operand" "r") 2472 (match_operand:X 1 "register_operand" "r")] 2473 UNSPEC_TIE))] 2474 "" 2475 "" 2476 [(set_attr "length" "0")] 2477) 2478 2479;; This fixes a failure with gcc.c-torture/execute/pr64242.c at -O2 for a 2480;; 32-bit target when using -mtune=sifive-7-series. The first sched pass 2481;; runs before register elimination, and we have a non-obvious dependency 2482;; between a use of the soft fp and a set of the hard fp. We fix this by 2483;; emitting a clobber using the hard fp between the two insns. 2484(define_expand "restore_stack_nonlocal" 2485 [(match_operand 0 "register_operand") 2486 (match_operand 1 "memory_operand")] 2487 "" 2488{ 2489 emit_move_insn (operands[0], operands[1]); 2490 /* Prevent the following hard fp restore from being moved before the move 2491 insn above which uses a copy of the soft fp reg. */ 2492 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); 2493 DONE; 2494}) 2495 2496(include "sync.md") 2497(include "peephole.md") 2498(include "pic.md") 2499(include "generic.md") 2500(include "sifive-7.md") 2501