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