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