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