1;; Machine description for SPARC. 2;; Copyright (C) 1987-2018 Free Software Foundation, Inc. 3;; Contributed by Michael Tiemann (tiemann@cygnus.com) 4;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans, 5;; at Cygnus Support. 6 7;; This file is part of GCC. 8 9;; GCC is free software; you can redistribute it and/or modify 10;; it under the terms of the GNU General Public License as published by 11;; the Free Software Foundation; either version 3, or (at your option) 12;; any later version. 13 14;; GCC is distributed in the hope that it will be useful, 15;; but WITHOUT ANY WARRANTY; without even the implied warranty of 16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17;; GNU General Public License for more details. 18 19;; You should have received a copy of the GNU General Public License 20;; along with GCC; see the file COPYING3. If not see 21;; <http://www.gnu.org/licenses/>. 22 23(define_c_enum "unspec" [ 24 UNSPEC_MOVE_PIC 25 UNSPEC_UPDATE_RETURN 26 UNSPEC_LOAD_PCREL_SYM 27 UNSPEC_FRAME_BLOCKAGE 28 UNSPEC_MOVE_PIC_LABEL 29 UNSPEC_SETH44 30 UNSPEC_SETM44 31 UNSPEC_SETHH 32 UNSPEC_SETLM 33 UNSPEC_EMB_HISUM 34 UNSPEC_EMB_TEXTUHI 35 UNSPEC_EMB_TEXTHI 36 UNSPEC_EMB_TEXTULO 37 UNSPEC_EMB_SETHM 38 UNSPEC_MOVE_GOTDATA 39 40 UNSPEC_MEMBAR 41 UNSPEC_ATOMIC 42 43 UNSPEC_TLSGD 44 UNSPEC_TLSLDM 45 UNSPEC_TLSLDO 46 UNSPEC_TLSIE 47 UNSPEC_TLSLE 48 UNSPEC_TLSLD_BASE 49 50 UNSPEC_FPACK16 51 UNSPEC_FPACK32 52 UNSPEC_FPACKFIX 53 UNSPEC_FEXPAND 54 UNSPEC_MUL16AU 55 UNSPEC_MUL16AL 56 UNSPEC_MUL8UL 57 UNSPEC_MULDUL 58 UNSPEC_ALIGNDATA 59 UNSPEC_FCMP 60 UNSPEC_PDIST 61 UNSPEC_EDGE8 62 UNSPEC_EDGE8L 63 UNSPEC_EDGE16 64 UNSPEC_EDGE16L 65 UNSPEC_EDGE32 66 UNSPEC_EDGE32L 67 UNSPEC_ARRAY8 68 UNSPEC_ARRAY16 69 UNSPEC_ARRAY32 70 71 UNSPEC_SP_SET 72 UNSPEC_SP_TEST 73 74 UNSPEC_EDGE8N 75 UNSPEC_EDGE8LN 76 UNSPEC_EDGE16N 77 UNSPEC_EDGE16LN 78 UNSPEC_EDGE32N 79 UNSPEC_EDGE32LN 80 UNSPEC_BSHUFFLE 81 UNSPEC_CMASK8 82 UNSPEC_CMASK16 83 UNSPEC_CMASK32 84 UNSPEC_FCHKSM16 85 UNSPEC_PDISTN 86 UNSPEC_FUCMP 87 UNSPEC_FHADD 88 UNSPEC_FHSUB 89 UNSPEC_XMUL 90 UNSPEC_MUL8 91 UNSPEC_MUL8SU 92 UNSPEC_MULDSU 93 94 UNSPEC_ADDV 95 UNSPEC_SUBV 96 UNSPEC_NEGV 97 98 UNSPEC_DICTUNPACK 99 UNSPEC_FPCMPSHL 100 UNSPEC_FPUCMPSHL 101 UNSPEC_FPCMPDESHL 102 UNSPEC_FPCMPURSHL 103]) 104 105(define_c_enum "unspecv" [ 106 UNSPECV_BLOCKAGE 107 UNSPECV_PROBE_STACK_RANGE 108 109 UNSPECV_FLUSHW 110 UNSPECV_SAVEW 111 112 UNSPECV_FLUSH 113 114 UNSPECV_LDSTUB 115 UNSPECV_SWAP 116 UNSPECV_CAS 117 118 UNSPECV_LDFSR 119 UNSPECV_STFSR 120]) 121 122(define_constants 123 [(G0_REG 0) 124 (G1_REG 1) 125 (G2_REG 2) 126 (G3_REG 3) 127 (G4_REG 4) 128 (G5_REG 5) 129 (G6_REG 6) 130 (G7_REG 7) 131 (O0_REG 8) 132 (O1_REG 9) 133 (O2_REG 10) 134 (O3_REG 11) 135 (O4_REG 12) 136 (O5_REG 13) 137 (O6_REG 14) 138 (O7_REG 15) 139 (L0_REG 16) 140 (L1_REG 17) 141 (L2_REG 18) 142 (L3_REG 19) 143 (L4_REG 20) 144 (L5_REG 21) 145 (L6_REG 22) 146 (L7_REG 23) 147 (I0_REG 24) 148 (I1_REG 25) 149 (I2_REG 26) 150 (I3_REG 27) 151 (I4_REG 28) 152 (I5_REG 29) 153 (I6_REG 30) 154 (I7_REG 31) 155 (F0_REG 32) 156 (F1_REG 33) 157 (F2_REG 34) 158 (F3_REG 35) 159 (F4_REG 36) 160 (F5_REG 37) 161 (F6_REG 38) 162 (F7_REG 39) 163 (F8_REG 40) 164 (F9_REG 41) 165 (F10_REG 42) 166 (F11_REG 43) 167 (F12_REG 44) 168 (F13_REG 45) 169 (F14_REG 46) 170 (F15_REG 47) 171 (F16_REG 48) 172 (F17_REG 49) 173 (F18_REG 50) 174 (F19_REG 51) 175 (F20_REG 52) 176 (F21_REG 53) 177 (F22_REG 54) 178 (F23_REG 55) 179 (F24_REG 56) 180 (F25_REG 57) 181 (F26_REG 58) 182 (F27_REG 59) 183 (F28_REG 60) 184 (F29_REG 61) 185 (F30_REG 62) 186 (F31_REG 63) 187 (F32_REG 64) 188 (F34_REG 66) 189 (F36_REG 68) 190 (F38_REG 70) 191 (F40_REG 72) 192 (F42_REG 74) 193 (F44_REG 76) 194 (F46_REG 78) 195 (F48_REG 80) 196 (F50_REG 82) 197 (F52_REG 84) 198 (F54_REG 86) 199 (F56_REG 88) 200 (F58_REG 90) 201 (F60_REG 92) 202 (F62_REG 94) 203 (FCC0_REG 96) 204 (FCC1_REG 97) 205 (FCC2_REG 98) 206 (FCC3_REG 99) 207 (CC_REG 100) 208 (SFP_REG 101) 209 (GSR_REG 102) 210 ]) 211 212(define_mode_iterator I [QI HI SI DI]) 213(define_mode_iterator P [(SI "TARGET_ARCH32") (DI "TARGET_ARCH64")]) 214(define_mode_iterator W [SI (DI "TARGET_ARCH64")]) 215(define_mode_iterator F [SF DF TF]) 216 217;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this 218;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name 219;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding 220;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of 221;; 'f' for all DF/TFmode values, including those that are specific to the v8. 222 223;; Attribute for cpu type. 224;; These must match the values of the enum processor_type in sparc-opts.h. 225(define_attr "cpu" 226 "v7, 227 cypress, 228 v8, 229 supersparc, 230 hypersparc, 231 leon, 232 leon3, 233 leon3v7, 234 sparclite, 235 f930, 236 f934, 237 sparclite86x, 238 sparclet, 239 tsc701, 240 v9, 241 ultrasparc, 242 ultrasparc3, 243 niagara, 244 niagara2, 245 niagara3, 246 niagara4, 247 niagara7, 248 m8" 249 (const (symbol_ref "sparc_cpu_attr"))) 250 251;; Attribute for the instruction set. 252;; At present we only need to distinguish v9/!v9, but for clarity we 253;; test TARGET_V8 too. 254(define_attr "isa" "v7,v8,v9,sparclet" 255 (const 256 (cond [(symbol_ref "TARGET_V9") (const_string "v9") 257 (symbol_ref "TARGET_V8") (const_string "v8") 258 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")] 259 (const_string "v7")))) 260 261(define_attr "cpu_feature" "none,fpu,fpunotv9,v9,vis,vis3,vis4,vis4b" 262 (const_string "none")) 263 264(define_attr "lra" "disabled,enabled" 265 (const_string "enabled")) 266 267(define_attr "enabled" "" 268 (cond [(eq_attr "cpu_feature" "none") 269 (cond [(eq_attr "lra" "disabled") (symbol_ref "!TARGET_LRA")] (const_int 1)) 270 (eq_attr "cpu_feature" "fpu") (symbol_ref "TARGET_FPU") 271 (eq_attr "cpu_feature" "fpunotv9") (symbol_ref "TARGET_FPU && !TARGET_V9") 272 (eq_attr "cpu_feature" "v9") (symbol_ref "TARGET_V9") 273 (eq_attr "cpu_feature" "vis") (symbol_ref "TARGET_VIS") 274 (eq_attr "cpu_feature" "vis3") (symbol_ref "TARGET_VIS3") 275 (eq_attr "cpu_feature" "vis4") (symbol_ref "TARGET_VIS4") 276 (eq_attr "cpu_feature" "vis4b") (symbol_ref "TARGET_VIS4B")] 277 (const_int 0))) 278 279;; The SPARC instructions used by the backend are organized into a 280;; hierarchy using the insn attributes "type" and "subtype". 281;; 282;; The mnemonics used in the list below are the architectural names 283;; used in the Oracle SPARC Architecture specs. A / character 284;; separates the type from the subtype where appropriate. For 285;; brevity, text enclosed in {} denotes alternatives, while text 286;; enclosed in [] is optional. 287;; 288;; Please keep this list updated. It is of great help for keeping the 289;; correctness and coherence of the DFA schedulers. 290;; 291;; ialu: <empty> 292;; ialuX: ADD[X]C SUB[X]C 293;; shift: SLL[X] SRL[X] SRA[X] 294;; cmove: MOV{A,N,NE,E,G,LE,GE,L,GU,LEU,CC,CS,POS,NEG,VC,VS} 295;; MOVF{A,N,U,G,UG,L,UL,LG,NE,E,UE,GE,UGE,LE,ULE,O} 296;; MOVR{Z,LEZ,LZ,NZ,GZ,GEZ} 297;; compare: ADDcc ADDCcc ANDcc ORcc SUBcc SUBCcc XORcc XNORcc 298;; imul: MULX SMUL[cc] UMUL UMULXHI XMULX XMULXHI 299;; idiv: UDIVX SDIVX 300;; flush: FLUSH 301;; load/regular: LD{UB,UH,UW} LDFSR 302;; load/prefetch: PREFETCH 303;; fpload: LDF LDDF LDQF 304;; sload: LD{SB,SH,SW} 305;; store: ST{B,H,W,X} STFSR 306;; fpstore: STF STDF STQF 307;; cbcond: CWB{NE,E,G,LE,GE,L,GU,LEU,CC,CS,POS,NEG,VC,VS} 308;; CXB{NE,E,G,LE,GE,L,GU,LEU,CC,CS,POS,NEG,VC,VS} 309;; uncond_branch: BA BPA JMPL 310;; branch: B{NE,E,G,LE,GE,L,GU,LEU,CC,CS,POS,NEG,VC,VS} 311;; BP{NE,E,G,LE,GE,L,GU,LEU,CC,CS,POS,NEG,VC,VS} 312;; FB{U,G,UG,L,UL,LG,NE,BE,UE,GE,UGE,LE,ULE,O} 313;; call: CALL 314;; return: RESTORE RETURN 315;; fpmove: FABS{s,d,q} FMOV{s,d,q} FNEG{s,d,q} 316;; fpcmove: FMOV{S,D,Q}{icc,xcc,fcc} 317;; fpcrmove: FMOVR{s,d,q}{Z,LEZ,LZ,NZ,GZ,GEZ} 318;; fp: FADD{s,d,q} FSUB{s,d,q} FHSUB{s,d} FNHADD{s,d} FNADD{s,d} 319;; FiTO{s,d,q} FsTO{i,x,d,q} FdTO{i,x,s,q} FxTO{d,s,q} FqTO{i,x,s,d} 320;; fpcmp: FCMP{s,d,q} FCMPE{s,d,q} 321;; fpmul: FMADD{s,d} FMSUB{s,d} FMUL{s,d,q} FNMADD{s,d} 322;; FNMSUB{s,d} FNMUL{s,d} FNsMULd FsMULd 323;; FdMULq 324;; array: ARRAY{8,16,32} 325;; bmask: BMASK 326;; edge: EDGE{8,16,32}[L]cc 327;; edgen: EDGE{8,16,32}[L]n 328;; fpdivs: FDIV{s,q} 329;; fpsqrts: FSQRT{s,q} 330;; fpdivd: FDIVd 331;; fpsqrtd: FSQRTd 332;; lzd: LZCNT 333;; fga/addsub64: FP{ADD,SUB}64 334;; fga/fpu: FCHKSM16 FEXPANd FMEAN16 FPMERGE 335;; FS{LL,RA,RL}{16,32} 336;; fga/maxmin: FP{MAX,MIN}[U]{8,16,32} 337;; fga/cmask: CMASK{8,16,32} 338;; fga/other: BSHUFFLE FALIGNDATAg FP{ADD,SUB}[S]{8,16,32} 339;; FP{ADD,SUB}US{8,16} DICTUNPACK 340;; gsr/reg: RDGSR WRGSR 341;; gsr/alignaddr: ALIGNADDRESS[_LITTLE] 342;; vismv/double: FSRC2d 343;; vismv/single: MOVwTOs FSRC2s 344;; vismv/movstouw: MOVsTOuw 345;; vismv/movxtod: MOVxTOd 346;; vismv/movdtox: MOVdTOx 347;; visl/single: F{AND,NAND,NOR,OR,NOT1}s 348;; F{AND,OR}NOT{1,2}s 349;; FONEs F{ZERO,XNOR,XOR}s FNOT2s 350;; visl/double: FONEd FZEROd FNOT1d F{OR,AND,XOR}d F{NOR,NAND,XNOR}d 351;; F{OR,AND}NOT1d F{OR,AND}NOT2d 352;; viscmp: FPCMP{LE,GT,NE,EQ}{8,16,32} FPCMPU{LE,GT,NE,EQ}{8,16,32} 353;; FPCMP{LE,GT,EQ,NE}{8,16,32}SHL FPCMPU{LE,GT,EQ,NE}{8,16,32}SHL 354;; FPCMPDE{8,16,32}SHL FPCMPUR{8,16,32}SHL 355;; fgm_pack: FPACKFIX FPACK{8,16,32} 356;; fgm_mul: FMUL8SUx16 FMUL8ULx16 FMUL8x16 FMUL8x16AL 357;; FMUL8x16AU FMULD8SUx16 FMULD8ULx16 358;; pdist: PDIST 359;; pdistn: PDISTN 360 361(define_attr "type" 362 "ialu,compare,shift, 363 load,sload,store, 364 uncond_branch,branch,call,sibcall,call_no_delay_slot,return, 365 cbcond,uncond_cbcond, 366 imul,idiv, 367 fpload,fpstore, 368 fp,fpmove, 369 fpcmove,fpcrmove, 370 fpcmp, 371 fpmul,fpdivs,fpdivd, 372 fpsqrts,fpsqrtd, 373 fga,visl,vismv,viscmp, 374 fgm_pack,fgm_mul,pdist,pdistn,edge,edgen,gsr,array,bmask, 375 cmove, 376 ialuX, 377 multi,savew,flushw,iflush,trap,lzd" 378 (const_string "ialu")) 379 380(define_attr "subtype" 381 "single,double,movstouw,movxtod,movdtox, 382 addsub64,cmask,fpu,maxmin,other, 383 reg,alignaddr, 384 prefetch,regular" 385 (const_string "single")) 386 387;; True if branch/call has empty delay slot and will emit a nop in it 388(define_attr "empty_delay_slot" "false,true" 389 (symbol_ref "(empty_delay_slot (insn) 390 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)")) 391 392;; True if we are making use of compare-and-branch instructions. 393;; True if we should emit a nop after a cbcond instruction 394(define_attr "emit_cbcond_nop" "false,true" 395 (symbol_ref "(emit_cbcond_nop (insn) 396 ? EMIT_CBCOND_NOP_TRUE : EMIT_CBCOND_NOP_FALSE)")) 397 398(define_attr "branch_type" "none,icc,fcc,reg" 399 (const_string "none")) 400 401(define_attr "pic" "false,true" 402 (symbol_ref "(flag_pic != 0 403 ? PIC_TRUE : PIC_FALSE)")) 404 405(define_attr "calls_alloca" "false,true" 406 (symbol_ref "(cfun->calls_alloca != 0 407 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)")) 408 409(define_attr "calls_eh_return" "false,true" 410 (symbol_ref "(crtl->calls_eh_return != 0 411 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)")) 412 413(define_attr "leaf_function" "false,true" 414 (symbol_ref "(crtl->uses_only_leaf_regs != 0 415 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)")) 416 417(define_attr "delayed_branch" "false,true" 418 (symbol_ref "(flag_delayed_branch != 0 419 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)")) 420 421(define_attr "flat" "false,true" 422 (symbol_ref "(TARGET_FLAT != 0 423 ? FLAT_TRUE : FLAT_FALSE)")) 424 425(define_attr "fix_ut699" "false,true" 426 (symbol_ref "(sparc_fix_ut699 != 0 427 ? FIX_UT699_TRUE : FIX_UT699_FALSE)")) 428 429(define_attr "fix_b2bst" "false,true" 430 (symbol_ref "(sparc_fix_b2bst != 0 431 ? FIX_B2BST_TRUE : FIX_B2BST_FALSE)")) 432 433(define_attr "fix_lost_divsqrt" "false,true" 434 (symbol_ref "(sparc_fix_lost_divsqrt != 0 435 ? FIX_LOST_DIVSQRT_TRUE : FIX_LOST_DIVSQRT_FALSE)")) 436 437(define_attr "fix_gr712rc" "false,true" 438 (symbol_ref "(sparc_fix_gr712rc != 0 439 ? FIX_GR712RC_TRUE : FIX_GR712RC_FALSE)")) 440 441;; Length (in # of insns). 442;; Beware that setting a length greater or equal to 3 for conditional branches 443;; has a side-effect (see output_cbranch and output_v9branch). 444(define_attr "length" "" 445 (cond [(eq_attr "type" "uncond_branch,call") 446 (if_then_else (eq_attr "empty_delay_slot" "true") 447 (const_int 2) 448 (const_int 1)) 449 (eq_attr "type" "sibcall") 450 (if_then_else (ior (eq_attr "leaf_function" "true") 451 (eq_attr "flat" "true")) 452 (if_then_else (eq_attr "empty_delay_slot" "true") 453 (const_int 3) 454 (const_int 2)) 455 (if_then_else (eq_attr "empty_delay_slot" "true") 456 (const_int 2) 457 (const_int 1))) 458 (eq_attr "branch_type" "icc") 459 (if_then_else (match_operand 0 "v9_comparison_operator" "") 460 (if_then_else (lt (pc) (match_dup 1)) 461 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000)) 462 (if_then_else (eq_attr "empty_delay_slot" "true") 463 (const_int 2) 464 (const_int 1)) 465 (if_then_else (eq_attr "empty_delay_slot" "true") 466 (const_int 4) 467 (const_int 3))) 468 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000)) 469 (if_then_else (eq_attr "empty_delay_slot" "true") 470 (const_int 2) 471 (const_int 1)) 472 (if_then_else (eq_attr "empty_delay_slot" "true") 473 (const_int 4) 474 (const_int 3)))) 475 (if_then_else (eq_attr "empty_delay_slot" "true") 476 (const_int 2) 477 (const_int 1))) 478 (eq_attr "branch_type" "fcc") 479 (if_then_else (match_operand 0 "fcc0_register_operand" "") 480 (if_then_else (eq_attr "empty_delay_slot" "true") 481 (if_then_else (not (match_test "TARGET_V9")) 482 (const_int 3) 483 (const_int 2)) 484 (if_then_else (not (match_test "TARGET_V9")) 485 (const_int 2) 486 (const_int 1))) 487 (if_then_else (lt (pc) (match_dup 2)) 488 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000)) 489 (if_then_else (eq_attr "empty_delay_slot" "true") 490 (const_int 2) 491 (const_int 1)) 492 (if_then_else (eq_attr "empty_delay_slot" "true") 493 (const_int 4) 494 (const_int 3))) 495 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000)) 496 (if_then_else (eq_attr "empty_delay_slot" "true") 497 (const_int 2) 498 (const_int 1)) 499 (if_then_else (eq_attr "empty_delay_slot" "true") 500 (const_int 4) 501 (const_int 3))))) 502 (eq_attr "branch_type" "reg") 503 (if_then_else (lt (pc) (match_dup 2)) 504 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000)) 505 (if_then_else (eq_attr "empty_delay_slot" "true") 506 (const_int 2) 507 (const_int 1)) 508 (if_then_else (eq_attr "empty_delay_slot" "true") 509 (const_int 4) 510 (const_int 3))) 511 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000)) 512 (if_then_else (eq_attr "empty_delay_slot" "true") 513 (const_int 2) 514 (const_int 1)) 515 (if_then_else (eq_attr "empty_delay_slot" "true") 516 (const_int 4) 517 (const_int 3)))) 518 (eq_attr "type" "cbcond") 519 (if_then_else (lt (pc) (match_dup 3)) 520 (if_then_else (lt (minus (match_dup 3) (pc)) (const_int 500)) 521 (if_then_else (eq_attr "emit_cbcond_nop" "true") 522 (const_int 2) 523 (const_int 1)) 524 (const_int 4)) 525 (if_then_else (lt (minus (pc) (match_dup 3)) (const_int 500)) 526 (if_then_else (eq_attr "emit_cbcond_nop" "true") 527 (const_int 2) 528 (const_int 1)) 529 (const_int 4))) 530 (eq_attr "type" "uncond_cbcond") 531 (if_then_else (lt (pc) (match_dup 0)) 532 (if_then_else (lt (minus (match_dup 0) (pc)) (const_int 500)) 533 (if_then_else (eq_attr "emit_cbcond_nop" "true") 534 (const_int 2) 535 (const_int 1)) 536 (const_int 1)) 537 (if_then_else (lt (minus (pc) (match_dup 0)) (const_int 500)) 538 (if_then_else (eq_attr "emit_cbcond_nop" "true") 539 (const_int 2) 540 (const_int 1)) 541 (const_int 1))) 542 ] (const_int 1))) 543 544;; FP precision. 545(define_attr "fptype" "single,double" 546 (const_string "single")) 547 548;; FP precision specific to the UT699. 549(define_attr "fptype_ut699" "none,single" 550 (const_string "none")) 551 552;; UltraSPARC-III integer load type. 553(define_attr "us3load_type" "2cycle,3cycle" 554 (const_string "2cycle")) 555 556(define_asm_attributes 557 [(set_attr "length" "2") 558 (set_attr "type" "multi")]) 559 560;; Attributes for branch scheduling 561(define_attr "in_call_delay" "false,true" 562 (symbol_ref "(eligible_for_call_delay (insn) 563 ? IN_CALL_DELAY_TRUE : IN_CALL_DELAY_FALSE)")) 564 565(define_attr "in_sibcall_delay" "false,true" 566 (symbol_ref "(eligible_for_sibcall_delay (insn) 567 ? IN_SIBCALL_DELAY_TRUE : IN_SIBCALL_DELAY_FALSE)")) 568 569(define_attr "in_return_delay" "false,true" 570 (symbol_ref "(eligible_for_return_delay (insn) 571 ? IN_RETURN_DELAY_TRUE : IN_RETURN_DELAY_FALSE)")) 572 573;; ??? !v9: Should implement the notion of predelay slots for floating-point 574;; branches. This would allow us to remove the nop always inserted before 575;; a floating point branch. 576 577;; ??? It is OK for fill_simple_delay_slots to put load/store instructions 578;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so. 579;; This is because doing so will add several pipeline stalls to the path 580;; that the load/store did not come from. Unfortunately, there is no way 581;; to prevent fill_eager_delay_slots from using load/store without completely 582;; disabling them. For the SPEC benchmark set, this is a serious lose, 583;; because it prevents us from moving back the final store of inner loops. 584 585(define_attr "in_branch_delay" "false,true" 586 (cond [(eq_attr "type" "uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi") 587 (const_string "false") 588 (and (eq_attr "fix_lost_divsqrt" "true") 589 (eq_attr "type" "fpdivs,fpsqrts,fpdivd,fpsqrtd")) 590 (const_string "false") 591 (and (eq_attr "fix_b2bst" "true") (eq_attr "type" "store,fpstore")) 592 (const_string "false") 593 (and (eq_attr "fix_ut699" "true") (eq_attr "type" "load,sload")) 594 (const_string "false") 595 (and (eq_attr "fix_ut699" "true") 596 (and (eq_attr "type" "fpload,fp,fpmove,fpmul,fpdivs,fpsqrts") 597 (ior (eq_attr "fptype" "single") 598 (eq_attr "fptype_ut699" "single")))) 599 (const_string "false") 600 (eq_attr "length" "1") 601 (const_string "true") 602 ] (const_string "false"))) 603 604(define_attr "in_integer_branch_annul_delay" "false,true" 605 (cond [(and (eq_attr "fix_gr712rc" "true") 606 (eq_attr "type" "fp,fpcmp,fpmove,fpcmove,fpmul, 607 fpdivs,fpsqrts,fpdivd,fpsqrtd")) 608 (const_string "false") 609 (eq_attr "in_branch_delay" "true") 610 (const_string "true") 611 ] (const_string "false"))) 612 613(define_delay (eq_attr "type" "call") 614 [(eq_attr "in_call_delay" "true") (nil) (nil)]) 615 616(define_delay (eq_attr "type" "sibcall") 617 [(eq_attr "in_sibcall_delay" "true") (nil) (nil)]) 618 619(define_delay (eq_attr "type" "return") 620 [(eq_attr "in_return_delay" "true") (nil) (nil)]) 621 622(define_delay (and (eq_attr "type" "branch") 623 (not (eq_attr "branch_type" "icc"))) 624 [(eq_attr "in_branch_delay" "true") (nil) (eq_attr "in_branch_delay" "true")]) 625 626(define_delay (and (eq_attr "type" "branch") 627 (eq_attr "branch_type" "icc")) 628 [(eq_attr "in_branch_delay" "true") (nil) 629 (eq_attr "in_integer_branch_annul_delay" "true")]) 630 631(define_delay (eq_attr "type" "uncond_branch") 632 [(eq_attr "in_branch_delay" "true") (nil) (nil)]) 633 634 635;; Include SPARC DFA schedulers 636 637(include "cypress.md") 638(include "supersparc.md") 639(include "hypersparc.md") 640(include "leon.md") 641(include "sparclet.md") 642(include "ultra1_2.md") 643(include "ultra3.md") 644(include "niagara.md") 645(include "niagara2.md") 646(include "niagara4.md") 647(include "niagara7.md") 648(include "m8.md") 649 650 651;; Operand and operator predicates and constraints 652 653(include "predicates.md") 654(include "constraints.md") 655 656 657;; Compare instructions. 658 659;; These are just the DEFINE_INSNs to match the patterns and the 660;; DEFINE_SPLITs for some of the scc insns that actually require 661;; more than one machine instruction. DEFINE_EXPANDs are further down. 662 663(define_insn "*cmpsi_insn" 664 [(set (reg:CC CC_REG) 665 (compare:CC (match_operand:SI 0 "register_operand" "r") 666 (match_operand:SI 1 "arith_operand" "rI")))] 667 "" 668 "cmp\t%0, %1" 669 [(set_attr "type" "compare")]) 670 671(define_insn "*cmpdi_sp64" 672 [(set (reg:CCX CC_REG) 673 (compare:CCX (match_operand:DI 0 "register_operand" "r") 674 (match_operand:DI 1 "arith_operand" "rI")))] 675 "TARGET_ARCH64" 676 "cmp\t%0, %1" 677 [(set_attr "type" "compare")]) 678 679(define_insn "*cmpsi_sne" 680 [(set (reg:CCC CC_REG) 681 (compare:CCC (not:SI (match_operand:SI 0 "arith_operand" "rI")) 682 (const_int -1)))] 683 "" 684 "cmp\t%%g0, %0" 685 [(set_attr "type" "compare")]) 686 687(define_insn "*cmpdi_sne" 688 [(set (reg:CCXC CC_REG) 689 (compare:CCXC (not:DI (match_operand:DI 0 "arith_operand" "rI")) 690 (const_int -1)))] 691 "TARGET_ARCH64" 692 "cmp\t%%g0, %0" 693 [(set_attr "type" "compare")]) 694 695(define_insn "*cmpsf_fpe" 696 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c") 697 (compare:CCFPE (match_operand:SF 1 "register_operand" "f") 698 (match_operand:SF 2 "register_operand" "f")))] 699 "TARGET_FPU" 700{ 701 if (TARGET_V9) 702 return "fcmpes\t%0, %1, %2"; 703 return "fcmpes\t%1, %2"; 704} 705 [(set_attr "type" "fpcmp")]) 706 707(define_insn "*cmpdf_fpe" 708 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c") 709 (compare:CCFPE (match_operand:DF 1 "register_operand" "e") 710 (match_operand:DF 2 "register_operand" "e")))] 711 "TARGET_FPU" 712{ 713 if (TARGET_V9) 714 return "fcmped\t%0, %1, %2"; 715 return "fcmped\t%1, %2"; 716} 717 [(set_attr "type" "fpcmp") 718 (set_attr "fptype" "double")]) 719 720(define_insn "*cmptf_fpe" 721 [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c") 722 (compare:CCFPE (match_operand:TF 1 "register_operand" "e") 723 (match_operand:TF 2 "register_operand" "e")))] 724 "TARGET_FPU && TARGET_HARD_QUAD" 725{ 726 if (TARGET_V9) 727 return "fcmpeq\t%0, %1, %2"; 728 return "fcmpeq\t%1, %2"; 729} 730 [(set_attr "type" "fpcmp")]) 731 732(define_insn "*cmpsf_fp" 733 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c") 734 (compare:CCFP (match_operand:SF 1 "register_operand" "f") 735 (match_operand:SF 2 "register_operand" "f")))] 736 "TARGET_FPU" 737{ 738 if (TARGET_V9) 739 return "fcmps\t%0, %1, %2"; 740 return "fcmps\t%1, %2"; 741} 742 [(set_attr "type" "fpcmp")]) 743 744(define_insn "*cmpdf_fp" 745 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c") 746 (compare:CCFP (match_operand:DF 1 "register_operand" "e") 747 (match_operand:DF 2 "register_operand" "e")))] 748 "TARGET_FPU" 749{ 750 if (TARGET_V9) 751 return "fcmpd\t%0, %1, %2"; 752 return "fcmpd\t%1, %2"; 753} 754 [(set_attr "type" "fpcmp") 755 (set_attr "fptype" "double")]) 756 757(define_insn "*cmptf_fp" 758 [(set (match_operand:CCFP 0 "fcc_register_operand" "=c") 759 (compare:CCFP (match_operand:TF 1 "register_operand" "e") 760 (match_operand:TF 2 "register_operand" "e")))] 761 "TARGET_FPU && TARGET_HARD_QUAD" 762{ 763 if (TARGET_V9) 764 return "fcmpq\t%0, %1, %2"; 765 return "fcmpq\t%1, %2"; 766} 767 [(set_attr "type" "fpcmp")]) 768 769;; Next come the scc insns. 770 771;; Note that the boolean result (operand 0) takes on DImode 772;; (not SImode) when TARGET_ARCH64. 773 774(define_expand "cstoresi4" 775 [(use (match_operator 1 "comparison_operator" 776 [(match_operand:SI 2 "compare_operand" "") 777 (match_operand:SI 3 "arith_operand" "")])) 778 (clobber (match_operand:SI 0 "cstore_result_operand"))] 779 "" 780{ 781 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx) 782 operands[2] = force_reg (SImode, operands[2]); 783 if (emit_scc_insn (operands)) DONE; else FAIL; 784}) 785 786(define_expand "cstoredi4" 787 [(use (match_operator 1 "comparison_operator" 788 [(match_operand:DI 2 "compare_operand" "") 789 (match_operand:DI 3 "arith_operand" "")])) 790 (clobber (match_operand:SI 0 "cstore_result_operand"))] 791 "TARGET_ARCH64" 792{ 793 if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx) 794 operands[2] = force_reg (DImode, operands[2]); 795 if (emit_scc_insn (operands)) DONE; else FAIL; 796}) 797 798(define_expand "cstore<F:mode>4" 799 [(use (match_operator 1 "comparison_operator" 800 [(match_operand:F 2 "register_operand" "") 801 (match_operand:F 3 "register_operand" "")])) 802 (clobber (match_operand:SI 0 "cstore_result_operand"))] 803 "TARGET_FPU" 804{ 805 if (emit_scc_insn (operands)) DONE; else FAIL; 806}) 807 808;; The SNE and SEQ patterns are special because they can be done 809;; without any branching and do not involve a COMPARE. 810 811(define_insn_and_split "*snesi<W:mode>_zero" 812 [(set (match_operand:W 0 "register_operand" "=r") 813 (ne:W (match_operand:SI 1 "register_operand" "r") 814 (const_int 0))) 815 (clobber (reg:CC CC_REG))] 816 "" 817 "#" 818 "" 819 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1))) 820 (set (match_dup 0) (ltu:W (reg:CCC CC_REG) (const_int 0)))] 821 "" 822 [(set_attr "length" "2")]) 823 824(define_insn_and_split "*neg_snesi<W:mode>_zero" 825 [(set (match_operand:W 0 "register_operand" "=r") 826 (neg:W (ne:W (match_operand:SI 1 "register_operand" "r") 827 (const_int 0)))) 828 (clobber (reg:CC CC_REG))] 829 "" 830 "#" 831 "" 832 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1))) 833 (set (match_dup 0) (neg:W (ltu:W (reg:CCC CC_REG) (const_int 0))))] 834 "" 835 [(set_attr "length" "2")]) 836 837(define_insn_and_split "*snedi<W:mode>_zero" 838 [(set (match_operand:W 0 "register_operand" "=&r") 839 (ne:W (match_operand:DI 1 "register_operand" "r") 840 (const_int 0)))] 841 "TARGET_ARCH64 && !TARGET_VIS3" 842 "#" 843 "&& !reg_overlap_mentioned_p (operands[1], operands[0])" 844 [(set (match_dup 0) (const_int 0)) 845 (set (match_dup 0) (if_then_else:W (ne:DI (match_dup 1) (const_int 0)) 846 (const_int 1) 847 (match_dup 0)))] 848 "" 849 [(set_attr "length" "2")]) 850 851(define_insn_and_split "*snedi<W:mode>_zero_vis3" 852 [(set (match_operand:W 0 "register_operand" "=r") 853 (ne:W (match_operand:DI 1 "register_operand" "r") 854 (const_int 0))) 855 (clobber (reg:CCX CC_REG))] 856 "TARGET_ARCH64 && TARGET_VIS3" 857 "#" 858 "" 859 [(set (reg:CCXC CC_REG) (compare:CCXC (not:DI (match_dup 1)) (const_int -1))) 860 (set (match_dup 0) (ltu:W (reg:CCXC CC_REG) (const_int 0)))] 861 "" 862 [(set_attr "length" "2")]) 863 864(define_insn_and_split "*neg_snedi<W:mode>_zero" 865 [(set (match_operand:W 0 "register_operand" "=&r") 866 (neg:W (ne:W (match_operand:DI 1 "register_operand" "r") 867 (const_int 0))))] 868 "TARGET_ARCH64 && !TARGET_SUBXC" 869 "#" 870 "&& !reg_overlap_mentioned_p (operands[1], operands[0])" 871 [(set (match_dup 0) (const_int 0)) 872 (set (match_dup 0) (if_then_else:W (ne:DI (match_dup 1) (const_int 0)) 873 (const_int -1) 874 (match_dup 0)))] 875 "" 876 [(set_attr "length" "2")]) 877 878(define_insn_and_split "*neg_snedi<W:mode>_zero_subxc" 879 [(set (match_operand:W 0 "register_operand" "=&r") 880 (neg:W (ne:W (match_operand:DI 1 "register_operand" "r") 881 (const_int 0)))) 882 (clobber (reg:CCX CC_REG))] 883 "TARGET_ARCH64 && TARGET_SUBXC" 884 "#" 885 "" 886 [(set (reg:CCXC CC_REG) (compare:CCXC (not:DI (match_dup 1)) (const_int -1))) 887 (set (match_dup 0) (neg:W (ltu:W (reg:CCXC CC_REG) (const_int 0))))] 888 "" 889 [(set_attr "length" "2")]) 890 891(define_insn_and_split "*seqsi<W:mode>_zero" 892 [(set (match_operand:W 0 "register_operand" "=r") 893 (eq:W (match_operand:SI 1 "register_operand" "r") 894 (const_int 0))) 895 (clobber (reg:CC CC_REG))] 896 "" 897 "#" 898 "" 899 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1))) 900 (set (match_dup 0) (geu:W (reg:CCC CC_REG) (const_int 0)))] 901 "" 902 [(set_attr "length" "2")]) 903 904(define_insn_and_split "*neg_seqsi<W:mode>_zero" 905 [(set (match_operand:W 0 "register_operand" "=r") 906 (neg:W (eq:W (match_operand:SI 1 "register_operand" "r") 907 (const_int 0)))) 908 (clobber (reg:CC CC_REG))] 909 "" 910 "#" 911 "" 912 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1))) 913 (set (match_dup 0) (neg:W (geu:W (reg:CCC CC_REG) (const_int 0))))] 914 "" 915 [(set_attr "length" "2")]) 916 917(define_insn_and_split "*seqdi<W:mode>_zero" 918 [(set (match_operand:W 0 "register_operand" "=&r") 919 (eq:W (match_operand:DI 1 "register_operand" "r") 920 (const_int 0)))] 921 "TARGET_ARCH64" 922 "#" 923 "&& !reg_overlap_mentioned_p (operands[1], operands[0])" 924 [(set (match_dup 0) (const_int 0)) 925 (set (match_dup 0) (if_then_else:W (eq:DI (match_dup 1) (const_int 0)) 926 (const_int 1) 927 (match_dup 0)))] 928 "" 929 [(set_attr "length" "2")]) 930 931(define_insn_and_split "*neg_seqdi<W:mode>_zero" 932 [(set (match_operand:W 0 "register_operand" "=&r") 933 (neg:W (eq:W (match_operand:DI 1 "register_operand" "r") 934 (const_int 0))))] 935 "TARGET_ARCH64" 936 "#" 937 "&& !reg_overlap_mentioned_p (operands[1], operands[0])" 938 [(set (match_dup 0) (const_int 0)) 939 (set (match_dup 0) (if_then_else:W (eq:DI (match_dup 1) (const_int 0)) 940 (const_int -1) 941 (match_dup 0)))] 942 "" 943 [(set_attr "length" "2")]) 944 945;; We can also do (x + (i == 0)) and related, so put them in. 946 947(define_insn_and_split "*plus_snesi<W:mode>_zero" 948 [(set (match_operand:W 0 "register_operand" "=r") 949 (plus:W (ne:W (match_operand:SI 1 "register_operand" "r") 950 (const_int 0)) 951 (match_operand:W 2 "register_operand" "r"))) 952 (clobber (reg:CC CC_REG))] 953 "" 954 "#" 955 "" 956 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1))) 957 (set (match_dup 0) (plus:W (ltu:W (reg:CCC CC_REG) (const_int 0)) 958 (match_dup 2)))] 959 "" 960 [(set_attr "length" "2")]) 961 962(define_insn_and_split "*plus_plus_snesi<W:mode>_zero" 963 [(set (match_operand:W 0 "register_operand" "=r") 964 (plus:W (plus:W (ne:W (match_operand:SI 1 "register_operand" "r") 965 (const_int 0)) 966 (match_operand:W 2 "register_operand" "r")) 967 (match_operand:W 3 "register_operand" "r"))) 968 (clobber (reg:CC CC_REG))] 969 "" 970 "#" 971 "" 972 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1))) 973 (set (match_dup 0) (plus:W (plus:W (ltu:W (reg:CCC CC_REG) (const_int 0)) 974 (match_dup 2)) 975 (match_dup 3)))] 976 "" 977 [(set_attr "length" "2")]) 978 979(define_insn_and_split "*plus_snedi<W:mode>_zero" 980 [(set (match_operand:W 0 "register_operand" "=r") 981 (plus:W (ne:W (match_operand:DI 1 "register_operand" "r") 982 (const_int 0)) 983 (match_operand:W 2 "register_operand" "r"))) 984 (clobber (reg:CCX CC_REG))] 985 "TARGET_ARCH64 && TARGET_VIS3" 986 "#" 987 "" 988 [(set (reg:CCXC CC_REG) (compare:CCXC (not:DI (match_dup 1)) (const_int -1))) 989 (set (match_dup 0) (plus:W (ltu:W (reg:CCXC CC_REG) (const_int 0)) 990 (match_dup 2)))] 991 "" 992 [(set_attr "length" "2")]) 993 994(define_insn_and_split "*plus_plus_snedi<W:mode>_zero" 995 [(set (match_operand:W 0 "register_operand" "=r") 996 (plus:W (plus:W (ne:W (match_operand:DI 1 "register_operand" "r") 997 (const_int 0)) 998 (match_operand:W 2 "register_operand" "r")) 999 (match_operand:W 3 "register_operand" "r"))) 1000 (clobber (reg:CCX CC_REG))] 1001 "TARGET_ARCH64 && TARGET_VIS3" 1002 "#" 1003 "" 1004 [(set (reg:CCXC CC_REG) (compare:CCXC (not:DI (match_dup 1)) (const_int -1))) 1005 (set (match_dup 0) (plus:W (plus:W (ltu:W (reg:CCXC CC_REG) (const_int 0)) 1006 (match_dup 2)) 1007 (match_dup 3)))] 1008 "" 1009 [(set_attr "length" "2")]) 1010 1011(define_insn_and_split "*minus_snesi<W:mode>_zero" 1012 [(set (match_operand:W 0 "register_operand" "=r") 1013 (minus:W (match_operand:W 2 "register_operand" "r") 1014 (ne:W (match_operand:SI 1 "register_operand" "r") 1015 (const_int 0)))) 1016 (clobber (reg:CC CC_REG))] 1017 "" 1018 "#" 1019 "" 1020 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1))) 1021 (set (match_dup 0) (minus:W (match_dup 2) 1022 (ltu:W (reg:CCC CC_REG) (const_int 0))))] 1023 "" 1024 [(set_attr "length" "2")]) 1025 1026(define_insn_and_split "*minus_minus_snesi<W:mode>_zero" 1027 [(set (match_operand:W 0 "register_operand" "=r") 1028 (minus:W (minus:W (match_operand:W 2 "register_operand" "r") 1029 (ne:W (match_operand:SI 1 "register_operand" "r") 1030 (const_int 0))) 1031 (match_operand:W 3 "register_operand" "r"))) 1032 (clobber (reg:CC CC_REG))] 1033 "" 1034 "#" 1035 "" 1036 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1))) 1037 (set (match_dup 0) (minus:W (minus:W (match_dup 2) 1038 (ltu:W (reg:CCC CC_REG) (const_int 0))) 1039 (match_dup 3)))] 1040 "" 1041 [(set_attr "length" "2")]) 1042 1043(define_insn_and_split "*minus_snedi<W:mode>_zero" 1044 [(set (match_operand:W 0 "register_operand" "=r") 1045 (minus:W (match_operand:W 2 "register_operand" "r") 1046 (ne:W (match_operand:DI 1 "register_operand" "r") 1047 (const_int 0)))) 1048 (clobber (reg:CCX CC_REG))] 1049 "TARGET_ARCH64 && TARGET_SUBXC" 1050 "#" 1051 "" 1052 [(set (reg:CCXC CC_REG) (compare:CCXC (not:DI (match_dup 1)) (const_int -1))) 1053 (set (match_dup 0) (minus:W (match_dup 2) 1054 (ltu:W (reg:CCXC CC_REG) (const_int 0))))] 1055 "" 1056 [(set_attr "length" "2")]) 1057 1058(define_insn_and_split "*minus_minus_snedi<W:mode>_zero" 1059 [(set (match_operand:W 0 "register_operand" "=r") 1060 (minus:W (minus:W (match_operand:W 2 "register_operand" "r") 1061 (ne:W (match_operand:DI 1 "register_operand" "r") 1062 (const_int 0))) 1063 (match_operand:W 3 "register_operand" "r"))) 1064 (clobber (reg:CCX CC_REG))] 1065 "TARGET_ARCH64 && TARGET_SUBXC" 1066 "#" 1067 "" 1068 [(set (reg:CCXC CC_REG) (compare:CCXC (not:DI (match_dup 1)) (const_int -1))) 1069 (set (match_dup 0) (minus:W (minus:W (match_dup 2) 1070 (ltu:W (reg:CCXC CC_REG) (const_int 0))) 1071 (match_dup 3)))] 1072 "" 1073 [(set_attr "length" "2")]) 1074 1075(define_insn_and_split "*plus_seqsi<W:mode>_zero" 1076 [(set (match_operand:W 0 "register_operand" "=r") 1077 (plus:W (eq:W (match_operand:SI 1 "register_operand" "r") 1078 (const_int 0)) 1079 (match_operand:W 2 "register_operand" "r"))) 1080 (clobber (reg:CC CC_REG))] 1081 "" 1082 "#" 1083 "" 1084 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1))) 1085 (set (match_dup 0) (plus:W (geu:W (reg:CCC CC_REG) (const_int 0)) 1086 (match_dup 2)))] 1087 "" 1088 [(set_attr "length" "2")]) 1089 1090(define_insn_and_split "*minus_seqsi<W:mode>_zero" 1091 [(set (match_operand:W 0 "register_operand" "=r") 1092 (minus:W (match_operand:W 2 "register_operand" "r") 1093 (eq:W (match_operand:SI 1 "register_operand" "r") 1094 (const_int 0)))) 1095 (clobber (reg:CC CC_REG))] 1096 "" 1097 "#" 1098 "" 1099 [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1))) 1100 (set (match_dup 0) (minus:W (match_dup 2) 1101 (geu:W (reg:CCC CC_REG) (const_int 0))))] 1102 "" 1103 [(set_attr "length" "2")]) 1104 1105;; We can also do GEU and LTU directly, but these operate after a compare. 1106 1107(define_insn "*sltu<W:mode>_insn" 1108 [(set (match_operand:W 0 "register_operand" "=r") 1109 (ltu:W (match_operand 1 "icc_register_operand" "X") (const_int 0)))] 1110 "GET_MODE (operands[1]) == CCmode || GET_MODE (operands[1]) == CCCmode" 1111 "addx\t%%g0, 0, %0" 1112 [(set_attr "type" "ialuX")]) 1113 1114(define_insn "*plus_sltu<W:mode>" 1115 [(set (match_operand:W 0 "register_operand" "=r") 1116 (plus:W (ltu:W (match_operand 2 "icc_register_operand" "X") 1117 (const_int 0)) 1118 (match_operand:W 1 "arith_operand" "rI")))] 1119 "GET_MODE (operands[2]) == CCmode || GET_MODE (operands[2]) == CCCmode" 1120 "addx\t%%g0, %1, %0" 1121 [(set_attr "type" "ialuX")]) 1122 1123(define_insn "*plus_plus_sltu<W:mode>" 1124 [(set (match_operand:W 0 "register_operand" "=r") 1125 (plus:W (plus:W (ltu:W (match_operand 3 "icc_register_operand" "X") 1126 (const_int 0)) 1127 (match_operand:W 1 "register_operand" "%r")) 1128 (match_operand:W 2 "arith_operand" "rI")))] 1129 "GET_MODE (operands[3]) == CCmode || GET_MODE (operands[3]) == CCCmode" 1130 "addx\t%1, %2, %0" 1131 [(set_attr "type" "ialuX")]) 1132 1133(define_insn "*neg_sgeu<W:mode>" 1134 [(set (match_operand:W 0 "register_operand" "=r") 1135 (neg:W (geu:W (match_operand 1 "icc_register_operand" "X") 1136 (const_int 0))))] 1137 "GET_MODE (operands[1]) == CCmode || GET_MODE (operands[1]) == CCCmode" 1138 "addx\t%%g0, -1, %0" 1139 [(set_attr "type" "ialuX")]) 1140 1141(define_insn "*neg_sgeusidi" 1142 [(set (match_operand:DI 0 "register_operand" "=r") 1143 (sign_extend:DI (neg:SI (geu:SI (match_operand 1 "icc_register_operand" "X") 1144 (const_int 0)))))] 1145 "TARGET_ARCH64 1146 && (GET_MODE (operands[1]) == CCmode || GET_MODE (operands[1]) == CCCmode)" 1147 "addx\t%%g0, -1, %0" 1148 [(set_attr "type" "ialuX")]) 1149 1150(define_insn "*minus_sgeu<W:mode>" 1151 [(set (match_operand:W 0 "register_operand" "=r") 1152 (minus:W (match_operand:W 1 "register_operand" "r") 1153 (geu:W (match_operand 2 "icc_register_operand" "X") 1154 (const_int 0))))] 1155 "GET_MODE (operands[2]) == CCmode || GET_MODE (operands[2]) == CCCmode" 1156 "addx\t%1, -1, %0" 1157 [(set_attr "type" "ialuX")]) 1158 1159(define_insn "*addx<W:mode>" 1160 [(set (match_operand:W 0 "register_operand" "=r") 1161 (plus:W (plus:W (match_operand:W 1 "register_operand" "%r") 1162 (match_operand:W 2 "arith_operand" "rI")) 1163 (ltu:W (match_operand 3 "icc_register_operand" "X") 1164 (const_int 0))))] 1165 "GET_MODE (operands[3]) == CCmode || GET_MODE (operands[3]) == CCCmode" 1166 "addx\t%1, %2, %0" 1167 [(set_attr "type" "ialuX")]) 1168 1169(define_insn "*sltu<W:mode>_insn_vis3" 1170 [(set (match_operand:W 0 "register_operand" "=r") 1171 (ltu:W (match_operand 1 "icc_register_operand" "X") (const_int 0)))] 1172 "TARGET_ARCH64 && TARGET_VIS3 1173 && (GET_MODE (operands[1]) == CCXmode || GET_MODE (operands[1]) == CCXCmode)" 1174 "addxc\t%%g0, %%g0, %0" 1175 [(set_attr "type" "ialuX")]) 1176 1177(define_insn "*plus_sltu<W:mode>_vis3" 1178 [(set (match_operand:W 0 "register_operand" "=r") 1179 (plus:W (ltu:W (match_operand 2 "icc_register_operand" "X") 1180 (const_int 0)) 1181 (match_operand:W 1 "register_operand" "r")))] 1182 "TARGET_ARCH64 && TARGET_VIS3 1183 && (GET_MODE (operands[2]) == CCXmode || GET_MODE (operands[2]) == CCXCmode)" 1184 "addxc\t%%g0, %1, %0" 1185 [(set_attr "type" "ialuX")]) 1186 1187(define_insn "*plus_plus_sltu<W:mode>_vis3" 1188 [(set (match_operand:W 0 "register_operand" "=r") 1189 (plus:W (plus:W (ltu:W (match_operand 3 "icc_register_operand" "X") 1190 (const_int 0)) 1191 (match_operand:W 1 "register_operand" "%r")) 1192 (match_operand:W 2 "register_operand" "r")))] 1193 "TARGET_ARCH64 && TARGET_VIS3 1194 && (GET_MODE (operands[3]) == CCXmode || GET_MODE (operands[3]) == CCXCmode)" 1195 "addxc\t%1, %2, %0" 1196 [(set_attr "type" "ialuX")]) 1197 1198(define_insn "*addxc<W:mode>" 1199 [(set (match_operand:W 0 "register_operand" "=r") 1200 (plus:W (plus:W (match_operand:W 1 "register_operand" "%r") 1201 (match_operand:W 2 "register_operand" "r")) 1202 (ltu:W (match_operand 3 "icc_register_operand" "X") 1203 (const_int 0))))] 1204 "TARGET_ARCH64 && TARGET_VIS3 1205 && (GET_MODE (operands[3]) == CCXmode || GET_MODE (operands[3]) == CCXCmode)" 1206 "addxc\t%1, %2, %0" 1207 [(set_attr "type" "ialuX")]) 1208 1209(define_insn "*neg_sltu<W:mode>" 1210 [(set (match_operand:W 0 "register_operand" "=r") 1211 (neg:W (ltu:W (match_operand 1 "icc_register_operand" "X") 1212 (const_int 0))))] 1213 "GET_MODE (operands[1]) == CCmode || GET_MODE (operands[1]) == CCCmode" 1214 "subx\t%%g0, 0, %0" 1215 [(set_attr "type" "ialuX")]) 1216 1217(define_insn "*neg_sltusidi" 1218 [(set (match_operand:DI 0 "register_operand" "=r") 1219 (sign_extend:DI (neg:SI (ltu:SI (match_operand 1 "icc_register_operand" "X") 1220 (const_int 0)))))] 1221 "TARGET_ARCH64 1222 && (GET_MODE (operands[1]) == CCmode || GET_MODE (operands[1]) == CCCmode)" 1223 "subx\t%%g0, 0, %0" 1224 [(set_attr "type" "ialuX")]) 1225 1226(define_insn "*minus_neg_sltu<W:mode>" 1227 [(set (match_operand:W 0 "register_operand" "=r") 1228 (minus:W (neg:W (ltu:W (match_operand 2 "icc_register_operand" "X") 1229 (const_int 0))) 1230 (match_operand:W 1 "arith_operand" "rI")))] 1231 "GET_MODE (operands[2]) == CCmode || GET_MODE (operands[2]) == CCCmode" 1232 "subx\t%%g0, %1, %0" 1233 [(set_attr "type" "ialuX")]) 1234 1235(define_insn "*neg_plus_sltu<W:mode>" 1236 [(set (match_operand:W 0 "register_operand" "=r") 1237 (neg:W (plus:W (ltu:W (match_operand 2 "icc_register_operand" "X") 1238 (const_int 0)) 1239 (match_operand:W 1 "arith_operand" "rI"))))] 1240 "GET_MODE (operands[2]) == CCmode || GET_MODE (operands[2]) == CCCmode" 1241 "subx\t%%g0, %1, %0" 1242 [(set_attr "type" "ialuX")]) 1243 1244(define_insn "*minus_sltu<W:mode>" 1245 [(set (match_operand:W 0 "register_operand" "=r") 1246 (minus:W (match_operand:W 1 "register_operand" "r") 1247 (ltu:W (match_operand 2 "icc_register_operand" "X") 1248 (const_int 0))))] 1249 "GET_MODE (operands[2]) == CCmode || GET_MODE (operands[2]) == CCCmode" 1250 "subx\t%1, 0, %0" 1251 [(set_attr "type" "ialuX")]) 1252 1253(define_insn "*minus_minus_sltu<W:mode>" 1254 [(set (match_operand:W 0 "register_operand" "=r") 1255 (minus:W (minus:W (match_operand:W 1 "register_or_zero_operand" "rJ") 1256 (ltu:W (match_operand 3 "icc_register_operand" "X") 1257 (const_int 0))) 1258 (match_operand:W 2 "arith_operand" "rI")))] 1259 "GET_MODE (operands[3]) == CCmode || GET_MODE (operands[3]) == CCCmode" 1260 "subx\t%r1, %2, %0" 1261 [(set_attr "type" "ialuX")]) 1262 1263(define_insn "*sgeu<W:mode>_insn" 1264 [(set (match_operand:W 0 "register_operand" "=r") 1265 (geu:W (match_operand 1 "icc_register_operand" "X") (const_int 0)))] 1266 "GET_MODE (operands[1]) == CCmode || GET_MODE (operands[1]) == CCCmode" 1267 "subx\t%%g0, -1, %0" 1268 [(set_attr "type" "ialuX")]) 1269 1270(define_insn "*plus_sgeu<W:mode>" 1271 [(set (match_operand:W 0 "register_operand" "=r") 1272 (plus:W (geu:W (match_operand 2 "icc_register_operand" "X") 1273 (const_int 0)) 1274 (match_operand:W 1 "register_operand" "r")))] 1275 "GET_MODE (operands[2]) == CCmode || GET_MODE (operands[2]) == CCCmode" 1276 "subx\t%1, -1, %0" 1277 [(set_attr "type" "ialuX")]) 1278 1279(define_insn "*subx<W:mode>" 1280 [(set (match_operand:W 0 "register_operand" "=r") 1281 (minus:W (minus:W (match_operand:W 1 "register_or_zero_operand" "rJ") 1282 (match_operand:W 2 "arith_operand" "rI")) 1283 (ltu:W (match_operand 3 "icc_register_operand" "X") 1284 (const_int 0))))] 1285 "GET_MODE (operands[3]) == CCmode || GET_MODE (operands[3]) == CCCmode" 1286 "subx\t%r1, %2, %0" 1287 [(set_attr "type" "ialuX")]) 1288 1289(define_insn "*neg_sltu<W:mode>_subxc" 1290 [(set (match_operand:W 0 "register_operand" "=r") 1291 (neg:W (ltu:W (match_operand 1 "icc_register_operand" "X") 1292 (const_int 0))))] 1293 "TARGET_ARCH64 && TARGET_SUBXC 1294 && (GET_MODE (operands[1]) == CCXmode || GET_MODE (operands[1]) == CCXCmode)" 1295 "subxc\t%%g0, %%g0, %0" 1296 [(set_attr "type" "ialuX")]) 1297 1298(define_insn "*minus_neg_sltu<W:mode>_subxc" 1299 [(set (match_operand:W 0 "register_operand" "=r") 1300 (minus:W (neg:W (ltu:W (match_operand 2 "icc_register_operand" "X") 1301 (const_int 0))) 1302 (match_operand:W 1 "register_operand" "r")))] 1303 "TARGET_ARCH64 && TARGET_SUBXC 1304 && (GET_MODE (operands[2]) == CCXmode || GET_MODE (operands[2]) == CCXCmode)" 1305 "subxc\t%%g0, %1, %0" 1306 [(set_attr "type" "ialuX")]) 1307 1308(define_insn "*neg_plus_sltu<W:mode>_subxc" 1309 [(set (match_operand:W 0 "register_operand" "=r") 1310 (neg:W (plus:W (ltu:W (match_operand 2 "icc_register_operand" "X") 1311 (const_int 0)) 1312 (match_operand:W 1 "register_operand" "r"))))] 1313 "TARGET_ARCH64 && TARGET_SUBXC 1314 && (GET_MODE (operands[2]) == CCXmode || GET_MODE (operands[2]) == CCXCmode)" 1315 "subxc\t%%g0, %1, %0" 1316 [(set_attr "type" "ialuX")]) 1317 1318(define_insn "*minus_sltu<W:mode>_subxc" 1319 [(set (match_operand:W 0 "register_operand" "=r") 1320 (minus:W (match_operand:W 1 "register_operand" "r") 1321 (ltu:W (match_operand 2 "icc_register_operand" "X") 1322 (const_int 0))))] 1323 "TARGET_ARCH64 && TARGET_SUBXC 1324 && (GET_MODE (operands[2]) == CCXmode || GET_MODE (operands[2]) == CCXCmode)" 1325 "subxc\t%1, %%g0, %0" 1326 [(set_attr "type" "ialuX")]) 1327 1328(define_insn "*minus_minus_sltu<W:mode>_subxc" 1329 [(set (match_operand:W 0 "register_operand" "=r") 1330 (minus:W (minus:W (match_operand:W 1 "register_or_zero_operand" "rJ") 1331 (ltu:W (match_operand 3 "icc_register_operand" "X") 1332 (const_int 0))) 1333 (match_operand:W 2 "register_operand" "r")))] 1334 "TARGET_ARCH64 && TARGET_SUBXC 1335 && (GET_MODE (operands[3]) == CCXmode || GET_MODE (operands[3]) == CCXCmode)" 1336 "subxc\t%r1, %2, %0" 1337 [(set_attr "type" "ialuX")]) 1338 1339(define_insn "*subxc<W:mode>" 1340 [(set (match_operand:W 0 "register_operand" "=r") 1341 (minus:W (minus:W (match_operand:W 1 "register_or_zero_operand" "rJ") 1342 (match_operand:W 2 "register_operand" "r")) 1343 (ltu:W (match_operand 3 "icc_register_operand" "X") 1344 (const_int 0))))] 1345 "TARGET_ARCH64 && TARGET_SUBXC 1346 && (GET_MODE (operands[3]) == CCXmode || GET_MODE (operands[3]) == CCXCmode)" 1347 "subxc\t%r1, %2, %0" 1348 [(set_attr "type" "ialuX")]) 1349 1350(define_split 1351 [(set (match_operand:W 0 "register_operand" "") 1352 (match_operator:W 1 "icc_comparison_operator" 1353 [(match_operand 2 "icc_register_operand" "") (const_int 0)]))] 1354 "TARGET_V9 1355 /* 64-bit LTU is better implemented using addxc with VIS3. */ 1356 && !(GET_CODE (operands[1]) == LTU 1357 && (GET_MODE (operands[2]) == CCXmode 1358 || GET_MODE (operands[2]) == CCXCmode) 1359 && TARGET_VIS3) 1360 /* 32-bit LTU/GEU are better implemented using addx/subx. */ 1361 && !((GET_CODE (operands[1]) == LTU || GET_CODE (operands[1]) == GEU) 1362 && (GET_MODE (operands[2]) == CCmode 1363 || GET_MODE (operands[2]) == CCCmode))" 1364 [(set (match_dup 0) (const_int 0)) 1365 (set (match_dup 0) 1366 (if_then_else:SI (match_op_dup:W 1 [(match_dup 2) (const_int 0)]) 1367 (const_int 1) 1368 (match_dup 0)))] 1369 "") 1370 1371;; These control RTL generation for conditional jump insns 1372 1373(define_expand "cbranchcc4" 1374 [(set (pc) 1375 (if_then_else (match_operator 0 "comparison_operator" 1376 [(match_operand 1 "compare_operand" "") 1377 (match_operand 2 "const_zero_operand" "")]) 1378 (label_ref (match_operand 3 "" "")) 1379 (pc)))] 1380 "" 1381 "") 1382 1383(define_expand "cbranchsi4" 1384 [(use (match_operator 0 "comparison_operator" 1385 [(match_operand:SI 1 "compare_operand" "") 1386 (match_operand:SI 2 "arith_operand" "")])) 1387 (use (match_operand 3 ""))] 1388 "" 1389{ 1390 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx) 1391 operands[1] = force_reg (SImode, operands[1]); 1392 emit_conditional_branch_insn (operands); 1393 DONE; 1394}) 1395 1396(define_expand "cbranchdi4" 1397 [(use (match_operator 0 "comparison_operator" 1398 [(match_operand:DI 1 "compare_operand" "") 1399 (match_operand:DI 2 "arith_operand" "")])) 1400 (use (match_operand 3 ""))] 1401 "TARGET_ARCH64" 1402{ 1403 if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx) 1404 operands[1] = force_reg (DImode, operands[1]); 1405 emit_conditional_branch_insn (operands); 1406 DONE; 1407}) 1408 1409(define_expand "cbranch<F:mode>4" 1410 [(use (match_operator 0 "comparison_operator" 1411 [(match_operand:F 1 "register_operand" "") 1412 (match_operand:F 2 "register_operand" "")])) 1413 (use (match_operand 3 ""))] 1414 "TARGET_FPU" 1415{ 1416 emit_conditional_branch_insn (operands); 1417 DONE; 1418}) 1419 1420 1421;; Now match both normal and inverted jump. 1422 1423;; XXX fpcmp nop braindamage 1424(define_insn "*normal_branch" 1425 [(set (pc) 1426 (if_then_else (match_operator 0 "icc_comparison_operator" 1427 [(reg CC_REG) (const_int 0)]) 1428 (label_ref (match_operand 1 "" "")) 1429 (pc)))] 1430 "" 1431{ 1432 return output_cbranch (operands[0], operands[1], 1, 0, 1433 final_sequence && INSN_ANNULLED_BRANCH_P (insn), 1434 insn); 1435} 1436 [(set_attr "type" "branch") 1437 (set_attr "branch_type" "icc")]) 1438 1439;; XXX fpcmp nop braindamage 1440(define_insn "*inverted_branch" 1441 [(set (pc) 1442 (if_then_else (match_operator 0 "icc_comparison_operator" 1443 [(reg CC_REG) (const_int 0)]) 1444 (pc) 1445 (label_ref (match_operand 1 "" ""))))] 1446 "" 1447{ 1448 return output_cbranch (operands[0], operands[1], 1, 1, 1449 final_sequence && INSN_ANNULLED_BRANCH_P (insn), 1450 insn); 1451} 1452 [(set_attr "type" "branch") 1453 (set_attr "branch_type" "icc")]) 1454 1455;; XXX fpcmp nop braindamage 1456(define_insn "*normal_fp_branch" 1457 [(set (pc) 1458 (if_then_else (match_operator 1 "comparison_operator" 1459 [(match_operand:CCFP 0 "fcc_register_operand" "c") 1460 (const_int 0)]) 1461 (label_ref (match_operand 2 "" "")) 1462 (pc)))] 1463 "" 1464{ 1465 return output_cbranch (operands[1], operands[2], 2, 0, 1466 final_sequence && INSN_ANNULLED_BRANCH_P (insn), 1467 insn); 1468} 1469 [(set_attr "type" "branch") 1470 (set_attr "branch_type" "fcc")]) 1471 1472;; XXX fpcmp nop braindamage 1473(define_insn "*inverted_fp_branch" 1474 [(set (pc) 1475 (if_then_else (match_operator 1 "comparison_operator" 1476 [(match_operand:CCFP 0 "fcc_register_operand" "c") 1477 (const_int 0)]) 1478 (pc) 1479 (label_ref (match_operand 2 "" ""))))] 1480 "" 1481{ 1482 return output_cbranch (operands[1], operands[2], 2, 1, 1483 final_sequence && INSN_ANNULLED_BRANCH_P (insn), 1484 insn); 1485} 1486 [(set_attr "type" "branch") 1487 (set_attr "branch_type" "fcc")]) 1488 1489;; XXX fpcmp nop braindamage 1490(define_insn "*normal_fpe_branch" 1491 [(set (pc) 1492 (if_then_else (match_operator 1 "comparison_operator" 1493 [(match_operand:CCFPE 0 "fcc_register_operand" "c") 1494 (const_int 0)]) 1495 (label_ref (match_operand 2 "" "")) 1496 (pc)))] 1497 "" 1498{ 1499 return output_cbranch (operands[1], operands[2], 2, 0, 1500 final_sequence && INSN_ANNULLED_BRANCH_P (insn), 1501 insn); 1502} 1503 [(set_attr "type" "branch") 1504 (set_attr "branch_type" "fcc")]) 1505 1506;; XXX fpcmp nop braindamage 1507(define_insn "*inverted_fpe_branch" 1508 [(set (pc) 1509 (if_then_else (match_operator 1 "comparison_operator" 1510 [(match_operand:CCFPE 0 "fcc_register_operand" "c") 1511 (const_int 0)]) 1512 (pc) 1513 (label_ref (match_operand 2 "" ""))))] 1514 "" 1515{ 1516 return output_cbranch (operands[1], operands[2], 2, 1, 1517 final_sequence && INSN_ANNULLED_BRANCH_P (insn), 1518 insn); 1519} 1520 [(set_attr "type" "branch") 1521 (set_attr "branch_type" "fcc")]) 1522 1523;; SPARC V9-specific jump insns. None of these are guaranteed to be 1524;; in the architecture. 1525 1526(define_insn "*cbcond_sp32" 1527 [(set (pc) 1528 (if_then_else (match_operator 0 "comparison_operator" 1529 [(match_operand:SI 1 "register_operand" "r") 1530 (match_operand:SI 2 "arith5_operand" "rA")]) 1531 (label_ref (match_operand 3 "" "")) 1532 (pc)))] 1533 "TARGET_CBCOND" 1534{ 1535 return output_cbcond (operands[0], operands[3], insn); 1536} 1537 [(set_attr "type" "cbcond")]) 1538 1539(define_insn "*cbcond_sp64" 1540 [(set (pc) 1541 (if_then_else (match_operator 0 "comparison_operator" 1542 [(match_operand:DI 1 "register_operand" "r") 1543 (match_operand:DI 2 "arith5_operand" "rA")]) 1544 (label_ref (match_operand 3 "" "")) 1545 (pc)))] 1546 "TARGET_ARCH64 && TARGET_CBCOND" 1547{ 1548 return output_cbcond (operands[0], operands[3], insn); 1549} 1550 [(set_attr "type" "cbcond")]) 1551 1552;; There are no 32-bit brreg insns. 1553 1554(define_insn "*normal_int_branch_sp64" 1555 [(set (pc) 1556 (if_then_else (match_operator 0 "v9_register_comparison_operator" 1557 [(match_operand:DI 1 "register_operand" "r") 1558 (const_int 0)]) 1559 (label_ref (match_operand 2 "" "")) 1560 (pc)))] 1561 "TARGET_ARCH64" 1562{ 1563 return output_v9branch (operands[0], operands[2], 1, 2, 0, 1564 final_sequence && INSN_ANNULLED_BRANCH_P (insn), 1565 insn); 1566} 1567 [(set_attr "type" "branch") 1568 (set_attr "branch_type" "reg")]) 1569 1570(define_insn "*inverted_int_branch_sp64" 1571 [(set (pc) 1572 (if_then_else (match_operator 0 "v9_register_comparison_operator" 1573 [(match_operand:DI 1 "register_operand" "r") 1574 (const_int 0)]) 1575 (pc) 1576 (label_ref (match_operand 2 "" ""))))] 1577 "TARGET_ARCH64" 1578{ 1579 return output_v9branch (operands[0], operands[2], 1, 2, 1, 1580 final_sequence && INSN_ANNULLED_BRANCH_P (insn), 1581 insn); 1582} 1583 [(set_attr "type" "branch") 1584 (set_attr "branch_type" "reg")]) 1585 1586 1587;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic 1588;; value subject to a PC-relative relocation. Operand 2 is a helper function 1589;; that adds the PC value at the call point to register #(operand 3). 1590;; 1591;; Even on V9 we use this call sequence with a stub, instead of "rd %pc, ..." 1592;; because the RDPC instruction is extremely expensive and incurs a complete 1593;; instruction pipeline flush. 1594 1595(define_insn "load_pcrel_sym<P:mode>" 1596 [(set (match_operand:P 0 "register_operand" "=r") 1597 (unspec:P [(match_operand:P 1 "symbolic_operand" "") 1598 (match_operand:P 2 "call_address_operand" "") 1599 (match_operand:P 3 "const_int_operand" "")] 1600 UNSPEC_LOAD_PCREL_SYM)) 1601 (clobber (reg:P O7_REG))] 1602 "REGNO (operands[0]) == INTVAL (operands[3])" 1603{ 1604 return output_load_pcrel_sym (operands); 1605} 1606 [(set (attr "type") (const_string "multi")) 1607 (set (attr "length") 1608 (if_then_else (eq_attr "delayed_branch" "true") 1609 (const_int 3) 1610 (const_int 4)))]) 1611 1612 1613;; Integer move instructions 1614 1615(define_expand "movqi" 1616 [(set (match_operand:QI 0 "nonimmediate_operand" "") 1617 (match_operand:QI 1 "general_operand" ""))] 1618 "" 1619{ 1620 if (sparc_expand_move (QImode, operands)) 1621 DONE; 1622}) 1623 1624(define_insn "*movqi_insn" 1625 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m") 1626 (match_operand:QI 1 "input_operand" "rI,m,rJ"))] 1627 "(register_operand (operands[0], QImode) 1628 || register_or_zero_operand (operands[1], QImode))" 1629 "@ 1630 mov\t%1, %0 1631 ldub\t%1, %0 1632 stb\t%r1, %0" 1633 [(set_attr "type" "*,load,store") 1634 (set_attr "subtype" "*,regular,*") 1635 (set_attr "us3load_type" "*,3cycle,*")]) 1636 1637(define_expand "movhi" 1638 [(set (match_operand:HI 0 "nonimmediate_operand" "") 1639 (match_operand:HI 1 "general_operand" ""))] 1640 "" 1641{ 1642 if (sparc_expand_move (HImode, operands)) 1643 DONE; 1644}) 1645 1646(define_insn "*movhi_insn" 1647 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m") 1648 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))] 1649 "(register_operand (operands[0], HImode) 1650 || register_or_zero_operand (operands[1], HImode))" 1651 "@ 1652 mov\t%1, %0 1653 sethi\t%%hi(%a1), %0 1654 lduh\t%1, %0 1655 sth\t%r1, %0" 1656 [(set_attr "type" "*,*,load,store") 1657 (set_attr "subtype" "*,*,regular,*") 1658 (set_attr "us3load_type" "*,*,3cycle,*")]) 1659 1660;; We always work with constants here. 1661(define_insn "*movhi_lo_sum" 1662 [(set (match_operand:HI 0 "register_operand" "=r") 1663 (ior:HI (match_operand:HI 1 "register_operand" "%r") 1664 (match_operand:HI 2 "small_int_operand" "I")))] 1665 "" 1666 "or\t%1, %2, %0") 1667 1668(define_expand "movsi" 1669 [(set (match_operand:SI 0 "nonimmediate_operand" "") 1670 (match_operand:SI 1 "general_operand" ""))] 1671 "" 1672{ 1673 if (sparc_expand_move (SImode, operands)) 1674 DONE; 1675}) 1676 1677(define_insn "*movsi_insn" 1678 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, r,*f,*f,*f, m,d,d") 1679 (match_operand:SI 1 "input_operand" "rI,K,m,rJ,*f, r, f, m,*f,J,P"))] 1680 "register_operand (operands[0], SImode) 1681 || register_or_zero_or_all_ones_operand (operands[1], SImode)" 1682 "@ 1683 mov\t%1, %0 1684 sethi\t%%hi(%a1), %0 1685 ld\t%1, %0 1686 st\t%r1, %0 1687 movstouw\t%1, %0 1688 movwtos\t%1, %0 1689 fmovs\t%1, %0 1690 ld\t%1, %0 1691 st\t%1, %0 1692 fzeros\t%0 1693 fones\t%0" 1694 [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl") 1695 (set_attr "subtype" "*,*,regular,*,movstouw,single,*,*,*,single,single") 1696 (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")]) 1697 1698(define_insn "*movsi_lo_sum" 1699 [(set (match_operand:SI 0 "register_operand" "=r") 1700 (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 1701 (match_operand:SI 2 "immediate_operand" "in")))] 1702 "!flag_pic" 1703 "or\t%1, %%lo(%a2), %0") 1704 1705(define_insn "*movsi_high" 1706 [(set (match_operand:SI 0 "register_operand" "=r") 1707 (high:SI (match_operand:SI 1 "immediate_operand" "in")))] 1708 "!flag_pic" 1709 "sethi\t%%hi(%a1), %0") 1710 1711;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC 1712;; so that CSE won't optimize the address computation away. 1713(define_insn "movsi_lo_sum_pic" 1714 [(set (match_operand:SI 0 "register_operand" "=r") 1715 (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 1716 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 1717 UNSPEC_MOVE_PIC)))] 1718 "flag_pic" 1719{ 1720#ifdef HAVE_AS_SPARC_GOTDATA_OP 1721 return "xor\t%1, %%gdop_lox10(%a2), %0"; 1722#else 1723 return "or\t%1, %%lo(%a2), %0"; 1724#endif 1725}) 1726 1727(define_insn "movsi_high_pic" 1728 [(set (match_operand:SI 0 "register_operand" "=r") 1729 (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))] 1730 "flag_pic && check_pic (1)" 1731{ 1732#ifdef HAVE_AS_SPARC_GOTDATA_OP 1733 return "sethi\t%%gdop_hix22(%a1), %0"; 1734#else 1735 return "sethi\t%%hi(%a1), %0"; 1736#endif 1737}) 1738 1739(define_insn "movsi_pic_gotdata_op" 1740 [(set (match_operand:SI 0 "register_operand" "=r") 1741 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 1742 (match_operand:SI 2 "register_operand" "r") 1743 (match_operand 3 "symbolic_operand" "")] 1744 UNSPEC_MOVE_GOTDATA))] 1745 "flag_pic && check_pic (1)" 1746{ 1747#ifdef HAVE_AS_SPARC_GOTDATA_OP 1748 return "ld\t[%1 + %2], %0, %%gdop(%a3)"; 1749#else 1750 return "ld\t[%1 + %2], %0"; 1751#endif 1752} 1753 [(set_attr "type" "load") 1754 (set_attr "subtype" "regular")]) 1755 1756(define_expand "movsi_pic_label_ref" 1757 [(set (match_dup 3) (high:SI 1758 (unspec:SI [(match_operand:SI 1 "symbolic_operand" "") 1759 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) 1760 (set (match_dup 4) (lo_sum:SI (match_dup 3) 1761 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) 1762 (set (match_operand:SI 0 "register_operand" "=r") 1763 (minus:SI (match_dup 5) (match_dup 4)))] 1764 "flag_pic" 1765{ 1766 crtl->uses_pic_offset_table = 1; 1767 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); 1768 if (!can_create_pseudo_p ()) 1769 { 1770 operands[3] = operands[0]; 1771 operands[4] = operands[0]; 1772 } 1773 else 1774 { 1775 operands[3] = gen_reg_rtx (SImode); 1776 operands[4] = gen_reg_rtx (SImode); 1777 } 1778 operands[5] = pic_offset_table_rtx; 1779}) 1780 1781(define_insn "*movsi_high_pic_label_ref" 1782 [(set (match_operand:SI 0 "register_operand" "=r") 1783 (high:SI 1784 (unspec:SI [(match_operand:SI 1 "symbolic_operand" "") 1785 (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))] 1786 "flag_pic" 1787 "sethi\t%%hi(%a2-(%a1-.)), %0") 1788 1789(define_insn "*movsi_lo_sum_pic_label_ref" 1790 [(set (match_operand:SI 0 "register_operand" "=r") 1791 (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 1792 (unspec:SI [(match_operand:SI 2 "symbolic_operand" "") 1793 (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))] 1794 "flag_pic" 1795 "or\t%1, %%lo(%a3-(%a2-.)), %0") 1796 1797;; Set up the PIC register for VxWorks. 1798 1799(define_expand "vxworks_load_got" 1800 [(set (match_dup 0) 1801 (high:SI (match_dup 1))) 1802 (set (match_dup 0) 1803 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1)))) 1804 (set (match_dup 0) 1805 (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))] 1806 "TARGET_VXWORKS_RTP" 1807{ 1808 operands[0] = pic_offset_table_rtx; 1809 operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE); 1810 operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX); 1811}) 1812 1813(define_expand "movdi" 1814 [(set (match_operand:DI 0 "nonimmediate_operand" "") 1815 (match_operand:DI 1 "general_operand" ""))] 1816 "" 1817{ 1818 if (sparc_expand_move (DImode, operands)) 1819 DONE; 1820}) 1821 1822;; Be careful, fmovd does not exist when !v9. 1823;; We match MEM moves directly when we have correct even 1824;; numbered registers, but fall into splits otherwise. 1825;; The constraint ordering here is really important to 1826;; avoid insane problems in reload, especially for patterns 1827;; of the form: 1828;; 1829;; (set (mem:DI (plus:SI (reg:SI 30 %fp) 1830;; (const_int -5016))) 1831;; (reg:DI 2 %g2)) 1832;; 1833 1834(define_insn "*movdi_insn_sp32" 1835 [(set (match_operand:DI 0 "nonimmediate_operand" 1836 "=T,o,U,T,r,o,r,r,?*f,?T,?*f,?o,?*e,?*e, r,?*f,?*e,?T,*b,*b") 1837 (match_operand:DI 1 "input_operand" 1838 " J,J,T,U,o,r,i,r, T,*f, o,*f, *e, *e,?*f, r, T,*e, J, P"))] 1839 "TARGET_ARCH32 1840 && (register_operand (operands[0], DImode) 1841 || register_or_zero_operand (operands[1], DImode))" 1842 "@ 1843 stx\t%r1, %0 1844 # 1845 ldd\t%1, %0 1846 std\t%1, %0 1847 ldd\t%1, %0 1848 std\t%1, %0 1849 # 1850 # 1851 ldd\t%1, %0 1852 std\t%1, %0 1853 # 1854 # 1855 fmovd\t%1, %0 1856 # 1857 # 1858 # 1859 ldd\t%1, %0 1860 std\t%1, %0 1861 fzero\t%0 1862 fone\t%0" 1863 [(set_attr "type" "store,*,load,store,load,store,*,*,fpload,fpstore,*,*,fpmove,*,*,*,fpload,fpstore,visl, 1864visl") 1865 (set_attr "subtype" "*,*,regular,*,regular,*,*,*,*,*,*,*,*,*,*,*,*,*,double,double") 1866 (set_attr "length" "*,2,*,*,*,*,2,2,*,*,2,2,*,2,2,2,*,*,*,*") 1867 (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double") 1868 (set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis") 1869 (set_attr "lra" "*,*,disabled,disabled,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")]) 1870 1871(define_insn "*movdi_insn_sp64" 1872 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b") 1873 (match_operand:DI 1 "input_operand" "rI,N,m,rJ,*e, r, *e, W,*e,J,P"))] 1874 "TARGET_ARCH64 1875 && (register_operand (operands[0], DImode) 1876 || register_or_zero_or_all_ones_operand (operands[1], DImode))" 1877 "@ 1878 mov\t%1, %0 1879 sethi\t%%hi(%a1), %0 1880 ldx\t%1, %0 1881 stx\t%r1, %0 1882 movdtox\t%1, %0 1883 movxtod\t%1, %0 1884 fmovd\t%1, %0 1885 ldd\t%1, %0 1886 std\t%1, %0 1887 fzero\t%0 1888 fone\t%0" 1889 [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl") 1890 (set_attr "subtype" "*,*,regular,*,movdtox,movxtod,*,*,*,double,double") 1891 (set_attr "fptype" "*,*,*,*,*,*,double,*,*,double,double") 1892 (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")]) 1893 1894(define_expand "movdi_pic_label_ref" 1895 [(set (match_dup 3) (high:DI 1896 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "") 1897 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) 1898 (set (match_dup 4) (lo_sum:DI (match_dup 3) 1899 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) 1900 (set (match_operand:DI 0 "register_operand" "=r") 1901 (minus:DI (match_dup 5) (match_dup 4)))] 1902 "TARGET_ARCH64 && flag_pic" 1903{ 1904 crtl->uses_pic_offset_table = 1; 1905 operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); 1906 if (!can_create_pseudo_p ()) 1907 { 1908 operands[3] = operands[0]; 1909 operands[4] = operands[0]; 1910 } 1911 else 1912 { 1913 operands[3] = gen_reg_rtx (DImode); 1914 operands[4] = gen_reg_rtx (DImode); 1915 } 1916 operands[5] = pic_offset_table_rtx; 1917}) 1918 1919(define_insn "*movdi_high_pic_label_ref" 1920 [(set (match_operand:DI 0 "register_operand" "=r") 1921 (high:DI 1922 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "") 1923 (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))] 1924 "TARGET_ARCH64 && flag_pic" 1925 "sethi\t%%hi(%a2-(%a1-.)), %0") 1926 1927(define_insn "*movdi_lo_sum_pic_label_ref" 1928 [(set (match_operand:DI 0 "register_operand" "=r") 1929 (lo_sum:DI (match_operand:DI 1 "register_operand" "r") 1930 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "") 1931 (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))] 1932 "TARGET_ARCH64 && flag_pic" 1933 "or\t%1, %%lo(%a3-(%a2-.)), %0") 1934 1935;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64 1936;; in sparc.c to see what is going on here... PIC stuff comes first. 1937 1938(define_insn "movdi_lo_sum_pic" 1939 [(set (match_operand:DI 0 "register_operand" "=r") 1940 (lo_sum:DI (match_operand:DI 1 "register_operand" "r") 1941 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 1942 UNSPEC_MOVE_PIC)))] 1943 "TARGET_ARCH64 && flag_pic" 1944{ 1945#ifdef HAVE_AS_SPARC_GOTDATA_OP 1946 return "xor\t%1, %%gdop_lox10(%a2), %0"; 1947#else 1948 return "or\t%1, %%lo(%a2), %0"; 1949#endif 1950}) 1951 1952(define_insn "movdi_high_pic" 1953 [(set (match_operand:DI 0 "register_operand" "=r") 1954 (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))] 1955 "TARGET_ARCH64 && flag_pic && check_pic (1)" 1956{ 1957#ifdef HAVE_AS_SPARC_GOTDATA_OP 1958 return "sethi\t%%gdop_hix22(%a1), %0"; 1959#else 1960 return "sethi\t%%hi(%a1), %0"; 1961#endif 1962}) 1963 1964(define_insn "movdi_pic_gotdata_op" 1965 [(set (match_operand:DI 0 "register_operand" "=r") 1966 (unspec:DI [(match_operand:DI 1 "register_operand" "r") 1967 (match_operand:DI 2 "register_operand" "r") 1968 (match_operand 3 "symbolic_operand" "")] 1969 UNSPEC_MOVE_GOTDATA))] 1970 "TARGET_ARCH64 && flag_pic && check_pic (1)" 1971{ 1972#ifdef HAVE_AS_SPARC_GOTDATA_OP 1973 return "ldx\t[%1 + %2], %0, %%gdop(%a3)"; 1974#else 1975 return "ldx\t[%1 + %2], %0"; 1976#endif 1977} 1978 [(set_attr "type" "load") 1979 (set_attr "subtype" "regular")]) 1980 1981(define_insn "*sethi_di_medlow_embmedany_pic" 1982 [(set (match_operand:DI 0 "register_operand" "=r") 1983 (high:DI (match_operand:DI 1 "medium_pic_operand" "")))] 1984 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && flag_pic && check_pic (1)" 1985 "sethi\t%%hi(%a1), %0") 1986 1987(define_insn "*sethi_di_medlow" 1988 [(set (match_operand:DI 0 "register_operand" "=r") 1989 (high:DI (match_operand:DI 1 "symbolic_operand" "")))] 1990 "TARGET_CM_MEDLOW && !flag_pic" 1991 "sethi\t%%hi(%a1), %0") 1992 1993(define_insn "*losum_di_medlow" 1994 [(set (match_operand:DI 0 "register_operand" "=r") 1995 (lo_sum:DI (match_operand:DI 1 "register_operand" "r") 1996 (match_operand:DI 2 "symbolic_operand" "")))] 1997 "TARGET_CM_MEDLOW && !flag_pic" 1998 "or\t%1, %%lo(%a2), %0") 1999 2000(define_insn "seth44" 2001 [(set (match_operand:DI 0 "register_operand" "=r") 2002 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 2003 UNSPEC_SETH44)))] 2004 "TARGET_CM_MEDMID && !flag_pic" 2005 "sethi\t%%h44(%a1), %0") 2006 2007(define_insn "setm44" 2008 [(set (match_operand:DI 0 "register_operand" "=r") 2009 (lo_sum:DI (match_operand:DI 1 "register_operand" "r") 2010 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 2011 UNSPEC_SETM44)))] 2012 "TARGET_CM_MEDMID && !flag_pic" 2013 "or\t%1, %%m44(%a2), %0") 2014 2015(define_insn "setl44" 2016 [(set (match_operand:DI 0 "register_operand" "=r") 2017 (lo_sum:DI (match_operand:DI 1 "register_operand" "r") 2018 (match_operand:DI 2 "symbolic_operand" "")))] 2019 "TARGET_CM_MEDMID && !flag_pic" 2020 "or\t%1, %%l44(%a2), %0") 2021 2022(define_insn "sethh" 2023 [(set (match_operand:DI 0 "register_operand" "=r") 2024 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 2025 UNSPEC_SETHH)))] 2026 "TARGET_CM_MEDANY && !flag_pic" 2027 "sethi\t%%hh(%a1), %0") 2028 2029(define_insn "setlm" 2030 [(set (match_operand:DI 0 "register_operand" "=r") 2031 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 2032 UNSPEC_SETLM)))] 2033 "TARGET_CM_MEDANY && !flag_pic" 2034 "sethi\t%%lm(%a1), %0") 2035 2036(define_insn "sethm" 2037 [(set (match_operand:DI 0 "register_operand" "=r") 2038 (lo_sum:DI (match_operand:DI 1 "register_operand" "r") 2039 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 2040 UNSPEC_EMB_SETHM)))] 2041 "TARGET_CM_MEDANY && !flag_pic" 2042 "or\t%1, %%hm(%a2), %0") 2043 2044(define_insn "setlo" 2045 [(set (match_operand:DI 0 "register_operand" "=r") 2046 (lo_sum:DI (match_operand:DI 1 "register_operand" "r") 2047 (match_operand:DI 2 "symbolic_operand" "")))] 2048 "TARGET_CM_MEDANY && !flag_pic" 2049 "or\t%1, %%lo(%a2), %0") 2050 2051(define_insn "embmedany_sethi" 2052 [(set (match_operand:DI 0 "register_operand" "=r") 2053 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 2054 UNSPEC_EMB_HISUM)))] 2055 "TARGET_CM_EMBMEDANY && !flag_pic" 2056 "sethi\t%%hi(%a1), %0") 2057 2058(define_insn "embmedany_losum" 2059 [(set (match_operand:DI 0 "register_operand" "=r") 2060 (lo_sum:DI (match_operand:DI 1 "register_operand" "r") 2061 (match_operand:DI 2 "data_segment_operand" "")))] 2062 "TARGET_CM_EMBMEDANY && !flag_pic" 2063 "add\t%1, %%lo(%a2), %0") 2064 2065(define_insn "embmedany_brsum" 2066 [(set (match_operand:DI 0 "register_operand" "=r") 2067 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 2068 UNSPEC_EMB_HISUM))] 2069 "TARGET_CM_EMBMEDANY && !flag_pic" 2070 "add\t%1, %_, %0") 2071 2072(define_insn "embmedany_textuhi" 2073 [(set (match_operand:DI 0 "register_operand" "=r") 2074 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 2075 UNSPEC_EMB_TEXTUHI)))] 2076 "TARGET_CM_EMBMEDANY && !flag_pic" 2077 "sethi\t%%uhi(%a1), %0") 2078 2079(define_insn "embmedany_texthi" 2080 [(set (match_operand:DI 0 "register_operand" "=r") 2081 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 2082 UNSPEC_EMB_TEXTHI)))] 2083 "TARGET_CM_EMBMEDANY && !flag_pic" 2084 "sethi\t%%hi(%a1), %0") 2085 2086(define_insn "embmedany_textulo" 2087 [(set (match_operand:DI 0 "register_operand" "=r") 2088 (lo_sum:DI (match_operand:DI 1 "register_operand" "r") 2089 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 2090 UNSPEC_EMB_TEXTULO)))] 2091 "TARGET_CM_EMBMEDANY && !flag_pic" 2092 "or\t%1, %%ulo(%a2), %0") 2093 2094(define_insn "embmedany_textlo" 2095 [(set (match_operand:DI 0 "register_operand" "=r") 2096 (lo_sum:DI (match_operand:DI 1 "register_operand" "r") 2097 (match_operand:DI 2 "text_segment_operand" "")))] 2098 "TARGET_CM_EMBMEDANY && !flag_pic" 2099 "or\t%1, %%lo(%a2), %0") 2100 2101;; Now some patterns to help reload out a bit. 2102(define_expand "reload_indi" 2103 [(parallel [(match_operand:DI 0 "register_operand" "=r") 2104 (match_operand:DI 1 "immediate_operand" "") 2105 (match_operand:TI 2 "register_operand" "=&r")])] 2106 "(TARGET_CM_MEDANY || TARGET_CM_EMBMEDANY) && !flag_pic" 2107{ 2108 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]); 2109 DONE; 2110}) 2111 2112(define_expand "reload_outdi" 2113 [(parallel [(match_operand:DI 0 "register_operand" "=r") 2114 (match_operand:DI 1 "immediate_operand" "") 2115 (match_operand:TI 2 "register_operand" "=&r")])] 2116 "(TARGET_CM_MEDANY || TARGET_CM_EMBMEDANY) && !flag_pic" 2117{ 2118 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]); 2119 DONE; 2120}) 2121 2122;; Split up putting CONSTs and REGs into DI regs when !arch64 2123(define_split 2124 [(set (match_operand:DI 0 "register_operand" "") 2125 (match_operand:DI 1 "const_int_operand" ""))] 2126 "reload_completed 2127 && TARGET_ARCH32 2128 && ((GET_CODE (operands[0]) == REG 2129 && SPARC_INT_REG_P (REGNO (operands[0]))) 2130 || (GET_CODE (operands[0]) == SUBREG 2131 && GET_CODE (SUBREG_REG (operands[0])) == REG 2132 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))" 2133 [(clobber (const_int 0))] 2134{ 2135 HOST_WIDE_INT low = trunc_int_for_mode (INTVAL (operands[1]), SImode); 2136 HOST_WIDE_INT high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode); 2137 rtx high_part = gen_highpart (SImode, operands[0]); 2138 rtx low_part = gen_lowpart (SImode, operands[0]); 2139 2140 emit_move_insn_1 (high_part, GEN_INT (high)); 2141 2142 /* Slick... but this loses if the constant can be done in one insn. */ 2143 if (low == high && !SPARC_SETHI32_P (high) && !SPARC_SIMM13_P (high)) 2144 emit_move_insn_1 (low_part, high_part); 2145 else 2146 emit_move_insn_1 (low_part, GEN_INT (low)); 2147 2148 DONE; 2149}) 2150 2151(define_split 2152 [(set (match_operand:DI 0 "register_operand" "") 2153 (match_operand:DI 1 "register_operand" ""))] 2154 "reload_completed 2155 && (!TARGET_V9 2156 || (TARGET_ARCH32 2157 && sparc_split_reg_reg_legitimate (operands[0], operands[1])))" 2158 [(clobber (const_int 0))] 2159{ 2160 sparc_split_reg_reg (operands[0], operands[1], SImode); 2161 DONE; 2162}) 2163 2164;; Now handle the cases of memory moves from/to non-even 2165;; DI mode register pairs. 2166(define_split 2167 [(set (match_operand:DI 0 "register_operand" "") 2168 (match_operand:DI 1 "memory_operand" ""))] 2169 "reload_completed 2170 && TARGET_ARCH32 2171 && sparc_split_reg_mem_legitimate (operands[0], operands[1])" 2172 [(clobber (const_int 0))] 2173{ 2174 sparc_split_reg_mem (operands[0], operands[1], SImode); 2175 DONE; 2176}) 2177 2178(define_split 2179 [(set (match_operand:DI 0 "memory_operand" "") 2180 (match_operand:DI 1 "register_operand" ""))] 2181 "reload_completed 2182 && TARGET_ARCH32 2183 && sparc_split_reg_mem_legitimate (operands[1], operands[0])" 2184 [(clobber (const_int 0))] 2185{ 2186 sparc_split_mem_reg (operands[0], operands[1], SImode); 2187 DONE; 2188}) 2189 2190(define_split 2191 [(set (match_operand:DI 0 "memory_operand" "") 2192 (match_operand:DI 1 "const_zero_operand" ""))] 2193 "reload_completed 2194 && (!TARGET_V9 2195 || (TARGET_ARCH32 2196 && !mem_min_alignment (operands[0], 8))) 2197 && offsettable_memref_p (operands[0])" 2198 [(clobber (const_int 0))] 2199{ 2200 emit_move_insn_1 (adjust_address (operands[0], SImode, 0), const0_rtx); 2201 emit_move_insn_1 (adjust_address (operands[0], SImode, 4), const0_rtx); 2202 DONE; 2203}) 2204 2205(define_expand "movti" 2206 [(set (match_operand:TI 0 "nonimmediate_operand" "") 2207 (match_operand:TI 1 "general_operand" ""))] 2208 "TARGET_ARCH64" 2209{ 2210 if (sparc_expand_move (TImode, operands)) 2211 DONE; 2212}) 2213 2214;; We need to prevent reload from splitting TImode moves, because it 2215;; might decide to overwrite a pointer with the value it points to. 2216;; In that case we have to do the loads in the appropriate order so 2217;; that the pointer is not destroyed too early. 2218 2219(define_insn "*movti_insn_sp64" 2220 [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?o,b") 2221 (match_operand:TI 1 "input_operand" "roJ,rJ, eo, e,J"))] 2222 "TARGET_ARCH64 2223 && !TARGET_HARD_QUAD 2224 && (register_operand (operands[0], TImode) 2225 || register_or_zero_operand (operands[1], TImode))" 2226 "#" 2227 [(set_attr "length" "2,2,2,2,2") 2228 (set_attr "cpu_feature" "*,*,fpu,fpu,vis")]) 2229 2230(define_insn "*movti_insn_sp64_hq" 2231 [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?*e,?m,b") 2232 (match_operand:TI 1 "input_operand" "roJ,rJ, e, m, e,J"))] 2233 "TARGET_ARCH64 2234 && TARGET_HARD_QUAD 2235 && (register_operand (operands[0], TImode) 2236 || register_or_zero_operand (operands[1], TImode))" 2237 "@ 2238 # 2239 # 2240 fmovq\t%1, %0 2241 ldq\t%1, %0 2242 stq\t%1, %0 2243 #" 2244 [(set_attr "type" "*,*,fpmove,fpload,fpstore,*") 2245 (set_attr "length" "2,2,*,*,*,2")]) 2246 2247;; Now all the splits to handle multi-insn TI mode moves. 2248(define_split 2249 [(set (match_operand:TI 0 "register_operand" "") 2250 (match_operand:TI 1 "register_operand" ""))] 2251 "reload_completed 2252 && ((TARGET_FPU 2253 && !TARGET_HARD_QUAD) 2254 || (!fp_register_operand (operands[0], TImode) 2255 && !fp_register_operand (operands[1], TImode)))" 2256 [(clobber (const_int 0))] 2257{ 2258 rtx set_dest = operands[0]; 2259 rtx set_src = operands[1]; 2260 rtx dest1, dest2; 2261 rtx src1, src2; 2262 2263 dest1 = gen_highpart (DImode, set_dest); 2264 dest2 = gen_lowpart (DImode, set_dest); 2265 src1 = gen_highpart (DImode, set_src); 2266 src2 = gen_lowpart (DImode, set_src); 2267 2268 /* Now emit using the real source and destination we found, swapping 2269 the order if we detect overlap. */ 2270 if (reg_overlap_mentioned_p (dest1, src2)) 2271 { 2272 emit_insn (gen_movdi (dest2, src2)); 2273 emit_insn (gen_movdi (dest1, src1)); 2274 } 2275 else 2276 { 2277 emit_insn (gen_movdi (dest1, src1)); 2278 emit_insn (gen_movdi (dest2, src2)); 2279 } 2280 DONE; 2281}) 2282 2283(define_split 2284 [(set (match_operand:TI 0 "nonimmediate_operand" "") 2285 (match_operand:TI 1 "const_zero_operand" ""))] 2286 "reload_completed" 2287 [(clobber (const_int 0))] 2288{ 2289 rtx set_dest = operands[0]; 2290 rtx dest1, dest2; 2291 2292 switch (GET_CODE (set_dest)) 2293 { 2294 case REG: 2295 dest1 = gen_highpart (DImode, set_dest); 2296 dest2 = gen_lowpart (DImode, set_dest); 2297 break; 2298 case MEM: 2299 dest1 = adjust_address (set_dest, DImode, 0); 2300 dest2 = adjust_address (set_dest, DImode, 8); 2301 break; 2302 default: 2303 gcc_unreachable (); 2304 } 2305 2306 emit_insn (gen_movdi (dest1, const0_rtx)); 2307 emit_insn (gen_movdi (dest2, const0_rtx)); 2308 DONE; 2309}) 2310 2311(define_split 2312 [(set (match_operand:TI 0 "register_operand" "") 2313 (match_operand:TI 1 "memory_operand" ""))] 2314 "reload_completed 2315 && offsettable_memref_p (operands[1]) 2316 && (!TARGET_HARD_QUAD 2317 || !fp_register_operand (operands[0], TImode))" 2318 [(clobber (const_int 0))] 2319{ 2320 rtx word0 = adjust_address (operands[1], DImode, 0); 2321 rtx word1 = adjust_address (operands[1], DImode, 8); 2322 rtx set_dest, dest1, dest2; 2323 2324 set_dest = operands[0]; 2325 2326 dest1 = gen_highpart (DImode, set_dest); 2327 dest2 = gen_lowpart (DImode, set_dest); 2328 2329 /* Now output, ordering such that we don't clobber any registers 2330 mentioned in the address. */ 2331 if (reg_overlap_mentioned_p (dest1, word1)) 2332 2333 { 2334 emit_insn (gen_movdi (dest2, word1)); 2335 emit_insn (gen_movdi (dest1, word0)); 2336 } 2337 else 2338 { 2339 emit_insn (gen_movdi (dest1, word0)); 2340 emit_insn (gen_movdi (dest2, word1)); 2341 } 2342 DONE; 2343}) 2344 2345(define_split 2346 [(set (match_operand:TI 0 "memory_operand" "") 2347 (match_operand:TI 1 "register_operand" ""))] 2348 "reload_completed 2349 && offsettable_memref_p (operands[0]) 2350 && (!TARGET_HARD_QUAD 2351 || !fp_register_operand (operands[1], TImode))" 2352 [(clobber (const_int 0))] 2353{ 2354 rtx set_src = operands[1]; 2355 2356 emit_insn (gen_movdi (adjust_address (operands[0], DImode, 0), 2357 gen_highpart (DImode, set_src))); 2358 emit_insn (gen_movdi (adjust_address (operands[0], DImode, 8), 2359 gen_lowpart (DImode, set_src))); 2360 DONE; 2361}) 2362 2363 2364;; Floating point move instructions 2365 2366(define_expand "movsf" 2367 [(set (match_operand:SF 0 "nonimmediate_operand" "") 2368 (match_operand:SF 1 "general_operand" ""))] 2369 "" 2370{ 2371 if (sparc_expand_move (SFmode, operands)) 2372 DONE; 2373}) 2374 2375(define_insn "*movsf_insn" 2376 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f,f,*r,m, m") 2377 (match_operand:SF 1 "input_operand" "G,C,f,*rR, Q, S, f,*r,m, m,f,*rG"))] 2378 "(register_operand (operands[0], SFmode) 2379 || register_or_zero_or_all_ones_operand (operands[1], SFmode))" 2380{ 2381 if (GET_CODE (operands[1]) == CONST_DOUBLE 2382 && (which_alternative == 3 2383 || which_alternative == 4 2384 || which_alternative == 5)) 2385 { 2386 long i; 2387 2388 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), i); 2389 operands[1] = GEN_INT (i); 2390 } 2391 2392 switch (which_alternative) 2393 { 2394 case 0: 2395 return "fzeros\t%0"; 2396 case 1: 2397 return "fones\t%0"; 2398 case 2: 2399 return "fmovs\t%1, %0"; 2400 case 3: 2401 return "mov\t%1, %0"; 2402 case 4: 2403 return "sethi\t%%hi(%a1), %0"; 2404 case 5: 2405 return "#"; 2406 case 6: 2407 return "movstouw\t%1, %0"; 2408 case 7: 2409 return "movwtos\t%1, %0"; 2410 case 8: 2411 case 9: 2412 return "ld\t%1, %0"; 2413 case 10: 2414 case 11: 2415 return "st\t%r1, %0"; 2416 default: 2417 gcc_unreachable (); 2418 } 2419} 2420 [(set_attr "type" "visl,visl,fpmove,*,*,*,vismv,vismv,fpload,load,fpstore,store") 2421 (set_attr "subtype" "single,single,*,*,*,*,movstouw,single,*,regular,*,*") 2422 (set_attr "cpu_feature" "vis,vis,fpu,*,*,*,vis3,vis3,fpu,*,fpu,*")]) 2423 2424;; The following 3 patterns build SFmode constants in integer registers. 2425 2426(define_insn "*movsf_lo_sum" 2427 [(set (match_operand:SF 0 "register_operand" "=r") 2428 (lo_sum:SF (match_operand:SF 1 "register_operand" "r") 2429 (match_operand:SF 2 "fp_const_high_losum_operand" "S")))] 2430 "" 2431{ 2432 long i; 2433 2434 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[2]), i); 2435 operands[2] = GEN_INT (i); 2436 return "or\t%1, %%lo(%a2), %0"; 2437}) 2438 2439(define_insn "*movsf_high" 2440 [(set (match_operand:SF 0 "register_operand" "=r") 2441 (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))] 2442 "" 2443{ 2444 long i; 2445 2446 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), i); 2447 operands[1] = GEN_INT (i); 2448 return "sethi\t%%hi(%1), %0"; 2449}) 2450 2451(define_split 2452 [(set (match_operand:SF 0 "register_operand" "") 2453 (match_operand:SF 1 "fp_const_high_losum_operand" ""))] 2454 "REG_P (operands[0]) && SPARC_INT_REG_P (REGNO (operands[0]))" 2455 [(set (match_dup 0) (high:SF (match_dup 1))) 2456 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))]) 2457 2458(define_expand "movdf" 2459 [(set (match_operand:DF 0 "nonimmediate_operand" "") 2460 (match_operand:DF 1 "general_operand" ""))] 2461 "" 2462{ 2463 if (sparc_expand_move (DFmode, operands)) 2464 DONE; 2465}) 2466 2467(define_insn "*movdf_insn_sp32" 2468 [(set (match_operand:DF 0 "nonimmediate_operand" 2469 "=T,o,b,b,e,e,*r, f, e,T,U,T, f,o, *r,*r, o") 2470 (match_operand:DF 1 "input_operand" 2471 " G,G,G,C,e,e, f,*r,T#F,e,T,U,o#F,f,*rF, o,*r"))] 2472 "TARGET_ARCH32 2473 && (register_operand (operands[0], DFmode) 2474 || register_or_zero_or_all_ones_operand (operands[1], DFmode))" 2475 "@ 2476 stx\t%r1, %0 2477 # 2478 fzero\t%0 2479 fone\t%0 2480 fmovd\t%1, %0 2481 # 2482 # 2483 # 2484 ldd\t%1, %0 2485 std\t%1, %0 2486 ldd\t%1, %0 2487 std\t%1, %0 2488 # 2489 # 2490 # 2491 ldd\t%1, %0 2492 std\t%1, %0" 2493 [(set_attr "type" "store,*,visl,visl,fpmove,*,*,*,fpload,fpstore,load,store,*,*,*,load,store") 2494 (set_attr "subtype" "*,*,double,double,*,*,*,*,*,*,regular,*,*,*,*,regular,*") 2495 (set_attr "length" "*,2,*,*,*,2,2,2,*,*,*,*,2,2,2,*,*") 2496 (set_attr "fptype" "*,*,double,double,double,*,*,*,*,*,*,*,*,*,*,*,*") 2497 (set_attr "cpu_feature" "v9,*,vis,vis,v9,fpunotv9,vis3,vis3,fpu,fpu,*,*,fpu,fpu,*,*,*") 2498 (set_attr "lra" "*,*,*,*,*,*,*,*,*,*,disabled,disabled,*,*,*,*,*")]) 2499 2500(define_insn "*movdf_insn_sp64" 2501 [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e, e,W, *r,*r, m,*r") 2502 (match_operand:DF 1 "input_operand" "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))] 2503 "TARGET_ARCH64 2504 && (register_operand (operands[0], DFmode) 2505 || register_or_zero_or_all_ones_operand (operands[1], DFmode))" 2506 "@ 2507 fzero\t%0 2508 fone\t%0 2509 fmovd\t%1, %0 2510 movdtox\t%1, %0 2511 movxtod\t%1, %0 2512 ldd\t%1, %0 2513 std\t%1, %0 2514 mov\t%r1, %0 2515 ldx\t%1, %0 2516 stx\t%r1, %0 2517 #" 2518 [(set_attr "type" "visl,visl,fpmove,vismv,vismv,load,store,*,load,store,*") 2519 (set_attr "subtype" "double,double,*,movdtox,movxtod,regular,*,*,regular,*,*") 2520 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,2") 2521 (set_attr "fptype" "double,double,double,double,double,*,*,*,*,*,*") 2522 (set_attr "cpu_feature" "vis,vis,fpu,vis3,vis3,fpu,fpu,*,*,*,*")]) 2523 2524;; This pattern builds DFmode constants in integer registers. 2525(define_split 2526 [(set (match_operand:DF 0 "register_operand" "") 2527 (match_operand:DF 1 "const_double_operand" ""))] 2528 "reload_completed 2529 && REG_P (operands[0]) 2530 && SPARC_INT_REG_P (REGNO (operands[0])) 2531 && !const_zero_operand (operands[1], GET_MODE (operands[0]))" 2532 [(clobber (const_int 0))] 2533{ 2534 operands[0] = gen_raw_REG (DImode, REGNO (operands[0])); 2535 2536 if (TARGET_ARCH64) 2537 { 2538 rtx tem = simplify_subreg (DImode, operands[1], DFmode, 0); 2539 emit_insn (gen_movdi (operands[0], tem)); 2540 } 2541 else 2542 { 2543 rtx hi = simplify_subreg (SImode, operands[1], DFmode, 0); 2544 rtx lo = simplify_subreg (SImode, operands[1], DFmode, 4); 2545 rtx high_part = gen_highpart (SImode, operands[0]); 2546 rtx low_part = gen_lowpart (SImode, operands[0]); 2547 2548 gcc_assert (GET_CODE (hi) == CONST_INT); 2549 gcc_assert (GET_CODE (lo) == CONST_INT); 2550 2551 emit_move_insn_1 (high_part, hi); 2552 2553 /* Slick... but this loses if the constant can be done in one insn. */ 2554 if (lo == hi 2555 && !SPARC_SETHI32_P (INTVAL (hi)) 2556 && !SPARC_SIMM13_P (INTVAL (hi))) 2557 emit_move_insn_1 (low_part, high_part); 2558 else 2559 emit_move_insn_1 (low_part, lo); 2560 } 2561 DONE; 2562}) 2563 2564;; Ok, now the splits to handle all the multi insn and 2565;; mis-aligned memory address cases. 2566;; In these splits please take note that we must be 2567;; careful when V9 but not ARCH64 because the integer 2568;; register DFmode cases must be handled. 2569(define_split 2570 [(set (match_operand:DF 0 "register_operand" "") 2571 (match_operand:DF 1 "const_zero_operand" ""))] 2572 "reload_completed 2573 && TARGET_ARCH32 2574 && ((GET_CODE (operands[0]) == REG 2575 && SPARC_INT_REG_P (REGNO (operands[0]))) 2576 || (GET_CODE (operands[0]) == SUBREG 2577 && GET_CODE (SUBREG_REG (operands[0])) == REG 2578 && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))" 2579 [(clobber (const_int 0))] 2580{ 2581 emit_move_insn_1 (gen_highpart (SFmode, operands[0]), CONST0_RTX (SFmode)); 2582 emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), CONST0_RTX (SFmode)); 2583 DONE; 2584}) 2585 2586(define_split 2587 [(set (match_operand:DF 0 "register_operand" "") 2588 (match_operand:DF 1 "register_operand" ""))] 2589 "reload_completed 2590 && (!TARGET_V9 2591 || (TARGET_ARCH32 2592 && sparc_split_reg_reg_legitimate (operands[0], operands[1])))" 2593 [(clobber (const_int 0))] 2594{ 2595 sparc_split_reg_reg (operands[0], operands[1], SFmode); 2596 DONE; 2597}) 2598 2599(define_split 2600 [(set (match_operand:DF 0 "register_operand" "") 2601 (match_operand:DF 1 "memory_operand" ""))] 2602 "reload_completed 2603 && TARGET_ARCH32 2604 && sparc_split_reg_mem_legitimate (operands[0], operands[1])" 2605 [(clobber (const_int 0))] 2606{ 2607 sparc_split_reg_mem (operands[0], operands[1], SFmode); 2608 DONE; 2609}) 2610 2611(define_split 2612 [(set (match_operand:DF 0 "memory_operand" "") 2613 (match_operand:DF 1 "register_operand" ""))] 2614 "reload_completed 2615 && TARGET_ARCH32 2616 && sparc_split_reg_mem_legitimate (operands[1], operands[0])" 2617 [(clobber (const_int 0))] 2618{ 2619 sparc_split_mem_reg (operands[0], operands[1], SFmode); 2620 DONE; 2621}) 2622 2623(define_split 2624 [(set (match_operand:DF 0 "memory_operand" "") 2625 (match_operand:DF 1 "const_zero_operand" ""))] 2626 "reload_completed 2627 && (!TARGET_V9 2628 || (TARGET_ARCH32 2629 && !mem_min_alignment (operands[0], 8))) 2630 && offsettable_memref_p (operands[0])" 2631 [(clobber (const_int 0))] 2632{ 2633 emit_move_insn_1 (adjust_address (operands[0], SFmode, 0), CONST0_RTX (SFmode)); 2634 emit_move_insn_1 (adjust_address (operands[0], SFmode, 4), CONST0_RTX (SFmode)); 2635 DONE; 2636}) 2637 2638(define_expand "movtf" 2639 [(set (match_operand:TF 0 "nonimmediate_operand" "") 2640 (match_operand:TF 1 "general_operand" ""))] 2641 "" 2642{ 2643 if (sparc_expand_move (TFmode, operands)) 2644 DONE; 2645}) 2646 2647(define_insn "*movtf_insn_sp32" 2648 [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o, r") 2649 (match_operand:TF 1 "input_operand" " G,oe,e,rG,roG"))] 2650 "TARGET_ARCH32 2651 && (register_operand (operands[0], TFmode) 2652 || register_or_zero_operand (operands[1], TFmode))" 2653 "#" 2654 [(set_attr "length" "4,4,4,4,4") 2655 (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")]) 2656 2657(define_insn "*movtf_insn_sp64" 2658 [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o, r") 2659 (match_operand:TF 1 "input_operand" "G,oe,e,rG,roG"))] 2660 "TARGET_ARCH64 2661 && !TARGET_HARD_QUAD 2662 && (register_operand (operands[0], TFmode) 2663 || register_or_zero_operand (operands[1], TFmode))" 2664 "#" 2665 [(set_attr "length" "2,2,2,2,2") 2666 (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")]) 2667 2668(define_insn "*movtf_insn_sp64_hq" 2669 [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m, o, r") 2670 (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))] 2671 "TARGET_ARCH64 2672 && TARGET_HARD_QUAD 2673 && (register_operand (operands[0], TFmode) 2674 || register_or_zero_operand (operands[1], TFmode))" 2675 "@ 2676 # 2677 fmovq\t%1, %0 2678 ldq\t%1, %0 2679 stq\t%1, %0 2680 # 2681 #" 2682 [(set_attr "type" "*,fpmove,fpload,fpstore,*,*") 2683 (set_attr "length" "2,*,*,*,2,2")]) 2684 2685;; Now all the splits to handle multi-insn TF mode moves. 2686(define_split 2687 [(set (match_operand:TF 0 "register_operand" "") 2688 (match_operand:TF 1 "register_operand" ""))] 2689 "reload_completed 2690 && (TARGET_ARCH32 2691 || (TARGET_FPU 2692 && !TARGET_HARD_QUAD) 2693 || (!fp_register_operand (operands[0], TFmode) 2694 && !fp_register_operand (operands[1], TFmode)))" 2695 [(clobber (const_int 0))] 2696{ 2697 rtx set_dest = operands[0]; 2698 rtx set_src = operands[1]; 2699 rtx dest1, dest2; 2700 rtx src1, src2; 2701 2702 dest1 = gen_df_reg (set_dest, 0); 2703 dest2 = gen_df_reg (set_dest, 1); 2704 src1 = gen_df_reg (set_src, 0); 2705 src2 = gen_df_reg (set_src, 1); 2706 2707 /* Now emit using the real source and destination we found, swapping 2708 the order if we detect overlap. */ 2709 if (reg_overlap_mentioned_p (dest1, src2)) 2710 { 2711 emit_insn (gen_movdf (dest2, src2)); 2712 emit_insn (gen_movdf (dest1, src1)); 2713 } 2714 else 2715 { 2716 emit_insn (gen_movdf (dest1, src1)); 2717 emit_insn (gen_movdf (dest2, src2)); 2718 } 2719 DONE; 2720}) 2721 2722(define_split 2723 [(set (match_operand:TF 0 "nonimmediate_operand" "") 2724 (match_operand:TF 1 "const_zero_operand" ""))] 2725 "reload_completed" 2726 [(clobber (const_int 0))] 2727{ 2728 rtx set_dest = operands[0]; 2729 rtx dest1, dest2; 2730 2731 switch (GET_CODE (set_dest)) 2732 { 2733 case REG: 2734 dest1 = gen_df_reg (set_dest, 0); 2735 dest2 = gen_df_reg (set_dest, 1); 2736 break; 2737 case MEM: 2738 dest1 = adjust_address (set_dest, DFmode, 0); 2739 dest2 = adjust_address (set_dest, DFmode, 8); 2740 break; 2741 default: 2742 gcc_unreachable (); 2743 } 2744 2745 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode))); 2746 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode))); 2747 DONE; 2748}) 2749 2750(define_split 2751 [(set (match_operand:TF 0 "register_operand" "") 2752 (match_operand:TF 1 "memory_operand" ""))] 2753 "(reload_completed 2754 && offsettable_memref_p (operands[1]) 2755 && (TARGET_ARCH32 2756 || !TARGET_HARD_QUAD 2757 || !fp_register_operand (operands[0], TFmode)))" 2758 [(clobber (const_int 0))] 2759{ 2760 rtx word0 = adjust_address (operands[1], DFmode, 0); 2761 rtx word1 = adjust_address (operands[1], DFmode, 8); 2762 rtx set_dest, dest1, dest2; 2763 2764 set_dest = operands[0]; 2765 2766 dest1 = gen_df_reg (set_dest, 0); 2767 dest2 = gen_df_reg (set_dest, 1); 2768 2769 /* Now output, ordering such that we don't clobber any registers 2770 mentioned in the address. */ 2771 if (reg_overlap_mentioned_p (dest1, word1)) 2772 2773 { 2774 emit_insn (gen_movdf (dest2, word1)); 2775 emit_insn (gen_movdf (dest1, word0)); 2776 } 2777 else 2778 { 2779 emit_insn (gen_movdf (dest1, word0)); 2780 emit_insn (gen_movdf (dest2, word1)); 2781 } 2782 DONE; 2783}) 2784 2785(define_split 2786 [(set (match_operand:TF 0 "memory_operand" "") 2787 (match_operand:TF 1 "register_operand" ""))] 2788 "(reload_completed 2789 && offsettable_memref_p (operands[0]) 2790 && (TARGET_ARCH32 2791 || !TARGET_HARD_QUAD 2792 || !fp_register_operand (operands[1], TFmode)))" 2793 [(clobber (const_int 0))] 2794{ 2795 rtx set_src = operands[1]; 2796 2797 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0), 2798 gen_df_reg (set_src, 0))); 2799 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8), 2800 gen_df_reg (set_src, 1))); 2801 DONE; 2802}) 2803 2804 2805;; SPARC-V9 conditional move instructions 2806 2807;; We can handle larger constants here for some flavors, but for now we keep 2808;; it simple and only allow those constants supported by all flavors. 2809;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand 2810;; 3 contains the constant if one is present, but we handle either for 2811;; generality (sparc.c puts a constant in operand 2). 2812;; 2813;; Our instruction patterns, on the other hand, canonicalize such that 2814;; operand 3 must be the set destination. 2815 2816(define_expand "mov<I:mode>cc" 2817 [(set (match_operand:I 0 "register_operand" "") 2818 (if_then_else:I (match_operand 1 "comparison_operator" "") 2819 (match_operand:I 2 "arith10_operand" "") 2820 (match_operand:I 3 "arith10_operand" "")))] 2821 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)" 2822{ 2823 if (!sparc_expand_conditional_move (<I:MODE>mode, operands)) 2824 FAIL; 2825 DONE; 2826}) 2827 2828(define_expand "mov<F:mode>cc" 2829 [(set (match_operand:F 0 "register_operand" "") 2830 (if_then_else:F (match_operand 1 "comparison_operator" "") 2831 (match_operand:F 2 "register_operand" "") 2832 (match_operand:F 3 "register_operand" "")))] 2833 "TARGET_V9 && TARGET_FPU" 2834{ 2835 if (!sparc_expand_conditional_move (<F:MODE>mode, operands)) 2836 FAIL; 2837 DONE; 2838}) 2839 2840(define_insn "*mov<I:mode>_cc_v9" 2841 [(set (match_operand:I 0 "register_operand" "=r") 2842 (if_then_else:I (match_operator 1 "icc_or_fcc_comparison_operator" 2843 [(match_operand 2 "icc_or_fcc_register_operand" "X") 2844 (const_int 0)]) 2845 (match_operand:I 3 "arith11_operand" "rL") 2846 (match_operand:I 4 "register_operand" "0")))] 2847 "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)" 2848 "mov%C1\t%x2, %3, %0" 2849 [(set_attr "type" "cmove")]) 2850 2851(define_insn "*mov<I:mode>_cc_reg_sp64" 2852 [(set (match_operand:I 0 "register_operand" "=r") 2853 (if_then_else:I (match_operator 1 "v9_register_comparison_operator" 2854 [(match_operand:DI 2 "register_operand" "r") 2855 (const_int 0)]) 2856 (match_operand:I 3 "arith10_operand" "rM") 2857 (match_operand:I 4 "register_operand" "0")))] 2858 "TARGET_ARCH64" 2859 "movr%D1\t%2, %r3, %0" 2860 [(set_attr "type" "cmove")]) 2861 2862(define_insn "*movsf_cc_v9" 2863 [(set (match_operand:SF 0 "register_operand" "=f") 2864 (if_then_else:SF (match_operator 1 "icc_or_fcc_comparison_operator" 2865 [(match_operand 2 "icc_or_fcc_register_operand" "X") 2866 (const_int 0)]) 2867 (match_operand:SF 3 "register_operand" "f") 2868 (match_operand:SF 4 "register_operand" "0")))] 2869 "TARGET_V9 && TARGET_FPU" 2870 "fmovs%C1\t%x2, %3, %0" 2871 [(set_attr "type" "fpcmove")]) 2872 2873(define_insn "*movsf_cc_reg_sp64" 2874 [(set (match_operand:SF 0 "register_operand" "=f") 2875 (if_then_else:SF (match_operator 1 "v9_register_comparison_operator" 2876 [(match_operand:DI 2 "register_operand" "r") 2877 (const_int 0)]) 2878 (match_operand:SF 3 "register_operand" "f") 2879 (match_operand:SF 4 "register_operand" "0")))] 2880 "TARGET_ARCH64 && TARGET_FPU" 2881 "fmovrs%D1\t%2, %3, %0" 2882 [(set_attr "type" "fpcrmove")]) 2883 2884;; Named because invoked by movtf_cc_v9 2885(define_insn "movdf_cc_v9" 2886 [(set (match_operand:DF 0 "register_operand" "=e") 2887 (if_then_else:DF (match_operator 1 "icc_or_fcc_comparison_operator" 2888 [(match_operand 2 "icc_or_fcc_register_operand" "X") 2889 (const_int 0)]) 2890 (match_operand:DF 3 "register_operand" "e") 2891 (match_operand:DF 4 "register_operand" "0")))] 2892 "TARGET_V9 && TARGET_FPU" 2893 "fmovd%C1\t%x2, %3, %0" 2894 [(set_attr "type" "fpcmove") 2895 (set_attr "fptype" "double")]) 2896 2897;; Named because invoked by movtf_cc_reg_sp64 2898(define_insn "movdf_cc_reg_sp64" 2899 [(set (match_operand:DF 0 "register_operand" "=e") 2900 (if_then_else:DF (match_operator 1 "v9_register_comparison_operator" 2901 [(match_operand:DI 2 "register_operand" "r") 2902 (const_int 0)]) 2903 (match_operand:DF 3 "register_operand" "e") 2904 (match_operand:DF 4 "register_operand" "0")))] 2905 "TARGET_ARCH64 && TARGET_FPU" 2906 "fmovrd%D1\t%2, %3, %0" 2907 [(set_attr "type" "fpcrmove") 2908 (set_attr "fptype" "double")]) 2909 2910(define_insn "*movtf_cc_hq_v9" 2911 [(set (match_operand:TF 0 "register_operand" "=e") 2912 (if_then_else:TF (match_operator 1 "icc_or_fcc_comparison_operator" 2913 [(match_operand 2 "icc_or_fcc_register_operand" "X") 2914 (const_int 0)]) 2915 (match_operand:TF 3 "register_operand" "e") 2916 (match_operand:TF 4 "register_operand" "0")))] 2917 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" 2918 "fmovq%C1\t%x2, %3, %0" 2919 [(set_attr "type" "fpcmove")]) 2920 2921(define_insn "*movtf_cc_reg_hq_sp64" 2922 [(set (match_operand:TF 0 "register_operand" "=e") 2923 (if_then_else:TF (match_operator 1 "v9_register_comparison_operator" 2924 [(match_operand:DI 2 "register_operand" "r") 2925 (const_int 0)]) 2926 (match_operand:TF 3 "register_operand" "e") 2927 (match_operand:TF 4 "register_operand" "0")))] 2928 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD" 2929 "fmovrq%D1\t%2, %3, %0" 2930 [(set_attr "type" "fpcrmove")]) 2931 2932(define_insn_and_split "*movtf_cc_v9" 2933 [(set (match_operand:TF 0 "register_operand" "=e") 2934 (if_then_else:TF (match_operator 1 "icc_or_fcc_comparison_operator" 2935 [(match_operand 2 "icc_or_fcc_register_operand" "X") 2936 (const_int 0)]) 2937 (match_operand:TF 3 "register_operand" "e") 2938 (match_operand:TF 4 "register_operand" "0")))] 2939 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD" 2940 "#" 2941 "&& reload_completed" 2942 [(clobber (const_int 0))] 2943{ 2944 rtx set_dest = operands[0]; 2945 rtx set_srca = operands[3]; 2946 rtx dest1, dest2; 2947 rtx srca1, srca2; 2948 2949 dest1 = gen_df_reg (set_dest, 0); 2950 dest2 = gen_df_reg (set_dest, 1); 2951 srca1 = gen_df_reg (set_srca, 0); 2952 srca2 = gen_df_reg (set_srca, 1); 2953 2954 if (reg_overlap_mentioned_p (dest1, srca2)) 2955 { 2956 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], 2957 srca2, dest2)); 2958 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], 2959 srca1, dest1)); 2960 } 2961 else 2962 { 2963 emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], 2964 srca1, dest1)); 2965 emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], 2966 srca2, dest2)); 2967 } 2968 DONE; 2969} 2970 [(set_attr "length" "2")]) 2971 2972(define_insn_and_split "*movtf_cc_reg_sp64" 2973 [(set (match_operand:TF 0 "register_operand" "=e") 2974 (if_then_else:TF (match_operator 1 "v9_register_comparison_operator" 2975 [(match_operand:DI 2 "register_operand" "r") 2976 (const_int 0)]) 2977 (match_operand:TF 3 "register_operand" "e") 2978 (match_operand:TF 4 "register_operand" "0")))] 2979 "TARGET_ARCH64 && TARGET_FPU && !TARGET_HARD_QUAD" 2980 "#" 2981 "&& reload_completed" 2982 [(clobber (const_int 0))] 2983{ 2984 rtx set_dest = operands[0]; 2985 rtx set_srca = operands[3]; 2986 rtx dest1, dest2; 2987 rtx srca1, srca2; 2988 2989 dest1 = gen_df_reg (set_dest, 0); 2990 dest2 = gen_df_reg (set_dest, 1); 2991 srca1 = gen_df_reg (set_srca, 0); 2992 srca2 = gen_df_reg (set_srca, 1); 2993 2994 if (reg_overlap_mentioned_p (dest1, srca2)) 2995 { 2996 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], 2997 srca2, dest2)); 2998 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], 2999 srca1, dest1)); 3000 } 3001 else 3002 { 3003 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], 3004 srca1, dest1)); 3005 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], 3006 srca2, dest2)); 3007 } 3008 DONE; 3009} 3010 [(set_attr "length" "2")]) 3011 3012 3013;; Zero-extension instructions 3014 3015;; These patterns originally accepted general_operands, however, slightly 3016;; better code is generated by only accepting register_operands, and then 3017;; letting combine generate the ldu[hb] insns. 3018 3019(define_expand "zero_extendhisi2" 3020 [(set (match_operand:SI 0 "register_operand" "") 3021 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))] 3022 "" 3023{ 3024 rtx temp = gen_reg_rtx (SImode); 3025 rtx shift_16 = GEN_INT (16); 3026 int op1_subbyte = 0; 3027 3028 if (GET_CODE (operand1) == SUBREG) 3029 { 3030 op1_subbyte = SUBREG_BYTE (operand1); 3031 op1_subbyte /= GET_MODE_SIZE (SImode); 3032 op1_subbyte *= GET_MODE_SIZE (SImode); 3033 operand1 = XEXP (operand1, 0); 3034 } 3035 3036 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte), 3037 shift_16)); 3038 emit_insn (gen_lshrsi3 (operand0, temp, shift_16)); 3039 DONE; 3040}) 3041 3042(define_insn "*zero_extendhisi2_insn" 3043 [(set (match_operand:SI 0 "register_operand" "=r") 3044 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))] 3045 "" 3046 "lduh\t%1, %0" 3047 [(set_attr "type" "load") 3048 (set_attr "subtype" "regular") 3049 (set_attr "us3load_type" "3cycle")]) 3050 3051(define_expand "zero_extendqihi2" 3052 [(set (match_operand:HI 0 "register_operand" "") 3053 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))] 3054 "" 3055 "") 3056 3057(define_insn "*zero_extendqihi2_insn" 3058 [(set (match_operand:HI 0 "register_operand" "=r,r") 3059 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))] 3060 "GET_CODE (operands[1]) != CONST_INT" 3061 "@ 3062 and\t%1, 0xff, %0 3063 ldub\t%1, %0" 3064 [(set_attr "type" "*,load") 3065 (set_attr "subtype" "*,regular") 3066 (set_attr "us3load_type" "*,3cycle")]) 3067 3068(define_expand "zero_extendqisi2" 3069 [(set (match_operand:SI 0 "register_operand" "") 3070 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))] 3071 "" 3072 "") 3073 3074(define_insn "*zero_extendqisi2_insn" 3075 [(set (match_operand:SI 0 "register_operand" "=r,r") 3076 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))] 3077 "GET_CODE (operands[1]) != CONST_INT" 3078 "@ 3079 and\t%1, 0xff, %0 3080 ldub\t%1, %0" 3081 [(set_attr "type" "*,load") 3082 (set_attr "subtype" "*,regular") 3083 (set_attr "us3load_type" "*,3cycle")]) 3084 3085(define_expand "zero_extendqidi2" 3086 [(set (match_operand:DI 0 "register_operand" "") 3087 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))] 3088 "TARGET_ARCH64" 3089 "") 3090 3091(define_insn "*zero_extendqidi2_insn" 3092 [(set (match_operand:DI 0 "register_operand" "=r,r") 3093 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))] 3094 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT" 3095 "@ 3096 and\t%1, 0xff, %0 3097 ldub\t%1, %0" 3098 [(set_attr "type" "*,load") 3099 (set_attr "subtype" "*,regular") 3100 (set_attr "us3load_type" "*,3cycle")]) 3101 3102(define_expand "zero_extendhidi2" 3103 [(set (match_operand:DI 0 "register_operand" "") 3104 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))] 3105 "TARGET_ARCH64" 3106{ 3107 rtx temp = gen_reg_rtx (DImode); 3108 rtx shift_48 = GEN_INT (48); 3109 int op1_subbyte = 0; 3110 3111 if (GET_CODE (operand1) == SUBREG) 3112 { 3113 op1_subbyte = SUBREG_BYTE (operand1); 3114 op1_subbyte /= GET_MODE_SIZE (DImode); 3115 op1_subbyte *= GET_MODE_SIZE (DImode); 3116 operand1 = XEXP (operand1, 0); 3117 } 3118 3119 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte), 3120 shift_48)); 3121 emit_insn (gen_lshrdi3 (operand0, temp, shift_48)); 3122 DONE; 3123}) 3124 3125(define_insn "*zero_extendhidi2_insn" 3126 [(set (match_operand:DI 0 "register_operand" "=r") 3127 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))] 3128 "TARGET_ARCH64" 3129 "lduh\t%1, %0" 3130 [(set_attr "type" "load") 3131 (set_attr "subtype" "regular") 3132 (set_attr "us3load_type" "3cycle")]) 3133 3134;; ??? Write truncdisi pattern using sra? 3135 3136(define_expand "zero_extendsidi2" 3137 [(set (match_operand:DI 0 "register_operand" "") 3138 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))] 3139 "" 3140 "") 3141 3142(define_insn "*zero_extendsidi2_insn_sp64" 3143 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 3144 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))] 3145 "TARGET_ARCH64 3146 && GET_CODE (operands[1]) != CONST_INT" 3147 "@ 3148 srl\t%1, 0, %0 3149 lduw\t%1, %0 3150 movstouw\t%1, %0" 3151 [(set_attr "type" "shift,load,vismv") 3152 (set_attr "subtype" "*,regular,movstouw") 3153 (set_attr "cpu_feature" "*,*,vis3")]) 3154 3155(define_insn_and_split "*zero_extendsidi2_insn_sp32" 3156 [(set (match_operand:DI 0 "register_operand" "=r") 3157 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))] 3158 "TARGET_ARCH32" 3159 "#" 3160 "&& reload_completed" 3161 [(set (match_dup 2) (match_dup 1)) 3162 (set (match_dup 3) (const_int 0))] 3163 "operands[2] = gen_lowpart (SImode, operands[0]); 3164 operands[3] = gen_highpart (SImode, operands[0]);" 3165 [(set_attr "length" "2")]) 3166 3167;; Simplify comparisons of extended values. 3168 3169(define_insn "*cmp_zero_extendqisi2" 3170 [(set (reg:CC CC_REG) 3171 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r")) 3172 (const_int 0)))] 3173 "" 3174 "andcc\t%0, 0xff, %%g0" 3175 [(set_attr "type" "compare")]) 3176 3177(define_insn "*cmp_zero_qi" 3178 [(set (reg:CC CC_REG) 3179 (compare:CC (match_operand:QI 0 "register_operand" "r") 3180 (const_int 0)))] 3181 "" 3182 "andcc\t%0, 0xff, %%g0" 3183 [(set_attr "type" "compare")]) 3184 3185(define_insn "*cmp_zero_extendqisi2_set" 3186 [(set (reg:CC CC_REG) 3187 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) 3188 (const_int 0))) 3189 (set (match_operand:SI 0 "register_operand" "=r") 3190 (zero_extend:SI (match_dup 1)))] 3191 "" 3192 "andcc\t%1, 0xff, %0" 3193 [(set_attr "type" "compare")]) 3194 3195(define_insn "*cmp_zero_extendqisi2_andcc_set" 3196 [(set (reg:CC CC_REG) 3197 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r") 3198 (const_int 255)) 3199 (const_int 0))) 3200 (set (match_operand:SI 0 "register_operand" "=r") 3201 (zero_extend:SI (subreg:QI (match_dup 1) 0)))] 3202 "" 3203 "andcc\t%1, 0xff, %0" 3204 [(set_attr "type" "compare")]) 3205 3206(define_insn "*cmp_zero_extendqidi2" 3207 [(set (reg:CCX CC_REG) 3208 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r")) 3209 (const_int 0)))] 3210 "TARGET_ARCH64" 3211 "andcc\t%0, 0xff, %%g0" 3212 [(set_attr "type" "compare")]) 3213 3214(define_insn "*cmp_zero_qi_sp64" 3215 [(set (reg:CCX CC_REG) 3216 (compare:CCX (match_operand:QI 0 "register_operand" "r") 3217 (const_int 0)))] 3218 "TARGET_ARCH64" 3219 "andcc\t%0, 0xff, %%g0" 3220 [(set_attr "type" "compare")]) 3221 3222(define_insn "*cmp_zero_extendqidi2_set" 3223 [(set (reg:CCX CC_REG) 3224 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r")) 3225 (const_int 0))) 3226 (set (match_operand:DI 0 "register_operand" "=r") 3227 (zero_extend:DI (match_dup 1)))] 3228 "TARGET_ARCH64" 3229 "andcc\t%1, 0xff, %0" 3230 [(set_attr "type" "compare")]) 3231 3232(define_insn "*cmp_zero_extendqidi2_andcc_set" 3233 [(set (reg:CCX CC_REG) 3234 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r") 3235 (const_int 255)) 3236 (const_int 0))) 3237 (set (match_operand:DI 0 "register_operand" "=r") 3238 (zero_extend:DI (subreg:QI (match_dup 1) 0)))] 3239 "TARGET_ARCH64" 3240 "andcc\t%1, 0xff, %0" 3241 [(set_attr "type" "compare")]) 3242 3243;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare. 3244 3245(define_insn "*cmp_siqi_trunc" 3246 [(set (reg:CC CC_REG) 3247 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3) 3248 (const_int 0)))] 3249 "" 3250 "andcc\t%0, 0xff, %%g0" 3251 [(set_attr "type" "compare")]) 3252 3253(define_insn "*cmp_siqi_trunc_set" 3254 [(set (reg:CC CC_REG) 3255 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3) 3256 (const_int 0))) 3257 (set (match_operand:QI 0 "register_operand" "=r") 3258 (subreg:QI (match_dup 1) 3))] 3259 "" 3260 "andcc\t%1, 0xff, %0" 3261 [(set_attr "type" "compare")]) 3262 3263(define_insn "*cmp_diqi_trunc" 3264 [(set (reg:CC CC_REG) 3265 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7) 3266 (const_int 0)))] 3267 "TARGET_ARCH64" 3268 "andcc\t%0, 0xff, %%g0" 3269 [(set_attr "type" "compare")]) 3270 3271(define_insn "*cmp_diqi_trunc_set" 3272 [(set (reg:CC CC_REG) 3273 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7) 3274 (const_int 0))) 3275 (set (match_operand:QI 0 "register_operand" "=r") 3276 (subreg:QI (match_dup 1) 7))] 3277 "TARGET_ARCH64" 3278 "andcc\t%1, 0xff, %0" 3279 [(set_attr "type" "compare")]) 3280 3281 3282;; Sign-extension instructions 3283 3284;; These patterns originally accepted general_operands, however, slightly 3285;; better code is generated by only accepting register_operands, and then 3286;; letting combine generate the lds[hb] insns. 3287 3288(define_expand "extendhisi2" 3289 [(set (match_operand:SI 0 "register_operand" "") 3290 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] 3291 "" 3292{ 3293 rtx temp = gen_reg_rtx (SImode); 3294 rtx shift_16 = GEN_INT (16); 3295 int op1_subbyte = 0; 3296 3297 if (GET_CODE (operand1) == SUBREG) 3298 { 3299 op1_subbyte = SUBREG_BYTE (operand1); 3300 op1_subbyte /= GET_MODE_SIZE (SImode); 3301 op1_subbyte *= GET_MODE_SIZE (SImode); 3302 operand1 = XEXP (operand1, 0); 3303 } 3304 3305 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte), 3306 shift_16)); 3307 emit_insn (gen_ashrsi3 (operand0, temp, shift_16)); 3308 DONE; 3309}) 3310 3311(define_insn "*sign_extendhisi2_insn" 3312 [(set (match_operand:SI 0 "register_operand" "=r") 3313 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))] 3314 "" 3315 "ldsh\t%1, %0" 3316 [(set_attr "type" "sload") 3317 (set_attr "us3load_type" "3cycle")]) 3318 3319(define_expand "extendqihi2" 3320 [(set (match_operand:HI 0 "register_operand" "") 3321 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))] 3322 "" 3323{ 3324 rtx temp = gen_reg_rtx (SImode); 3325 rtx shift_24 = GEN_INT (24); 3326 int op1_subbyte = 0; 3327 int op0_subbyte = 0; 3328 3329 if (GET_CODE (operand1) == SUBREG) 3330 { 3331 op1_subbyte = SUBREG_BYTE (operand1); 3332 op1_subbyte /= GET_MODE_SIZE (SImode); 3333 op1_subbyte *= GET_MODE_SIZE (SImode); 3334 operand1 = XEXP (operand1, 0); 3335 } 3336 if (GET_CODE (operand0) == SUBREG) 3337 { 3338 op0_subbyte = SUBREG_BYTE (operand0); 3339 op0_subbyte /= GET_MODE_SIZE (SImode); 3340 op0_subbyte *= GET_MODE_SIZE (SImode); 3341 operand0 = XEXP (operand0, 0); 3342 } 3343 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte), 3344 shift_24)); 3345 if (GET_MODE (operand0) != SImode) 3346 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte); 3347 emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); 3348 DONE; 3349}) 3350 3351(define_insn "*sign_extendqihi2_insn" 3352 [(set (match_operand:HI 0 "register_operand" "=r") 3353 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))] 3354 "" 3355 "ldsb\t%1, %0" 3356 [(set_attr "type" "sload") 3357 (set_attr "us3load_type" "3cycle")]) 3358 3359(define_expand "extendqisi2" 3360 [(set (match_operand:SI 0 "register_operand" "") 3361 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))] 3362 "" 3363{ 3364 rtx temp = gen_reg_rtx (SImode); 3365 rtx shift_24 = GEN_INT (24); 3366 int op1_subbyte = 0; 3367 3368 if (GET_CODE (operand1) == SUBREG) 3369 { 3370 op1_subbyte = SUBREG_BYTE (operand1); 3371 op1_subbyte /= GET_MODE_SIZE (SImode); 3372 op1_subbyte *= GET_MODE_SIZE (SImode); 3373 operand1 = XEXP (operand1, 0); 3374 } 3375 3376 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte), 3377 shift_24)); 3378 emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); 3379 DONE; 3380}) 3381 3382(define_insn "*sign_extendqisi2_insn" 3383 [(set (match_operand:SI 0 "register_operand" "=r") 3384 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))] 3385 "" 3386 "ldsb\t%1, %0" 3387 [(set_attr "type" "sload") 3388 (set_attr "us3load_type" "3cycle")]) 3389 3390(define_expand "extendqidi2" 3391 [(set (match_operand:DI 0 "register_operand" "") 3392 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))] 3393 "TARGET_ARCH64" 3394{ 3395 rtx temp = gen_reg_rtx (DImode); 3396 rtx shift_56 = GEN_INT (56); 3397 int op1_subbyte = 0; 3398 3399 if (GET_CODE (operand1) == SUBREG) 3400 { 3401 op1_subbyte = SUBREG_BYTE (operand1); 3402 op1_subbyte /= GET_MODE_SIZE (DImode); 3403 op1_subbyte *= GET_MODE_SIZE (DImode); 3404 operand1 = XEXP (operand1, 0); 3405 } 3406 3407 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte), 3408 shift_56)); 3409 emit_insn (gen_ashrdi3 (operand0, temp, shift_56)); 3410 DONE; 3411}) 3412 3413(define_insn "*sign_extendqidi2_insn" 3414 [(set (match_operand:DI 0 "register_operand" "=r") 3415 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))] 3416 "TARGET_ARCH64" 3417 "ldsb\t%1, %0" 3418 [(set_attr "type" "sload") 3419 (set_attr "us3load_type" "3cycle")]) 3420 3421(define_expand "extendhidi2" 3422 [(set (match_operand:DI 0 "register_operand" "") 3423 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))] 3424 "TARGET_ARCH64" 3425{ 3426 rtx temp = gen_reg_rtx (DImode); 3427 rtx shift_48 = GEN_INT (48); 3428 int op1_subbyte = 0; 3429 3430 if (GET_CODE (operand1) == SUBREG) 3431 { 3432 op1_subbyte = SUBREG_BYTE (operand1); 3433 op1_subbyte /= GET_MODE_SIZE (DImode); 3434 op1_subbyte *= GET_MODE_SIZE (DImode); 3435 operand1 = XEXP (operand1, 0); 3436 } 3437 3438 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte), 3439 shift_48)); 3440 emit_insn (gen_ashrdi3 (operand0, temp, shift_48)); 3441 DONE; 3442}) 3443 3444(define_insn "*sign_extendhidi2_insn" 3445 [(set (match_operand:DI 0 "register_operand" "=r") 3446 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))] 3447 "TARGET_ARCH64" 3448 "ldsh\t%1, %0" 3449 [(set_attr "type" "sload") 3450 (set_attr "us3load_type" "3cycle")]) 3451 3452(define_expand "extendsidi2" 3453 [(set (match_operand:DI 0 "register_operand" "") 3454 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))] 3455 "TARGET_ARCH64" 3456 "") 3457 3458(define_insn "*sign_extendsidi2_insn" 3459 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 3460 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))] 3461 "TARGET_ARCH64" 3462 "@ 3463 sra\t%1, 0, %0 3464 ldsw\t%1, %0 3465 movstosw\t%1, %0" 3466 [(set_attr "type" "shift,sload,vismv") 3467 (set_attr "us3load_type" "*,3cycle,*") 3468 (set_attr "cpu_feature" "*,*,vis3")]) 3469 3470 3471;; Special pattern for optimizing bit-field compares. This is needed 3472;; because combine uses this as a canonical form. 3473 3474(define_insn "*cmp_zero_extract" 3475 [(set (reg:CC CC_REG) 3476 (compare:CC 3477 (zero_extract:SI (match_operand:SI 0 "register_operand" "r") 3478 (match_operand:SI 1 "small_int_operand" "I") 3479 (match_operand:SI 2 "small_int_operand" "I")) 3480 (const_int 0)))] 3481 "INTVAL (operands[2]) > 19" 3482{ 3483 int len = INTVAL (operands[1]); 3484 int pos = 32 - INTVAL (operands[2]) - len; 3485 HOST_WIDE_INT mask = ((1 << len) - 1) << pos; 3486 operands[1] = GEN_INT (mask); 3487 return "andcc\t%0, %1, %%g0"; 3488} 3489 [(set_attr "type" "compare")]) 3490 3491(define_insn "*cmp_zero_extract_sp64" 3492 [(set (reg:CCX CC_REG) 3493 (compare:CCX 3494 (zero_extract:DI (match_operand:DI 0 "register_operand" "r") 3495 (match_operand:SI 1 "small_int_operand" "I") 3496 (match_operand:SI 2 "small_int_operand" "I")) 3497 (const_int 0)))] 3498 "TARGET_ARCH64 && INTVAL (operands[2]) > 51" 3499{ 3500 int len = INTVAL (operands[1]); 3501 int pos = 64 - INTVAL (operands[2]) - len; 3502 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos; 3503 operands[1] = GEN_INT (mask); 3504 return "andcc\t%0, %1, %%g0"; 3505} 3506 [(set_attr "type" "compare")]) 3507 3508 3509;; Conversions between float, double and long double. 3510 3511(define_insn "extendsfdf2" 3512 [(set (match_operand:DF 0 "register_operand" "=e") 3513 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))] 3514 "TARGET_FPU" 3515 "fstod\t%1, %0" 3516 [(set_attr "type" "fp") 3517 (set_attr "fptype" "double")]) 3518 3519(define_expand "extendsftf2" 3520 [(set (match_operand:TF 0 "nonimmediate_operand" "") 3521 (float_extend:TF (match_operand:SF 1 "register_operand" "")))] 3522 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" 3523 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;") 3524 3525(define_insn "*extendsftf2_hq" 3526 [(set (match_operand:TF 0 "register_operand" "=e") 3527 (float_extend:TF (match_operand:SF 1 "register_operand" "f")))] 3528 "TARGET_FPU && TARGET_HARD_QUAD" 3529 "fstoq\t%1, %0" 3530 [(set_attr "type" "fp")]) 3531 3532(define_expand "extenddftf2" 3533 [(set (match_operand:TF 0 "nonimmediate_operand" "") 3534 (float_extend:TF (match_operand:DF 1 "register_operand" "")))] 3535 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" 3536 "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;") 3537 3538(define_insn "*extenddftf2_hq" 3539 [(set (match_operand:TF 0 "register_operand" "=e") 3540 (float_extend:TF (match_operand:DF 1 "register_operand" "e")))] 3541 "TARGET_FPU && TARGET_HARD_QUAD" 3542 "fdtoq\t%1, %0" 3543 [(set_attr "type" "fp")]) 3544 3545(define_insn "truncdfsf2" 3546 [(set (match_operand:SF 0 "register_operand" "=f") 3547 (float_truncate:SF (match_operand:DF 1 "register_operand" "e")))] 3548 "TARGET_FPU" 3549 "fdtos\t%1, %0" 3550 [(set_attr "type" "fp") 3551 (set_attr "fptype" "double") 3552 (set_attr "fptype_ut699" "single")]) 3553 3554(define_expand "trunctfsf2" 3555 [(set (match_operand:SF 0 "register_operand" "") 3556 (float_truncate:SF (match_operand:TF 1 "general_operand" "")))] 3557 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" 3558 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;") 3559 3560(define_insn "*trunctfsf2_hq" 3561 [(set (match_operand:SF 0 "register_operand" "=f") 3562 (float_truncate:SF (match_operand:TF 1 "register_operand" "e")))] 3563 "TARGET_FPU && TARGET_HARD_QUAD" 3564 "fqtos\t%1, %0" 3565 [(set_attr "type" "fp")]) 3566 3567(define_expand "trunctfdf2" 3568 [(set (match_operand:DF 0 "register_operand" "") 3569 (float_truncate:DF (match_operand:TF 1 "general_operand" "")))] 3570 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" 3571 "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;") 3572 3573(define_insn "*trunctfdf2_hq" 3574 [(set (match_operand:DF 0 "register_operand" "=e") 3575 (float_truncate:DF (match_operand:TF 1 "register_operand" "e")))] 3576 "TARGET_FPU && TARGET_HARD_QUAD" 3577 "fqtod\t%1, %0" 3578 [(set_attr "type" "fp")]) 3579 3580 3581;; Conversion between fixed point and floating point. 3582 3583(define_insn "floatsisf2" 3584 [(set (match_operand:SF 0 "register_operand" "=f") 3585 (float:SF (match_operand:SI 1 "register_operand" "f")))] 3586 "TARGET_FPU" 3587 "fitos\t%1, %0" 3588 [(set_attr "type" "fp") 3589 (set_attr "fptype" "single")]) 3590 3591(define_insn "floatsidf2" 3592 [(set (match_operand:DF 0 "register_operand" "=e") 3593 (float:DF (match_operand:SI 1 "register_operand" "f")))] 3594 "TARGET_FPU" 3595 "fitod\t%1, %0" 3596 [(set_attr "type" "fp") 3597 (set_attr "fptype" "double")]) 3598 3599(define_expand "floatsitf2" 3600 [(set (match_operand:TF 0 "nonimmediate_operand" "") 3601 (float:TF (match_operand:SI 1 "register_operand" "")))] 3602 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" 3603 "emit_tfmode_cvt (FLOAT, operands); DONE;") 3604 3605(define_insn "*floatsitf2_hq" 3606 [(set (match_operand:TF 0 "register_operand" "=e") 3607 (float:TF (match_operand:SI 1 "register_operand" "f")))] 3608 "TARGET_FPU && TARGET_HARD_QUAD" 3609 "fitoq\t%1, %0" 3610 [(set_attr "type" "fp")]) 3611 3612(define_expand "floatunssitf2" 3613 [(set (match_operand:TF 0 "nonimmediate_operand" "") 3614 (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))] 3615 "TARGET_FPU && TARGET_ARCH64 && !TARGET_HARD_QUAD" 3616 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;") 3617 3618;; Now the same for 64 bit sources. 3619 3620(define_insn "floatdisf2" 3621 [(set (match_operand:SF 0 "register_operand" "=f") 3622 (float:SF (match_operand:DI 1 "register_operand" "e")))] 3623 "TARGET_V9 && TARGET_FPU" 3624 "fxtos\t%1, %0" 3625 [(set_attr "type" "fp") 3626 (set_attr "fptype" "double")]) 3627 3628(define_expand "floatunsdisf2" 3629 [(use (match_operand:SF 0 "register_operand" "")) 3630 (use (match_operand:DI 1 "general_operand" ""))] 3631 "TARGET_ARCH64 && TARGET_FPU" 3632 "sparc_emit_floatunsdi (operands, SFmode); DONE;") 3633 3634(define_insn "floatdidf2" 3635 [(set (match_operand:DF 0 "register_operand" "=e") 3636 (float:DF (match_operand:DI 1 "register_operand" "e")))] 3637 "TARGET_V9 && TARGET_FPU" 3638 "fxtod\t%1, %0" 3639 [(set_attr "type" "fp") 3640 (set_attr "fptype" "double")]) 3641 3642(define_expand "floatunsdidf2" 3643 [(use (match_operand:DF 0 "register_operand" "")) 3644 (use (match_operand:DI 1 "general_operand" ""))] 3645 "TARGET_ARCH64 && TARGET_FPU" 3646 "sparc_emit_floatunsdi (operands, DFmode); DONE;") 3647 3648(define_expand "floatditf2" 3649 [(set (match_operand:TF 0 "nonimmediate_operand" "") 3650 (float:TF (match_operand:DI 1 "register_operand" "")))] 3651 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)" 3652 "emit_tfmode_cvt (FLOAT, operands); DONE;") 3653 3654(define_insn "*floatditf2_hq" 3655 [(set (match_operand:TF 0 "register_operand" "=e") 3656 (float:TF (match_operand:DI 1 "register_operand" "e")))] 3657 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" 3658 "fxtoq\t%1, %0" 3659 [(set_attr "type" "fp")]) 3660 3661(define_expand "floatunsditf2" 3662 [(set (match_operand:TF 0 "nonimmediate_operand" "") 3663 (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))] 3664 "TARGET_FPU && TARGET_ARCH64 && !TARGET_HARD_QUAD" 3665 "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;") 3666 3667;; Convert a float to an actual integer. 3668;; Truncation is performed as part of the conversion. 3669 3670(define_insn "fix_truncsfsi2" 3671 [(set (match_operand:SI 0 "register_operand" "=f") 3672 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] 3673 "TARGET_FPU" 3674 "fstoi\t%1, %0" 3675 [(set_attr "type" "fp") 3676 (set_attr "fptype" "single")]) 3677 3678(define_insn "fix_truncdfsi2" 3679 [(set (match_operand:SI 0 "register_operand" "=f") 3680 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))] 3681 "TARGET_FPU" 3682 "fdtoi\t%1, %0" 3683 [(set_attr "type" "fp") 3684 (set_attr "fptype" "double") 3685 (set_attr "fptype_ut699" "single")]) 3686 3687(define_expand "fix_trunctfsi2" 3688 [(set (match_operand:SI 0 "register_operand" "") 3689 (fix:SI (match_operand:TF 1 "general_operand" "")))] 3690 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" 3691 "emit_tfmode_cvt (FIX, operands); DONE;") 3692 3693(define_insn "*fix_trunctfsi2_hq" 3694 [(set (match_operand:SI 0 "register_operand" "=f") 3695 (fix:SI (match_operand:TF 1 "register_operand" "e")))] 3696 "TARGET_FPU && TARGET_HARD_QUAD" 3697 "fqtoi\t%1, %0" 3698 [(set_attr "type" "fp")]) 3699 3700(define_expand "fixuns_trunctfsi2" 3701 [(set (match_operand:SI 0 "register_operand" "") 3702 (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))] 3703 "TARGET_FPU && TARGET_ARCH64 && !TARGET_HARD_QUAD" 3704 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;") 3705 3706;; Now the same, for V9 targets 3707 3708(define_insn "fix_truncsfdi2" 3709 [(set (match_operand:DI 0 "register_operand" "=e") 3710 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] 3711 "TARGET_V9 && TARGET_FPU" 3712 "fstox\t%1, %0" 3713 [(set_attr "type" "fp") 3714 (set_attr "fptype" "double")]) 3715 3716(define_expand "fixuns_truncsfdi2" 3717 [(use (match_operand:DI 0 "register_operand" "")) 3718 (use (match_operand:SF 1 "general_operand" ""))] 3719 "TARGET_ARCH64 && TARGET_FPU" 3720 "sparc_emit_fixunsdi (operands, SFmode); DONE;") 3721 3722(define_insn "fix_truncdfdi2" 3723 [(set (match_operand:DI 0 "register_operand" "=e") 3724 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))] 3725 "TARGET_V9 && TARGET_FPU" 3726 "fdtox\t%1, %0" 3727 [(set_attr "type" "fp") 3728 (set_attr "fptype" "double")]) 3729 3730(define_expand "fixuns_truncdfdi2" 3731 [(use (match_operand:DI 0 "register_operand" "")) 3732 (use (match_operand:DF 1 "general_operand" ""))] 3733 "TARGET_ARCH64 && TARGET_FPU" 3734 "sparc_emit_fixunsdi (operands, DFmode); DONE;") 3735 3736(define_expand "fix_trunctfdi2" 3737 [(set (match_operand:DI 0 "register_operand" "") 3738 (fix:DI (match_operand:TF 1 "general_operand" "")))] 3739 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" 3740 "emit_tfmode_cvt (FIX, operands); DONE;") 3741 3742(define_insn "*fix_trunctfdi2_hq" 3743 [(set (match_operand:DI 0 "register_operand" "=e") 3744 (fix:DI (match_operand:TF 1 "register_operand" "e")))] 3745 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" 3746 "fqtox\t%1, %0" 3747 [(set_attr "type" "fp")]) 3748 3749(define_expand "fixuns_trunctfdi2" 3750 [(set (match_operand:DI 0 "register_operand" "") 3751 (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))] 3752 "TARGET_FPU && TARGET_ARCH64 && !TARGET_HARD_QUAD" 3753 "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;") 3754 3755 3756;; Integer addition/subtraction instructions. 3757 3758(define_expand "adddi3" 3759 [(set (match_operand:DI 0 "register_operand" "") 3760 (plus:DI (match_operand:DI 1 "register_operand" "") 3761 (match_operand:DI 2 "arith_double_add_operand" "")))] 3762 "" 3763{ 3764 if (TARGET_ARCH32) 3765 { 3766 emit_insn (gen_adddi3_sp32 (operands[0], operands[1], operands[2])); 3767 DONE; 3768 } 3769}) 3770 3771(define_expand "uaddvdi4" 3772 [(parallel [(set (reg:CCXC CC_REG) 3773 (compare:CCXC (plus:DI (match_operand:DI 1 "register_operand") 3774 (match_operand:DI 2 "arith_add_operand")) 3775 (match_dup 1))) 3776 (set (match_operand:DI 0 "register_operand") 3777 (plus:DI (match_dup 1) (match_dup 2)))]) 3778 (set (pc) (if_then_else (ltu (reg:CCXC CC_REG) (const_int 0)) 3779 (label_ref (match_operand 3)) 3780 (pc)))] 3781 "" 3782{ 3783 if (TARGET_ARCH32) 3784 { 3785 emit_insn (gen_uaddvdi4_sp32 (operands[0], operands[1], operands[2])); 3786 rtx x = gen_rtx_LTU (VOIDmode, gen_rtx_REG (CCCmode, SPARC_ICC_REG), 3787 const0_rtx); 3788 emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[3])); 3789 DONE; 3790 } 3791}) 3792 3793(define_expand "addvdi4" 3794 [(parallel [(set (reg:CCXV CC_REG) 3795 (compare:CCXV (plus:DI (match_operand:DI 1 "register_operand") 3796 (match_operand:DI 2 "arith_add_operand")) 3797 (unspec:DI [(match_dup 1) (match_dup 2)] 3798 UNSPEC_ADDV))) 3799 (set (match_operand:DI 0 "register_operand") 3800 (plus:DI (match_dup 1) (match_dup 2)))]) 3801 (set (pc) (if_then_else (ne (reg:CCXV CC_REG) (const_int 0)) 3802 (label_ref (match_operand 3)) 3803 (pc)))] 3804 "" 3805{ 3806 if (TARGET_ARCH32) 3807 { 3808 emit_insn (gen_addvdi4_sp32 (operands[0], operands[1], operands[2])); 3809 rtx x = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCVmode, SPARC_ICC_REG), 3810 const0_rtx); 3811 emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[3])); 3812 DONE; 3813 } 3814}) 3815 3816(define_insn_and_split "adddi3_sp32" 3817 [(set (match_operand:DI 0 "register_operand" "=&r") 3818 (plus:DI (match_operand:DI 1 "register_operand" "%r") 3819 (match_operand:DI 2 "arith_double_operand" "rHI"))) 3820 (clobber (reg:CC CC_REG))] 3821 "TARGET_ARCH32" 3822 "#" 3823 "&& reload_completed" 3824 [(parallel [(set (reg:CCC CC_REG) 3825 (compare:CCC (plus:SI (match_dup 4) (match_dup 5)) 3826 (match_dup 4))) 3827 (set (match_dup 3) 3828 (plus:SI (match_dup 4) (match_dup 5)))]) 3829 (set (match_dup 6) 3830 (plus:SI (plus:SI (match_dup 7) (match_dup 8)) 3831 (ltu:SI (reg:CCC CC_REG) (const_int 0))))] 3832{ 3833 operands[3] = gen_lowpart (SImode, operands[0]); 3834 operands[4] = gen_lowpart (SImode, operands[1]); 3835 operands[5] = gen_lowpart (SImode, operands[2]); 3836 operands[6] = gen_highpart (SImode, operands[0]); 3837 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]); 3838 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]); 3839} 3840 [(set_attr "length" "2")]) 3841 3842(define_insn_and_split "uaddvdi4_sp32" 3843 [(set (reg:CCC CC_REG) 3844 (compare:CCC (plus:DI (match_operand:DI 1 "register_operand" "%r") 3845 (match_operand:DI 2 "arith_double_operand" "rHI")) 3846 (match_dup 1))) 3847 (set (match_operand:DI 0 "register_operand" "=&r") 3848 (plus:DI (match_dup 1) (match_dup 2)))] 3849 "TARGET_ARCH32" 3850 "#" 3851 "&& reload_completed" 3852 [(parallel [(set (reg:CCC CC_REG) 3853 (compare:CCC (plus:SI (match_dup 4) (match_dup 5)) 3854 (match_dup 4))) 3855 (set (match_dup 3) 3856 (plus:SI (match_dup 4) (match_dup 5)))]) 3857 (parallel [(set (reg:CCC CC_REG) 3858 (compare:CCC (zero_extend:DI 3859 (plus:SI (plus:SI (match_dup 7) (match_dup 8)) 3860 (ltu:SI (reg:CCC CC_REG) 3861 (const_int 0)))) 3862 (plus:DI (plus:DI (zero_extend:DI (match_dup 7)) 3863 (zero_extend:DI (match_dup 8))) 3864 (ltu:DI (reg:CCC CC_REG) 3865 (const_int 0))))) 3866 (set (match_dup 6) 3867 (plus:SI (plus:SI (match_dup 7) (match_dup 8)) 3868 (ltu:SI (reg:CCC CC_REG) 3869 (const_int 0))))])] 3870{ 3871 operands[3] = gen_lowpart (SImode, operands[0]); 3872 operands[4] = gen_lowpart (SImode, operands[1]); 3873 operands[5] = gen_lowpart (SImode, operands[2]); 3874 operands[6] = gen_highpart (SImode, operands[0]); 3875 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]); 3876 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]); 3877} 3878 [(set_attr "length" "2")]) 3879 3880(define_insn_and_split "addvdi4_sp32" 3881 [(set (reg:CCV CC_REG) 3882 (compare:CCV (plus:DI (match_operand:DI 1 "register_operand" "%r") 3883 (match_operand:DI 2 "arith_double_operand" "rHI")) 3884 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV))) 3885 (set (match_operand:DI 0 "register_operand" "=&r") 3886 (plus:DI (match_dup 1) (match_dup 2)))] 3887 "TARGET_ARCH32" 3888 "#" 3889 "&& reload_completed" 3890 [(parallel [(set (reg:CCC CC_REG) 3891 (compare:CCC (plus:SI (match_dup 4) (match_dup 5)) 3892 (match_dup 4))) 3893 (set (match_dup 3) 3894 (plus:SI (match_dup 4) (match_dup 5)))]) 3895 (parallel [(set (reg:CCV CC_REG) 3896 (compare:CCV (plus:SI (plus:SI (match_dup 7) (match_dup 8)) 3897 (ltu:SI (reg:CCC CC_REG) 3898 (const_int 0))) 3899 (unspec:SI [(plus:SI (match_dup 7) (match_dup 8)) 3900 (ltu:SI (reg:CCC CC_REG) 3901 (const_int 0))] 3902 UNSPEC_ADDV))) 3903 (set (match_dup 6) 3904 (plus:SI (plus:SI (match_dup 7) (match_dup 8)) 3905 (ltu:SI (reg:CCC CC_REG) (const_int 0))))])] 3906{ 3907 operands[3] = gen_lowpart (SImode, operands[0]); 3908 operands[4] = gen_lowpart (SImode, operands[1]); 3909 operands[5] = gen_lowpart (SImode, operands[2]); 3910 operands[6] = gen_highpart (SImode, operands[0]); 3911 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]); 3912 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]); 3913} 3914 [(set_attr "length" "2")]) 3915 3916(define_insn_and_split "*addx_extend_sp32" 3917 [(set (match_operand:DI 0 "register_operand" "=r") 3918 (zero_extend:DI (plus:SI (plus:SI 3919 (match_operand:SI 1 "register_operand" "%r") 3920 (match_operand:SI 2 "arith_operand" "rI")) 3921 (ltu:SI (reg:CCC CC_REG) (const_int 0)))))] 3922 "TARGET_ARCH32" 3923 "#" 3924 "&& reload_completed" 3925 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2)) 3926 (ltu:SI (reg:CCC CC_REG) (const_int 0)))) 3927 (set (match_dup 4) (const_int 0))] 3928 "operands[3] = gen_lowpart (SImode, operands[0]); 3929 operands[4] = gen_highpart (SImode, operands[0]);" 3930 [(set_attr "length" "2")]) 3931 3932(define_insn_and_split "*adddi3_extend_sp32" 3933 [(set (match_operand:DI 0 "register_operand" "=&r") 3934 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) 3935 (match_operand:DI 2 "register_operand" "r"))) 3936 (clobber (reg:CC CC_REG))] 3937 "TARGET_ARCH32" 3938 "#" 3939 "&& reload_completed" 3940 [(parallel [(set (reg:CCC CC_REG) 3941 (compare:CCC (plus:SI (match_dup 3) (match_dup 1)) 3942 (match_dup 3))) 3943 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))]) 3944 (set (match_dup 6) 3945 (plus:SI (plus:SI (match_dup 4) (const_int 0)) 3946 (ltu:SI (reg:CCC CC_REG) (const_int 0))))] 3947 "operands[3] = gen_lowpart (SImode, operands[2]); 3948 operands[4] = gen_highpart (SImode, operands[2]); 3949 operands[5] = gen_lowpart (SImode, operands[0]); 3950 operands[6] = gen_highpart (SImode, operands[0]);" 3951 [(set_attr "length" "2")]) 3952 3953(define_insn "*adddi3_sp64" 3954 [(set (match_operand:DI 0 "register_operand" "=r,r") 3955 (plus:DI (match_operand:DI 1 "register_operand" "%r,r") 3956 (match_operand:DI 2 "arith_add_operand" "rI,O")))] 3957 "TARGET_ARCH64" 3958 "@ 3959 add\t%1, %2, %0 3960 sub\t%1, -%2, %0") 3961 3962(define_insn "addsi3" 3963 [(set (match_operand:SI 0 "register_operand" "=r,r") 3964 (plus:SI (match_operand:SI 1 "register_operand" "%r,r") 3965 (match_operand:SI 2 "arith_add_operand" "rI,O")))] 3966 "" 3967 "@ 3968 add\t%1, %2, %0 3969 sub\t%1, -%2, %0" 3970 [(set_attr "type" "*,*") 3971 (set_attr "fptype" "*,*")]) 3972 3973(define_expand "uaddvsi4" 3974 [(parallel [(set (reg:CCC CC_REG) 3975 (compare:CCC (plus:SI (match_operand:SI 1 "register_operand") 3976 (match_operand:SI 2 "arith_operand")) 3977 (match_dup 1))) 3978 (set (match_operand:SI 0 "register_operand") 3979 (plus:SI (match_dup 1) (match_dup 2)))]) 3980 (set (pc) (if_then_else (ltu (reg:CCC CC_REG) (const_int 0)) 3981 (label_ref (match_operand 3)) 3982 (pc)))] 3983 "") 3984 3985(define_expand "addvsi4" 3986 [(parallel [(set (reg:CCV CC_REG) 3987 (compare:CCV (plus:SI (match_operand:SI 1 "register_operand") 3988 (match_operand:SI 2 "arith_operand")) 3989 (unspec:SI [(match_dup 1) (match_dup 2)] 3990 UNSPEC_ADDV))) 3991 (set (match_operand:SI 0 "register_operand") 3992 (plus:SI (match_dup 1) (match_dup 2)))]) 3993 (set (pc) (if_then_else (ne (reg:CCV CC_REG) (const_int 0)) 3994 (label_ref (match_operand 3)) 3995 (pc)))] 3996 "") 3997 3998(define_insn "*cmp_ccnz_plus" 3999 [(set (reg:CCNZ CC_REG) 4000 (compare:CCNZ (plus:SI (match_operand:SI 0 "register_operand" "%r") 4001 (match_operand:SI 1 "arith_operand" "rI")) 4002 (const_int 0)))] 4003 "" 4004 "addcc\t%0, %1, %%g0" 4005 [(set_attr "type" "compare")]) 4006 4007(define_insn "*cmp_ccxnz_plus" 4008 [(set (reg:CCXNZ CC_REG) 4009 (compare:CCXNZ (plus:DI (match_operand:DI 0 "register_operand" "%r") 4010 (match_operand:DI 1 "arith_operand" "rI")) 4011 (const_int 0)))] 4012 "TARGET_ARCH64" 4013 "addcc\t%0, %1, %%g0" 4014 [(set_attr "type" "compare")]) 4015 4016(define_insn "*cmp_ccnz_plus_set" 4017 [(set (reg:CCNZ CC_REG) 4018 (compare:CCNZ (plus:SI (match_operand:SI 1 "register_operand" "%r") 4019 (match_operand:SI 2 "arith_operand" "rI")) 4020 (const_int 0))) 4021 (set (match_operand:SI 0 "register_operand" "=r") 4022 (plus:SI (match_dup 1) (match_dup 2)))] 4023 "" 4024 "addcc\t%1, %2, %0" 4025 [(set_attr "type" "compare")]) 4026 4027(define_insn "*cmp_ccxnz_plus_set" 4028 [(set (reg:CCXNZ CC_REG) 4029 (compare:CCXNZ (plus:DI (match_operand:DI 1 "register_operand" "%r") 4030 (match_operand:DI 2 "arith_operand" "rI")) 4031 (const_int 0))) 4032 (set (match_operand:DI 0 "register_operand" "=r") 4033 (plus:DI (match_dup 1) (match_dup 2)))] 4034 "TARGET_ARCH64" 4035 "addcc\t%1, %2, %0" 4036 [(set_attr "type" "compare")]) 4037 4038(define_insn "*cmp_ccc_plus" 4039 [(set (reg:CCC CC_REG) 4040 (compare:CCC (plus:SI (match_operand:SI 0 "register_operand" "%r") 4041 (match_operand:SI 1 "arith_operand" "rI")) 4042 (match_dup 0)))] 4043 "" 4044 "addcc\t%0, %1, %%g0" 4045 [(set_attr "type" "compare")]) 4046 4047(define_insn "*cmp_ccxc_plus" 4048 [(set (reg:CCXC CC_REG) 4049 (compare:CCXC (plus:DI (match_operand:DI 0 "register_operand" "%r") 4050 (match_operand:DI 1 "arith_operand" "rI")) 4051 (match_dup 0)))] 4052 "TARGET_ARCH64" 4053 "addcc\t%0, %1, %%g0" 4054 [(set_attr "type" "compare")]) 4055 4056(define_insn "*cmp_ccc_plus_set" 4057 [(set (reg:CCC CC_REG) 4058 (compare:CCC (plus:SI (match_operand:SI 1 "register_operand" "%r") 4059 (match_operand:SI 2 "arith_operand" "rI")) 4060 (match_dup 1))) 4061 (set (match_operand:SI 0 "register_operand" "=r") 4062 (plus:SI (match_dup 1) (match_dup 2)))] 4063 "" 4064 "addcc\t%1, %2, %0" 4065 [(set_attr "type" "compare")]) 4066 4067(define_insn "*cmp_ccxc_plus_set" 4068 [(set (reg:CCXC CC_REG) 4069 (compare:CCXC (plus:DI (match_operand:DI 1 "register_operand" "%r") 4070 (match_operand:DI 2 "arith_operand" "rI")) 4071 (match_dup 1))) 4072 (set (match_operand:DI 0 "register_operand" "=r") 4073 (plus:DI (match_dup 1) (match_dup 2)))] 4074 "TARGET_ARCH64" 4075 "addcc\t%1, %2, %0" 4076 [(set_attr "type" "compare")]) 4077 4078(define_insn "*cmp_ccc_plus_sltu_set" 4079 [(set (reg:CCC CC_REG) 4080 (compare:CCC (zero_extend:DI 4081 (plus:SI 4082 (plus:SI (match_operand:SI 1 "register_operand" "%r") 4083 (match_operand:SI 2 "arith_operand" "rI")) 4084 (ltu:SI (reg:CCC CC_REG) (const_int 0)))) 4085 (plus:DI (plus:DI (zero_extend:DI (match_dup 1)) 4086 (zero_extend:DI (match_dup 2))) 4087 (ltu:DI (reg:CCC CC_REG) (const_int 0))))) 4088 (set (match_operand:SI 0 "register_operand" "=r") 4089 (plus:SI (plus:SI (match_dup 1) (match_dup 2)) 4090 (ltu:SI (reg:CCC CC_REG) (const_int 0))))] 4091 "" 4092 "addxcc\t%1, %2, %0" 4093 [(set_attr "type" "compare")]) 4094 4095(define_insn "*cmp_ccv_plus" 4096 [(set (reg:CCV CC_REG) 4097 (compare:CCV (plus:SI (match_operand:SI 0 "register_operand" "%r") 4098 (match_operand:SI 1 "arith_operand" "rI")) 4099 (unspec:SI [(match_dup 0) (match_dup 1)] UNSPEC_ADDV)))] 4100 "" 4101 "addcc\t%0, %1, %%g0" 4102 [(set_attr "type" "compare")]) 4103 4104(define_insn "*cmp_ccxv_plus" 4105 [(set (reg:CCXV CC_REG) 4106 (compare:CCXV (plus:DI (match_operand:DI 0 "register_operand" "%r") 4107 (match_operand:DI 1 "arith_operand" "rI")) 4108 (unspec:DI [(match_dup 0) (match_dup 1)] UNSPEC_ADDV)))] 4109 "TARGET_ARCH64" 4110 "addcc\t%0, %1, %%g0" 4111 [(set_attr "type" "compare")]) 4112 4113(define_insn "*cmp_ccv_plus_set" 4114 [(set (reg:CCV CC_REG) 4115 (compare:CCV (plus:SI (match_operand:SI 1 "register_operand" "%r") 4116 (match_operand:SI 2 "arith_operand" "rI")) 4117 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV))) 4118 (set (match_operand:SI 0 "register_operand" "=r") 4119 (plus:SI (match_dup 1) (match_dup 2)))] 4120 "" 4121 "addcc\t%1, %2, %0" 4122 [(set_attr "type" "compare")]) 4123 4124(define_insn "*cmp_ccxv_plus_set" 4125 [(set (reg:CCXV CC_REG) 4126 (compare:CCXV (plus:DI (match_operand:DI 1 "register_operand" "%r") 4127 (match_operand:DI 2 "arith_operand" "rI")) 4128 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV))) 4129 (set (match_operand:DI 0 "register_operand" "=r") 4130 (plus:DI (match_dup 1) (match_dup 2)))] 4131 "TARGET_ARCH64" 4132 "addcc\t%1, %2, %0" 4133 [(set_attr "type" "compare")]) 4134 4135(define_insn "*cmp_ccv_plus_sltu_set" 4136 [(set (reg:CCV CC_REG) 4137 (compare:CCV (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "%r") 4138 (match_operand:SI 2 "arith_operand" "rI")) 4139 (ltu:SI (reg:CCC CC_REG) (const_int 0))) 4140 (unspec:SI [(plus:SI (match_dup 1) (match_dup 2)) 4141 (ltu:SI (reg:CCC CC_REG) (const_int 0))] 4142 UNSPEC_ADDV))) 4143 (set (match_operand:SI 0 "register_operand" "=r") 4144 (plus:SI (plus:SI (match_dup 1) (match_dup 2)) 4145 (ltu:SI (reg:CCC CC_REG) (const_int 0))))] 4146 "" 4147 "addxcc\t%1, %2, %0" 4148 [(set_attr "type" "compare")]) 4149 4150 4151(define_expand "subdi3" 4152 [(set (match_operand:DI 0 "register_operand" "") 4153 (minus:DI (match_operand:DI 1 "register_operand" "") 4154 (match_operand:DI 2 "arith_double_add_operand" "")))] 4155 "" 4156{ 4157 if (TARGET_ARCH32) 4158 { 4159 emit_insn (gen_subdi3_sp32 (operands[0], operands[1], operands[2])); 4160 DONE; 4161 } 4162}) 4163 4164(define_expand "usubvdi4" 4165 [(parallel [(set (reg:CCX CC_REG) 4166 (compare:CCX (match_operand:DI 1 "register_or_zero_operand") 4167 (match_operand:DI 2 "arith_add_operand"))) 4168 (set (match_operand:DI 0 "register_operand") 4169 (minus:DI (match_dup 1) (match_dup 2)))]) 4170 (set (pc) (if_then_else (ltu (reg:CCX CC_REG) (const_int 0)) 4171 (label_ref (match_operand 3)) 4172 (pc)))] 4173 "" 4174{ 4175 if (operands[1] == const0_rtx) 4176 { 4177 emit_insn (gen_unegvdi3 (operands[0], operands[2], operands[3])); 4178 DONE; 4179 } 4180 4181 if (TARGET_ARCH32) 4182 { 4183 emit_insn (gen_usubvdi4_sp32 (operands[0], operands[1], operands[2])); 4184 rtx x = gen_rtx_LTU (VOIDmode, gen_rtx_REG (CCCmode, SPARC_ICC_REG), 4185 const0_rtx); 4186 emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[3])); 4187 DONE; 4188 } 4189}) 4190 4191(define_expand "subvdi4" 4192 [(parallel [(set (reg:CCXV CC_REG) 4193 (compare:CCXV (minus:DI (match_operand:DI 1 "register_operand") 4194 (match_operand:DI 2 "arith_add_operand")) 4195 (unspec:DI [(match_dup 1) (match_dup 2)] 4196 UNSPEC_SUBV))) 4197 (set (match_operand:DI 0 "register_operand") 4198 (minus:DI (match_dup 1) (match_dup 2)))]) 4199 (set (pc) (if_then_else (ne (reg:CCXV CC_REG) (const_int 0)) 4200 (label_ref (match_operand 3)) 4201 (pc)))] 4202 "" 4203{ 4204 if (TARGET_ARCH32) 4205 { 4206 emit_insn (gen_subvdi4_sp32 (operands[0], operands[1], operands[2])); 4207 rtx x = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCVmode, SPARC_ICC_REG), 4208 const0_rtx); 4209 emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[3])); 4210 DONE; 4211 } 4212}) 4213 4214(define_insn_and_split "subdi3_sp32" 4215 [(set (match_operand:DI 0 "register_operand" "=&r") 4216 (minus:DI (match_operand:DI 1 "register_operand" "r") 4217 (match_operand:DI 2 "arith_double_operand" "rHI"))) 4218 (clobber (reg:CC CC_REG))] 4219 "TARGET_ARCH32" 4220 "#" 4221 "&& reload_completed" 4222 [(parallel [(set (reg:CC CC_REG) 4223 (compare:CC (match_dup 4) (match_dup 5))) 4224 (set (match_dup 3) 4225 (minus:SI (match_dup 4) (match_dup 5)))]) 4226 (set (match_dup 6) 4227 (minus:SI (minus:SI (match_dup 7) (match_dup 8)) 4228 (ltu:SI (reg:CC CC_REG) (const_int 0))))] 4229{ 4230 operands[3] = gen_lowpart (SImode, operands[0]); 4231 operands[4] = gen_lowpart (SImode, operands[1]); 4232 operands[5] = gen_lowpart (SImode, operands[2]); 4233 operands[6] = gen_highpart (SImode, operands[0]); 4234 operands[7] = gen_highpart (SImode, operands[1]); 4235 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]); 4236} 4237 [(set_attr "length" "2")]) 4238 4239(define_insn_and_split "usubvdi4_sp32" 4240 [(set (reg:CCC CC_REG) 4241 (compare:CCC (match_operand:DI 1 "register_operand" "r") 4242 (match_operand:DI 2 "arith_double_operand" "rHI"))) 4243 (set (match_operand:DI 0 "register_operand" "=&r") 4244 (minus:DI (match_dup 1) (match_dup 2)))] 4245 "TARGET_ARCH32" 4246 "#" 4247 "&& reload_completed" 4248 [(parallel [(set (reg:CC CC_REG) 4249 (compare:CC (match_dup 4) (match_dup 5))) 4250 (set (match_dup 3) 4251 (minus:SI (match_dup 4) (match_dup 5)))]) 4252 (parallel [(set (reg:CCC CC_REG) 4253 (compare:CCC (zero_extend:DI 4254 (minus:SI (minus:SI (match_dup 7) 4255 (ltu:SI (reg:CC CC_REG) 4256 (const_int 0))) 4257 (match_dup 8))) 4258 (minus:DI 4259 (minus:DI (zero_extend:DI (match_dup 7)) 4260 (ltu:DI (reg:CC CC_REG) 4261 (const_int 0))) 4262 (zero_extend:DI (match_dup 8))))) 4263 (set (match_dup 6) 4264 (minus:SI (minus:SI (match_dup 7) 4265 (ltu:SI (reg:CC CC_REG) 4266 (const_int 0))) 4267 (match_dup 8)))])] 4268{ 4269 operands[3] = gen_lowpart (SImode, operands[0]); 4270 operands[4] = gen_lowpart (SImode, operands[1]); 4271 operands[5] = gen_lowpart (SImode, operands[2]); 4272 operands[6] = gen_highpart (SImode, operands[0]); 4273 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]); 4274 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]); 4275} 4276 [(set_attr "length" "2")]) 4277 4278(define_insn_and_split "subvdi4_sp32" 4279 [(set (reg:CCV CC_REG) 4280 (compare:CCV (minus:DI (match_operand:DI 1 "register_operand" "%r") 4281 (match_operand:DI 2 "arith_double_operand" "rHI")) 4282 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV))) 4283 (set (match_operand:DI 0 "register_operand" "=&r") 4284 (minus:DI (match_dup 1) (match_dup 2)))] 4285 "TARGET_ARCH32" 4286 "#" 4287 "&& reload_completed" 4288 [(parallel [(set (reg:CC CC_REG) 4289 (compare:CC (match_dup 4) (match_dup 5))) 4290 (set (match_dup 3) 4291 (minus:SI (match_dup 4) (match_dup 5)))]) 4292 (parallel [(set (reg:CCV CC_REG) 4293 (compare:CCV (minus:SI (minus:SI (match_dup 7) (match_dup 8)) 4294 (ltu:SI (reg:CC CC_REG) 4295 (const_int 0))) 4296 (unspec:SI [(minus:SI (match_dup 7) (match_dup 8)) 4297 (ltu:SI (reg:CC CC_REG) 4298 (const_int 0))] 4299 UNSPEC_SUBV))) 4300 (set (match_dup 6) 4301 (minus:SI (minus:SI (match_dup 7) (match_dup 8)) 4302 (ltu:SI (reg:CC CC_REG) (const_int 0))))])] 4303{ 4304 operands[3] = gen_lowpart (SImode, operands[0]); 4305 operands[4] = gen_lowpart (SImode, operands[1]); 4306 operands[5] = gen_lowpart (SImode, operands[2]); 4307 operands[6] = gen_highpart (SImode, operands[0]); 4308 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]); 4309 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]); 4310} 4311 [(set_attr "length" "2")]) 4312 4313(define_insn_and_split "*subx_extend_sp32" 4314 [(set (match_operand:DI 0 "register_operand" "=r") 4315 (zero_extend:DI (minus:SI (minus:SI 4316 (match_operand:SI 1 "register_or_zero_operand" "rJ") 4317 (match_operand:SI 2 "arith_operand" "rI")) 4318 (ltu:SI (reg:CCC CC_REG) (const_int 0)))))] 4319 "TARGET_ARCH32" 4320 "#" 4321 "&& reload_completed" 4322 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2)) 4323 (ltu:SI (reg:CCC CC_REG) (const_int 0)))) 4324 (set (match_dup 4) (const_int 0))] 4325 "operands[3] = gen_lowpart (SImode, operands[0]); 4326 operands[4] = gen_highpart (SImode, operands[0]);" 4327 [(set_attr "length" "2")]) 4328 4329(define_insn_and_split "*subdi3_extend_sp32" 4330 [(set (match_operand:DI 0 "register_operand" "=&r") 4331 (minus:DI (match_operand:DI 1 "register_operand" "r") 4332 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))) 4333 (clobber (reg:CC CC_REG))] 4334 "TARGET_ARCH32" 4335 "#" 4336 "&& reload_completed" 4337 [(parallel [(set (reg:CC CC_REG) 4338 (compare:CC (match_dup 3) (match_dup 2))) 4339 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))]) 4340 (set (match_dup 6) 4341 (minus:SI (minus:SI (match_dup 4) (const_int 0)) 4342 (ltu:SI (reg:CC CC_REG) (const_int 0))))] 4343 "operands[3] = gen_lowpart (SImode, operands[1]); 4344 operands[4] = gen_highpart (SImode, operands[1]); 4345 operands[5] = gen_lowpart (SImode, operands[0]); 4346 operands[6] = gen_highpart (SImode, operands[0]);" 4347 [(set_attr "length" "2")]) 4348 4349(define_insn "*subdi3_sp64" 4350 [(set (match_operand:DI 0 "register_operand" "=r,r") 4351 (minus:DI (match_operand:DI 1 "register_operand" "r,r") 4352 (match_operand:DI 2 "arith_add_operand" "rI,O")))] 4353 "TARGET_ARCH64" 4354 "@ 4355 sub\t%1, %2, %0 4356 add\t%1, -%2, %0") 4357 4358(define_insn "subsi3" 4359 [(set (match_operand:SI 0 "register_operand" "=r,r") 4360 (minus:SI (match_operand:SI 1 "register_operand" "r,r") 4361 (match_operand:SI 2 "arith_add_operand" "rI,O")))] 4362 "" 4363 "@ 4364 sub\t%1, %2, %0 4365 add\t%1, -%2, %0" 4366 [(set_attr "type" "*,*") 4367 (set_attr "fptype" "*,*")]) 4368 4369(define_expand "usubvsi4" 4370 [(parallel [(set (reg:CC CC_REG) 4371 (compare:CC (match_operand:SI 1 "register_or_zero_operand") 4372 (match_operand:SI 2 "arith_operand"))) 4373 (set (match_operand:SI 0 "register_operand") 4374 (minus:SI (match_dup 1) (match_dup 2)))]) 4375 (set (pc) (if_then_else (ltu (reg:CC CC_REG) (const_int 0)) 4376 (label_ref (match_operand 3)) 4377 (pc)))] 4378 "" 4379{ 4380 if (operands[1] == const0_rtx) 4381 { 4382 emit_insn (gen_unegvsi3 (operands[0], operands[2], operands[3])); 4383 DONE; 4384 } 4385}) 4386 4387(define_expand "subvsi4" 4388 [(parallel [(set (reg:CCV CC_REG) 4389 (compare:CCV (minus:SI (match_operand:SI 1 "register_operand") 4390 (match_operand:SI 2 "arith_operand")) 4391 (unspec:SI [(match_dup 1) (match_dup 2)] 4392 UNSPEC_SUBV))) 4393 (set (match_operand:SI 0 "register_operand") 4394 (minus:SI (match_dup 1) (match_dup 2)))]) 4395 (set (pc) (if_then_else (ne (reg:CCV CC_REG) (const_int 0)) 4396 (label_ref (match_operand 3)) 4397 (pc)))] 4398 "") 4399 4400(define_insn "*cmp_ccnz_minus" 4401 [(set (reg:CCNZ CC_REG) 4402 (compare:CCNZ (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ") 4403 (match_operand:SI 1 "arith_operand" "rI")) 4404 (const_int 0)))] 4405 "" 4406 "subcc\t%r0, %1, %%g0" 4407 [(set_attr "type" "compare")]) 4408 4409(define_insn "*cmp_ccxnz_minus" 4410 [(set (reg:CCXNZ CC_REG) 4411 (compare:CCXNZ (minus:DI (match_operand:DI 0 "register_or_zero_operand" "rJ") 4412 (match_operand:DI 1 "arith_operand" "rI")) 4413 (const_int 0)))] 4414 "TARGET_ARCH64" 4415 "subcc\t%r0, %1, %%g0" 4416 [(set_attr "type" "compare")]) 4417 4418(define_insn "*cmp_ccnz_minus_set" 4419 [(set (reg:CCNZ CC_REG) 4420 (compare:CCNZ (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") 4421 (match_operand:SI 2 "arith_operand" "rI")) 4422 (const_int 0))) 4423 (set (match_operand:SI 0 "register_operand" "=r") 4424 (minus:SI (match_dup 1) (match_dup 2)))] 4425 "" 4426 "subcc\t%r1, %2, %0" 4427 [(set_attr "type" "compare")]) 4428 4429(define_insn "*cmp_ccxnz_minus_set" 4430 [(set (reg:CCXNZ CC_REG) 4431 (compare:CCXNZ (minus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ") 4432 (match_operand:DI 2 "arith_operand" "rI")) 4433 (const_int 0))) 4434 (set (match_operand:DI 0 "register_operand" "=r") 4435 (minus:DI (match_dup 1) (match_dup 2)))] 4436 "TARGET_ARCH64" 4437 "subcc\t%r1, %2, %0" 4438 [(set_attr "type" "compare")]) 4439 4440(define_insn "*cmpsi_set" 4441 [(set (reg:CC CC_REG) 4442 (compare:CC (match_operand:SI 1 "register_or_zero_operand" "rJ") 4443 (match_operand:SI 2 "arith_operand" "rI"))) 4444 (set (match_operand:SI 0 "register_operand" "=r") 4445 (minus:SI (match_dup 1) (match_dup 2)))] 4446 "" 4447 "subcc\t%r1, %2, %0" 4448 [(set_attr "type" "compare")]) 4449 4450(define_insn "*cmpdi_set" 4451 [(set (reg:CCX CC_REG) 4452 (compare:CCX (match_operand:DI 1 "register_or_zero_operand" "rJ") 4453 (match_operand:DI 2 "arith_operand" "rI"))) 4454 (set (match_operand:DI 0 "register_operand" "=r") 4455 (minus:DI (match_dup 1) (match_dup 2)))] 4456 "TARGET_ARCH64" 4457 "subcc\t%r1, %2, %0" 4458 [(set_attr "type" "compare")]) 4459 4460(define_insn "*cmp_ccc_minus_sltu_set" 4461 [(set (reg:CCC CC_REG) 4462 (compare:CCC (zero_extend:DI 4463 (minus:SI 4464 (minus:SI 4465 (match_operand:SI 1 "register_or_zero_operand" "rJ") 4466 (ltu:SI (reg:CC CC_REG) (const_int 0))) 4467 (match_operand:SI 2 "arith_operand" "rI"))) 4468 (minus:DI 4469 (minus:DI 4470 (zero_extend:DI (match_dup 1)) 4471 (ltu:DI (reg:CC CC_REG) (const_int 0))) 4472 (zero_extend:DI (match_dup 2))))) 4473 (set (match_operand:SI 0 "register_operand" "=r") 4474 (minus:SI (minus:SI (match_dup 1) 4475 (ltu:SI (reg:CC CC_REG) (const_int 0))) 4476 (match_dup 2)))] 4477 "" 4478 "subxcc\t%r1, %2, %0" 4479 [(set_attr "type" "compare")]) 4480 4481(define_insn "*cmp_ccv_minus" 4482 [(set (reg:CCV CC_REG) 4483 (compare:CCV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ") 4484 (match_operand:SI 1 "arith_operand" "rI")) 4485 (unspec:SI [(match_dup 0) (match_dup 1)] UNSPEC_SUBV)))] 4486 "" 4487 "subcc\t%r0, %1, %%g0" 4488 [(set_attr "type" "compare")]) 4489 4490(define_insn "*cmp_ccxv_minus" 4491 [(set (reg:CCXV CC_REG) 4492 (compare:CCXV (minus:DI (match_operand:DI 0 "register_or_zero_operand" "rJ") 4493 (match_operand:DI 1 "arith_operand" "rI")) 4494 (unspec:DI [(match_dup 0) (match_dup 1)] UNSPEC_SUBV)))] 4495 "TARGET_ARCH64" 4496 "subcc\t%r0, %1, %%g0" 4497 [(set_attr "type" "compare")]) 4498 4499(define_insn "*cmp_ccv_minus_set" 4500 [(set (reg:CCV CC_REG) 4501 (compare:CCV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") 4502 (match_operand:SI 2 "arith_operand" "rI")) 4503 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV))) 4504 (set (match_operand:SI 0 "register_operand" "=r") 4505 (minus:SI (match_dup 1) (match_dup 2)))] 4506 "" 4507 "subcc\t%r1, %2, %0" 4508 [(set_attr "type" "compare")]) 4509 4510(define_insn "*cmp_ccxv_minus_set" 4511 [(set (reg:CCXV CC_REG) 4512 (compare:CCXV (minus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ") 4513 (match_operand:DI 2 "arith_operand" "rI")) 4514 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV))) 4515 (set (match_operand:DI 0 "register_operand" "=r") 4516 (minus:DI (match_dup 1) (match_dup 2)))] 4517 "TARGET_ARCH64" 4518 "subcc\t%r1, %2, %0" 4519 [(set_attr "type" "compare")]) 4520 4521(define_insn "*cmp_ccv_minus_sltu_set" 4522 [(set (reg:CCV CC_REG) 4523 (compare:CCV 4524 (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") 4525 (match_operand:SI 2 "arith_operand" "rI")) 4526 (ltu:SI (reg:CC CC_REG) (const_int 0))) 4527 (unspec:SI [(minus:SI (match_dup 1) (match_dup 2)) 4528 (ltu:SI (reg:CC CC_REG) (const_int 0))] 4529 UNSPEC_SUBV))) 4530 (set (match_operand:SI 0 "register_operand" "=r") 4531 (minus:SI (minus:SI (match_dup 1) (match_dup 2)) 4532 (ltu:SI (reg:CC CC_REG) (const_int 0))))] 4533 "" 4534 "subxcc\t%1, %2, %0" 4535 [(set_attr "type" "compare")]) 4536 4537 4538;; Integer multiply/divide instructions. 4539 4540;; The 32-bit multiply/divide instructions are deprecated on v9, but at 4541;; least in UltraSPARC I, II and IIi it is a win tick-wise. 4542 4543(define_expand "mulsi3" 4544 [(set (match_operand:SI 0 "register_operand" "") 4545 (mult:SI (match_operand:SI 1 "arith_operand" "") 4546 (match_operand:SI 2 "arith_operand" "")))] 4547 "TARGET_HARD_MUL || TARGET_ARCH64" 4548 "") 4549 4550(define_insn "*mulsi3_sp32" 4551 [(set (match_operand:SI 0 "register_operand" "=r") 4552 (mult:SI (match_operand:SI 1 "arith_operand" "%r") 4553 (match_operand:SI 2 "arith_operand" "rI")))] 4554 "TARGET_HARD_MUL" 4555 "smul\t%1, %2, %0" 4556 [(set_attr "type" "imul")]) 4557 4558(define_insn "*mulsi3_sp64" 4559 [(set (match_operand:SI 0 "register_operand" "=r") 4560 (mult:SI (match_operand:SI 1 "arith_operand" "%r") 4561 (match_operand:SI 2 "arith_operand" "rI")))] 4562 "TARGET_ARCH64" 4563 "mulx\t%1, %2, %0" 4564 [(set_attr "type" "imul")]) 4565 4566(define_expand "muldi3" 4567 [(set (match_operand:DI 0 "register_operand" "") 4568 (mult:DI (match_operand:DI 1 "arith_operand" "") 4569 (match_operand:DI 2 "arith_operand" "")))] 4570 "TARGET_ARCH64 || TARGET_V8PLUS" 4571{ 4572 if (TARGET_V8PLUS) 4573 { 4574 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2])); 4575 DONE; 4576 } 4577}) 4578 4579(define_insn "*muldi3_sp64" 4580 [(set (match_operand:DI 0 "register_operand" "=r") 4581 (mult:DI (match_operand:DI 1 "arith_operand" "%r") 4582 (match_operand:DI 2 "arith_operand" "rI")))] 4583 "TARGET_ARCH64" 4584 "mulx\t%1, %2, %0" 4585 [(set_attr "type" "imul")]) 4586 4587;; V8plus wide multiply. 4588(define_insn "muldi3_v8plus" 4589 [(set (match_operand:DI 0 "register_operand" "=r,h") 4590 (mult:DI (match_operand:DI 1 "arith_operand" "%r,0") 4591 (match_operand:DI 2 "arith_operand" "rI,rI"))) 4592 (clobber (match_scratch:SI 3 "=&h,X")) 4593 (clobber (match_scratch:SI 4 "=&h,X"))] 4594 "TARGET_V8PLUS" 4595{ 4596 return output_v8plus_mult (insn, operands, \"mulx\"); 4597} 4598 [(set_attr "type" "multi") 4599 (set_attr "length" "9,8")]) 4600 4601(define_insn "*cmp_mul_set" 4602 [(set (reg:CC CC_REG) 4603 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r") 4604 (match_operand:SI 2 "arith_operand" "rI")) 4605 (const_int 0))) 4606 (set (match_operand:SI 0 "register_operand" "=r") 4607 (mult:SI (match_dup 1) (match_dup 2)))] 4608 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" 4609 "smulcc\t%1, %2, %0" 4610 [(set_attr "type" "imul")]) 4611 4612(define_expand "mulsidi3" 4613 [(set (match_operand:DI 0 "register_operand" "") 4614 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) 4615 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))] 4616 "TARGET_HARD_MUL" 4617{ 4618 if (CONSTANT_P (operands[2])) 4619 { 4620 if (TARGET_V8PLUS) 4621 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1], 4622 operands[2])); 4623 else if (TARGET_ARCH32) 4624 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1], 4625 operands[2])); 4626 else 4627 emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1], 4628 operands[2])); 4629 DONE; 4630 } 4631 if (TARGET_V8PLUS) 4632 { 4633 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2])); 4634 DONE; 4635 } 4636}) 4637 4638;; V9 puts the 64-bit product in a 64-bit register. Only out or global 4639;; registers can hold 64-bit values in the V8plus environment. 4640(define_insn "mulsidi3_v8plus" 4641 [(set (match_operand:DI 0 "register_operand" "=h,r") 4642 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) 4643 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))) 4644 (clobber (match_scratch:SI 3 "=X,&h"))] 4645 "TARGET_V8PLUS" 4646 "@ 4647 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0 4648 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0" 4649 [(set_attr "type" "multi") 4650 (set_attr "length" "2,3")]) 4651 4652(define_insn "const_mulsidi3_v8plus" 4653 [(set (match_operand:DI 0 "register_operand" "=h,r") 4654 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) 4655 (match_operand:DI 2 "small_int_operand" "I,I"))) 4656 (clobber (match_scratch:SI 3 "=X,&h"))] 4657 "TARGET_V8PLUS" 4658 "@ 4659 smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0 4660 smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0" 4661 [(set_attr "type" "multi") 4662 (set_attr "length" "2,3")]) 4663 4664(define_insn "*mulsidi3_sp32" 4665 [(set (match_operand:DI 0 "register_operand" "=r") 4666 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) 4667 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))] 4668 "TARGET_HARD_MUL32" 4669{ 4670 return TARGET_SPARCLET 4671 ? "smuld\t%1, %2, %L0" 4672 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0"; 4673} 4674 [(set (attr "type") 4675 (if_then_else (eq_attr "isa" "sparclet") 4676 (const_string "imul") (const_string "multi"))) 4677 (set (attr "length") 4678 (if_then_else (eq_attr "isa" "sparclet") 4679 (const_int 1) (const_int 2)))]) 4680 4681(define_insn "*mulsidi3_sp64" 4682 [(set (match_operand:DI 0 "register_operand" "=r") 4683 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) 4684 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))] 4685 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" 4686 "smul\t%1, %2, %0" 4687 [(set_attr "type" "imul")]) 4688 4689;; Extra pattern, because sign_extend of a constant isn't valid. 4690 4691(define_insn "const_mulsidi3_sp32" 4692 [(set (match_operand:DI 0 "register_operand" "=r") 4693 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) 4694 (match_operand:DI 2 "small_int_operand" "I")))] 4695 "TARGET_HARD_MUL32" 4696{ 4697 return TARGET_SPARCLET 4698 ? "smuld\t%1, %2, %L0" 4699 : "smul\t%1, %2, %L0\n\trd\t%%y, %H0"; 4700} 4701 [(set (attr "type") 4702 (if_then_else (eq_attr "isa" "sparclet") 4703 (const_string "imul") (const_string "multi"))) 4704 (set (attr "length") 4705 (if_then_else (eq_attr "isa" "sparclet") 4706 (const_int 1) (const_int 2)))]) 4707 4708(define_insn "const_mulsidi3_sp64" 4709 [(set (match_operand:DI 0 "register_operand" "=r") 4710 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) 4711 (match_operand:DI 2 "small_int_operand" "I")))] 4712 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" 4713 "smul\t%1, %2, %0" 4714 [(set_attr "type" "imul")]) 4715 4716(define_expand "smulsi3_highpart" 4717 [(set (match_operand:SI 0 "register_operand" "") 4718 (truncate:SI 4719 (lshiftrt:DI 4720 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) 4721 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))) 4722 (const_int 32))))] 4723 "TARGET_HARD_MUL && TARGET_ARCH32" 4724{ 4725 if (CONSTANT_P (operands[2])) 4726 { 4727 if (TARGET_V8PLUS) 4728 { 4729 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0], 4730 operands[1], 4731 operands[2], 4732 GEN_INT (32))); 4733 DONE; 4734 } 4735 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2])); 4736 DONE; 4737 } 4738 if (TARGET_V8PLUS) 4739 { 4740 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1], 4741 operands[2], GEN_INT (32))); 4742 DONE; 4743 } 4744}) 4745 4746(define_insn "smulsi3_highpart_v8plus" 4747 [(set (match_operand:SI 0 "register_operand" "=h,r") 4748 (truncate:SI 4749 (lshiftrt:DI 4750 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) 4751 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))) 4752 (match_operand:SI 3 "small_int_operand" "I,I")))) 4753 (clobber (match_scratch:SI 4 "=X,&h"))] 4754 "TARGET_V8PLUS" 4755 "@ 4756 smul\t%1, %2, %0\;srlx\t%0, %3, %0 4757 smul\t%1, %2, %4\;srlx\t%4, %3, %0" 4758 [(set_attr "type" "multi") 4759 (set_attr "length" "2")]) 4760 4761;; The combiner changes TRUNCATE in the previous pattern to SUBREG. 4762(define_insn "" 4763 [(set (match_operand:SI 0 "register_operand" "=h,r") 4764 (subreg:SI 4765 (lshiftrt:DI 4766 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) 4767 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))) 4768 (match_operand:SI 3 "small_int_operand" "I,I")) 4)) 4769 (clobber (match_scratch:SI 4 "=X,&h"))] 4770 "TARGET_V8PLUS" 4771 "@ 4772 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0 4773 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0" 4774 [(set_attr "type" "multi") 4775 (set_attr "length" "2")]) 4776 4777(define_insn "const_smulsi3_highpart_v8plus" 4778 [(set (match_operand:SI 0 "register_operand" "=h,r") 4779 (truncate:SI 4780 (lshiftrt:DI 4781 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) 4782 (match_operand:DI 2 "small_int_operand" "I,I")) 4783 (match_operand:SI 3 "small_int_operand" "I,I")))) 4784 (clobber (match_scratch:SI 4 "=X,&h"))] 4785 "TARGET_V8PLUS" 4786 "@ 4787 smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0 4788 smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0" 4789 [(set_attr "type" "multi") 4790 (set_attr "length" "2")]) 4791 4792(define_insn "*smulsi3_highpart_sp32" 4793 [(set (match_operand:SI 0 "register_operand" "=r") 4794 (truncate:SI 4795 (lshiftrt:DI 4796 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) 4797 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))) 4798 (const_int 32))))] 4799 "TARGET_HARD_MUL32" 4800 "smul\t%1, %2, %%g0\n\trd\t%%y, %0" 4801 [(set_attr "type" "multi") 4802 (set_attr "length" "2")]) 4803 4804(define_insn "const_smulsi3_highpart" 4805 [(set (match_operand:SI 0 "register_operand" "=r") 4806 (truncate:SI 4807 (lshiftrt:DI 4808 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) 4809 (match_operand:DI 2 "small_int_operand" "i")) 4810 (const_int 32))))] 4811 "TARGET_HARD_MUL32" 4812 "smul\t%1, %2, %%g0\n\trd\t%%y, %0" 4813 [(set_attr "type" "multi") 4814 (set_attr "length" "2")]) 4815 4816(define_expand "umulsidi3" 4817 [(set (match_operand:DI 0 "register_operand" "") 4818 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) 4819 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))] 4820 "TARGET_HARD_MUL" 4821{ 4822 if (CONSTANT_P (operands[2])) 4823 { 4824 if (TARGET_V8PLUS) 4825 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1], 4826 operands[2])); 4827 else if (TARGET_ARCH32) 4828 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1], 4829 operands[2])); 4830 else 4831 emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1], 4832 operands[2])); 4833 DONE; 4834 } 4835 if (TARGET_V8PLUS) 4836 { 4837 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2])); 4838 DONE; 4839 } 4840}) 4841 4842(define_insn "umulsidi3_v8plus" 4843 [(set (match_operand:DI 0 "register_operand" "=h,r") 4844 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) 4845 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))) 4846 (clobber (match_scratch:SI 3 "=X,&h"))] 4847 "TARGET_V8PLUS" 4848 "@ 4849 umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0 4850 umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0" 4851 [(set_attr "type" "multi") 4852 (set_attr "length" "2,3")]) 4853 4854(define_insn "*umulsidi3_sp32" 4855 [(set (match_operand:DI 0 "register_operand" "=r") 4856 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) 4857 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))] 4858 "TARGET_HARD_MUL32" 4859{ 4860 return TARGET_SPARCLET 4861 ? "umuld\t%1, %2, %L0" 4862 : "umul\t%1, %2, %L0\n\trd\t%%y, %H0"; 4863} 4864 [(set (attr "type") 4865 (if_then_else (eq_attr "isa" "sparclet") 4866 (const_string "imul") (const_string "multi"))) 4867 (set (attr "length") 4868 (if_then_else (eq_attr "isa" "sparclet") 4869 (const_int 1) (const_int 2)))]) 4870 4871(define_insn "*umulsidi3_sp64" 4872 [(set (match_operand:DI 0 "register_operand" "=r") 4873 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) 4874 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))] 4875 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" 4876 "umul\t%1, %2, %0" 4877 [(set_attr "type" "imul")]) 4878 4879;; Extra pattern, because sign_extend of a constant isn't valid. 4880 4881(define_insn "const_umulsidi3_sp32" 4882 [(set (match_operand:DI 0 "register_operand" "=r") 4883 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) 4884 (match_operand:DI 2 "uns_small_int_operand" "")))] 4885 "TARGET_HARD_MUL32" 4886{ 4887 return TARGET_SPARCLET 4888 ? "umuld\t%1, %s2, %L0" 4889 : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0"; 4890} 4891 [(set (attr "type") 4892 (if_then_else (eq_attr "isa" "sparclet") 4893 (const_string "imul") (const_string "multi"))) 4894 (set (attr "length") 4895 (if_then_else (eq_attr "isa" "sparclet") 4896 (const_int 1) (const_int 2)))]) 4897 4898(define_insn "const_umulsidi3_sp64" 4899 [(set (match_operand:DI 0 "register_operand" "=r") 4900 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) 4901 (match_operand:DI 2 "uns_small_int_operand" "")))] 4902 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" 4903 "umul\t%1, %s2, %0" 4904 [(set_attr "type" "imul")]) 4905 4906(define_insn "const_umulsidi3_v8plus" 4907 [(set (match_operand:DI 0 "register_operand" "=h,r") 4908 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) 4909 (match_operand:DI 2 "uns_small_int_operand" ""))) 4910 (clobber (match_scratch:SI 3 "=X,h"))] 4911 "TARGET_V8PLUS" 4912 "@ 4913 umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0 4914 umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0" 4915 [(set_attr "type" "multi") 4916 (set_attr "length" "2,3")]) 4917 4918(define_expand "umulsi3_highpart" 4919 [(set (match_operand:SI 0 "register_operand" "") 4920 (truncate:SI 4921 (lshiftrt:DI 4922 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) 4923 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))) 4924 (const_int 32))))] 4925 "TARGET_HARD_MUL && TARGET_ARCH32" 4926{ 4927 if (CONSTANT_P (operands[2])) 4928 { 4929 if (TARGET_V8PLUS) 4930 { 4931 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0], 4932 operands[1], 4933 operands[2], 4934 GEN_INT (32))); 4935 DONE; 4936 } 4937 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2])); 4938 DONE; 4939 } 4940 if (TARGET_V8PLUS) 4941 { 4942 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1], 4943 operands[2], GEN_INT (32))); 4944 DONE; 4945 } 4946}) 4947 4948(define_insn "umulsi3_highpart_v8plus" 4949 [(set (match_operand:SI 0 "register_operand" "=h,r") 4950 (truncate:SI 4951 (lshiftrt:DI 4952 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) 4953 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))) 4954 (match_operand:SI 3 "small_int_operand" "I,I")))) 4955 (clobber (match_scratch:SI 4 "=X,h"))] 4956 "TARGET_V8PLUS" 4957 "@ 4958 umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0 4959 umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0" 4960 [(set_attr "type" "multi") 4961 (set_attr "length" "2")]) 4962 4963(define_insn "const_umulsi3_highpart_v8plus" 4964 [(set (match_operand:SI 0 "register_operand" "=h,r") 4965 (truncate:SI 4966 (lshiftrt:DI 4967 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) 4968 (match_operand:DI 2 "uns_small_int_operand" "")) 4969 (match_operand:SI 3 "small_int_operand" "I,I")))) 4970 (clobber (match_scratch:SI 4 "=X,h"))] 4971 "TARGET_V8PLUS" 4972 "@ 4973 umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0 4974 umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0" 4975 [(set_attr "type" "multi") 4976 (set_attr "length" "2")]) 4977 4978(define_insn "*umulsi3_highpart_sp32" 4979 [(set (match_operand:SI 0 "register_operand" "=r") 4980 (truncate:SI 4981 (lshiftrt:DI 4982 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) 4983 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))) 4984 (const_int 32))))] 4985 "TARGET_HARD_MUL32" 4986 "umul\t%1, %2, %%g0\n\trd\t%%y, %0" 4987 [(set_attr "type" "multi") 4988 (set_attr "length" "2")]) 4989 4990(define_insn "const_umulsi3_highpart" 4991 [(set (match_operand:SI 0 "register_operand" "=r") 4992 (truncate:SI 4993 (lshiftrt:DI 4994 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) 4995 (match_operand:DI 2 "uns_small_int_operand" "")) 4996 (const_int 32))))] 4997 "TARGET_HARD_MUL32" 4998 "umul\t%1, %s2, %%g0\n\trd\t%%y, %0" 4999 [(set_attr "type" "multi") 5000 (set_attr "length" "2")]) 5001 5002 5003(define_expand "umulxhi_vis" 5004 [(set (match_operand:DI 0 "register_operand" "") 5005 (truncate:DI 5006 (lshiftrt:TI 5007 (mult:TI (zero_extend:TI (match_operand:DI 1 "arith_operand" "")) 5008 (zero_extend:TI (match_operand:DI 2 "arith_operand" ""))) 5009 (const_int 64))))] 5010 "TARGET_VIS3" 5011{ 5012 if (TARGET_ARCH32) 5013 { 5014 emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2])); 5015 DONE; 5016 } 5017}) 5018 5019(define_insn "*umulxhi_sp64" 5020 [(set (match_operand:DI 0 "register_operand" "=r") 5021 (truncate:DI 5022 (lshiftrt:TI 5023 (mult:TI (zero_extend:TI (match_operand:DI 1 "arith_operand" "%r")) 5024 (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI"))) 5025 (const_int 64))))] 5026 "TARGET_VIS3 && TARGET_ARCH64" 5027 "umulxhi\t%1, %2, %0" 5028 [(set_attr "type" "imul")]) 5029 5030(define_insn "umulxhi_v8plus" 5031 [(set (match_operand:DI 0 "register_operand" "=r,h") 5032 (truncate:DI 5033 (lshiftrt:TI 5034 (mult:TI (zero_extend:TI (match_operand:DI 1 "arith_operand" "%r,0")) 5035 (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI,rI"))) 5036 (const_int 64)))) 5037 (clobber (match_scratch:SI 3 "=&h,X")) 5038 (clobber (match_scratch:SI 4 "=&h,X"))] 5039 "TARGET_VIS3 && TARGET_ARCH32" 5040{ 5041 return output_v8plus_mult (insn, operands, \"umulxhi\"); 5042} 5043 [(set_attr "type" "imul") 5044 (set_attr "length" "9,8")]) 5045 5046(define_expand "xmulx_vis" 5047 [(set (match_operand:DI 0 "register_operand" "") 5048 (truncate:DI 5049 (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" "")) 5050 (zero_extend:TI (match_operand:DI 2 "arith_operand" ""))] 5051 UNSPEC_XMUL)))] 5052 "TARGET_VIS3" 5053{ 5054 if (TARGET_ARCH32) 5055 { 5056 emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2])); 5057 DONE; 5058 } 5059}) 5060 5061(define_insn "*xmulx_sp64" 5062 [(set (match_operand:DI 0 "register_operand" "=r") 5063 (truncate:DI 5064 (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" "%r")) 5065 (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI"))] 5066 UNSPEC_XMUL)))] 5067 "TARGET_VIS3 && TARGET_ARCH64" 5068 "xmulx\t%1, %2, %0" 5069 [(set_attr "type" "imul")]) 5070 5071(define_insn "xmulx_v8plus" 5072 [(set (match_operand:DI 0 "register_operand" "=r,h") 5073 (truncate:DI 5074 (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" "%r,0")) 5075 (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI,rI"))] 5076 UNSPEC_XMUL))) 5077 (clobber (match_scratch:SI 3 "=&h,X")) 5078 (clobber (match_scratch:SI 4 "=&h,X"))] 5079 "TARGET_VIS3 && TARGET_ARCH32" 5080{ 5081 return output_v8plus_mult (insn, operands, \"xmulx\"); 5082} 5083 [(set_attr "type" "imul") 5084 (set_attr "length" "9,8")]) 5085 5086(define_expand "xmulxhi_vis" 5087 [(set (match_operand:DI 0 "register_operand" "") 5088 (truncate:DI 5089 (lshiftrt:TI 5090 (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" "")) 5091 (zero_extend:TI (match_operand:DI 2 "arith_operand" ""))] 5092 UNSPEC_XMUL) 5093 (const_int 64))))] 5094 "TARGET_VIS3" 5095{ 5096 if (TARGET_ARCH32) 5097 { 5098 emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2])); 5099 DONE; 5100 } 5101}) 5102 5103(define_insn "*xmulxhi_sp64" 5104 [(set (match_operand:DI 0 "register_operand" "=r") 5105 (truncate:DI 5106 (lshiftrt:TI 5107 (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" "%r")) 5108 (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI"))] 5109 UNSPEC_XMUL) 5110 (const_int 64))))] 5111 "TARGET_VIS3 && TARGET_ARCH64" 5112 "xmulxhi\t%1, %2, %0" 5113 [(set_attr "type" "imul")]) 5114 5115(define_insn "xmulxhi_v8plus" 5116 [(set (match_operand:DI 0 "register_operand" "=r,h") 5117 (truncate:DI 5118 (lshiftrt:TI 5119 (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" "%r,0")) 5120 (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI,rI"))] 5121 UNSPEC_XMUL) 5122 (const_int 64)))) 5123 (clobber (match_scratch:SI 3 "=&h,X")) 5124 (clobber (match_scratch:SI 4 "=&h,X"))] 5125 "TARGET_VIS3 && TARGET_ARCH32" 5126{ 5127 return output_v8plus_mult (insn, operands, \"xmulxhi\"); 5128} 5129 [(set_attr "type" "imul") 5130 (set_attr "length" "9,8")]) 5131 5132(define_expand "divsi3" 5133 [(parallel [(set (match_operand:SI 0 "register_operand" "") 5134 (div:SI (match_operand:SI 1 "register_operand" "") 5135 (match_operand:SI 2 "input_operand" ""))) 5136 (clobber (match_scratch:SI 3 ""))])] 5137 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" 5138{ 5139 if (TARGET_ARCH64) 5140 { 5141 operands[3] = gen_reg_rtx(SImode); 5142 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31))); 5143 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2], 5144 operands[3])); 5145 DONE; 5146 } 5147}) 5148 5149;; The V8 architecture specifies that there must be at least 3 instructions 5150;; between a write to the Y register and a use of it for correct results. 5151;; We try to fill one of them with a simple constant or a memory load. 5152 5153(define_insn "divsi3_sp32" 5154 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 5155 (div:SI (match_operand:SI 1 "register_operand" "r,r,r") 5156 (match_operand:SI 2 "input_operand" "rI,K,m"))) 5157 (clobber (match_scratch:SI 3 "=&r,&r,&r"))] 5158 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32" 5159{ 5160 output_asm_insn ("sra\t%1, 31, %3", operands); 5161 output_asm_insn ("wr\t%3, 0, %%y", operands); 5162 5163 switch (which_alternative) 5164 { 5165 case 0: 5166 if (TARGET_V9) 5167 return "sdiv\t%1, %2, %0"; 5168 else 5169 return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0"; 5170 case 1: 5171 if (TARGET_V9) 5172 return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0"; 5173 else 5174 return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0"; 5175 case 2: 5176 if (TARGET_V9) 5177 return "ld\t%2, %3\n\tsdiv\t%1, %3, %0"; 5178 else 5179 return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0"; 5180 default: 5181 gcc_unreachable (); 5182 } 5183} 5184 [(set_attr "type" "multi") 5185 (set (attr "length") 5186 (if_then_else (eq_attr "isa" "v9") 5187 (const_int 4) (const_int 6)))]) 5188 5189(define_insn "divsi3_sp64" 5190 [(set (match_operand:SI 0 "register_operand" "=r") 5191 (div:SI (match_operand:SI 1 "register_operand" "r") 5192 (match_operand:SI 2 "input_operand" "rI"))) 5193 (use (match_operand:SI 3 "register_operand" "r"))] 5194 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" 5195 "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0" 5196 [(set_attr "type" "multi") 5197 (set_attr "length" "2")]) 5198 5199(define_insn "divdi3" 5200 [(set (match_operand:DI 0 "register_operand" "=r") 5201 (div:DI (match_operand:DI 1 "register_operand" "r") 5202 (match_operand:DI 2 "arith_operand" "rI")))] 5203 "TARGET_ARCH64" 5204 "sdivx\t%1, %2, %0" 5205 [(set_attr "type" "idiv")]) 5206 5207(define_insn "*cmp_sdiv_cc_set" 5208 [(set (reg:CC CC_REG) 5209 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r") 5210 (match_operand:SI 2 "arith_operand" "rI")) 5211 (const_int 0))) 5212 (set (match_operand:SI 0 "register_operand" "=r") 5213 (div:SI (match_dup 1) (match_dup 2))) 5214 (clobber (match_scratch:SI 3 "=&r"))] 5215 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" 5216{ 5217 output_asm_insn ("sra\t%1, 31, %3", operands); 5218 output_asm_insn ("wr\t%3, 0, %%y", operands); 5219 5220 if (TARGET_V9) 5221 return "sdivcc\t%1, %2, %0"; 5222 else 5223 return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0"; 5224} 5225 [(set_attr "type" "multi") 5226 (set (attr "length") 5227 (if_then_else (eq_attr "isa" "v9") 5228 (const_int 3) (const_int 6)))]) 5229 5230(define_expand "udivsi3" 5231 [(set (match_operand:SI 0 "register_operand" "") 5232 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "") 5233 (match_operand:SI 2 "input_operand" "")))] 5234 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" 5235 "") 5236 5237;; The V8 architecture specifies that there must be at least 3 instructions 5238;; between a write to the Y register and a use of it for correct results. 5239;; We try to fill one of them with a simple constant or a memory load. 5240 5241(define_insn "udivsi3_sp32" 5242 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r") 5243 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m") 5244 (match_operand:SI 2 "input_operand" "rI,K,m,r")))] 5245 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32" 5246{ 5247 output_asm_insn ("wr\t%%g0, 0, %%y", operands); 5248 5249 switch (which_alternative) 5250 { 5251 case 0: 5252 if (TARGET_V9) 5253 return "udiv\t%1, %2, %0"; 5254 else 5255 return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0"; 5256 case 1: 5257 if (TARGET_V9) 5258 return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0"; 5259 else 5260 return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0"; 5261 case 2: 5262 if (TARGET_V9) 5263 return "ld\t%2, %0\n\tudiv\t%1, %0, %0"; 5264 else 5265 return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0"; 5266 case 3: 5267 if (TARGET_V9) 5268 return "ld\t%1, %0\n\tudiv\t%0, %2, %0"; 5269 else 5270 return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0"; 5271 default: 5272 gcc_unreachable (); 5273 } 5274} 5275 [(set_attr "type" "multi") 5276 (set (attr "length") 5277 (if_then_else (eq_attr "isa" "v9") 5278 (const_int 3) (const_int 5)))]) 5279 5280(define_insn "udivsi3_sp64" 5281 [(set (match_operand:SI 0 "register_operand" "=r") 5282 (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r") 5283 (match_operand:SI 2 "input_operand" "rI")))] 5284 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" 5285 "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0" 5286 [(set_attr "type" "multi") 5287 (set_attr "length" "2")]) 5288 5289(define_insn "udivdi3" 5290 [(set (match_operand:DI 0 "register_operand" "=r") 5291 (udiv:DI (match_operand:DI 1 "register_operand" "r") 5292 (match_operand:DI 2 "arith_operand" "rI")))] 5293 "TARGET_ARCH64" 5294 "udivx\t%1, %2, %0" 5295 [(set_attr "type" "idiv")]) 5296 5297(define_insn "*cmp_udiv_cc_set" 5298 [(set (reg:CC CC_REG) 5299 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r") 5300 (match_operand:SI 2 "arith_operand" "rI")) 5301 (const_int 0))) 5302 (set (match_operand:SI 0 "register_operand" "=r") 5303 (udiv:SI (match_dup 1) (match_dup 2)))] 5304 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" 5305{ 5306 output_asm_insn ("wr\t%%g0, 0, %%y", operands); 5307 5308 if (TARGET_V9) 5309 return "udivcc\t%1, %2, %0"; 5310 else 5311 return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0"; 5312} 5313 [(set_attr "type" "multi") 5314 (set (attr "length") 5315 (if_then_else (eq_attr "isa" "v9") 5316 (const_int 2) (const_int 5)))]) 5317 5318 5319;; SPARClet multiply/accumulate insns 5320 5321(define_insn "*smacsi" 5322 [(set (match_operand:SI 0 "register_operand" "=r") 5323 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r") 5324 (match_operand:SI 2 "arith_operand" "rI")) 5325 (match_operand:SI 3 "register_operand" "0")))] 5326 "TARGET_SPARCLET" 5327 "smac\t%1, %2, %0" 5328 [(set_attr "type" "imul")]) 5329 5330(define_insn "*smacdi" 5331 [(set (match_operand:DI 0 "register_operand" "=r") 5332 (plus:DI (mult:DI (sign_extend:DI 5333 (match_operand:SI 1 "register_operand" "%r")) 5334 (sign_extend:DI 5335 (match_operand:SI 2 "register_operand" "r"))) 5336 (match_operand:DI 3 "register_operand" "0")))] 5337 "TARGET_SPARCLET" 5338 "smacd\t%1, %2, %L0" 5339 [(set_attr "type" "imul")]) 5340 5341(define_insn "*umacdi" 5342 [(set (match_operand:DI 0 "register_operand" "=r") 5343 (plus:DI (mult:DI (zero_extend:DI 5344 (match_operand:SI 1 "register_operand" "%r")) 5345 (zero_extend:DI 5346 (match_operand:SI 2 "register_operand" "r"))) 5347 (match_operand:DI 3 "register_operand" "0")))] 5348 "TARGET_SPARCLET" 5349 "umacd\t%1, %2, %L0" 5350 [(set_attr "type" "imul")]) 5351 5352 5353;; Boolean instructions. 5354 5355(define_insn "anddi3" 5356 [(set (match_operand:DI 0 "register_operand" "=r") 5357 (and:DI (match_operand:DI 1 "arith_operand" "%r") 5358 (match_operand:DI 2 "arith_operand" "rI")))] 5359 "TARGET_ARCH64" 5360 "and\t%1, %2, %0") 5361 5362(define_insn "andsi3" 5363 [(set (match_operand:SI 0 "register_operand" "=r") 5364 (and:SI (match_operand:SI 1 "arith_operand" "%r") 5365 (match_operand:SI 2 "arith_operand" "rI")))] 5366 "" 5367 "and\t%1, %2, %0") 5368 5369(define_split 5370 [(set (match_operand:SI 0 "register_operand" "") 5371 (and:SI (match_operand:SI 1 "register_operand" "") 5372 (match_operand:SI 2 "const_compl_high_operand" ""))) 5373 (clobber (match_operand:SI 3 "register_operand" ""))] 5374 "" 5375 [(set (match_dup 3) (match_dup 4)) 5376 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))] 5377{ 5378 operands[4] = GEN_INT (~INTVAL (operands[2])); 5379}) 5380 5381(define_insn "*and_not_di_sp64" 5382 [(set (match_operand:DI 0 "register_operand" "=r") 5383 (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r")) 5384 (match_operand:DI 2 "register_operand" "r")))] 5385 "TARGET_ARCH64" 5386 "andn\t%2, %1, %0") 5387 5388(define_insn "*and_not_si" 5389 [(set (match_operand:SI 0 "register_operand" "=r") 5390 (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r")) 5391 (match_operand:SI 2 "register_operand" "r")))] 5392 "" 5393 "andn\t%2, %1, %0") 5394 5395(define_insn "iordi3" 5396 [(set (match_operand:DI 0 "register_operand" "=r") 5397 (ior:DI (match_operand:DI 1 "arith_operand" "%r") 5398 (match_operand:DI 2 "arith_operand" "rI")))] 5399 "TARGET_ARCH64" 5400 "or\t%1, %2, %0") 5401 5402(define_insn "iorsi3" 5403 [(set (match_operand:SI 0 "register_operand" "=r") 5404 (ior:SI (match_operand:SI 1 "arith_operand" "%r") 5405 (match_operand:SI 2 "arith_operand" "rI")))] 5406 "" 5407 "or\t%1, %2, %0") 5408 5409(define_split 5410 [(set (match_operand:SI 0 "register_operand" "") 5411 (ior:SI (match_operand:SI 1 "register_operand" "") 5412 (match_operand:SI 2 "const_compl_high_operand" ""))) 5413 (clobber (match_operand:SI 3 "register_operand" ""))] 5414 "" 5415 [(set (match_dup 3) (match_dup 4)) 5416 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))] 5417{ 5418 operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode); 5419}) 5420 5421(define_insn "*or_not_di_sp64" 5422 [(set (match_operand:DI 0 "register_operand" "=r") 5423 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r")) 5424 (match_operand:DI 2 "register_operand" "r")))] 5425 "TARGET_ARCH64" 5426 "orn\t%2, %1, %0") 5427 5428(define_insn "*or_not_si" 5429 [(set (match_operand:SI 0 "register_operand" "=r") 5430 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r")) 5431 (match_operand:SI 2 "register_operand" "r")))] 5432 "" 5433 "orn\t%2, %1, %0") 5434 5435(define_insn "xordi3" 5436 [(set (match_operand:DI 0 "register_operand" "=r") 5437 (xor:DI (match_operand:DI 1 "arith_operand" "%rJ") 5438 (match_operand:DI 2 "arith_operand" "rI")))] 5439 "TARGET_ARCH64" 5440 "xor\t%r1, %2, %0") 5441 5442(define_insn "xorsi3" 5443 [(set (match_operand:SI 0 "register_operand" "=r") 5444 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ") 5445 (match_operand:SI 2 "arith_operand" "rI")))] 5446 "" 5447 "xor\t%r1, %2, %0") 5448 5449(define_split 5450 [(set (match_operand:SI 0 "register_operand" "") 5451 (xor:SI (match_operand:SI 1 "register_operand" "") 5452 (match_operand:SI 2 "const_compl_high_operand" ""))) 5453 (clobber (match_operand:SI 3 "register_operand" ""))] 5454 "" 5455 [(set (match_dup 3) (match_dup 4)) 5456 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))] 5457{ 5458 operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode); 5459}) 5460 5461(define_split 5462 [(set (match_operand:SI 0 "register_operand" "") 5463 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "") 5464 (match_operand:SI 2 "const_compl_high_operand" "")))) 5465 (clobber (match_operand:SI 3 "register_operand" ""))] 5466 "" 5467 [(set (match_dup 3) (match_dup 4)) 5468 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))] 5469{ 5470 operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode); 5471}) 5472 5473(define_insn "*xor_not_di_sp64" 5474 [(set (match_operand:DI 0 "register_operand" "=r") 5475 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ") 5476 (match_operand:DI 2 "arith_operand" "rI"))))] 5477 "TARGET_ARCH64" 5478 "xnor\t%r1, %2, %0") 5479 5480(define_insn "*xor_not_si" 5481 [(set (match_operand:SI 0 "register_operand" "=r") 5482 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") 5483 (match_operand:SI 2 "arith_operand" "rI"))))] 5484 "" 5485 "xnor\t%r1, %2, %0") 5486 5487;; These correspond to the above in the case where we also (or only) 5488;; want to set the condition code. 5489 5490(define_insn "*cmp_cc_arith_op" 5491 [(set (reg:CC CC_REG) 5492 (compare:CC (match_operator:SI 2 "cc_arith_operator" 5493 [(match_operand:SI 0 "arith_operand" "%r") 5494 (match_operand:SI 1 "arith_operand" "rI")]) 5495 (const_int 0)))] 5496 "" 5497 "%A2cc\t%0, %1, %%g0" 5498 [(set_attr "type" "compare")]) 5499 5500(define_insn "*cmp_ccx_arith_op" 5501 [(set (reg:CCX CC_REG) 5502 (compare:CCX (match_operator:DI 2 "cc_arith_operator" 5503 [(match_operand:DI 0 "arith_operand" "%r") 5504 (match_operand:DI 1 "arith_operand" "rI")]) 5505 (const_int 0)))] 5506 "TARGET_ARCH64" 5507 "%A2cc\t%0, %1, %%g0" 5508 [(set_attr "type" "compare")]) 5509 5510(define_insn "*cmp_cc_arith_op_set" 5511 [(set (reg:CC CC_REG) 5512 (compare:CC (match_operator:SI 3 "cc_arith_operator" 5513 [(match_operand:SI 1 "arith_operand" "%r") 5514 (match_operand:SI 2 "arith_operand" "rI")]) 5515 (const_int 0))) 5516 (set (match_operand:SI 0 "register_operand" "=r") 5517 (match_operator:SI 4 "cc_arith_operator" 5518 [(match_dup 1) (match_dup 2)]))] 5519 "GET_CODE (operands[3]) == GET_CODE (operands[4])" 5520 "%A3cc\t%1, %2, %0" 5521 [(set_attr "type" "compare")]) 5522 5523(define_insn "*cmp_ccx_arith_op_set" 5524 [(set (reg:CCX CC_REG) 5525 (compare:CCX (match_operator:DI 3 "cc_arith_operator" 5526 [(match_operand:DI 1 "arith_operand" "%r") 5527 (match_operand:DI 2 "arith_operand" "rI")]) 5528 (const_int 0))) 5529 (set (match_operand:DI 0 "register_operand" "=r") 5530 (match_operator:DI 4 "cc_arith_operator" 5531 [(match_dup 1) (match_dup 2)]))] 5532 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])" 5533 "%A3cc\t%1, %2, %0" 5534 [(set_attr "type" "compare")]) 5535 5536(define_insn "*cmp_cc_xor_not" 5537 [(set (reg:CC CC_REG) 5538 (compare:CC 5539 (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ") 5540 (match_operand:SI 1 "arith_operand" "rI"))) 5541 (const_int 0)))] 5542 "" 5543 "xnorcc\t%r0, %1, %%g0" 5544 [(set_attr "type" "compare")]) 5545 5546(define_insn "*cmp_ccx_xor_not" 5547 [(set (reg:CCX CC_REG) 5548 (compare:CCX 5549 (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ") 5550 (match_operand:DI 1 "arith_operand" "rI"))) 5551 (const_int 0)))] 5552 "TARGET_ARCH64" 5553 "xnorcc\t%r0, %1, %%g0" 5554 [(set_attr "type" "compare")]) 5555 5556(define_insn "*cmp_cc_xor_not_set" 5557 [(set (reg:CC CC_REG) 5558 (compare:CC 5559 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ") 5560 (match_operand:SI 2 "arith_operand" "rI"))) 5561 (const_int 0))) 5562 (set (match_operand:SI 0 "register_operand" "=r") 5563 (not:SI (xor:SI (match_dup 1) (match_dup 2))))] 5564 "" 5565 "xnorcc\t%r1, %2, %0" 5566 [(set_attr "type" "compare")]) 5567 5568(define_insn "*cmp_ccx_xor_not_set" 5569 [(set (reg:CCX CC_REG) 5570 (compare:CCX 5571 (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ") 5572 (match_operand:DI 2 "arith_operand" "rI"))) 5573 (const_int 0))) 5574 (set (match_operand:DI 0 "register_operand" "=r") 5575 (not:DI (xor:DI (match_dup 1) (match_dup 2))))] 5576 "TARGET_ARCH64" 5577 "xnorcc\t%r1, %2, %0" 5578 [(set_attr "type" "compare")]) 5579 5580(define_insn "*cmp_cc_arith_op_not" 5581 [(set (reg:CC CC_REG) 5582 (compare:CC (match_operator:SI 2 "cc_arith_not_operator" 5583 [(not:SI (match_operand:SI 0 "arith_operand" "rI")) 5584 (match_operand:SI 1 "register_or_zero_operand" "rJ")]) 5585 (const_int 0)))] 5586 "" 5587 "%B2cc\t%r1, %0, %%g0" 5588 [(set_attr "type" "compare")]) 5589 5590(define_insn "*cmp_ccx_arith_op_not" 5591 [(set (reg:CCX CC_REG) 5592 (compare:CCX (match_operator:DI 2 "cc_arith_not_operator" 5593 [(not:DI (match_operand:DI 0 "arith_operand" "rI")) 5594 (match_operand:DI 1 "register_or_zero_operand" "rJ")]) 5595 (const_int 0)))] 5596 "TARGET_ARCH64" 5597 "%B2cc\t%r1, %0, %%g0" 5598 [(set_attr "type" "compare")]) 5599 5600(define_insn "*cmp_cc_arith_op_not_set" 5601 [(set (reg:CC CC_REG) 5602 (compare:CC (match_operator:SI 3 "cc_arith_not_operator" 5603 [(not:SI (match_operand:SI 1 "arith_operand" "rI")) 5604 (match_operand:SI 2 "register_or_zero_operand" "rJ")]) 5605 (const_int 0))) 5606 (set (match_operand:SI 0 "register_operand" "=r") 5607 (match_operator:SI 4 "cc_arith_not_operator" 5608 [(not:SI (match_dup 1)) (match_dup 2)]))] 5609 "GET_CODE (operands[3]) == GET_CODE (operands[4])" 5610 "%B3cc\t%r2, %1, %0" 5611 [(set_attr "type" "compare")]) 5612 5613(define_insn "*cmp_ccx_arith_op_not_set" 5614 [(set (reg:CCX CC_REG) 5615 (compare:CCX (match_operator:DI 3 "cc_arith_not_operator" 5616 [(not:DI (match_operand:DI 1 "arith_operand" "rI")) 5617 (match_operand:DI 2 "register_or_zero_operand" "rJ")]) 5618 (const_int 0))) 5619 (set (match_operand:DI 0 "register_operand" "=r") 5620 (match_operator:DI 4 "cc_arith_not_operator" 5621 [(not:DI (match_dup 1)) (match_dup 2)]))] 5622 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])" 5623 "%B3cc\t%r2, %1, %0" 5624 [(set_attr "type" "compare")]) 5625 5626;; We cannot use the "neg" pseudo insn because the Sun assembler 5627;; does not know how to make it work for constants. 5628 5629(define_expand "negdi2" 5630 [(set (match_operand:DI 0 "register_operand" "=r") 5631 (neg:DI (match_operand:DI 1 "register_operand" "r")))] 5632 "" 5633{ 5634 if (TARGET_ARCH32) 5635 { 5636 emit_insn (gen_negdi2_sp32 (operands[0], operands[1])); 5637 DONE; 5638 } 5639}) 5640 5641(define_expand "unegvdi3" 5642 [(parallel [(set (reg:CCXC CC_REG) 5643 (compare:CCXC (not:DI (match_operand:DI 1 "register_operand" "")) 5644 (const_int -1))) 5645 (set (match_operand:DI 0 "register_operand" "") 5646 (neg:DI (match_dup 1)))]) 5647 (set (pc) 5648 (if_then_else (ltu (reg:CCXC CC_REG) (const_int 0)) 5649 (label_ref (match_operand 2 "")) 5650 (pc)))] 5651 "" 5652{ 5653 if (TARGET_ARCH32) 5654 { 5655 emit_insn (gen_unegvdi3_sp32 (operands[0], operands[1])); 5656 rtx x = gen_rtx_LTU (VOIDmode, gen_rtx_REG (CCCmode, SPARC_ICC_REG), 5657 const0_rtx); 5658 emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[2])); 5659 DONE; 5660 } 5661}) 5662 5663(define_expand "negvdi3" 5664 [(parallel [(set (reg:CCXV CC_REG) 5665 (compare:CCXV (neg:DI (match_operand:DI 1 "register_operand" "")) 5666 (unspec:DI [(match_dup 1)] UNSPEC_NEGV))) 5667 (set (match_operand:DI 0 "register_operand" "") 5668 (neg:DI (match_dup 1)))]) 5669 (set (pc) 5670 (if_then_else (ne (reg:CCXV CC_REG) (const_int 0)) 5671 (label_ref (match_operand 2 "")) 5672 (pc)))] 5673 "" 5674{ 5675 if (TARGET_ARCH32) 5676 { 5677 emit_insn (gen_negvdi3_sp32 (operands[0], operands[1])); 5678 rtx x = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCVmode, SPARC_ICC_REG), 5679 const0_rtx); 5680 emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[2])); 5681 DONE; 5682 } 5683}) 5684 5685(define_insn_and_split "negdi2_sp32" 5686 [(set (match_operand:DI 0 "register_operand" "=&r") 5687 (neg:DI (match_operand:DI 1 "register_operand" "r"))) 5688 (clobber (reg:CC CC_REG))] 5689 "TARGET_ARCH32" 5690 "#" 5691 "&& reload_completed" 5692 [(parallel [(set (reg:CCC CC_REG) 5693 (compare:CCC (not:SI (match_dup 5)) (const_int -1))) 5694 (set (match_dup 4) (neg:SI (match_dup 5)))]) 5695 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3)) 5696 (ltu:SI (reg:CCC CC_REG) (const_int 0))))] 5697 "operands[2] = gen_highpart (SImode, operands[0]); 5698 operands[3] = gen_highpart (SImode, operands[1]); 5699 operands[4] = gen_lowpart (SImode, operands[0]); 5700 operands[5] = gen_lowpart (SImode, operands[1]);" 5701 [(set_attr "length" "2")]) 5702 5703(define_insn_and_split "unegvdi3_sp32" 5704 [(set (reg:CCC CC_REG) 5705 (compare:CCC (not:DI (match_operand:DI 1 "register_operand" "r")) 5706 (const_int -1))) 5707 (set (match_operand:DI 0 "register_operand" "=&r") 5708 (neg:DI (match_dup 1)))] 5709 "TARGET_ARCH32" 5710 "#" 5711 "&& reload_completed" 5712 [(parallel [(set (reg:CCC CC_REG) 5713 (compare:CCC (not:SI (match_dup 5)) (const_int -1))) 5714 (set (match_dup 4) (neg:SI (match_dup 5)))]) 5715 (parallel [(set (reg:CCC CC_REG) 5716 (compare:CCC (zero_extend:DI 5717 (neg:SI (plus:SI (match_dup 3) 5718 (ltu:SI (reg:CCC CC_REG) 5719 (const_int 0))))) 5720 (neg:DI (plus:DI (zero_extend:DI (match_dup 3)) 5721 (ltu:DI (reg:CCC CC_REG) 5722 (const_int 0)))))) 5723 (set (match_dup 2) (neg:SI (plus:SI (match_dup 3) 5724 (ltu:SI (reg:CCC CC_REG) 5725 (const_int 0)))))])] 5726 "operands[2] = gen_highpart (SImode, operands[0]); 5727 operands[3] = gen_highpart (SImode, operands[1]); 5728 operands[4] = gen_lowpart (SImode, operands[0]); 5729 operands[5] = gen_lowpart (SImode, operands[1]);" 5730 [(set_attr "length" "2")]) 5731 5732(define_insn_and_split "negvdi3_sp32" 5733 [(set (reg:CCV CC_REG) 5734 (compare:CCV (neg:DI (match_operand:DI 1 "register_operand" "r")) 5735 (unspec:DI [(match_dup 1)] UNSPEC_NEGV))) 5736 (set (match_operand:DI 0 "register_operand" "=&r") 5737 (neg:DI (match_dup 1)))] 5738 "TARGET_ARCH32" 5739 "#" 5740 "&& reload_completed" 5741 [(parallel [(set (reg:CCC CC_REG) 5742 (compare:CCC (not:SI (match_dup 5)) (const_int -1))) 5743 (set (match_dup 4) (neg:SI (match_dup 5)))]) 5744 (parallel [(set (reg:CCV CC_REG) 5745 (compare:CCV (neg:SI (plus:SI (match_dup 3) 5746 (ltu:SI (reg:CCC CC_REG) 5747 (const_int 0)))) 5748 (unspec:SI [(plus:SI (match_dup 3) 5749 (ltu:SI (reg:CCC CC_REG) 5750 (const_int 0)))] 5751 UNSPEC_NEGV))) 5752 (set (match_dup 2) (neg:SI (plus:SI (match_dup 3) 5753 (ltu:SI (reg:CCC CC_REG) 5754 (const_int 0)))))])] 5755 "operands[2] = gen_highpart (SImode, operands[0]); 5756 operands[3] = gen_highpart (SImode, operands[1]); 5757 operands[4] = gen_lowpart (SImode, operands[0]); 5758 operands[5] = gen_lowpart (SImode, operands[1]);" 5759 [(set_attr "length" "2")]) 5760 5761(define_insn "*negdi2_sp64" 5762 [(set (match_operand:DI 0 "register_operand" "=r") 5763 (neg:DI (match_operand:DI 1 "register_operand" "r")))] 5764 "TARGET_ARCH64" 5765 "sub\t%%g0, %1, %0") 5766 5767(define_insn "negsi2" 5768 [(set (match_operand:SI 0 "register_operand" "=r") 5769 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))] 5770 "" 5771 "sub\t%%g0, %1, %0") 5772 5773(define_expand "unegvsi3" 5774 [(parallel [(set (reg:CCC CC_REG) 5775 (compare:CCC (not:SI (match_operand:SI 1 "arith_operand" "")) 5776 (const_int -1))) 5777 (set (match_operand:SI 0 "register_operand" "") 5778 (neg:SI (match_dup 1)))]) 5779 (set (pc) 5780 (if_then_else (ltu (reg:CCC CC_REG) (const_int 0)) 5781 (label_ref (match_operand 2 "")) 5782 (pc)))] 5783 "") 5784 5785(define_expand "negvsi3" 5786 [(parallel [(set (reg:CCV CC_REG) 5787 (compare:CCV (neg:SI (match_operand:SI 1 "arith_operand" "")) 5788 (unspec:SI [(match_dup 1)] UNSPEC_NEGV))) 5789 (set (match_operand:SI 0 "register_operand" "") 5790 (neg:SI (match_dup 1)))]) 5791 (set (pc) 5792 (if_then_else (ne (reg:CCV CC_REG) (const_int 0)) 5793 (label_ref (match_operand 2 "")) 5794 (pc)))] 5795"") 5796 5797(define_insn "*cmp_ccnz_neg" 5798 [(set (reg:CCNZ CC_REG) 5799 (compare:CCNZ (neg:SI (match_operand:SI 0 "arith_operand" "rI")) 5800 (const_int 0)))] 5801 "" 5802 "subcc\t%%g0, %0, %%g0" 5803 [(set_attr "type" "compare")]) 5804 5805(define_insn "*cmp_ccxnz_neg" 5806 [(set (reg:CCXNZ CC_REG) 5807 (compare:CCXNZ (neg:DI (match_operand:DI 0 "arith_operand" "rI")) 5808 (const_int 0)))] 5809 "TARGET_ARCH64" 5810 "subcc\t%%g0, %0, %%g0" 5811 [(set_attr "type" "compare")]) 5812 5813(define_insn "*cmp_ccnz_neg_set" 5814 [(set (reg:CCNZ CC_REG) 5815 (compare:CCNZ (neg:SI (match_operand:SI 1 "arith_operand" "rI")) 5816 (const_int 0))) 5817 (set (match_operand:SI 0 "register_operand" "=r") 5818 (neg:SI (match_dup 1)))] 5819 "" 5820 "subcc\t%%g0, %1, %0" 5821 [(set_attr "type" "compare")]) 5822 5823(define_insn "*cmp_ccxnz_neg_set" 5824 [(set (reg:CCXNZ CC_REG) 5825 (compare:CCXNZ (neg:DI (match_operand:DI 1 "arith_operand" "rI")) 5826 (const_int 0))) 5827 (set (match_operand:DI 0 "register_operand" "=r") 5828 (neg:DI (match_dup 1)))] 5829 "TARGET_ARCH64" 5830 "subcc\t%%g0, %1, %0" 5831 [(set_attr "type" "compare")]) 5832 5833(define_insn "*cmp_ccc_neg_set" 5834 [(set (reg:CCC CC_REG) 5835 (compare:CCC (not:SI (match_operand:SI 1 "arith_operand" "rI")) 5836 (const_int -1))) 5837 (set (match_operand:SI 0 "register_operand" "=r") 5838 (neg:SI (match_dup 1)))] 5839 "" 5840 "subcc\t%%g0, %1, %0" 5841 [(set_attr "type" "compare")]) 5842 5843(define_insn "*cmp_ccxc_neg_set" 5844 [(set (reg:CCXC CC_REG) 5845 (compare:CCXC (not:DI (match_operand:DI 1 "arith_operand" "rI")) 5846 (const_int -1))) 5847 (set (match_operand:DI 0 "register_operand" "=r") 5848 (neg:DI (match_dup 1)))] 5849 "TARGET_ARCH64" 5850 "subcc\t%%g0, %1, %0" 5851 [(set_attr "type" "compare")]) 5852 5853(define_insn "*cmp_ccc_neg_sltu_set" 5854 [(set (reg:CCC CC_REG) 5855 (compare:CCC (zero_extend:DI 5856 (neg:SI (plus:SI (match_operand:SI 1 "arith_operand" "rI") 5857 (ltu:SI (reg:CCC CC_REG) 5858 (const_int 0))))) 5859 (neg:DI (plus:DI (zero_extend:DI (match_dup 1)) 5860 (ltu:DI (reg:CCC CC_REG) 5861 (const_int 0)))))) 5862 (set (match_operand:SI 0 "register_operand" "=r") 5863 (neg:SI (plus:SI (match_dup 1) 5864 (ltu:SI (reg:CCC CC_REG) (const_int 0)))))] 5865 "" 5866 "subxcc\t%%g0, %1, %0" 5867 [(set_attr "type" "compare")]) 5868 5869(define_insn "*cmp_ccv_neg" 5870 [(set (reg:CCV CC_REG) 5871 (compare:CCV (neg:SI (match_operand:SI 0 "arith_operand" "rI")) 5872 (unspec:SI [(match_dup 0)] UNSPEC_NEGV)))] 5873 "" 5874 "subcc\t%%g0, %0, %%g0" 5875 [(set_attr "type" "compare")]) 5876 5877(define_insn "*cmp_ccxv_neg" 5878 [(set (reg:CCXV CC_REG) 5879 (compare:CCXV (neg:DI (match_operand:DI 0 "arith_operand" "rI")) 5880 (unspec:DI [(match_dup 0)] UNSPEC_NEGV)))] 5881 "TARGET_ARCH64" 5882 "subcc\t%%g0, %0, %%g0" 5883 [(set_attr "type" "compare")]) 5884 5885(define_insn "*cmp_ccv_neg_set" 5886 [(set (reg:CCV CC_REG) 5887 (compare:CCV (neg:SI (match_operand:SI 1 "arith_operand" "rI")) 5888 (unspec:SI [(match_dup 1)] UNSPEC_NEGV))) 5889 (set (match_operand:SI 0 "register_operand" "=r") 5890 (neg:SI (match_dup 1)))] 5891 "" 5892 "subcc\t%%g0, %1, %0" 5893 [(set_attr "type" "compare")]) 5894 5895(define_insn "*cmp_ccxv_neg_set" 5896 [(set (reg:CCXV CC_REG) 5897 (compare:CCXV (neg:DI (match_operand:DI 1 "arith_operand" "rI")) 5898 (unspec:DI [(match_dup 1)] UNSPEC_NEGV))) 5899 (set (match_operand:DI 0 "register_operand" "=r") 5900 (neg:DI (match_dup 1)))] 5901 "TARGET_ARCH64" 5902 "subcc\t%%g0, %1, %0" 5903 [(set_attr "type" "compare")]) 5904 5905(define_insn "*cmp_ccv_neg_sltu_set" 5906 [(set (reg:CCV CC_REG) 5907 (compare:CCV (neg:SI (plus:SI (match_operand:SI 1 "arith_operand" "rI") 5908 (ltu:SI (reg:CCC CC_REG) (const_int 0)))) 5909 (unspec:SI [(plus:SI (match_dup 1) 5910 (ltu:SI (reg:CCC CC_REG) 5911 (const_int 0)))] 5912 UNSPEC_NEGV))) 5913 (set (match_operand:SI 0 "register_operand" "=r") 5914 (neg:SI (plus:SI (match_dup 1) 5915 (ltu:SI (reg:CCC CC_REG) (const_int 0)))))] 5916 "" 5917 "subxcc\t%%g0, %1, %0" 5918 [(set_attr "type" "compare")]) 5919 5920 5921(define_insn "one_cmpldi2" 5922 [(set (match_operand:DI 0 "register_operand" "=r") 5923 (not:DI (match_operand:DI 1 "arith_operand" "rI")))] 5924 "TARGET_ARCH64" 5925 "xnor\t%%g0, %1, %0") 5926 5927(define_insn "one_cmplsi2" 5928 [(set (match_operand:SI 0 "register_operand" "=r") 5929 (not:SI (match_operand:SI 1 "arith_operand" "rI")))] 5930 "" 5931 "xnor\t%%g0, %1, %0") 5932 5933(define_insn "*cmp_cc_not" 5934 [(set (reg:CC CC_REG) 5935 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI")) 5936 (const_int 0)))] 5937 "" 5938 "xnorcc\t%%g0, %0, %%g0" 5939 [(set_attr "type" "compare")]) 5940 5941(define_insn "*cmp_ccx_not" 5942 [(set (reg:CCX CC_REG) 5943 (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI")) 5944 (const_int 0)))] 5945 "TARGET_ARCH64" 5946 "xnorcc\t%%g0, %0, %%g0" 5947 [(set_attr "type" "compare")]) 5948 5949(define_insn "*cmp_cc_set_not" 5950 [(set (reg:CC CC_REG) 5951 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI")) 5952 (const_int 0))) 5953 (set (match_operand:SI 0 "register_operand" "=r") 5954 (not:SI (match_dup 1)))] 5955 "" 5956 "xnorcc\t%%g0, %1, %0" 5957 [(set_attr "type" "compare")]) 5958 5959(define_insn "*cmp_ccx_set_not" 5960 [(set (reg:CCX CC_REG) 5961 (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI")) 5962 (const_int 0))) 5963 (set (match_operand:DI 0 "register_operand" "=r") 5964 (not:DI (match_dup 1)))] 5965 "TARGET_ARCH64" 5966 "xnorcc\t%%g0, %1, %0" 5967 [(set_attr "type" "compare")]) 5968 5969(define_insn "*cmp_cc_set" 5970 [(set (match_operand:SI 0 "register_operand" "=r") 5971 (match_operand:SI 1 "register_operand" "r")) 5972 (set (reg:CC CC_REG) 5973 (compare:CC (match_dup 1) (const_int 0)))] 5974 "" 5975 "orcc\t%1, 0, %0" 5976 [(set_attr "type" "compare")]) 5977 5978(define_insn "*cmp_ccx_set64" 5979 [(set (match_operand:DI 0 "register_operand" "=r") 5980 (match_operand:DI 1 "register_operand" "r")) 5981 (set (reg:CCX CC_REG) 5982 (compare:CCX (match_dup 1) (const_int 0)))] 5983 "TARGET_ARCH64" 5984 "orcc\t%1, 0, %0" 5985 [(set_attr "type" "compare")]) 5986 5987 5988;; Floating point arithmetic instructions. 5989 5990(define_expand "addtf3" 5991 [(set (match_operand:TF 0 "nonimmediate_operand" "") 5992 (plus:TF (match_operand:TF 1 "general_operand" "") 5993 (match_operand:TF 2 "general_operand" "")))] 5994 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" 5995 "emit_tfmode_binop (PLUS, operands); DONE;") 5996 5997(define_insn "*addtf3_hq" 5998 [(set (match_operand:TF 0 "register_operand" "=e") 5999 (plus:TF (match_operand:TF 1 "register_operand" "e") 6000 (match_operand:TF 2 "register_operand" "e")))] 6001 "TARGET_FPU && TARGET_HARD_QUAD" 6002 "faddq\t%1, %2, %0" 6003 [(set_attr "type" "fp")]) 6004 6005(define_insn "adddf3" 6006 [(set (match_operand:DF 0 "register_operand" "=e") 6007 (plus:DF (match_operand:DF 1 "register_operand" "e") 6008 (match_operand:DF 2 "register_operand" "e")))] 6009 "TARGET_FPU" 6010 "faddd\t%1, %2, %0" 6011 [(set_attr "type" "fp") 6012 (set_attr "fptype" "double")]) 6013 6014(define_insn "addsf3" 6015 [(set (match_operand:SF 0 "register_operand" "=f") 6016 (plus:SF (match_operand:SF 1 "register_operand" "f") 6017 (match_operand:SF 2 "register_operand" "f")))] 6018 "TARGET_FPU" 6019 "fadds\t%1, %2, %0" 6020 [(set_attr "type" "fp")]) 6021 6022(define_expand "subtf3" 6023 [(set (match_operand:TF 0 "nonimmediate_operand" "") 6024 (minus:TF (match_operand:TF 1 "general_operand" "") 6025 (match_operand:TF 2 "general_operand" "")))] 6026 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" 6027 "emit_tfmode_binop (MINUS, operands); DONE;") 6028 6029(define_insn "*subtf3_hq" 6030 [(set (match_operand:TF 0 "register_operand" "=e") 6031 (minus:TF (match_operand:TF 1 "register_operand" "e") 6032 (match_operand:TF 2 "register_operand" "e")))] 6033 "TARGET_FPU && TARGET_HARD_QUAD" 6034 "fsubq\t%1, %2, %0" 6035 [(set_attr "type" "fp")]) 6036 6037(define_insn "subdf3" 6038 [(set (match_operand:DF 0 "register_operand" "=e") 6039 (minus:DF (match_operand:DF 1 "register_operand" "e") 6040 (match_operand:DF 2 "register_operand" "e")))] 6041 "TARGET_FPU" 6042 "fsubd\t%1, %2, %0" 6043 [(set_attr "type" "fp") 6044 (set_attr "fptype" "double")]) 6045 6046(define_insn "subsf3" 6047 [(set (match_operand:SF 0 "register_operand" "=f") 6048 (minus:SF (match_operand:SF 1 "register_operand" "f") 6049 (match_operand:SF 2 "register_operand" "f")))] 6050 "TARGET_FPU" 6051 "fsubs\t%1, %2, %0" 6052 [(set_attr "type" "fp")]) 6053 6054(define_expand "multf3" 6055 [(set (match_operand:TF 0 "nonimmediate_operand" "") 6056 (mult:TF (match_operand:TF 1 "general_operand" "") 6057 (match_operand:TF 2 "general_operand" "")))] 6058 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" 6059 "emit_tfmode_binop (MULT, operands); DONE;") 6060 6061(define_insn "*multf3_hq" 6062 [(set (match_operand:TF 0 "register_operand" "=e") 6063 (mult:TF (match_operand:TF 1 "register_operand" "e") 6064 (match_operand:TF 2 "register_operand" "e")))] 6065 "TARGET_FPU && TARGET_HARD_QUAD" 6066 "fmulq\t%1, %2, %0" 6067 [(set_attr "type" "fpmul")]) 6068 6069(define_insn "muldf3" 6070 [(set (match_operand:DF 0 "register_operand" "=e") 6071 (mult:DF (match_operand:DF 1 "register_operand" "e") 6072 (match_operand:DF 2 "register_operand" "e")))] 6073 "TARGET_FPU" 6074 "fmuld\t%1, %2, %0" 6075 [(set_attr "type" "fpmul") 6076 (set_attr "fptype" "double")]) 6077 6078(define_insn "mulsf3" 6079 [(set (match_operand:SF 0 "register_operand" "=f") 6080 (mult:SF (match_operand:SF 1 "register_operand" "f") 6081 (match_operand:SF 2 "register_operand" "f")))] 6082 "TARGET_FPU" 6083 "fmuls\t%1, %2, %0" 6084 [(set_attr "type" "fpmul")]) 6085 6086(define_insn "fmadf4" 6087 [(set (match_operand:DF 0 "register_operand" "=e") 6088 (fma:DF (match_operand:DF 1 "register_operand" "e") 6089 (match_operand:DF 2 "register_operand" "e") 6090 (match_operand:DF 3 "register_operand" "e")))] 6091 "TARGET_FMAF" 6092 "fmaddd\t%1, %2, %3, %0" 6093 [(set_attr "type" "fpmul")]) 6094 6095(define_insn "fmsdf4" 6096 [(set (match_operand:DF 0 "register_operand" "=e") 6097 (fma:DF (match_operand:DF 1 "register_operand" "e") 6098 (match_operand:DF 2 "register_operand" "e") 6099 (neg:DF (match_operand:DF 3 "register_operand" "e"))))] 6100 "TARGET_FMAF" 6101 "fmsubd\t%1, %2, %3, %0" 6102 [(set_attr "type" "fpmul")]) 6103 6104(define_insn "*nfmadf4" 6105 [(set (match_operand:DF 0 "register_operand" "=e") 6106 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e") 6107 (match_operand:DF 2 "register_operand" "e") 6108 (match_operand:DF 3 "register_operand" "e"))))] 6109 "TARGET_FMAF" 6110 "fnmaddd\t%1, %2, %3, %0" 6111 [(set_attr "type" "fpmul")]) 6112 6113(define_insn "*nfmsdf4" 6114 [(set (match_operand:DF 0 "register_operand" "=e") 6115 (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e") 6116 (match_operand:DF 2 "register_operand" "e") 6117 (neg:DF (match_operand:DF 3 "register_operand" "e")))))] 6118 "TARGET_FMAF" 6119 "fnmsubd\t%1, %2, %3, %0" 6120 [(set_attr "type" "fpmul")]) 6121 6122(define_insn "fmasf4" 6123 [(set (match_operand:SF 0 "register_operand" "=f") 6124 (fma:SF (match_operand:SF 1 "register_operand" "f") 6125 (match_operand:SF 2 "register_operand" "f") 6126 (match_operand:SF 3 "register_operand" "f")))] 6127 "TARGET_FMAF" 6128 "fmadds\t%1, %2, %3, %0" 6129 [(set_attr "type" "fpmul")]) 6130 6131(define_insn "fmssf4" 6132 [(set (match_operand:SF 0 "register_operand" "=f") 6133 (fma:SF (match_operand:SF 1 "register_operand" "f") 6134 (match_operand:SF 2 "register_operand" "f") 6135 (neg:SF (match_operand:SF 3 "register_operand" "f"))))] 6136 "TARGET_FMAF" 6137 "fmsubs\t%1, %2, %3, %0" 6138 [(set_attr "type" "fpmul")]) 6139 6140(define_insn "*nfmasf4" 6141 [(set (match_operand:SF 0 "register_operand" "=f") 6142 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f") 6143 (match_operand:SF 2 "register_operand" "f") 6144 (match_operand:SF 3 "register_operand" "f"))))] 6145 "TARGET_FMAF" 6146 "fnmadds\t%1, %2, %3, %0" 6147 [(set_attr "type" "fpmul")]) 6148 6149(define_insn "*nfmssf4" 6150 [(set (match_operand:SF 0 "register_operand" "=f") 6151 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f") 6152 (match_operand:SF 2 "register_operand" "f") 6153 (neg:SF (match_operand:SF 3 "register_operand" "f")))))] 6154 "TARGET_FMAF" 6155 "fnmsubs\t%1, %2, %3, %0" 6156 [(set_attr "type" "fpmul")]) 6157 6158(define_insn "*muldf3_extend" 6159 [(set (match_operand:DF 0 "register_operand" "=e") 6160 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f")) 6161 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))] 6162 "TARGET_FSMULD" 6163 "fsmuld\t%1, %2, %0" 6164 [(set_attr "type" "fpmul") 6165 (set_attr "fptype" "double")]) 6166 6167(define_insn "*multf3_extend" 6168 [(set (match_operand:TF 0 "register_operand" "=e") 6169 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e")) 6170 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))] 6171 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD" 6172 "fdmulq\t%1, %2, %0" 6173 [(set_attr "type" "fpmul")]) 6174 6175(define_expand "divtf3" 6176 [(set (match_operand:TF 0 "nonimmediate_operand" "") 6177 (div:TF (match_operand:TF 1 "general_operand" "") 6178 (match_operand:TF 2 "general_operand" "")))] 6179 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" 6180 "emit_tfmode_binop (DIV, operands); DONE;") 6181 6182;; don't have timing for quad-prec. divide. 6183(define_insn "*divtf3_hq" 6184 [(set (match_operand:TF 0 "register_operand" "=e") 6185 (div:TF (match_operand:TF 1 "register_operand" "e") 6186 (match_operand:TF 2 "register_operand" "e")))] 6187 "TARGET_FPU && TARGET_HARD_QUAD" 6188 "fdivq\t%1, %2, %0" 6189 [(set_attr "type" "fpdivs")]) 6190 6191(define_expand "divdf3" 6192 [(set (match_operand:DF 0 "register_operand" "=e") 6193 (div:DF (match_operand:DF 1 "register_operand" "e") 6194 (match_operand:DF 2 "register_operand" "e")))] 6195 "TARGET_FPU" 6196 "") 6197 6198(define_insn "*divdf3_nofix" 6199 [(set (match_operand:DF 0 "register_operand" "=e") 6200 (div:DF (match_operand:DF 1 "register_operand" "e") 6201 (match_operand:DF 2 "register_operand" "e")))] 6202 "TARGET_FPU && !sparc_fix_ut699" 6203 "fdivd\t%1, %2, %0" 6204 [(set_attr "type" "fpdivd") 6205 (set_attr "fptype" "double")]) 6206 6207(define_insn "*divdf3_fix" 6208 [(set (match_operand:DF 0 "register_operand" "=e") 6209 (div:DF (match_operand:DF 1 "register_operand" "e") 6210 (match_operand:DF 2 "register_operand" "e")))] 6211 "TARGET_FPU && sparc_fix_ut699" 6212 "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]\n\tnop" 6213 [(set_attr "type" "fpdivd") 6214 (set_attr "fptype" "double") 6215 (set_attr "length" "3")]) 6216 6217(define_insn "divsf3" 6218 [(set (match_operand:SF 0 "register_operand" "=f") 6219 (div:SF (match_operand:SF 1 "register_operand" "f") 6220 (match_operand:SF 2 "register_operand" "f")))] 6221 "TARGET_FPU && !sparc_fix_ut699" 6222 "fdivs\t%1, %2, %0" 6223 [(set_attr "type" "fpdivs")]) 6224 6225(define_expand "negtf2" 6226 [(set (match_operand:TF 0 "register_operand" "") 6227 (neg:TF (match_operand:TF 1 "register_operand" "")))] 6228 "TARGET_FPU" 6229 "") 6230 6231(define_insn "*negtf2_hq" 6232 [(set (match_operand:TF 0 "register_operand" "=e") 6233 (neg:TF (match_operand:TF 1 "register_operand" "e")))] 6234 "TARGET_FPU && TARGET_HARD_QUAD" 6235 "fnegq\t%1, %0" 6236 [(set_attr "type" "fpmove")]) 6237 6238(define_insn_and_split "*negtf2" 6239 [(set (match_operand:TF 0 "register_operand" "=e") 6240 (neg:TF (match_operand:TF 1 "register_operand" "e")))] 6241 "TARGET_FPU && !TARGET_HARD_QUAD" 6242 "#" 6243 "&& reload_completed" 6244 [(clobber (const_int 0))] 6245{ 6246 rtx set_dest = operands[0]; 6247 rtx set_src = operands[1]; 6248 rtx dest1, dest2; 6249 rtx src1, src2; 6250 6251 dest1 = gen_df_reg (set_dest, 0); 6252 dest2 = gen_df_reg (set_dest, 1); 6253 src1 = gen_df_reg (set_src, 0); 6254 src2 = gen_df_reg (set_src, 1); 6255 6256 /* Now emit using the real source and destination we found, swapping 6257 the order if we detect overlap. */ 6258 if (reg_overlap_mentioned_p (dest1, src2)) 6259 { 6260 emit_insn (gen_movdf (dest2, src2)); 6261 emit_insn (gen_negdf2 (dest1, src1)); 6262 } 6263 else 6264 { 6265 emit_insn (gen_negdf2 (dest1, src1)); 6266 if (REGNO (dest2) != REGNO (src2)) 6267 emit_insn (gen_movdf (dest2, src2)); 6268 } 6269 DONE; 6270} 6271 [(set_attr "length" "2")]) 6272 6273(define_expand "negdf2" 6274 [(set (match_operand:DF 0 "register_operand" "") 6275 (neg:DF (match_operand:DF 1 "register_operand" "")))] 6276 "TARGET_FPU" 6277 "") 6278 6279(define_insn_and_split "*negdf2_notv9" 6280 [(set (match_operand:DF 0 "register_operand" "=e") 6281 (neg:DF (match_operand:DF 1 "register_operand" "e")))] 6282 "TARGET_FPU && !TARGET_V9" 6283 "#" 6284 "&& reload_completed" 6285 [(clobber (const_int 0))] 6286{ 6287 rtx set_dest = operands[0]; 6288 rtx set_src = operands[1]; 6289 rtx dest1, dest2; 6290 rtx src1, src2; 6291 6292 dest1 = gen_highpart (SFmode, set_dest); 6293 dest2 = gen_lowpart (SFmode, set_dest); 6294 src1 = gen_highpart (SFmode, set_src); 6295 src2 = gen_lowpart (SFmode, set_src); 6296 6297 /* Now emit using the real source and destination we found, swapping 6298 the order if we detect overlap. */ 6299 if (reg_overlap_mentioned_p (dest1, src2)) 6300 { 6301 emit_insn (gen_movsf (dest2, src2)); 6302 emit_insn (gen_negsf2 (dest1, src1)); 6303 } 6304 else 6305 { 6306 emit_insn (gen_negsf2 (dest1, src1)); 6307 if (REGNO (dest2) != REGNO (src2)) 6308 emit_insn (gen_movsf (dest2, src2)); 6309 } 6310 DONE; 6311} 6312 [(set_attr "length" "2")]) 6313 6314(define_insn "*negdf2_v9" 6315 [(set (match_operand:DF 0 "register_operand" "=e") 6316 (neg:DF (match_operand:DF 1 "register_operand" "e")))] 6317 "TARGET_FPU && TARGET_V9" 6318 "fnegd\t%1, %0" 6319 [(set_attr "type" "fpmove") 6320 (set_attr "fptype" "double")]) 6321 6322(define_insn "negsf2" 6323 [(set (match_operand:SF 0 "register_operand" "=f") 6324 (neg:SF (match_operand:SF 1 "register_operand" "f")))] 6325 "TARGET_FPU" 6326 "fnegs\t%1, %0" 6327 [(set_attr "type" "fpmove")]) 6328 6329(define_expand "abstf2" 6330 [(set (match_operand:TF 0 "register_operand" "") 6331 (abs:TF (match_operand:TF 1 "register_operand" "")))] 6332 "TARGET_FPU" 6333 "") 6334 6335(define_insn "*abstf2_hq" 6336 [(set (match_operand:TF 0 "register_operand" "=e") 6337 (abs:TF (match_operand:TF 1 "register_operand" "e")))] 6338 "TARGET_FPU && TARGET_HARD_QUAD" 6339 "fabsq\t%1, %0" 6340 [(set_attr "type" "fpmove")]) 6341 6342(define_insn_and_split "*abstf2" 6343 [(set (match_operand:TF 0 "register_operand" "=e") 6344 (abs:TF (match_operand:TF 1 "register_operand" "e")))] 6345 "TARGET_FPU && !TARGET_HARD_QUAD" 6346 "#" 6347 "&& reload_completed" 6348 [(clobber (const_int 0))] 6349{ 6350 rtx set_dest = operands[0]; 6351 rtx set_src = operands[1]; 6352 rtx dest1, dest2; 6353 rtx src1, src2; 6354 6355 dest1 = gen_df_reg (set_dest, 0); 6356 dest2 = gen_df_reg (set_dest, 1); 6357 src1 = gen_df_reg (set_src, 0); 6358 src2 = gen_df_reg (set_src, 1); 6359 6360 /* Now emit using the real source and destination we found, swapping 6361 the order if we detect overlap. */ 6362 if (reg_overlap_mentioned_p (dest1, src2)) 6363 { 6364 emit_insn (gen_movdf (dest2, src2)); 6365 emit_insn (gen_absdf2 (dest1, src1)); 6366 } 6367 else 6368 { 6369 emit_insn (gen_absdf2 (dest1, src1)); 6370 if (REGNO (dest2) != REGNO (src2)) 6371 emit_insn (gen_movdf (dest2, src2)); 6372 } 6373 DONE; 6374} 6375 [(set_attr "length" "2")]) 6376 6377(define_expand "absdf2" 6378 [(set (match_operand:DF 0 "register_operand" "") 6379 (abs:DF (match_operand:DF 1 "register_operand" "")))] 6380 "TARGET_FPU" 6381 "") 6382 6383(define_insn_and_split "*absdf2_notv9" 6384 [(set (match_operand:DF 0 "register_operand" "=e") 6385 (abs:DF (match_operand:DF 1 "register_operand" "e")))] 6386 "TARGET_FPU && !TARGET_V9" 6387 "#" 6388 "&& reload_completed" 6389 [(clobber (const_int 0))] 6390{ 6391 rtx set_dest = operands[0]; 6392 rtx set_src = operands[1]; 6393 rtx dest1, dest2; 6394 rtx src1, src2; 6395 6396 dest1 = gen_highpart (SFmode, set_dest); 6397 dest2 = gen_lowpart (SFmode, set_dest); 6398 src1 = gen_highpart (SFmode, set_src); 6399 src2 = gen_lowpart (SFmode, set_src); 6400 6401 /* Now emit using the real source and destination we found, swapping 6402 the order if we detect overlap. */ 6403 if (reg_overlap_mentioned_p (dest1, src2)) 6404 { 6405 emit_insn (gen_movsf (dest2, src2)); 6406 emit_insn (gen_abssf2 (dest1, src1)); 6407 } 6408 else 6409 { 6410 emit_insn (gen_abssf2 (dest1, src1)); 6411 if (REGNO (dest2) != REGNO (src2)) 6412 emit_insn (gen_movsf (dest2, src2)); 6413 } 6414 DONE; 6415} 6416 [(set_attr "length" "2")]) 6417 6418(define_insn "*absdf2_v9" 6419 [(set (match_operand:DF 0 "register_operand" "=e") 6420 (abs:DF (match_operand:DF 1 "register_operand" "e")))] 6421 "TARGET_FPU && TARGET_V9" 6422 "fabsd\t%1, %0" 6423 [(set_attr "type" "fpmove") 6424 (set_attr "fptype" "double")]) 6425 6426(define_insn "abssf2" 6427 [(set (match_operand:SF 0 "register_operand" "=f") 6428 (abs:SF (match_operand:SF 1 "register_operand" "f")))] 6429 "TARGET_FPU" 6430 "fabss\t%1, %0" 6431 [(set_attr "type" "fpmove")]) 6432 6433(define_expand "sqrttf2" 6434 [(set (match_operand:TF 0 "nonimmediate_operand" "") 6435 (sqrt:TF (match_operand:TF 1 "general_operand" "")))] 6436 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" 6437 "emit_tfmode_unop (SQRT, operands); DONE;") 6438 6439(define_insn "*sqrttf2_hq" 6440 [(set (match_operand:TF 0 "register_operand" "=e") 6441 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))] 6442 "TARGET_FPU && TARGET_HARD_QUAD" 6443 "fsqrtq\t%1, %0" 6444 [(set_attr "type" "fpsqrts")]) 6445 6446(define_expand "sqrtdf2" 6447 [(set (match_operand:DF 0 "register_operand" "=e") 6448 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))] 6449 "TARGET_FPU" 6450 "") 6451 6452(define_insn "*sqrtdf2_nofix" 6453 [(set (match_operand:DF 0 "register_operand" "=e") 6454 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))] 6455 "TARGET_FPU && !sparc_fix_ut699" 6456 "fsqrtd\t%1, %0" 6457 [(set_attr "type" "fpsqrtd") 6458 (set_attr "fptype" "double")]) 6459 6460(define_insn "*sqrtdf2_fix" 6461 [(set (match_operand:DF 0 "register_operand" "=e") 6462 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))] 6463 "TARGET_FPU && sparc_fix_ut699" 6464 "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]\n\tnop" 6465 [(set_attr "type" "fpsqrtd") 6466 (set_attr "fptype" "double") 6467 (set_attr "length" "3")]) 6468 6469(define_insn "sqrtsf2" 6470 [(set (match_operand:SF 0 "register_operand" "=f") 6471 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))] 6472 "TARGET_FPU && !sparc_fix_ut699" 6473 "fsqrts\t%1, %0" 6474 [(set_attr "type" "fpsqrts")]) 6475 6476 6477;; Arithmetic shift instructions. 6478 6479(define_insn "ashlsi3" 6480 [(set (match_operand:SI 0 "register_operand" "=r") 6481 (ashift:SI (match_operand:SI 1 "register_operand" "r") 6482 (match_operand:SI 2 "arith_operand" "rI")))] 6483 "" 6484{ 6485 if (GET_CODE (operands[2]) == CONST_INT) 6486 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); 6487 return "sll\t%1, %2, %0"; 6488} 6489 [(set_attr "type" "shift")]) 6490 6491(define_expand "ashldi3" 6492 [(set (match_operand:DI 0 "register_operand" "=r") 6493 (ashift:DI (match_operand:DI 1 "register_operand" "r") 6494 (match_operand:SI 2 "arith_operand" "rI")))] 6495 "TARGET_ARCH64 || TARGET_V8PLUS" 6496{ 6497 if (TARGET_ARCH32) 6498 { 6499 if (GET_CODE (operands[2]) == CONST_INT) 6500 FAIL; 6501 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2])); 6502 DONE; 6503 } 6504}) 6505 6506(define_insn "*ashldi3_sp64" 6507 [(set (match_operand:DI 0 "register_operand" "=r") 6508 (ashift:DI (match_operand:DI 1 "register_operand" "r") 6509 (match_operand:SI 2 "arith_operand" "rI")))] 6510 "TARGET_ARCH64" 6511{ 6512 if (GET_CODE (operands[2]) == CONST_INT) 6513 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); 6514 return "sllx\t%1, %2, %0"; 6515} 6516 [(set_attr "type" "shift")]) 6517 6518(define_insn "ashldi3_v8plus" 6519 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r") 6520 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI") 6521 (match_operand:SI 2 "arith_operand" "rI,rI,rI"))) 6522 (clobber (match_scratch:SI 3 "=X,X,&h"))] 6523 "TARGET_V8PLUS" 6524{ 6525 return output_v8plus_shift (insn ,operands, \"sllx\"); 6526} 6527 [(set_attr "type" "multi") 6528 (set_attr "length" "5,5,6")]) 6529 6530(define_insn "*cmp_ccnz_ashift_1" 6531 [(set (reg:CCNZ CC_REG) 6532 (compare:CCNZ (ashift:SI (match_operand:SI 0 "register_operand" "r") 6533 (const_int 1)) 6534 (const_int 0)))] 6535 "" 6536 "addcc\t%0, %0, %%g0" 6537 [(set_attr "type" "compare")]) 6538 6539(define_insn "*cmp_ccnz_set_ashift_1" 6540 [(set (reg:CCNZ CC_REG) 6541 (compare:CCNZ (ashift:SI (match_operand:SI 1 "register_operand" "r") 6542 (const_int 1)) 6543 (const_int 0))) 6544 (set (match_operand:SI 0 "register_operand" "=r") 6545 (ashift:SI (match_dup 1) (const_int 1)))] 6546 "" 6547 "addcc\t%1, %1, %0" 6548 [(set_attr "type" "compare")]) 6549 6550(define_insn "ashrsi3" 6551 [(set (match_operand:SI 0 "register_operand" "=r") 6552 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") 6553 (match_operand:SI 2 "arith_operand" "rI")))] 6554 "" 6555{ 6556 if (GET_CODE (operands[2]) == CONST_INT) 6557 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); 6558 return "sra\t%1, %2, %0"; 6559} 6560 [(set_attr "type" "shift")]) 6561 6562(define_insn "*ashrsi3_extend0" 6563 [(set (match_operand:DI 0 "register_operand" "=r") 6564 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") 6565 (match_operand:SI 2 "arith_operand" "rI"))))] 6566 "TARGET_ARCH64" 6567{ 6568 if (GET_CODE (operands[2]) == CONST_INT) 6569 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); 6570 return "sra\t%1, %2, %0"; 6571} 6572 [(set_attr "type" "shift")]) 6573 6574;; This handles the case where 6575;; (sign_extend:DI (ashiftrt:SI (match_operand:SI) (match_operand:SI))) 6576;; but combiner "simplifies" it for us. 6577(define_insn "*ashrsi3_extend1" 6578 [(set (match_operand:DI 0 "register_operand" "=r") 6579 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0) 6580 (const_int 32)) 6581 (match_operand:SI 2 "small_int_operand" "I")))] 6582 "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64" 6583{ 6584 operands[2] = GEN_INT (INTVAL (operands[2]) - 32); 6585 return "sra\t%1, %2, %0"; 6586} 6587 [(set_attr "type" "shift")]) 6588 6589;; This handles the case where 6590;; (ashiftrt:DI (sign_extend:DI (match_operand:SI)) (const_int)) 6591;; but combiner "simplifies" it for us. 6592(define_insn "*ashrsi3_extend2" 6593 [(set (match_operand:DI 0 "register_operand" "=r") 6594 (sign_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0) 6595 (match_operand 2 "small_int_operand" "I") 6596 (const_int 32)))] 6597 "TARGET_ARCH64 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 32" 6598{ 6599 operands[2] = GEN_INT (32 - INTVAL (operands[2])); 6600 return "sra\t%1, %2, %0"; 6601} 6602 [(set_attr "type" "shift")]) 6603 6604(define_expand "ashrdi3" 6605 [(set (match_operand:DI 0 "register_operand" "=r") 6606 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") 6607 (match_operand:SI 2 "arith_operand" "rI")))] 6608 "TARGET_ARCH64 || TARGET_V8PLUS" 6609{ 6610 if (TARGET_ARCH32) 6611 { 6612 if (GET_CODE (operands[2]) == CONST_INT) 6613 FAIL; /* prefer generic code in this case */ 6614 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2])); 6615 DONE; 6616 } 6617}) 6618 6619(define_insn "*ashrdi3_sp64" 6620 [(set (match_operand:DI 0 "register_operand" "=r") 6621 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") 6622 (match_operand:SI 2 "arith_operand" "rI")))] 6623 "TARGET_ARCH64" 6624{ 6625 if (GET_CODE (operands[2]) == CONST_INT) 6626 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); 6627 return "srax\t%1, %2, %0"; 6628} 6629 [(set_attr "type" "shift")]) 6630 6631(define_insn "ashrdi3_v8plus" 6632 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r") 6633 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI") 6634 (match_operand:SI 2 "arith_operand" "rI,rI,rI"))) 6635 (clobber (match_scratch:SI 3 "=X,X,&h"))] 6636 "TARGET_V8PLUS" 6637{ 6638 return output_v8plus_shift (insn, operands, \"srax\"); 6639} 6640 [(set_attr "type" "multi") 6641 (set_attr "length" "5,5,6")]) 6642 6643(define_insn "lshrsi3" 6644 [(set (match_operand:SI 0 "register_operand" "=r") 6645 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") 6646 (match_operand:SI 2 "arith_operand" "rI")))] 6647 "" 6648{ 6649 if (GET_CODE (operands[2]) == CONST_INT) 6650 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); 6651 return "srl\t%1, %2, %0"; 6652} 6653 [(set_attr "type" "shift")]) 6654 6655(define_insn "*lshrsi3_extend0" 6656 [(set (match_operand:DI 0 "register_operand" "=r") 6657 (zero_extend:DI 6658 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") 6659 (match_operand:SI 2 "arith_operand" "rI"))))] 6660 "TARGET_ARCH64" 6661{ 6662 if (GET_CODE (operands[2]) == CONST_INT) 6663 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); 6664 return "srl\t%1, %2, %0"; 6665} 6666 [(set_attr "type" "shift")]) 6667 6668;; This handles the case where 6669;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))) 6670;; but combiner "simplifies" it for us. 6671(define_insn "*lshrsi3_extend1" 6672 [(set (match_operand:DI 0 "register_operand" "=r") 6673 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") 6674 (match_operand:SI 2 "arith_operand" "rI")) 0) 6675 (match_operand 3 "const_int_operand" "")))] 6676 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff" 6677{ 6678 if (GET_CODE (operands[2]) == CONST_INT) 6679 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); 6680 return "srl\t%1, %2, %0"; 6681} 6682 [(set_attr "type" "shift")]) 6683 6684;; This handles the case where 6685;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int)) 6686;; but combiner "simplifies" it for us. 6687(define_insn "*lshrsi3_extend2" 6688 [(set (match_operand:DI 0 "register_operand" "=r") 6689 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0) 6690 (match_operand 2 "small_int_operand" "I") 6691 (const_int 32)))] 6692 "TARGET_ARCH64 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 32" 6693{ 6694 operands[2] = GEN_INT (32 - INTVAL (operands[2])); 6695 return "srl\t%1, %2, %0"; 6696} 6697 [(set_attr "type" "shift")]) 6698 6699(define_expand "lshrdi3" 6700 [(set (match_operand:DI 0 "register_operand" "=r") 6701 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") 6702 (match_operand:SI 2 "arith_operand" "rI")))] 6703 "TARGET_ARCH64 || TARGET_V8PLUS" 6704{ 6705 if (TARGET_ARCH32) 6706 { 6707 if (GET_CODE (operands[2]) == CONST_INT) 6708 FAIL; 6709 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2])); 6710 DONE; 6711 } 6712}) 6713 6714(define_insn "*lshrdi3_sp64" 6715 [(set (match_operand:DI 0 "register_operand" "=r") 6716 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") 6717 (match_operand:SI 2 "arith_operand" "rI")))] 6718 "TARGET_ARCH64" 6719{ 6720 if (GET_CODE (operands[2]) == CONST_INT) 6721 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); 6722 return "srlx\t%1, %2, %0"; 6723} 6724 [(set_attr "type" "shift")]) 6725 6726(define_insn "lshrdi3_v8plus" 6727 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r") 6728 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI") 6729 (match_operand:SI 2 "arith_operand" "rI,rI,rI"))) 6730 (clobber (match_scratch:SI 3 "=X,X,&h"))] 6731 "TARGET_V8PLUS" 6732{ 6733 return output_v8plus_shift (insn, operands, \"srlx\"); 6734} 6735 [(set_attr "type" "multi") 6736 (set_attr "length" "5,5,6")]) 6737 6738(define_insn "" 6739 [(set (match_operand:SI 0 "register_operand" "=r") 6740 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") 6741 (const_int 32)) 4) 6742 (match_operand:SI 2 "small_int_operand" "I")))] 6743 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32" 6744{ 6745 operands[2] = GEN_INT (INTVAL (operands[2]) + 32); 6746 return "srax\t%1, %2, %0"; 6747} 6748 [(set_attr "type" "shift")]) 6749 6750(define_insn "" 6751 [(set (match_operand:SI 0 "register_operand" "=r") 6752 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") 6753 (const_int 32)) 4) 6754 (match_operand:SI 2 "small_int_operand" "I")))] 6755 "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32" 6756{ 6757 operands[2] = GEN_INT (INTVAL (operands[2]) + 32); 6758 return "srlx\t%1, %2, %0"; 6759} 6760 [(set_attr "type" "shift")]) 6761 6762(define_insn "" 6763 [(set (match_operand:SI 0 "register_operand" "=r") 6764 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") 6765 (match_operand:SI 2 "small_int_operand" "I")) 4) 6766 (match_operand:SI 3 "small_int_operand" "I")))] 6767 "TARGET_ARCH64 6768 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32 6769 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32 6770 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64" 6771{ 6772 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3])); 6773 6774 return "srax\t%1, %2, %0"; 6775} 6776 [(set_attr "type" "shift")]) 6777 6778(define_insn "" 6779 [(set (match_operand:SI 0 "register_operand" "=r") 6780 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") 6781 (match_operand:SI 2 "small_int_operand" "I")) 4) 6782 (match_operand:SI 3 "small_int_operand" "I")))] 6783 "TARGET_ARCH64 6784 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32 6785 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32 6786 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64" 6787{ 6788 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3])); 6789 6790 return "srlx\t%1, %2, %0"; 6791} 6792 [(set_attr "type" "shift")]) 6793 6794 6795;; Unconditional and other jump instructions. 6796 6797(define_expand "jump" 6798 [(set (pc) (label_ref (match_operand 0 "" "")))] 6799 "") 6800 6801(define_insn "*jump_ubranch" 6802 [(set (pc) (label_ref (match_operand 0 "" "")))] 6803 "!TARGET_CBCOND" 6804{ 6805 return output_ubranch (operands[0], insn); 6806} 6807 [(set_attr "type" "uncond_branch")]) 6808 6809(define_insn "*jump_cbcond" 6810 [(set (pc) (label_ref (match_operand 0 "" "")))] 6811 "TARGET_CBCOND" 6812{ 6813 return output_ubranch (operands[0], insn); 6814} 6815 [(set_attr "type" "uncond_cbcond")]) 6816 6817(define_expand "tablejump" 6818 [(parallel [(set (pc) (match_operand 0 "register_operand" "r")) 6819 (use (label_ref (match_operand 1 "" "")))])] 6820 "" 6821{ 6822 gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE); 6823 6824 /* In pic mode, our address differences are against the base of the 6825 table. Add that base value back in; CSE ought to be able to combine 6826 the two address loads. */ 6827 if (flag_pic) 6828 { 6829 rtx tmp, tmp2; 6830 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]); 6831 tmp2 = operands[0]; 6832 if (CASE_VECTOR_MODE != Pmode) 6833 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2); 6834 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp); 6835 operands[0] = memory_address (Pmode, tmp); 6836 } 6837}) 6838 6839(define_insn "*tablejump<P:mode>" 6840 [(set (pc) (match_operand:P 0 "address_operand" "p")) 6841 (use (label_ref (match_operand 1 "" "")))] 6842 "" 6843 "jmp\t%a0%#" 6844 [(set_attr "type" "uncond_branch")]) 6845 6846 6847;; Jump to subroutine instructions. 6848 6849(define_expand "call" 6850 ;; Note that this expression is not used for generating RTL. 6851 ;; All the RTL is generated explicitly below. 6852 [(call (match_operand 0 "call_operand" "") 6853 (match_operand 3 "" "i"))] 6854 ;; operands[2] is next_arg_register 6855 ;; operands[3] is struct_value_size_rtx. 6856 "" 6857{ 6858 rtx fn_rtx; 6859 6860 gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE); 6861 6862 gcc_assert (GET_CODE (operands[3]) == CONST_INT); 6863 6864 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF) 6865 { 6866 /* This is really a PIC sequence. We want to represent 6867 it as a funny jump so its delay slots can be filled. 6868 6869 ??? But if this really *is* a CALL, will not it clobber the 6870 call-clobbered registers? We lose this if it is a JUMP_INSN. 6871 Why cannot we have delay slots filled if it were a CALL? */ 6872 6873 /* We accept negative sizes for untyped calls. */ 6874 if (TARGET_ARCH32 && INTVAL (operands[3]) != 0) 6875 emit_jump_insn 6876 (gen_rtx_PARALLEL 6877 (VOIDmode, 6878 gen_rtvec (3, 6879 gen_rtx_SET (pc_rtx, XEXP (operands[0], 0)), 6880 operands[3], 6881 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15))))); 6882 else 6883 emit_jump_insn 6884 (gen_rtx_PARALLEL 6885 (VOIDmode, 6886 gen_rtvec (2, 6887 gen_rtx_SET (pc_rtx, XEXP (operands[0], 0)), 6888 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15))))); 6889 goto finish_call; 6890 } 6891 6892 fn_rtx = operands[0]; 6893 6894 /* We accept negative sizes for untyped calls. */ 6895 if (TARGET_ARCH32 && INTVAL (operands[3]) != 0) 6896 sparc_emit_call_insn 6897 (gen_rtx_PARALLEL 6898 (VOIDmode, 6899 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx), 6900 operands[3], 6901 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))), 6902 XEXP (fn_rtx, 0)); 6903 else 6904 sparc_emit_call_insn 6905 (gen_rtx_PARALLEL 6906 (VOIDmode, 6907 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx), 6908 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))), 6909 XEXP (fn_rtx, 0)); 6910 6911 finish_call: 6912 6913 DONE; 6914}) 6915 6916;; We can't use the same pattern for these two insns, because then registers 6917;; in the address may not be properly reloaded. 6918 6919(define_insn "*call_address<P:mode>" 6920 [(call (mem:P (match_operand:P 0 "address_operand" "p")) 6921 (match_operand 1 "" "")) 6922 (clobber (reg:P O7_REG))] 6923 ;;- Do not use operand 1 for most machines. 6924 "" 6925 "call\t%a0, %1%#" 6926 [(set_attr "type" "call")]) 6927 6928(define_insn "*call_symbolic<P:mode>" 6929 [(call (mem:P (match_operand:P 0 "symbolic_operand" "s")) 6930 (match_operand 1 "" "")) 6931 (clobber (reg:P O7_REG))] 6932 ;;- Do not use operand 1 for most machines. 6933 "" 6934 "call\t%a0, %1%#" 6935 [(set_attr "type" "call")]) 6936 6937;; This is a call that wants a structure value. 6938;; There is no such critter for v9 (??? we may need one anyway). 6939(define_insn "*call_address_struct_value_sp32" 6940 [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) 6941 (match_operand 1 "" "")) 6942 (match_operand 2 "immediate_operand" "") 6943 (clobber (reg:SI O7_REG))] 6944 ;;- Do not use operand 1 for most machines. 6945 "TARGET_ARCH32 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0" 6946{ 6947 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff); 6948 return "call\t%a0, %1\n\t nop\n\tunimp\t%2"; 6949} 6950 [(set_attr "type" "call_no_delay_slot") 6951 (set_attr "length" "3")]) 6952 6953;; This is a call that wants a structure value. 6954;; There is no such critter for v9 (??? we may need one anyway). 6955(define_insn "*call_symbolic_struct_value_sp32" 6956 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) 6957 (match_operand 1 "" "")) 6958 (match_operand 2 "immediate_operand" "") 6959 (clobber (reg:SI O7_REG))] 6960 ;;- Do not use operand 1 for most machines. 6961 "TARGET_ARCH32 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0" 6962{ 6963 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff); 6964 return "call\t%a0, %1\n\t nop\n\tunimp\t%2"; 6965} 6966 [(set_attr "type" "call_no_delay_slot") 6967 (set_attr "length" "3")]) 6968 6969;; This is a call that may want a structure value. This is used for 6970;; untyped_calls. 6971(define_insn "*call_address_untyped_struct_value_sp32" 6972 [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) 6973 (match_operand 1 "" "")) 6974 (match_operand 2 "immediate_operand" "") 6975 (clobber (reg:SI O7_REG))] 6976 ;;- Do not use operand 1 for most machines. 6977 "TARGET_ARCH32 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0" 6978 "call\t%a0, %1\n\t nop\n\tnop" 6979 [(set_attr "type" "call_no_delay_slot") 6980 (set_attr "length" "3")]) 6981 6982;; This is a call that may want a structure value. This is used for 6983;; untyped_calls. 6984(define_insn "*call_symbolic_untyped_struct_value_sp32" 6985 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) 6986 (match_operand 1 "" "")) 6987 (match_operand 2 "immediate_operand" "") 6988 (clobber (reg:SI O7_REG))] 6989 ;;- Do not use operand 1 for most machines. 6990 "TARGET_ARCH32 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0" 6991 "call\t%a0, %1\n\t nop\n\tnop" 6992 [(set_attr "type" "call_no_delay_slot") 6993 (set_attr "length" "3")]) 6994 6995(define_expand "call_value" 6996 ;; Note that this expression is not used for generating RTL. 6997 ;; All the RTL is generated explicitly below. 6998 [(set (match_operand 0 "register_operand" "") 6999 (call (match_operand 1 "call_operand" "") 7000 (match_operand 4 "" "")))] 7001 ;; operand 2 is stack_size_rtx 7002 ;; operand 3 is next_arg_register 7003 "" 7004{ 7005 rtx fn_rtx; 7006 rtvec vec; 7007 7008 gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE); 7009 7010 fn_rtx = operands[1]; 7011 7012 vec = gen_rtvec (2, 7013 gen_rtx_SET (operands[0], 7014 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)), 7015 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15))); 7016 7017 sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0)); 7018 7019 DONE; 7020}) 7021 7022(define_insn "*call_value_address<P:mode>" 7023 [(set (match_operand 0 "" "") 7024 (call (mem:P (match_operand:P 1 "address_operand" "p")) 7025 (match_operand 2 "" ""))) 7026 (clobber (reg:P O7_REG))] 7027 ;;- Do not use operand 2 for most machines. 7028 "" 7029 "call\t%a1, %2%#" 7030 [(set_attr "type" "call")]) 7031 7032(define_insn "*call_value_symbolic<P:mode>" 7033 [(set (match_operand 0 "" "") 7034 (call (mem:P (match_operand:P 1 "symbolic_operand" "s")) 7035 (match_operand 2 "" ""))) 7036 (clobber (reg:P O7_REG))] 7037 ;;- Do not use operand 2 for most machines. 7038 "" 7039 "call\t%a1, %2%#" 7040 [(set_attr "type" "call")]) 7041 7042(define_expand "untyped_call" 7043 [(parallel [(call (match_operand 0 "" "") 7044 (const_int 0)) 7045 (match_operand:BLK 1 "memory_operand" "") 7046 (match_operand 2 "" "")])] 7047 "" 7048{ 7049 rtx valreg1 = gen_rtx_REG (DImode, 8); 7050 rtx result = operands[1]; 7051 7052 /* Pass constm1 to indicate that it may expect a structure value, but 7053 we don't know what size it is. */ 7054 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx)); 7055 7056 /* Save the function value registers. */ 7057 emit_move_insn (adjust_address (result, DImode, 0), valreg1); 7058 if (TARGET_FPU) 7059 { 7060 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32); 7061 emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8), 7062 valreg2); 7063 } 7064 7065 /* The optimizer does not know that the call sets the function value 7066 registers we stored in the result block. We avoid problems by 7067 claiming that all hard registers are used and clobbered at this 7068 point. */ 7069 emit_insn (gen_blockage ()); 7070 7071 DONE; 7072}) 7073 7074 7075;; Tail call instructions. 7076 7077(define_expand "sibcall" 7078 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0)) 7079 (return)])] 7080 "" 7081 "") 7082 7083(define_insn "*sibcall_symbolic<P:mode>" 7084 [(call (mem:P (match_operand:P 0 "symbolic_operand" "s")) 7085 (match_operand 1 "" "")) 7086 (return)] 7087 "" 7088{ 7089 return output_sibcall (insn, operands[0]); 7090} 7091 [(set_attr "type" "sibcall")]) 7092 7093(define_expand "sibcall_value" 7094 [(parallel [(set (match_operand 0 "register_operand") 7095 (call (match_operand 1 "call_operand" "") (const_int 0))) 7096 (return)])] 7097 "" 7098 "") 7099 7100(define_insn "*sibcall_value_symbolic<P:mode>" 7101 [(set (match_operand 0 "" "") 7102 (call (mem:P (match_operand:P 1 "symbolic_operand" "s")) 7103 (match_operand 2 "" ""))) 7104 (return)] 7105 "" 7106{ 7107 return output_sibcall (insn, operands[1]); 7108} 7109 [(set_attr "type" "sibcall")]) 7110 7111 7112;; Special instructions. 7113 7114(define_expand "prologue" 7115 [(const_int 0)] 7116 "" 7117{ 7118 if (TARGET_FLAT) 7119 sparc_flat_expand_prologue (); 7120 else 7121 sparc_expand_prologue (); 7122 DONE; 7123}) 7124 7125;; The "register window save" insn is modelled as follows. The dwarf2 7126;; information is manually added in emit_window_save. 7127 7128(define_insn "window_save" 7129 [(unspec_volatile [(match_operand 0 "arith_operand" "rI")] UNSPECV_SAVEW)] 7130 "!TARGET_FLAT" 7131 "save\t%%sp, %0, %%sp" 7132 [(set_attr "type" "savew")]) 7133 7134(define_expand "epilogue" 7135 [(return)] 7136 "" 7137{ 7138 if (TARGET_FLAT) 7139 sparc_flat_expand_epilogue (false); 7140 else 7141 sparc_expand_epilogue (false); 7142}) 7143 7144(define_expand "sibcall_epilogue" 7145 [(return)] 7146 "" 7147{ 7148 if (TARGET_FLAT) 7149 sparc_flat_expand_epilogue (false); 7150 else 7151 sparc_expand_epilogue (false); 7152 DONE; 7153}) 7154 7155(define_expand "eh_return" 7156 [(use (match_operand 0 "general_operand" ""))] 7157 "" 7158{ 7159 emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]); 7160 emit_jump_insn (gen_eh_return_internal ()); 7161 emit_barrier (); 7162 DONE; 7163}) 7164 7165(define_insn_and_split "eh_return_internal" 7166 [(eh_return)] 7167 "" 7168 "#" 7169 "epilogue_completed" 7170 [(return)] 7171{ 7172 if (TARGET_FLAT) 7173 sparc_flat_expand_epilogue (true); 7174 else 7175 sparc_expand_epilogue (true); 7176}) 7177 7178(define_expand "return" 7179 [(return)] 7180 "sparc_can_use_return_insn_p ()" 7181{ 7182 if (cfun->calls_alloca) 7183 emit_insn (gen_frame_blockage ()); 7184}) 7185 7186(define_insn "*return_internal" 7187 [(return)] 7188 "" 7189{ 7190 return output_return (insn); 7191} 7192 [(set_attr "type" "return") 7193 (set (attr "length") 7194 (cond [(eq_attr "calls_eh_return" "true") 7195 (if_then_else (eq_attr "delayed_branch" "true") 7196 (if_then_else (ior (eq_attr "isa" "v9") 7197 (eq_attr "flat" "true")) 7198 (const_int 2) 7199 (const_int 3)) 7200 (if_then_else (eq_attr "flat" "true") 7201 (const_int 3) 7202 (const_int 4))) 7203 (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true")) 7204 (if_then_else (eq_attr "empty_delay_slot" "true") 7205 (const_int 2) 7206 (const_int 1)) 7207 (eq_attr "empty_delay_slot" "true") 7208 (if_then_else (eq_attr "delayed_branch" "true") 7209 (const_int 2) 7210 (const_int 3)) 7211 ] (const_int 1)))]) 7212 7213;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 7214;; all of memory. This blocks insns from being moved across this point. 7215 7216(define_insn "blockage" 7217 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 7218 "" 7219 "" 7220 [(set_attr "length" "0")]) 7221 7222;; Do not schedule instructions accessing memory before this point. 7223 7224(define_expand "frame_blockage" 7225 [(set (match_dup 0) 7226 (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))] 7227 "" 7228{ 7229 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 7230 MEM_VOLATILE_P (operands[0]) = 1; 7231 operands[1] = stack_pointer_rtx; 7232}) 7233 7234(define_insn "*frame_blockage<P:mode>" 7235 [(set (match_operand:BLK 0 "" "") 7236 (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))] 7237 "" 7238 "" 7239 [(set_attr "length" "0")]) 7240 7241(define_expand "probe_stack" 7242 [(set (match_operand 0 "memory_operand" "") (const_int 0))] 7243 "" 7244{ 7245 operands[0] 7246 = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS); 7247}) 7248 7249(define_insn "probe_stack_range<P:mode>" 7250 [(set (match_operand:P 0 "register_operand" "=r") 7251 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") 7252 (match_operand:P 2 "register_operand" "r")] 7253 UNSPECV_PROBE_STACK_RANGE))] 7254 "" 7255{ 7256 return output_probe_stack_range (operands[0], operands[2]); 7257} 7258 [(set_attr "type" "multi")]) 7259 7260;; Prepare to return any type including a structure value. 7261 7262(define_expand "untyped_return" 7263 [(match_operand:BLK 0 "memory_operand" "") 7264 (match_operand 1 "" "")] 7265 "" 7266{ 7267 rtx valreg1 = gen_rtx_REG (DImode, 24); 7268 rtx result = operands[0]; 7269 7270 if (TARGET_ARCH32) 7271 { 7272 rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM); 7273 rtx value = gen_reg_rtx (SImode); 7274 7275 /* Fetch the instruction where we will return to and see if it's an unimp 7276 instruction (the most significant 10 bits will be zero). If so, 7277 update the return address to skip the unimp instruction. */ 7278 emit_move_insn (value, 7279 gen_rtx_MEM (SImode, plus_constant (SImode, rtnreg, 8))); 7280 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22))); 7281 emit_insn (gen_update_return (rtnreg, value)); 7282 } 7283 7284 /* Reload the function value registers. 7285 Put USE insns before the return. */ 7286 emit_move_insn (valreg1, adjust_address (result, DImode, 0)); 7287 emit_use (valreg1); 7288 7289 if (TARGET_FPU) 7290 { 7291 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32); 7292 emit_move_insn (valreg2, 7293 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8)); 7294 emit_use (valreg2); 7295 } 7296 7297 /* Construct the return. */ 7298 expand_naked_return (); 7299 7300 DONE; 7301}) 7302 7303;; Adjust the return address conditionally. If the value of op1 is equal 7304;; to all zero then adjust the return address i.e. op0 = op0 + 4. 7305;; This is technically *half* the check required by the 32-bit SPARC 7306;; psABI. This check only ensures that an "unimp" insn was written by 7307;; the caller, but doesn't check to see if the expected size matches 7308;; (this is encoded in the 12 lower bits). This check is obsolete and 7309;; only used by the above code "untyped_return". 7310 7311(define_insn "update_return" 7312 [(unspec:SI [(match_operand:SI 0 "register_operand" "r") 7313 (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)] 7314 "TARGET_ARCH32" 7315{ 7316 if (flag_delayed_branch) 7317 return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0"; 7318 else 7319 return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0"; 7320} 7321 [(set (attr "type") (const_string "multi")) 7322 (set (attr "length") 7323 (if_then_else (eq_attr "delayed_branch" "true") 7324 (const_int 3) 7325 (const_int 4)))]) 7326 7327(define_insn "nop" 7328 [(const_int 0)] 7329 "" 7330 "nop") 7331 7332(define_expand "indirect_jump" 7333 [(set (pc) (match_operand 0 "address_operand" "p"))] 7334 "" 7335 "") 7336 7337(define_insn "*branch<P:mode>" 7338 [(set (pc) (match_operand:P 0 "address_operand" "p"))] 7339 "" 7340 "jmp\t%a0%#" 7341 [(set_attr "type" "uncond_branch")]) 7342 7343(define_expand "save_stack_nonlocal" 7344 [(set (match_operand 0 "memory_operand" "") 7345 (match_operand 1 "register_operand" "")) 7346 (set (match_dup 2) (match_dup 3))] 7347 "" 7348{ 7349 operands[0] = adjust_address (operands[0], Pmode, 0); 7350 operands[2] = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode)); 7351 operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); 7352}) 7353 7354(define_expand "restore_stack_nonlocal" 7355 [(set (match_operand 0 "register_operand" "") 7356 (match_operand 1 "memory_operand" ""))] 7357 "" 7358{ 7359 operands[1] = adjust_address (operands[1], Pmode, 0); 7360}) 7361 7362(define_expand "nonlocal_goto" 7363 [(match_operand 0 "general_operand" "") 7364 (match_operand 1 "general_operand" "") 7365 (match_operand 2 "memory_operand" "") 7366 (match_operand 3 "memory_operand" "")] 7367 "" 7368{ 7369 rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); 7370 rtx r_label = copy_to_reg (operands[1]); 7371 rtx r_sp = adjust_address (operands[2], Pmode, 0); 7372 rtx r_fp = operands[3]; 7373 rtx r_i7 = adjust_address (operands[2], Pmode, GET_MODE_SIZE (Pmode)); 7374 7375 /* We need to flush all the register windows so that their contents will 7376 be re-synchronized by the restore insn of the target function. */ 7377 if (!TARGET_FLAT) 7378 emit_insn (gen_flush_register_windows ()); 7379 7380 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); 7381 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); 7382 7383 /* Restore frame pointer for containing function. */ 7384 emit_move_insn (hard_frame_pointer_rtx, r_fp); 7385 emit_stack_restore (SAVE_NONLOCAL, r_sp); 7386 emit_move_insn (i7, r_i7); 7387 7388 /* USE of hard_frame_pointer_rtx added for consistency; 7389 not clear if really needed. */ 7390 emit_use (hard_frame_pointer_rtx); 7391 emit_use (stack_pointer_rtx); 7392 emit_use (i7); 7393 7394 emit_jump_insn (gen_indirect_jump (r_label)); 7395 emit_barrier (); 7396 DONE; 7397}) 7398 7399(define_expand "builtin_setjmp_receiver" 7400 [(label_ref (match_operand 0 "" ""))] 7401 "TARGET_VXWORKS_RTP && flag_pic" 7402{ 7403 load_got_register (); 7404 DONE; 7405}) 7406 7407;; Special insn to flush register windows. 7408 7409(define_insn "flush_register_windows" 7410 [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)] 7411 "" 7412{ 7413 return TARGET_V9 ? "flushw" : "ta\t3"; 7414} 7415 [(set_attr "type" "flushw")]) 7416 7417;; Special pattern for the FLUSH instruction. 7418 7419(define_insn "flush<P:mode>" 7420 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")] UNSPECV_FLUSH)] 7421 "" 7422{ 7423 return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; 7424} 7425 [(set_attr "type" "iflush")]) 7426 7427;; Special insns to load and store the 32-bit FP Status Register. 7428 7429(define_insn "ldfsr" 7430 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_LDFSR)] 7431 "TARGET_FPU" 7432 "ld\t%0, %%fsr" 7433 [(set_attr "type" "load") 7434 (set_attr "subtype" "regular")]) 7435 7436(define_insn "stfsr" 7437 [(set (match_operand:SI 0 "memory_operand" "=m") 7438 (unspec_volatile:SI [(const_int 0)] UNSPECV_STFSR))] 7439 "TARGET_FPU" 7440 "st\t%%fsr, %0" 7441 [(set_attr "type" "store")]) 7442 7443 7444;; Find first set instructions. 7445 7446(define_expand "popcountdi2" 7447 [(set (match_operand:DI 0 "register_operand" "") 7448 (popcount:DI (match_operand:DI 1 "register_operand" "")))] 7449 "TARGET_POPC" 7450{ 7451 if (TARGET_ARCH32) 7452 { 7453 emit_insn (gen_popcountdi_v8plus (operands[0], operands[1])); 7454 DONE; 7455 } 7456}) 7457 7458(define_insn "*popcountdi_sp64" 7459 [(set (match_operand:DI 0 "register_operand" "=r") 7460 (popcount:DI (match_operand:DI 1 "register_operand" "r")))] 7461 "TARGET_POPC && TARGET_ARCH64" 7462 "popc\t%1, %0") 7463 7464(define_insn "popcountdi_v8plus" 7465 [(set (match_operand:DI 0 "register_operand" "=r") 7466 (popcount:DI (match_operand:DI 1 "register_operand" "r"))) 7467 (clobber (match_scratch:SI 2 "=&h"))] 7468 "TARGET_POPC && TARGET_ARCH32" 7469{ 7470 if (sparc_check_64 (operands[1], insn) <= 0) 7471 output_asm_insn ("srl\t%L1, 0, %L1", operands); 7472 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0"; 7473} 7474 [(set_attr "type" "multi") 7475 (set_attr "length" "5")]) 7476 7477(define_expand "popcountsi2" 7478 [(set (match_dup 2) 7479 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) 7480 (set (match_operand:SI 0 "register_operand" "") 7481 (truncate:SI (popcount:DI (match_dup 2))))] 7482 "TARGET_POPC" 7483{ 7484 if (TARGET_ARCH32) 7485 { 7486 emit_insn (gen_popcountsi_v8plus (operands[0], operands[1])); 7487 DONE; 7488 } 7489 else 7490 operands[2] = gen_reg_rtx (DImode); 7491}) 7492 7493(define_insn "*popcountsi_sp64" 7494 [(set (match_operand:SI 0 "register_operand" "=r") 7495 (truncate:SI 7496 (popcount:DI (match_operand:DI 1 "register_operand" "r"))))] 7497 "TARGET_POPC && TARGET_ARCH64" 7498 "popc\t%1, %0") 7499 7500(define_insn "popcountsi_v8plus" 7501 [(set (match_operand:SI 0 "register_operand" "=r") 7502 (popcount:SI (match_operand:SI 1 "register_operand" "r")))] 7503 "TARGET_POPC && TARGET_ARCH32" 7504{ 7505 if (sparc_check_64 (operands[1], insn) <= 0) 7506 output_asm_insn ("srl\t%1, 0, %1", operands); 7507 return "popc\t%1, %0"; 7508} 7509 [(set_attr "type" "multi") 7510 (set_attr "length" "2")]) 7511 7512(define_expand "clzdi2" 7513 [(set (match_operand:DI 0 "register_operand" "") 7514 (clz:DI (match_operand:DI 1 "register_operand" "")))] 7515 "TARGET_VIS3" 7516{ 7517 if (TARGET_ARCH32) 7518 { 7519 emit_insn (gen_clzdi_v8plus (operands[0], operands[1])); 7520 DONE; 7521 } 7522}) 7523 7524(define_insn "*clzdi_sp64" 7525 [(set (match_operand:DI 0 "register_operand" "=r") 7526 (clz:DI (match_operand:DI 1 "register_operand" "r")))] 7527 "TARGET_VIS3 && TARGET_ARCH64" 7528 "lzd\t%1, %0" 7529 [(set_attr "type" "lzd")]) 7530 7531(define_insn "clzdi_v8plus" 7532 [(set (match_operand:DI 0 "register_operand" "=r") 7533 (clz:DI (match_operand:DI 1 "register_operand" "r"))) 7534 (clobber (match_scratch:SI 2 "=&h"))] 7535 "TARGET_VIS3 && TARGET_ARCH32" 7536{ 7537 if (sparc_check_64 (operands[1], insn) <= 0) 7538 output_asm_insn ("srl\t%L1, 0, %L1", operands); 7539 return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0"; 7540} 7541 [(set_attr "type" "multi") 7542 (set_attr "length" "5")]) 7543 7544(define_expand "clzsi2" 7545 [(set (match_dup 2) 7546 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) 7547 (set (match_dup 3) 7548 (truncate:SI (clz:DI (match_dup 2)))) 7549 (set (match_operand:SI 0 "register_operand" "") 7550 (minus:SI (match_dup 3) (const_int 32)))] 7551 "TARGET_VIS3" 7552{ 7553 if (TARGET_ARCH32) 7554 { 7555 emit_insn (gen_clzsi_v8plus (operands[0], operands[1])); 7556 DONE; 7557 } 7558 else 7559 { 7560 operands[2] = gen_reg_rtx (DImode); 7561 operands[3] = gen_reg_rtx (SImode); 7562 } 7563}) 7564 7565(define_insn "*clzsi_sp64" 7566 [(set (match_operand:SI 0 "register_operand" "=r") 7567 (truncate:SI 7568 (clz:DI (match_operand:DI 1 "register_operand" "r"))))] 7569 "TARGET_VIS3 && TARGET_ARCH64" 7570 "lzd\t%1, %0" 7571 [(set_attr "type" "lzd")]) 7572 7573(define_insn "clzsi_v8plus" 7574 [(set (match_operand:SI 0 "register_operand" "=r") 7575 (clz:SI (match_operand:SI 1 "register_operand" "r")))] 7576 "TARGET_VIS3 && TARGET_ARCH32" 7577{ 7578 if (sparc_check_64 (operands[1], insn) <= 0) 7579 output_asm_insn ("srl\t%1, 0, %1", operands); 7580 return "lzd\t%1, %0\n\tsub\t%0, 32, %0"; 7581} 7582 [(set_attr "type" "multi") 7583 (set_attr "length" "3")]) 7584 7585 7586;; Peepholes go at the end. 7587 7588;; Optimize consecutive loads or stores into ldd and std when possible. 7589;; The conditions in which we do this are very restricted and are 7590;; explained in the code for {registers,memory}_ok_for_ldd functions. 7591 7592(define_peephole2 7593 [(set (match_operand:SI 0 "memory_operand" "") 7594 (const_int 0)) 7595 (set (match_operand:SI 1 "memory_operand" "") 7596 (const_int 0))] 7597 "TARGET_V9 7598 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)" 7599 [(set (match_dup 0) (const_int 0))] 7600{ 7601 operands[0] = widen_mem_for_ldd_peep (operands[0], operands[1], DImode); 7602}) 7603 7604(define_peephole2 7605 [(set (match_operand:SI 0 "memory_operand" "") 7606 (const_int 0)) 7607 (set (match_operand:SI 1 "memory_operand" "") 7608 (const_int 0))] 7609 "TARGET_V9 7610 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)" 7611 [(set (match_dup 1) (const_int 0))] 7612{ 7613 operands[1] = widen_mem_for_ldd_peep (operands[1], operands[0], DImode); 7614}) 7615 7616(define_peephole2 7617 [(set (match_operand:SI 0 "register_operand" "") 7618 (match_operand:SI 1 "memory_operand" "")) 7619 (set (match_operand:SI 2 "register_operand" "") 7620 (match_operand:SI 3 "memory_operand" ""))] 7621 "registers_ok_for_ldd_peep (operands[0], operands[2]) 7622 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 7623 [(set (match_dup 0) (match_dup 1))] 7624{ 7625 operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DImode); 7626 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); 7627}) 7628 7629(define_peephole2 7630 [(set (match_operand:SI 0 "memory_operand" "") 7631 (match_operand:SI 1 "register_operand" "")) 7632 (set (match_operand:SI 2 "memory_operand" "") 7633 (match_operand:SI 3 "register_operand" ""))] 7634 "registers_ok_for_ldd_peep (operands[1], operands[3]) 7635 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)" 7636 [(set (match_dup 0) (match_dup 1))] 7637{ 7638 operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DImode); 7639 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1])); 7640}) 7641 7642(define_peephole2 7643 [(set (match_operand:SF 0 "register_operand" "") 7644 (match_operand:SF 1 "memory_operand" "")) 7645 (set (match_operand:SF 2 "register_operand" "") 7646 (match_operand:SF 3 "memory_operand" ""))] 7647 "registers_ok_for_ldd_peep (operands[0], operands[2]) 7648 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 7649 [(set (match_dup 0) (match_dup 1))] 7650{ 7651 operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DFmode); 7652 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0])); 7653}) 7654 7655(define_peephole2 7656 [(set (match_operand:SF 0 "memory_operand" "") 7657 (match_operand:SF 1 "register_operand" "")) 7658 (set (match_operand:SF 2 "memory_operand" "") 7659 (match_operand:SF 3 "register_operand" ""))] 7660 "registers_ok_for_ldd_peep (operands[1], operands[3]) 7661 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)" 7662 [(set (match_dup 0) (match_dup 1))] 7663{ 7664 operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DFmode); 7665 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1])); 7666}) 7667 7668(define_peephole2 7669 [(set (match_operand:SI 0 "register_operand" "") 7670 (match_operand:SI 1 "memory_operand" "")) 7671 (set (match_operand:SI 2 "register_operand" "") 7672 (match_operand:SI 3 "memory_operand" ""))] 7673 "registers_ok_for_ldd_peep (operands[2], operands[0]) 7674 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])" 7675 [(set (match_dup 2) (match_dup 3))] 7676{ 7677 operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DImode); 7678 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2])); 7679}) 7680 7681(define_peephole2 7682 [(set (match_operand:SI 0 "memory_operand" "") 7683 (match_operand:SI 1 "register_operand" "")) 7684 (set (match_operand:SI 2 "memory_operand" "") 7685 (match_operand:SI 3 "register_operand" ""))] 7686 "registers_ok_for_ldd_peep (operands[3], operands[1]) 7687 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 7688 [(set (match_dup 2) (match_dup 3))] 7689{ 7690 operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DImode); 7691 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3])); 7692}) 7693 7694(define_peephole2 7695 [(set (match_operand:SF 0 "register_operand" "") 7696 (match_operand:SF 1 "memory_operand" "")) 7697 (set (match_operand:SF 2 "register_operand" "") 7698 (match_operand:SF 3 "memory_operand" ""))] 7699 "registers_ok_for_ldd_peep (operands[2], operands[0]) 7700 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])" 7701 [(set (match_dup 2) (match_dup 3))] 7702{ 7703 operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DFmode); 7704 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2])); 7705}) 7706 7707(define_peephole2 7708 [(set (match_operand:SF 0 "memory_operand" "") 7709 (match_operand:SF 1 "register_operand" "")) 7710 (set (match_operand:SF 2 "memory_operand" "") 7711 (match_operand:SF 3 "register_operand" ""))] 7712 "registers_ok_for_ldd_peep (operands[3], operands[1]) 7713 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 7714 [(set (match_dup 2) (match_dup 3))] 7715{ 7716 operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DFmode); 7717 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3])); 7718}) 7719 7720;; Optimize the case of following a reg-reg move with a test 7721;; of reg just moved. Don't allow floating point regs for operand 0 or 1. 7722;; This can result from a float to fix conversion. 7723 7724(define_peephole2 7725 [(set (match_operand:SI 0 "register_operand" "") 7726 (match_operand:SI 1 "register_operand" "")) 7727 (set (reg:CC CC_REG) 7728 (compare:CC (match_operand:SI 2 "register_operand" "") 7729 (const_int 0)))] 7730 "(rtx_equal_p (operands[2], operands[0]) 7731 || rtx_equal_p (operands[2], operands[1])) 7732 && !SPARC_FP_REG_P (REGNO (operands[0])) 7733 && !SPARC_FP_REG_P (REGNO (operands[1]))" 7734 [(parallel [(set (match_dup 0) (match_dup 1)) 7735 (set (reg:CC CC_REG) 7736 (compare:CC (match_dup 1) (const_int 0)))])] 7737 "") 7738 7739(define_peephole2 7740 [(set (match_operand:DI 0 "register_operand" "") 7741 (match_operand:DI 1 "register_operand" "")) 7742 (set (reg:CCX CC_REG) 7743 (compare:CCX (match_operand:DI 2 "register_operand" "") 7744 (const_int 0)))] 7745 "TARGET_ARCH64 7746 && (rtx_equal_p (operands[2], operands[0]) 7747 || rtx_equal_p (operands[2], operands[1])) 7748 && !SPARC_FP_REG_P (REGNO (operands[0])) 7749 && !SPARC_FP_REG_P (REGNO (operands[1]))" 7750 [(parallel [(set (match_dup 0) (match_dup 1)) 7751 (set (reg:CCX CC_REG) 7752 (compare:CCX (match_dup 1) (const_int 0)))])] 7753 "") 7754 7755 7756;; Prefetch instructions. 7757 7758;; ??? UltraSPARC-III note: A memory operation loading into the floating point 7759;; register file, if it hits the prefetch cache, has a chance to dual-issue 7760;; with other memory operations. With DFA we might be able to model this, 7761;; but it requires a lot of state. 7762(define_expand "prefetch" 7763 [(match_operand 0 "address_operand" "") 7764 (match_operand 1 "const_int_operand" "") 7765 (match_operand 2 "const_int_operand" "")] 7766 "TARGET_V9" 7767{ 7768 if (TARGET_ARCH64) 7769 emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2])); 7770 else 7771 emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2])); 7772 DONE; 7773}) 7774 7775(define_insn "prefetch_64" 7776 [(prefetch (match_operand:DI 0 "address_operand" "p") 7777 (match_operand:DI 1 "const_int_operand" "n") 7778 (match_operand:DI 2 "const_int_operand" "n"))] 7779 "" 7780{ 7781 static const char * const prefetch_instr[2][2] = { 7782 { 7783 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */ 7784 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */ 7785 }, 7786 { 7787 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */ 7788 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */ 7789 } 7790 }; 7791 int read_or_write = INTVAL (operands[1]); 7792 int locality = INTVAL (operands[2]); 7793 7794 gcc_assert (read_or_write == 0 || read_or_write == 1); 7795 gcc_assert (locality >= 0 && locality < 4); 7796 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1]; 7797} 7798 [(set_attr "type" "load") 7799 (set_attr "subtype" "prefetch")]) 7800 7801(define_insn "prefetch_32" 7802 [(prefetch (match_operand:SI 0 "address_operand" "p") 7803 (match_operand:SI 1 "const_int_operand" "n") 7804 (match_operand:SI 2 "const_int_operand" "n"))] 7805 "" 7806{ 7807 static const char * const prefetch_instr[2][2] = { 7808 { 7809 "prefetch\t[%a0], 1", /* no locality: prefetch for one read */ 7810 "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */ 7811 }, 7812 { 7813 "prefetch\t[%a0], 3", /* no locality: prefetch for one write */ 7814 "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */ 7815 } 7816 }; 7817 int read_or_write = INTVAL (operands[1]); 7818 int locality = INTVAL (operands[2]); 7819 7820 gcc_assert (read_or_write == 0 || read_or_write == 1); 7821 gcc_assert (locality >= 0 && locality < 4); 7822 return prefetch_instr [read_or_write][locality == 0 ? 0 : 1]; 7823} 7824 [(set_attr "type" "load") 7825 (set_attr "subtype" "prefetch")]) 7826 7827 7828;; Trap instructions. 7829 7830(define_insn "trap" 7831 [(trap_if (const_int 1) (const_int 5))] 7832 "" 7833 "ta\t5" 7834 [(set_attr "type" "trap")]) 7835 7836(define_expand "ctrapsi4" 7837 [(trap_if (match_operator 0 "comparison_operator" 7838 [(match_operand:SI 1 "compare_operand" "") 7839 (match_operand:SI 2 "arith_operand" "")]) 7840 (match_operand 3 "arith_operand"))] 7841 "" 7842{ 7843 operands[1] = gen_compare_reg (operands[0]); 7844 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode) 7845 FAIL; 7846 operands[2] = const0_rtx; 7847}) 7848 7849(define_expand "ctrapdi4" 7850 [(trap_if (match_operator 0 "comparison_operator" 7851 [(match_operand:DI 1 "compare_operand" "") 7852 (match_operand:DI 2 "arith_operand" "")]) 7853 (match_operand 3 "arith_operand"))] 7854 "TARGET_ARCH64" 7855{ 7856 operands[1] = gen_compare_reg (operands[0]); 7857 if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode) 7858 FAIL; 7859 operands[2] = const0_rtx; 7860}) 7861 7862(define_insn "*trapsi_insn" 7863 [(trap_if (match_operator 0 "icc_comparison_operator" 7864 [(reg:CC CC_REG) (const_int 0)]) 7865 (match_operand:SI 1 "arith_operand" "rM"))] 7866 "" 7867{ 7868 if (TARGET_V9) 7869 return "t%C0\t%%icc, %1"; 7870 else 7871 return "t%C0\t%1"; 7872} 7873 [(set_attr "type" "trap")]) 7874 7875(define_insn "*trapdi_insn" 7876 [(trap_if (match_operator 0 "icc_comparison_operator" 7877 [(reg:CCX CC_REG) (const_int 0)]) 7878 (match_operand:SI 1 "arith_operand" "rM"))] 7879 "TARGET_V9" 7880 "t%C0\t%%xcc, %1" 7881 [(set_attr "type" "trap")]) 7882 7883 7884;; TLS support instructions. 7885 7886(define_insn "tgd_hi22<P:mode>" 7887 [(set (match_operand:P 0 "register_operand" "=r") 7888 (high:P (unspec:P [(match_operand 1 "tgd_symbolic_operand" "")] 7889 UNSPEC_TLSGD)))] 7890 "TARGET_TLS" 7891 "sethi\\t%%tgd_hi22(%a1), %0") 7892 7893(define_insn "tgd_lo10<P:mode>" 7894 [(set (match_operand:P 0 "register_operand" "=r") 7895 (lo_sum:P (match_operand:P 1 "register_operand" "r") 7896 (unspec:P [(match_operand 2 "tgd_symbolic_operand" "")] 7897 UNSPEC_TLSGD)))] 7898 "TARGET_TLS" 7899 "add\\t%1, %%tgd_lo10(%a2), %0") 7900 7901(define_insn "tgd_add<P:mode>" 7902 [(set (match_operand:P 0 "register_operand" "=r") 7903 (plus:P (match_operand:P 1 "register_operand" "r") 7904 (unspec:P [(match_operand:P 2 "register_operand" "r") 7905 (match_operand 3 "tgd_symbolic_operand" "")] 7906 UNSPEC_TLSGD)))] 7907 "TARGET_TLS" 7908 "add\\t%1, %2, %0, %%tgd_add(%a3)") 7909 7910(define_insn "tgd_call<P:mode>" 7911 [(set (match_operand 0 "register_operand" "=r") 7912 (call (mem:P (unspec:P [(match_operand:P 1 "symbolic_operand" "s") 7913 (match_operand 2 "tgd_symbolic_operand" "")] 7914 UNSPEC_TLSGD)) 7915 (match_operand 3 "" ""))) 7916 (clobber (reg:P O7_REG))] 7917 "TARGET_TLS" 7918 "call\t%a1, %%tgd_call(%a2)%#" 7919 [(set_attr "type" "call")]) 7920 7921(define_insn "tldm_hi22<P:mode>" 7922 [(set (match_operand:P 0 "register_operand" "=r") 7923 (high:P (unspec:P [(const_int 0)] UNSPEC_TLSLDM)))] 7924 "TARGET_TLS" 7925 "sethi\\t%%tldm_hi22(%&), %0") 7926 7927(define_insn "tldm_lo10<P:mode>" 7928 [(set (match_operand:P 0 "register_operand" "=r") 7929 (lo_sum:P (match_operand:P 1 "register_operand" "r") 7930 (unspec:P [(const_int 0)] UNSPEC_TLSLDM)))] 7931 "TARGET_TLS" 7932 "add\\t%1, %%tldm_lo10(%&), %0") 7933 7934(define_insn "tldm_add<P:mode>" 7935 [(set (match_operand:P 0 "register_operand" "=r") 7936 (plus:P (match_operand:P 1 "register_operand" "r") 7937 (unspec:P [(match_operand:P 2 "register_operand" "r")] 7938 UNSPEC_TLSLDM)))] 7939 "TARGET_TLS" 7940 "add\\t%1, %2, %0, %%tldm_add(%&)") 7941 7942(define_insn "tldm_call<P:mode>" 7943 [(set (match_operand 0 "register_operand" "=r") 7944 (call (mem:P (unspec:P [(match_operand:P 1 "symbolic_operand" "s")] 7945 UNSPEC_TLSLDM)) 7946 (match_operand 2 "" ""))) 7947 (clobber (reg:P O7_REG))] 7948 "TARGET_TLS" 7949 "call\t%a1, %%tldm_call(%&)%#" 7950 [(set_attr "type" "call")]) 7951 7952(define_insn "tldo_hix22<P:mode>" 7953 [(set (match_operand:P 0 "register_operand" "=r") 7954 (high:P (unspec:P [(match_operand 1 "tld_symbolic_operand" "")] 7955 UNSPEC_TLSLDO)))] 7956 "TARGET_TLS" 7957 "sethi\\t%%tldo_hix22(%a1), %0") 7958 7959(define_insn "tldo_lox10<P:mode>" 7960 [(set (match_operand:P 0 "register_operand" "=r") 7961 (lo_sum:P (match_operand:P 1 "register_operand" "r") 7962 (unspec:P [(match_operand 2 "tld_symbolic_operand" "")] 7963 UNSPEC_TLSLDO)))] 7964 "TARGET_TLS" 7965 "xor\\t%1, %%tldo_lox10(%a2), %0") 7966 7967(define_insn "tldo_add<P:mode>" 7968 [(set (match_operand:P 0 "register_operand" "=r") 7969 (plus:P (match_operand:P 1 "register_operand" "r") 7970 (unspec:P [(match_operand:P 2 "register_operand" "r") 7971 (match_operand 3 "tld_symbolic_operand" "")] 7972 UNSPEC_TLSLDO)))] 7973 "TARGET_TLS" 7974 "add\\t%1, %2, %0, %%tldo_add(%a3)") 7975 7976(define_insn "tie_hi22<P:mode>" 7977 [(set (match_operand:P 0 "register_operand" "=r") 7978 (high:P (unspec:P [(match_operand 1 "tie_symbolic_operand" "")] 7979 UNSPEC_TLSIE)))] 7980 "TARGET_TLS" 7981 "sethi\\t%%tie_hi22(%a1), %0") 7982 7983(define_insn "tie_lo10<P:mode>" 7984 [(set (match_operand:P 0 "register_operand" "=r") 7985 (lo_sum:P (match_operand:P 1 "register_operand" "r") 7986 (unspec:P [(match_operand 2 "tie_symbolic_operand" "")] 7987 UNSPEC_TLSIE)))] 7988 "TARGET_TLS" 7989 "add\\t%1, %%tie_lo10(%a2), %0") 7990 7991; Note the %%tie_ld operator 7992(define_insn "tie_ld32" 7993 [(set (match_operand:SI 0 "register_operand" "=r") 7994 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 7995 (match_operand:SI 2 "register_operand" "r") 7996 (match_operand 3 "tie_symbolic_operand" "")] 7997 UNSPEC_TLSIE))] 7998 "TARGET_TLS && TARGET_ARCH32" 7999 "ld\\t[%1 + %2], %0, %%tie_ld(%a3)" 8000 [(set_attr "type" "load") 8001 (set_attr "subtype" "regular")]) 8002 8003; Note the %%tie_ldx operator 8004(define_insn "tie_ld64" 8005 [(set (match_operand:DI 0 "register_operand" "=r") 8006 (unspec:DI [(match_operand:DI 1 "register_operand" "r") 8007 (match_operand:DI 2 "register_operand" "r") 8008 (match_operand 3 "tie_symbolic_operand" "")] 8009 UNSPEC_TLSIE))] 8010 "TARGET_TLS && TARGET_ARCH64" 8011 "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)" 8012 [(set_attr "type" "load") 8013 (set_attr "subtype" "regular")]) 8014 8015(define_insn "tie_add<P:mode>" 8016 [(set (match_operand:P 0 "register_operand" "=r") 8017 (plus:P (match_operand:P 1 "register_operand" "r") 8018 (unspec:P [(match_operand:P 2 "register_operand" "r") 8019 (match_operand 3 "tie_symbolic_operand" "")] 8020 UNSPEC_TLSIE)))] 8021 "TARGET_SUN_TLS" 8022 "add\\t%1, %2, %0, %%tie_add(%a3)") 8023 8024(define_insn "tle_hix22<P:mode>" 8025 [(set (match_operand:P 0 "register_operand" "=r") 8026 (high:P (unspec:P [(match_operand 1 "tle_symbolic_operand" "")] 8027 UNSPEC_TLSLE)))] 8028 "TARGET_TLS" 8029 "sethi\\t%%tle_hix22(%a1), %0") 8030 8031(define_insn "tle_lox10<P:mode>" 8032 [(set (match_operand:P 0 "register_operand" "=r") 8033 (lo_sum:P (match_operand:P 1 "register_operand" "r") 8034 (unspec:P [(match_operand 2 "tle_symbolic_operand" "")] 8035 UNSPEC_TLSLE)))] 8036 "TARGET_TLS" 8037 "xor\\t%1, %%tle_lox10(%a2), %0") 8038 8039;; Now patterns combining tldo_add with some integer loads or stores 8040(define_insn "*tldo_ldub<P:mode>" 8041 [(set (match_operand:QI 0 "register_operand" "=r") 8042 (mem:QI (plus:P (unspec:P [(match_operand:P 2 "register_operand" "r") 8043 (match_operand 3 "tld_symbolic_operand" "")] 8044 UNSPEC_TLSLDO) 8045 (match_operand:P 1 "register_operand" "r"))))] 8046 "TARGET_TLS" 8047 "ldub\t[%1 + %2], %0, %%tldo_add(%3)" 8048 [(set_attr "type" "load") 8049 (set_attr "subtype" "regular") 8050 (set_attr "us3load_type" "3cycle")]) 8051 8052(define_insn "*tldo_ldub1<P:mode>" 8053 [(set (match_operand:HI 0 "register_operand" "=r") 8054 (zero_extend:HI 8055 (mem:QI (plus:P (unspec:P [(match_operand:P 2 "register_operand" "r") 8056 (match_operand 3 "tld_symbolic_operand" "")] 8057 UNSPEC_TLSLDO) 8058 (match_operand:P 1 "register_operand" "r")))))] 8059 "TARGET_TLS" 8060 "ldub\t[%1 + %2], %0, %%tldo_add(%3)" 8061 [(set_attr "type" "load") 8062 (set_attr "subtype" "regular") 8063 (set_attr "us3load_type" "3cycle")]) 8064 8065(define_insn "*tldo_ldub2<P:mode>" 8066 [(set (match_operand:SI 0 "register_operand" "=r") 8067 (zero_extend:SI 8068 (mem:QI (plus:P (unspec:P [(match_operand:P 2 "register_operand" "r") 8069 (match_operand 3 "tld_symbolic_operand" "")] 8070 UNSPEC_TLSLDO) 8071 (match_operand:P 1 "register_operand" "r")))))] 8072 "TARGET_TLS" 8073 "ldub\t[%1 + %2], %0, %%tldo_add(%3)" 8074 [(set_attr "type" "load") 8075 (set_attr "subtype" "regular") 8076 (set_attr "us3load_type" "3cycle")]) 8077 8078(define_insn "*tldo_ldsb1<P:mode>" 8079 [(set (match_operand:HI 0 "register_operand" "=r") 8080 (sign_extend:HI 8081 (mem:QI (plus:P (unspec:P [(match_operand:P 2 "register_operand" "r") 8082 (match_operand 3 "tld_symbolic_operand" "")] 8083 UNSPEC_TLSLDO) 8084 (match_operand:P 1 "register_operand" "r")))))] 8085 "TARGET_TLS" 8086 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)" 8087 [(set_attr "type" "sload") 8088 (set_attr "us3load_type" "3cycle")]) 8089 8090(define_insn "*tldo_ldsb2<P:mode>" 8091 [(set (match_operand:SI 0 "register_operand" "=r") 8092 (sign_extend:SI 8093 (mem:QI (plus:P (unspec:P [(match_operand:P 2 "register_operand" "r") 8094 (match_operand 3 "tld_symbolic_operand" "")] 8095 UNSPEC_TLSLDO) 8096 (match_operand:P 1 "register_operand" "r")))))] 8097 "TARGET_TLS" 8098 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)" 8099 [(set_attr "type" "sload") 8100 (set_attr "us3load_type" "3cycle")]) 8101 8102(define_insn "*tldo_ldub3_sp64" 8103 [(set (match_operand:DI 0 "register_operand" "=r") 8104 (zero_extend:DI 8105 (mem:QI (plus:DI (unspec:DI [(match_operand:DI 2 "register_operand" "r") 8106 (match_operand 3 "tld_symbolic_operand" "")] 8107 UNSPEC_TLSLDO) 8108 (match_operand:DI 1 "register_operand" "r")))))] 8109 "TARGET_TLS && TARGET_ARCH64" 8110 "ldub\t[%1 + %2], %0, %%tldo_add(%3)" 8111 [(set_attr "type" "load") 8112 (set_attr "subtype" "regular") 8113 (set_attr "us3load_type" "3cycle")]) 8114 8115(define_insn "*tldo_ldsb3_sp64" 8116 [(set (match_operand:DI 0 "register_operand" "=r") 8117 (sign_extend:DI 8118 (mem:QI (plus:DI (unspec:DI [(match_operand:DI 2 "register_operand" "r") 8119 (match_operand 3 "tld_symbolic_operand" "")] 8120 UNSPEC_TLSLDO) 8121 (match_operand:DI 1 "register_operand" "r")))))] 8122 "TARGET_TLS && TARGET_ARCH64" 8123 "ldsb\t[%1 + %2], %0, %%tldo_add(%3)" 8124 [(set_attr "type" "sload") 8125 (set_attr "us3load_type" "3cycle")]) 8126 8127(define_insn "*tldo_lduh<P:mode>" 8128 [(set (match_operand:HI 0 "register_operand" "=r") 8129 (mem:HI (plus:P (unspec:P [(match_operand:P 2 "register_operand" "r") 8130 (match_operand 3 "tld_symbolic_operand" "")] 8131 UNSPEC_TLSLDO) 8132 (match_operand:P 1 "register_operand" "r"))))] 8133 "TARGET_TLS" 8134 "lduh\t[%1 + %2], %0, %%tldo_add(%3)" 8135 [(set_attr "type" "load") 8136 (set_attr "subtype" "regular") 8137 (set_attr "us3load_type" "3cycle")]) 8138 8139(define_insn "*tldo_lduh1<P:mode>" 8140 [(set (match_operand:SI 0 "register_operand" "=r") 8141 (zero_extend:SI 8142 (mem:HI (plus:P (unspec:P [(match_operand:P 2 "register_operand" "r") 8143 (match_operand 3 "tld_symbolic_operand" "")] 8144 UNSPEC_TLSLDO) 8145 (match_operand:P 1 "register_operand" "r")))))] 8146 "TARGET_TLS" 8147 "lduh\t[%1 + %2], %0, %%tldo_add(%3)" 8148 [(set_attr "type" "load") 8149 (set_attr "subtype" "regular") 8150 (set_attr "us3load_type" "3cycle")]) 8151 8152(define_insn "*tldo_ldsh1<P:mode>" 8153 [(set (match_operand:SI 0 "register_operand" "=r") 8154 (sign_extend:SI 8155 (mem:HI (plus:P (unspec:P [(match_operand:P 2 "register_operand" "r") 8156 (match_operand 3 "tld_symbolic_operand" "")] 8157 UNSPEC_TLSLDO) 8158 (match_operand:P 1 "register_operand" "r")))))] 8159 "TARGET_TLS" 8160 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)" 8161 [(set_attr "type" "sload") 8162 (set_attr "us3load_type" "3cycle")]) 8163 8164(define_insn "*tldo_lduh2_sp64" 8165 [(set (match_operand:DI 0 "register_operand" "=r") 8166 (zero_extend:DI 8167 (mem:HI (plus:DI (unspec:DI [(match_operand:DI 2 "register_operand" "r") 8168 (match_operand 3 "tld_symbolic_operand" "")] 8169 UNSPEC_TLSLDO) 8170 (match_operand:DI 1 "register_operand" "r")))))] 8171 "TARGET_TLS && TARGET_ARCH64" 8172 "lduh\t[%1 + %2], %0, %%tldo_add(%3)" 8173 [(set_attr "type" "load") 8174 (set_attr "subtype" "regular") 8175 (set_attr "us3load_type" "3cycle")]) 8176 8177(define_insn "*tldo_ldsh2_sp64" 8178 [(set (match_operand:DI 0 "register_operand" "=r") 8179 (sign_extend:DI 8180 (mem:HI (plus:DI (unspec:DI [(match_operand:DI 2 "register_operand" "r") 8181 (match_operand 3 "tld_symbolic_operand" "")] 8182 UNSPEC_TLSLDO) 8183 (match_operand:DI 1 "register_operand" "r")))))] 8184 "TARGET_TLS && TARGET_ARCH64" 8185 "ldsh\t[%1 + %2], %0, %%tldo_add(%3)" 8186 [(set_attr "type" "sload") 8187 (set_attr "us3load_type" "3cycle")]) 8188 8189(define_insn "*tldo_lduw<P:mode>" 8190 [(set (match_operand:SI 0 "register_operand" "=r") 8191 (mem:SI (plus:P (unspec:P [(match_operand:P 2 "register_operand" "r") 8192 (match_operand 3 "tld_symbolic_operand" "")] 8193 UNSPEC_TLSLDO) 8194 (match_operand:P 1 "register_operand" "r"))))] 8195 "TARGET_TLS" 8196 "ld\t[%1 + %2], %0, %%tldo_add(%3)" 8197 [(set_attr "type" "load") 8198 (set_attr "subtype" "regular")]) 8199 8200(define_insn "*tldo_lduw1_sp64" 8201 [(set (match_operand:DI 0 "register_operand" "=r") 8202 (zero_extend:DI 8203 (mem:SI (plus:DI (unspec:DI [(match_operand:DI 2 "register_operand" "r") 8204 (match_operand 3 "tld_symbolic_operand" "")] 8205 UNSPEC_TLSLDO) 8206 (match_operand:DI 1 "register_operand" "r")))))] 8207 "TARGET_TLS && TARGET_ARCH64" 8208 "lduw\t[%1 + %2], %0, %%tldo_add(%3)" 8209 [(set_attr "type" "load") 8210 (set_attr "subtype" "regular")]) 8211 8212(define_insn "*tldo_ldsw1_sp64" 8213 [(set (match_operand:DI 0 "register_operand" "=r") 8214 (sign_extend:DI 8215 (mem:SI (plus:DI (unspec:DI [(match_operand:DI 2 "register_operand" "r") 8216 (match_operand 3 "tld_symbolic_operand" "")] 8217 UNSPEC_TLSLDO) 8218 (match_operand:DI 1 "register_operand" "r")))))] 8219 "TARGET_TLS && TARGET_ARCH64" 8220 "ldsw\t[%1 + %2], %0, %%tldo_add(%3)" 8221 [(set_attr "type" "sload") 8222 (set_attr "us3load_type" "3cycle")]) 8223 8224(define_insn "*tldo_ldx_sp64" 8225 [(set (match_operand:DI 0 "register_operand" "=r") 8226 (mem:DI (plus:DI (unspec:DI [(match_operand:DI 2 "register_operand" "r") 8227 (match_operand 3 "tld_symbolic_operand" "")] 8228 UNSPEC_TLSLDO) 8229 (match_operand:DI 1 "register_operand" "r"))))] 8230 "TARGET_TLS && TARGET_ARCH64" 8231 "ldx\t[%1 + %2], %0, %%tldo_add(%3)" 8232 [(set_attr "type" "load") 8233 (set_attr "subtype" "regular")]) 8234 8235(define_insn "*tldo_stb<P:mode>" 8236 [(set (mem:QI (plus:P (unspec:P [(match_operand:P 2 "register_operand" "r") 8237 (match_operand 3 "tld_symbolic_operand" "")] 8238 UNSPEC_TLSLDO) 8239 (match_operand:P 1 "register_operand" "r"))) 8240 (match_operand:QI 0 "register_operand" "r"))] 8241 "TARGET_TLS" 8242 "stb\t%0, [%1 + %2], %%tldo_add(%3)" 8243 [(set_attr "type" "store")]) 8244 8245(define_insn "*tldo_sth<P:mode>" 8246 [(set (mem:HI (plus:P (unspec:P [(match_operand:P 2 "register_operand" "r") 8247 (match_operand 3 "tld_symbolic_operand" "")] 8248 UNSPEC_TLSLDO) 8249 (match_operand:P 1 "register_operand" "r"))) 8250 (match_operand:HI 0 "register_operand" "r"))] 8251 "TARGET_TLS" 8252 "sth\t%0, [%1 + %2], %%tldo_add(%3)" 8253 [(set_attr "type" "store")]) 8254 8255(define_insn "*tldo_stw<P:mode>" 8256 [(set (mem:SI (plus:P (unspec:P [(match_operand:P 2 "register_operand" "r") 8257 (match_operand 3 "tld_symbolic_operand" "")] 8258 UNSPEC_TLSLDO) 8259 (match_operand:P 1 "register_operand" "r"))) 8260 (match_operand:SI 0 "register_operand" "r"))] 8261 "TARGET_TLS" 8262 "st\t%0, [%1 + %2], %%tldo_add(%3)" 8263 [(set_attr "type" "store")]) 8264 8265(define_insn "*tldo_stx_sp64" 8266 [(set (mem:DI (plus:DI (unspec:DI [(match_operand:DI 2 "register_operand" "r") 8267 (match_operand 3 "tld_symbolic_operand" "")] 8268 UNSPEC_TLSLDO) 8269 (match_operand:DI 1 "register_operand" "r"))) 8270 (match_operand:DI 0 "register_operand" "r"))] 8271 "TARGET_TLS && TARGET_ARCH64" 8272 "stx\t%0, [%1 + %2], %%tldo_add(%3)" 8273 [(set_attr "type" "store")]) 8274 8275 8276;; Stack protector instructions. 8277 8278(define_expand "stack_protect_set" 8279 [(match_operand 0 "memory_operand" "") 8280 (match_operand 1 "memory_operand" "")] 8281 "" 8282{ 8283#ifdef TARGET_THREAD_SSP_OFFSET 8284 rtx tlsreg = gen_rtx_REG (Pmode, 7); 8285 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET)); 8286 operands[1] = gen_rtx_MEM (Pmode, addr); 8287#endif 8288 if (TARGET_ARCH64) 8289 emit_insn (gen_stack_protect_setdi (operands[0], operands[1])); 8290 else 8291 emit_insn (gen_stack_protect_setsi (operands[0], operands[1])); 8292 DONE; 8293}) 8294 8295(define_insn "stack_protect_setsi" 8296 [(set (match_operand:SI 0 "memory_operand" "=m") 8297 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 8298 (set (match_scratch:SI 2 "=&r") (const_int 0))] 8299 "TARGET_ARCH32" 8300 "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2" 8301 [(set_attr "type" "multi") 8302 (set_attr "length" "3")]) 8303 8304(define_insn "stack_protect_setdi" 8305 [(set (match_operand:DI 0 "memory_operand" "=m") 8306 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 8307 (set (match_scratch:DI 2 "=&r") (const_int 0))] 8308 "TARGET_ARCH64" 8309 "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2" 8310 [(set_attr "type" "multi") 8311 (set_attr "length" "3")]) 8312 8313(define_expand "stack_protect_test" 8314 [(match_operand 0 "memory_operand" "") 8315 (match_operand 1 "memory_operand" "") 8316 (match_operand 2 "" "")] 8317 "" 8318{ 8319 rtx result, test; 8320#ifdef TARGET_THREAD_SSP_OFFSET 8321 rtx tlsreg = gen_rtx_REG (Pmode, 7); 8322 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET)); 8323 operands[1] = gen_rtx_MEM (Pmode, addr); 8324#endif 8325 if (TARGET_ARCH64) 8326 { 8327 result = gen_reg_rtx (Pmode); 8328 emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1])); 8329 test = gen_rtx_EQ (VOIDmode, result, const0_rtx); 8330 emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2])); 8331 } 8332 else 8333 { 8334 emit_insn (gen_stack_protect_testsi (operands[0], operands[1])); 8335 result = gen_rtx_REG (CCmode, SPARC_ICC_REG); 8336 test = gen_rtx_EQ (VOIDmode, result, const0_rtx); 8337 emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2])); 8338 } 8339 DONE; 8340}) 8341 8342(define_insn "stack_protect_testsi" 8343 [(set (reg:CC CC_REG) 8344 (unspec:CC [(match_operand:SI 0 "memory_operand" "m") 8345 (match_operand:SI 1 "memory_operand" "m")] 8346 UNSPEC_SP_TEST)) 8347 (set (match_scratch:SI 3 "=r") (const_int 0)) 8348 (clobber (match_scratch:SI 2 "=&r"))] 8349 "TARGET_ARCH32" 8350 "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3" 8351 [(set_attr "type" "multi") 8352 (set_attr "length" "4")]) 8353 8354(define_insn "stack_protect_testdi" 8355 [(set (match_operand:DI 0 "register_operand" "=&r") 8356 (unspec:DI [(match_operand:DI 1 "memory_operand" "m") 8357 (match_operand:DI 2 "memory_operand" "m")] 8358 UNSPEC_SP_TEST)) 8359 (set (match_scratch:DI 3 "=r") (const_int 0))] 8360 "TARGET_ARCH64" 8361 "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3" 8362 [(set_attr "type" "multi") 8363 (set_attr "length" "4")]) 8364 8365 8366;; Vector instructions. 8367 8368(define_mode_iterator VM32 [V1SI V2HI V4QI]) 8369(define_mode_iterator VM64 [V1DI V2SI V4HI V8QI]) 8370(define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI]) 8371 8372(define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s") 8373 (V8QI "8")]) 8374(define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f") 8375 (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")]) 8376(define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single") 8377 (V1DI "double") (V2SI "double") (V4HI "double") 8378 (V8QI "double")]) 8379(define_mode_attr veltmode [(V1SI "si") (V2HI "hi") (V4QI "qi") (V1DI "di") 8380 (V2SI "si") (V4HI "hi") (V8QI "qi")]) 8381 8382(define_expand "mov<VMALL:mode>" 8383 [(set (match_operand:VMALL 0 "nonimmediate_operand" "") 8384 (match_operand:VMALL 1 "general_operand" ""))] 8385 "TARGET_VIS" 8386{ 8387 if (sparc_expand_move (<VMALL:MODE>mode, operands)) 8388 DONE; 8389}) 8390 8391(define_insn "*mov<VM32:mode>_insn" 8392 [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f") 8393 (match_operand:VM32 1 "input_operand" "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))] 8394 "TARGET_VIS 8395 && (register_operand (operands[0], <VM32:MODE>mode) 8396 || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))" 8397 "@ 8398 fzeros\t%0 8399 fones\t%0 8400 fsrc2s\t%1, %0 8401 ld\t%1, %0 8402 st\t%1, %0 8403 st\t%r1, %0 8404 ld\t%1, %0 8405 st\t%1, %0 8406 mov\t%1, %0 8407 movstouw\t%1, %0 8408 movwtos\t%1, %0" 8409 [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,*,vismv,vismv") 8410 (set_attr "subtype" "single,single,single,*,*,*,regular,*,*,movstouw,single") 8411 (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")]) 8412 8413(define_insn "*mov<VM64:mode>_insn_sp64" 8414 [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,W,m,*r, m,*r, e,*r") 8415 (match_operand:VM64 1 "input_operand" "Y,Z,e,W,e,Y, m,*r, e,*r,*r"))] 8416 "TARGET_VIS 8417 && TARGET_ARCH64 8418 && (register_operand (operands[0], <VM64:MODE>mode) 8419 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))" 8420 "@ 8421 fzero\t%0 8422 fone\t%0 8423 fsrc2\t%1, %0 8424 ldd\t%1, %0 8425 std\t%1, %0 8426 stx\t%r1, %0 8427 ldx\t%1, %0 8428 stx\t%1, %0 8429 movdtox\t%1, %0 8430 movxtod\t%1, %0 8431 mov\t%1, %0" 8432 [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,vismv,vismv,*") 8433 (set_attr "subtype" "double,double,double,*,*,*,regular,*,movdtox,movxtod,*") 8434 (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")]) 8435 8436(define_insn "*mov<VM64:mode>_insn_sp32" 8437 [(set (match_operand:VM64 0 "nonimmediate_operand" 8438 "=T,o,e,e,e,*r, f,e,T,U,T,f,o,*r,*r, o") 8439 (match_operand:VM64 1 "input_operand" 8440 " Y,Y,Y,Z,e, f,*r,T,e,T,U,o,f,*r, o,*r"))] 8441 "TARGET_VIS 8442 && TARGET_ARCH32 8443 && (register_operand (operands[0], <VM64:MODE>mode) 8444 || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))" 8445 "@ 8446 stx\t%r1, %0 8447 # 8448 fzero\t%0 8449 fone\t%0 8450 fsrc2\t%1, %0 8451 # 8452 # 8453 ldd\t%1, %0 8454 std\t%1, %0 8455 ldd\t%1, %0 8456 std\t%1, %0 8457 # 8458 # 8459 # 8460 ldd\t%1, %0 8461 std\t%1, %0" 8462 [(set_attr "type" "store,*,visl,visl,vismv,*,*,fpload,fpstore,load,store,*,*,*,load,store") 8463 (set_attr "subtype" "*,*,double,double,double,*,*,*,*,regular,*,*,*,*,regular,*") 8464 (set_attr "length" "*,2,*,*,*,2,2,*,*,*,*,2,2,2,*,*") 8465 (set_attr "cpu_feature" "*,*,vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*,*,*") 8466 (set_attr "lra" "*,*,*,*,*,*,*,*,*,disabled,disabled,*,*,*,*,*")]) 8467 8468(define_split 8469 [(set (match_operand:VM64 0 "register_operand" "") 8470 (match_operand:VM64 1 "register_operand" ""))] 8471 "reload_completed 8472 && TARGET_VIS 8473 && TARGET_ARCH32 8474 && sparc_split_reg_reg_legitimate (operands[0], operands[1])" 8475 [(clobber (const_int 0))] 8476{ 8477 sparc_split_reg_reg (operands[0], operands[1], SImode); 8478 DONE; 8479}) 8480 8481(define_split 8482 [(set (match_operand:VM64 0 "register_operand" "") 8483 (match_operand:VM64 1 "memory_operand" ""))] 8484 "reload_completed 8485 && TARGET_VIS 8486 && TARGET_ARCH32 8487 && sparc_split_reg_mem_legitimate (operands[0], operands[1])" 8488 [(clobber (const_int 0))] 8489{ 8490 sparc_split_reg_mem (operands[0], operands[1], SImode); 8491 DONE; 8492}) 8493 8494(define_split 8495 [(set (match_operand:VM64 0 "memory_operand" "") 8496 (match_operand:VM64 1 "register_operand" ""))] 8497 "reload_completed 8498 && TARGET_VIS 8499 && TARGET_ARCH32 8500 && sparc_split_reg_mem_legitimate (operands[1], operands[0])" 8501 [(clobber (const_int 0))] 8502{ 8503 sparc_split_mem_reg (operands[0], operands[1], SImode); 8504 DONE; 8505}) 8506 8507(define_split 8508 [(set (match_operand:VM64 0 "memory_operand" "") 8509 (match_operand:VM64 1 "const_zero_operand" ""))] 8510 "reload_completed 8511 && TARGET_VIS 8512 && TARGET_ARCH32 8513 && !mem_min_alignment (operands[0], 8) 8514 && offsettable_memref_p (operands[0])" 8515 [(clobber (const_int 0))] 8516{ 8517 emit_move_insn_1 (adjust_address (operands[0], SImode, 0), const0_rtx); 8518 emit_move_insn_1 (adjust_address (operands[0], SImode, 4), const0_rtx); 8519 DONE; 8520}) 8521 8522(define_expand "vec_init<VMALL:mode><VMALL:veltmode>" 8523 [(match_operand:VMALL 0 "register_operand" "") 8524 (match_operand:VMALL 1 "" "")] 8525 "TARGET_VIS" 8526{ 8527 sparc_expand_vector_init (operands[0], operands[1]); 8528 DONE; 8529}) 8530 8531(define_code_iterator plusminus [plus minus]) 8532(define_code_attr plusminus_insn [(plus "add") (minus "sub")]) 8533 8534(define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI]) 8535 8536(define_insn "<plusminus_insn><VADDSUB:mode>3" 8537 [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>") 8538 (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>") 8539 (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))] 8540 "TARGET_VIS" 8541 "fp<plusminus_insn><vbits>\t%1, %2, %0" 8542 [(set_attr "type" "fga") 8543 (set_attr "subtype" "other") 8544 (set_attr "fptype" "<vfptype>")]) 8545 8546(define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI]) 8547(define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s") 8548 (V1DI "") (V2SI "") (V4HI "") (V8QI "")]) 8549(define_code_iterator vlop [ior and xor]) 8550(define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")]) 8551(define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")]) 8552 8553(define_insn "<vlop:code><VL:mode>3" 8554 [(set (match_operand:VL 0 "register_operand" "=<vconstr>") 8555 (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>") 8556 (match_operand:VL 2 "register_operand" "<vconstr>")))] 8557 "TARGET_VIS" 8558 "f<vlinsn><vlsuf>\t%1, %2, %0" 8559 [(set_attr "type" "visl") 8560 (set_attr "fptype" "<vfptype>")]) 8561 8562(define_insn "*not_<vlop:code><VL:mode>3" 8563 [(set (match_operand:VL 0 "register_operand" "=<vconstr>") 8564 (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>") 8565 (match_operand:VL 2 "register_operand" "<vconstr>"))))] 8566 "TARGET_VIS" 8567 "f<vlninsn><vlsuf>\t%1, %2, %0" 8568 [(set_attr "type" "visl") 8569 (set_attr "fptype" "<vfptype>")]) 8570 8571;; (ior (not (op1)) (not (op2))) is the canonical form of NAND. 8572(define_insn "*nand<VL:mode>_vis" 8573 [(set (match_operand:VL 0 "register_operand" "=<vconstr>") 8574 (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")) 8575 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))] 8576 "TARGET_VIS" 8577 "fnand<vlsuf>\t%1, %2, %0" 8578 [(set_attr "type" "visl") 8579 (set_attr "fptype" "<vfptype>")]) 8580 8581(define_code_iterator vlnotop [ior and]) 8582 8583(define_insn "*<vlnotop:code>_not1<VL:mode>_vis" 8584 [(set (match_operand:VL 0 "register_operand" "=<vconstr>") 8585 (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")) 8586 (match_operand:VL 2 "register_operand" "<vconstr>")))] 8587 "TARGET_VIS" 8588 "f<vlinsn>not1<vlsuf>\t%1, %2, %0" 8589 [(set_attr "type" "visl") 8590 (set_attr "fptype" "<vfptype>")]) 8591 8592(define_insn "*<vlnotop:code>_not2<VL:mode>_vis" 8593 [(set (match_operand:VL 0 "register_operand" "=<vconstr>") 8594 (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>") 8595 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))] 8596 "TARGET_VIS" 8597 "f<vlinsn>not2<vlsuf>\t%1, %2, %0" 8598 [(set_attr "type" "visl") 8599 (set_attr "fptype" "<vfptype>")]) 8600 8601(define_insn "one_cmpl<VL:mode>2" 8602 [(set (match_operand:VL 0 "register_operand" "=<vconstr>") 8603 (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))] 8604 "TARGET_VIS" 8605 "fnot1<vlsuf>\t%1, %0" 8606 [(set_attr "type" "visl") 8607 (set_attr "fptype" "<vfptype>")]) 8608 8609;; Hard to generate VIS instructions. We have builtins for these. 8610 8611(define_insn "fpack16_vis" 8612 [(set (match_operand:V4QI 0 "register_operand" "=f") 8613 (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e") 8614 (reg:DI GSR_REG)] 8615 UNSPEC_FPACK16))] 8616 "TARGET_VIS" 8617 "fpack16\t%1, %0" 8618 [(set_attr "type" "fgm_pack") 8619 (set_attr "fptype" "double")]) 8620 8621(define_insn "fpackfix_vis" 8622 [(set (match_operand:V2HI 0 "register_operand" "=f") 8623 (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e") 8624 (reg:DI GSR_REG)] 8625 UNSPEC_FPACKFIX))] 8626 "TARGET_VIS" 8627 "fpackfix\t%1, %0" 8628 [(set_attr "type" "fgm_pack") 8629 (set_attr "fptype" "double")]) 8630 8631(define_insn "fpack32_vis" 8632 [(set (match_operand:V8QI 0 "register_operand" "=e") 8633 (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e") 8634 (match_operand:V8QI 2 "register_operand" "e") 8635 (reg:DI GSR_REG)] 8636 UNSPEC_FPACK32))] 8637 "TARGET_VIS" 8638 "fpack32\t%1, %2, %0" 8639 [(set_attr "type" "fgm_pack") 8640 (set_attr "fptype" "double")]) 8641 8642(define_insn "fexpand_vis" 8643 [(set (match_operand:V4HI 0 "register_operand" "=e") 8644 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")] 8645 UNSPEC_FEXPAND))] 8646 "TARGET_VIS" 8647 "fexpand\t%1, %0" 8648 [(set_attr "type" "fga") 8649 (set_attr "subtype" "fpu") 8650 (set_attr "fptype" "double")]) 8651 8652(define_insn "fpmerge_vis" 8653 [(set (match_operand:V8QI 0 "register_operand" "=e") 8654 (vec_select:V8QI 8655 (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f") 8656 (match_operand:V4QI 2 "register_operand" "f")) 8657 (parallel [(const_int 0) (const_int 4) 8658 (const_int 1) (const_int 5) 8659 (const_int 2) (const_int 6) 8660 (const_int 3) (const_int 7)])))] 8661 "TARGET_VIS" 8662 "fpmerge\t%1, %2, %0" 8663 [(set_attr "type" "fga") 8664 (set_attr "subtype" "fpu") 8665 (set_attr "fptype" "double")]) 8666 8667;; Partitioned multiply instructions 8668(define_insn "fmul8x16_vis" 8669 [(set (match_operand:V4HI 0 "register_operand" "=e") 8670 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f") 8671 (match_operand:V4HI 2 "register_operand" "e")] 8672 UNSPEC_MUL8))] 8673 "TARGET_VIS" 8674 "fmul8x16\t%1, %2, %0" 8675 [(set_attr "type" "fgm_mul") 8676 (set_attr "fptype" "double")]) 8677 8678(define_insn "fmul8x16au_vis" 8679 [(set (match_operand:V4HI 0 "register_operand" "=e") 8680 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f") 8681 (match_operand:V2HI 2 "register_operand" "f")] 8682 UNSPEC_MUL16AU))] 8683 "TARGET_VIS" 8684 "fmul8x16au\t%1, %2, %0" 8685 [(set_attr "type" "fgm_mul") 8686 (set_attr "fptype" "double")]) 8687 8688(define_insn "fmul8x16al_vis" 8689 [(set (match_operand:V4HI 0 "register_operand" "=e") 8690 (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f") 8691 (match_operand:V2HI 2 "register_operand" "f")] 8692 UNSPEC_MUL16AL))] 8693 "TARGET_VIS" 8694 "fmul8x16al\t%1, %2, %0" 8695 [(set_attr "type" "fgm_mul") 8696 (set_attr "fptype" "double")]) 8697 8698(define_insn "fmul8sux16_vis" 8699 [(set (match_operand:V4HI 0 "register_operand" "=e") 8700 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e") 8701 (match_operand:V4HI 2 "register_operand" "e")] 8702 UNSPEC_MUL8SU))] 8703 "TARGET_VIS" 8704 "fmul8sux16\t%1, %2, %0" 8705 [(set_attr "type" "fgm_mul") 8706 (set_attr "fptype" "double")]) 8707 8708(define_insn "fmul8ulx16_vis" 8709 [(set (match_operand:V4HI 0 "register_operand" "=e") 8710 (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e") 8711 (match_operand:V4HI 2 "register_operand" "e")] 8712 UNSPEC_MUL8UL))] 8713 "TARGET_VIS" 8714 "fmul8ulx16\t%1, %2, %0" 8715 [(set_attr "type" "fgm_mul") 8716 (set_attr "fptype" "double")]) 8717 8718(define_insn "fmuld8sux16_vis" 8719 [(set (match_operand:V2SI 0 "register_operand" "=e") 8720 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f") 8721 (match_operand:V2HI 2 "register_operand" "f")] 8722 UNSPEC_MULDSU))] 8723 "TARGET_VIS" 8724 "fmuld8sux16\t%1, %2, %0" 8725 [(set_attr "type" "fgm_mul") 8726 (set_attr "fptype" "double")]) 8727 8728(define_insn "fmuld8ulx16_vis" 8729 [(set (match_operand:V2SI 0 "register_operand" "=e") 8730 (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f") 8731 (match_operand:V2HI 2 "register_operand" "f")] 8732 UNSPEC_MULDUL))] 8733 "TARGET_VIS" 8734 "fmuld8ulx16\t%1, %2, %0" 8735 [(set_attr "type" "fgm_mul") 8736 (set_attr "fptype" "double")]) 8737 8738(define_expand "wrgsr_vis" 8739 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))] 8740 "TARGET_VIS" 8741{ 8742 if (TARGET_ARCH32) 8743 { 8744 emit_insn (gen_wrgsr_v8plus (operands[0])); 8745 DONE; 8746 } 8747}) 8748 8749(define_insn "*wrgsr_sp64" 8750 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))] 8751 "TARGET_VIS && TARGET_ARCH64" 8752 "wr\t%%g0, %0, %%gsr" 8753 [(set_attr "type" "gsr") 8754 (set_attr "subtype" "reg")]) 8755 8756(define_insn "wrgsr_v8plus" 8757 [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r")) 8758 (clobber (match_scratch:SI 1 "=X,&h"))] 8759 "TARGET_VIS && TARGET_ARCH32" 8760{ 8761 if (GET_CODE (operands[0]) == CONST_INT 8762 || sparc_check_64 (operands[0], insn)) 8763 return "wr\t%%g0, %0, %%gsr"; 8764 8765 output_asm_insn("srl\t%L0, 0, %L0", operands); 8766 return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr"; 8767} 8768 [(set_attr "type" "multi")]) 8769 8770(define_expand "rdgsr_vis" 8771 [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))] 8772 "TARGET_VIS" 8773{ 8774 if (TARGET_ARCH32) 8775 { 8776 emit_insn (gen_rdgsr_v8plus (operands[0])); 8777 DONE; 8778 } 8779}) 8780 8781(define_insn "*rdgsr_sp64" 8782 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))] 8783 "TARGET_VIS && TARGET_ARCH64" 8784 "rd\t%%gsr, %0" 8785 [(set_attr "type" "gsr") 8786 (set_attr "subtype" "reg")]) 8787 8788(define_insn "rdgsr_v8plus" 8789 [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG)) 8790 (clobber (match_scratch:SI 1 "=&h"))] 8791 "TARGET_VIS && TARGET_ARCH32" 8792{ 8793 return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0"; 8794} 8795 [(set_attr "type" "multi")]) 8796 8797;; Using faligndata only makes sense after an alignaddr since the choice of 8798;; bytes to take out of each operand is dependent on the results of the last 8799;; alignaddr. 8800(define_insn "faligndata<VM64:mode>_vis" 8801 [(set (match_operand:VM64 0 "register_operand" "=e") 8802 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e") 8803 (match_operand:VM64 2 "register_operand" "e") 8804 (reg:DI GSR_REG)] 8805 UNSPEC_ALIGNDATA))] 8806 "TARGET_VIS" 8807 "faligndata\t%1, %2, %0" 8808 [(set_attr "type" "fga") 8809 (set_attr "subtype" "other") 8810 (set_attr "fptype" "double")]) 8811 8812(define_insn "alignaddrsi_vis" 8813 [(set (match_operand:SI 0 "register_operand" "=r") 8814 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") 8815 (match_operand:SI 2 "register_or_zero_operand" "rJ"))) 8816 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0)) 8817 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 8818 "TARGET_VIS" 8819 "alignaddr\t%r1, %r2, %0" 8820 [(set_attr "type" "gsr") 8821 (set_attr "subtype" "alignaddr")]) 8822 8823(define_insn "alignaddrdi_vis" 8824 [(set (match_operand:DI 0 "register_operand" "=r") 8825 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ") 8826 (match_operand:DI 2 "register_or_zero_operand" "rJ"))) 8827 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0)) 8828 (plus:DI (match_dup 1) (match_dup 2)))] 8829 "TARGET_VIS" 8830 "alignaddr\t%r1, %r2, %0" 8831 [(set_attr "type" "gsr") 8832 (set_attr "subtype" "alignaddr")]) 8833 8834(define_insn "alignaddrlsi_vis" 8835 [(set (match_operand:SI 0 "register_operand" "=r") 8836 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") 8837 (match_operand:SI 2 "register_or_zero_operand" "rJ"))) 8838 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0)) 8839 (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))) 8840 (const_int 7)))] 8841 "TARGET_VIS" 8842 "alignaddrl\t%r1, %r2, %0" 8843 [(set_attr "type" "gsr") 8844 (set_attr "subtype" "alignaddr")]) 8845 8846(define_insn "alignaddrldi_vis" 8847 [(set (match_operand:DI 0 "register_operand" "=r") 8848 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ") 8849 (match_operand:DI 2 "register_or_zero_operand" "rJ"))) 8850 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0)) 8851 (xor:DI (plus:DI (match_dup 1) (match_dup 2)) 8852 (const_int 7)))] 8853 "TARGET_VIS" 8854 "alignaddrl\t%r1, %r2, %0" 8855 [(set_attr "type" "gsr") 8856 (set_attr "subtype" "alignaddr")]) 8857 8858(define_insn "pdist_vis" 8859 [(set (match_operand:DI 0 "register_operand" "=e") 8860 (unspec:DI [(match_operand:V8QI 1 "register_operand" "e") 8861 (match_operand:V8QI 2 "register_operand" "e") 8862 (match_operand:DI 3 "register_operand" "0")] 8863 UNSPEC_PDIST))] 8864 "TARGET_VIS" 8865 "pdist\t%1, %2, %0" 8866 [(set_attr "type" "pdist") 8867 (set_attr "fptype" "double")]) 8868 8869;; Edge instructions produce condition codes equivalent to a 'subcc' 8870;; with the same operands. 8871(define_insn "edge8<P:mode>_vis" 8872 [(set (reg:CCNZ CC_REG) 8873 (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") 8874 (match_operand:P 2 "register_or_zero_operand" "rJ")) 8875 (const_int 0))) 8876 (set (match_operand:P 0 "register_operand" "=r") 8877 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))] 8878 "TARGET_VIS" 8879 "edge8\t%r1, %r2, %0" 8880 [(set_attr "type" "edge")]) 8881 8882(define_insn "edge8l<P:mode>_vis" 8883 [(set (reg:CCNZ CC_REG) 8884 (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") 8885 (match_operand:P 2 "register_or_zero_operand" "rJ")) 8886 (const_int 0))) 8887 (set (match_operand:P 0 "register_operand" "=r") 8888 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))] 8889 "TARGET_VIS" 8890 "edge8l\t%r1, %r2, %0" 8891 [(set_attr "type" "edge")]) 8892 8893(define_insn "edge16<P:mode>_vis" 8894 [(set (reg:CCNZ CC_REG) 8895 (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") 8896 (match_operand:P 2 "register_or_zero_operand" "rJ")) 8897 (const_int 0))) 8898 (set (match_operand:P 0 "register_operand" "=r") 8899 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))] 8900 "TARGET_VIS" 8901 "edge16\t%r1, %r2, %0" 8902 [(set_attr "type" "edge")]) 8903 8904(define_insn "edge16l<P:mode>_vis" 8905 [(set (reg:CCNZ CC_REG) 8906 (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") 8907 (match_operand:P 2 "register_or_zero_operand" "rJ")) 8908 (const_int 0))) 8909 (set (match_operand:P 0 "register_operand" "=r") 8910 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))] 8911 "TARGET_VIS" 8912 "edge16l\t%r1, %r2, %0" 8913 [(set_attr "type" "edge")]) 8914 8915(define_insn "edge32<P:mode>_vis" 8916 [(set (reg:CCNZ CC_REG) 8917 (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") 8918 (match_operand:P 2 "register_or_zero_operand" "rJ")) 8919 (const_int 0))) 8920 (set (match_operand:P 0 "register_operand" "=r") 8921 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))] 8922 "TARGET_VIS" 8923 "edge32\t%r1, %r2, %0" 8924 [(set_attr "type" "edge")]) 8925 8926(define_insn "edge32l<P:mode>_vis" 8927 [(set (reg:CCNZ CC_REG) 8928 (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") 8929 (match_operand:P 2 "register_or_zero_operand" "rJ")) 8930 (const_int 0))) 8931 (set (match_operand:P 0 "register_operand" "=r") 8932 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))] 8933 "TARGET_VIS" 8934 "edge32l\t%r1, %r2, %0" 8935 [(set_attr "type" "edge")]) 8936 8937(define_code_iterator gcond [le ne gt eq]) 8938(define_mode_iterator GCM [V4HI V2SI]) 8939(define_mode_attr gcm_name [(V4HI "16") (V2SI "32")]) 8940 8941(define_insn "fcmp<gcond:code><GCM:gcm_name><P:mode>_vis" 8942 [(set (match_operand:P 0 "register_operand" "=r") 8943 (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e") 8944 (match_operand:GCM 2 "register_operand" "e"))] 8945 UNSPEC_FCMP))] 8946 "TARGET_VIS" 8947 "fcmp<gcond:code><GCM:gcm_name>\t%1, %2, %0" 8948 [(set_attr "type" "viscmp")]) 8949 8950(define_insn "fpcmp<gcond:code>8<P:mode>_vis" 8951 [(set (match_operand:P 0 "register_operand" "=r") 8952 (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e") 8953 (match_operand:V8QI 2 "register_operand" "e"))] 8954 UNSPEC_FCMP))] 8955 "TARGET_VIS4" 8956 "fpcmp<gcond:code>8\t%1, %2, %0" 8957 [(set_attr "type" "viscmp")]) 8958 8959(define_expand "vcond<GCM:mode><GCM:mode>" 8960 [(match_operand:GCM 0 "register_operand" "") 8961 (match_operand:GCM 1 "register_operand" "") 8962 (match_operand:GCM 2 "register_operand" "") 8963 (match_operator 3 "" 8964 [(match_operand:GCM 4 "register_operand" "") 8965 (match_operand:GCM 5 "register_operand" "")])] 8966 "TARGET_VIS3" 8967{ 8968 sparc_expand_vcond (<MODE>mode, operands, UNSPEC_CMASK<gcm_name>, UNSPEC_FCMP); 8969 DONE; 8970}) 8971 8972(define_expand "vconduv8qiv8qi" 8973 [(match_operand:V8QI 0 "register_operand" "") 8974 (match_operand:V8QI 1 "register_operand" "") 8975 (match_operand:V8QI 2 "register_operand" "") 8976 (match_operator 3 "" 8977 [(match_operand:V8QI 4 "register_operand" "") 8978 (match_operand:V8QI 5 "register_operand" "")])] 8979 "TARGET_VIS3" 8980{ 8981 sparc_expand_vcond (V8QImode, operands, UNSPEC_CMASK8, UNSPEC_FUCMP); 8982 DONE; 8983}) 8984 8985(define_insn "array8<P:mode>_vis" 8986 [(set (match_operand:P 0 "register_operand" "=r") 8987 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") 8988 (match_operand:P 2 "register_or_zero_operand" "rJ")] 8989 UNSPEC_ARRAY8))] 8990 "TARGET_VIS" 8991 "array8\t%r1, %r2, %0" 8992 [(set_attr "type" "array")]) 8993 8994(define_insn "array16<P:mode>_vis" 8995 [(set (match_operand:P 0 "register_operand" "=r") 8996 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") 8997 (match_operand:P 2 "register_or_zero_operand" "rJ")] 8998 UNSPEC_ARRAY16))] 8999 "TARGET_VIS" 9000 "array16\t%r1, %r2, %0" 9001 [(set_attr "type" "array")]) 9002 9003(define_insn "array32<P:mode>_vis" 9004 [(set (match_operand:P 0 "register_operand" "=r") 9005 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") 9006 (match_operand:P 2 "register_or_zero_operand" "rJ")] 9007 UNSPEC_ARRAY32))] 9008 "TARGET_VIS" 9009 "array32\t%r1, %r2, %0" 9010 [(set_attr "type" "array")]) 9011 9012(define_insn "bmaskdi_vis" 9013 [(set (match_operand:DI 0 "register_operand" "=r") 9014 (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ") 9015 (match_operand:DI 2 "register_or_zero_operand" "rJ"))) 9016 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32)) 9017 (plus:DI (match_dup 1) (match_dup 2)))] 9018 "TARGET_VIS2 && TARGET_ARCH64" 9019 "bmask\t%r1, %r2, %0" 9020 [(set_attr "type" "bmask")]) 9021 9022(define_insn "bmasksi_vis" 9023 [(set (match_operand:SI 0 "register_operand" "=r") 9024 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") 9025 (match_operand:SI 2 "register_or_zero_operand" "rJ"))) 9026 (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32)) 9027 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 9028 "TARGET_VIS2" 9029 "bmask\t%r1, %r2, %0" 9030 [(set_attr "type" "bmask")]) 9031 9032(define_insn "bshuffle<VM64:mode>_vis" 9033 [(set (match_operand:VM64 0 "register_operand" "=e") 9034 (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e") 9035 (match_operand:VM64 2 "register_operand" "e") 9036 (reg:DI GSR_REG)] 9037 UNSPEC_BSHUFFLE))] 9038 "TARGET_VIS2" 9039 "bshuffle\t%1, %2, %0" 9040 [(set_attr "type" "fga") 9041 (set_attr "subtype" "other") 9042 (set_attr "fptype" "double")]) 9043 9044;; Unlike constant permutation, we can vastly simplify the compression of 9045;; the 64-bit selector input to the 32-bit %gsr value by knowing what the 9046;; width of the input is. 9047(define_expand "vec_perm<VM64:mode>" 9048 [(match_operand:VM64 0 "register_operand" "") 9049 (match_operand:VM64 1 "register_operand" "") 9050 (match_operand:VM64 2 "register_operand" "") 9051 (match_operand:VM64 3 "register_operand" "")] 9052 "TARGET_VIS2" 9053{ 9054 sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]); 9055 emit_insn (gen_bshuffle<VM64:mode>_vis (operands[0], operands[1], operands[2])); 9056 DONE; 9057}) 9058 9059;; VIS 2.0 adds edge variants which do not set the condition codes 9060(define_insn "edge8n<P:mode>_vis" 9061 [(set (match_operand:P 0 "register_operand" "=r") 9062 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") 9063 (match_operand:P 2 "register_or_zero_operand" "rJ")] 9064 UNSPEC_EDGE8N))] 9065 "TARGET_VIS2" 9066 "edge8n\t%r1, %r2, %0" 9067 [(set_attr "type" "edgen")]) 9068 9069(define_insn "edge8ln<P:mode>_vis" 9070 [(set (match_operand:P 0 "register_operand" "=r") 9071 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") 9072 (match_operand:P 2 "register_or_zero_operand" "rJ")] 9073 UNSPEC_EDGE8LN))] 9074 "TARGET_VIS2" 9075 "edge8ln\t%r1, %r2, %0" 9076 [(set_attr "type" "edgen")]) 9077 9078(define_insn "edge16n<P:mode>_vis" 9079 [(set (match_operand:P 0 "register_operand" "=r") 9080 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") 9081 (match_operand:P 2 "register_or_zero_operand" "rJ")] 9082 UNSPEC_EDGE16N))] 9083 "TARGET_VIS2" 9084 "edge16n\t%r1, %r2, %0" 9085 [(set_attr "type" "edgen")]) 9086 9087(define_insn "edge16ln<P:mode>_vis" 9088 [(set (match_operand:P 0 "register_operand" "=r") 9089 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") 9090 (match_operand:P 2 "register_or_zero_operand" "rJ")] 9091 UNSPEC_EDGE16LN))] 9092 "TARGET_VIS2" 9093 "edge16ln\t%r1, %r2, %0" 9094 [(set_attr "type" "edgen")]) 9095 9096(define_insn "edge32n<P:mode>_vis" 9097 [(set (match_operand:P 0 "register_operand" "=r") 9098 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") 9099 (match_operand:P 2 "register_or_zero_operand" "rJ")] 9100 UNSPEC_EDGE32N))] 9101 "TARGET_VIS2" 9102 "edge32n\t%r1, %r2, %0" 9103 [(set_attr "type" "edgen")]) 9104 9105(define_insn "edge32ln<P:mode>_vis" 9106 [(set (match_operand:P 0 "register_operand" "=r") 9107 (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") 9108 (match_operand:P 2 "register_or_zero_operand" "rJ")] 9109 UNSPEC_EDGE32LN))] 9110 "TARGET_VIS2" 9111 "edge32ln\t%r1, %r2, %0" 9112 [(set_attr "type" "edge")]) 9113 9114;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle 9115(define_insn "cmask8<P:mode>_vis" 9116 [(set (reg:DI GSR_REG) 9117 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ") 9118 (reg:DI GSR_REG)] 9119 UNSPEC_CMASK8))] 9120 "TARGET_VIS3" 9121 "cmask8\t%r0" 9122 [(set_attr "type" "fga") 9123 (set_attr "subtype" "cmask")]) 9124 9125(define_insn "cmask16<P:mode>_vis" 9126 [(set (reg:DI GSR_REG) 9127 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ") 9128 (reg:DI GSR_REG)] 9129 UNSPEC_CMASK16))] 9130 "TARGET_VIS3" 9131 "cmask16\t%r0" 9132 [(set_attr "type" "fga") 9133 (set_attr "subtype" "cmask")]) 9134 9135(define_insn "cmask32<P:mode>_vis" 9136 [(set (reg:DI GSR_REG) 9137 (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ") 9138 (reg:DI GSR_REG)] 9139 UNSPEC_CMASK32))] 9140 "TARGET_VIS3" 9141 "cmask32\t%r0" 9142 [(set_attr "type" "fga") 9143 (set_attr "subtype" "cmask")]) 9144 9145(define_insn "fchksm16_vis" 9146 [(set (match_operand:V4HI 0 "register_operand" "=e") 9147 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e") 9148 (match_operand:V4HI 2 "register_operand" "e")] 9149 UNSPEC_FCHKSM16))] 9150 "TARGET_VIS3" 9151 "fchksm16\t%1, %2, %0" 9152 [(set_attr "type" "fga") 9153 (set_attr "subtype" "fpu")]) 9154 9155(define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt]) 9156(define_code_attr vis3_shift_insn 9157 [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")]) 9158(define_code_attr vis3_shift_patname 9159 [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")]) 9160 9161(define_insn "v<vis3_shift_patname><GCM:mode>3" 9162 [(set (match_operand:GCM 0 "register_operand" "=<vconstr>") 9163 (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>") 9164 (match_operand:GCM 2 "register_operand" "<vconstr>")))] 9165 "TARGET_VIS3" 9166 "<vis3_shift_insn><vbits>\t%1, %2, %0" 9167 [(set_attr "type" "fga") 9168 (set_attr "subtype" "fpu")]) 9169 9170(define_insn "pdistn<P:mode>_vis" 9171 [(set (match_operand:P 0 "register_operand" "=r") 9172 (unspec:P [(match_operand:V8QI 1 "register_operand" "e") 9173 (match_operand:V8QI 2 "register_operand" "e")] 9174 UNSPEC_PDISTN))] 9175 "TARGET_VIS3" 9176 "pdistn\t%1, %2, %0" 9177 [(set_attr "type" "pdistn") 9178 (set_attr "fptype" "double")]) 9179 9180(define_insn "fmean16_vis" 9181 [(set (match_operand:V4HI 0 "register_operand" "=e") 9182 (truncate:V4HI 9183 (lshiftrt:V4SI 9184 (plus:V4SI 9185 (plus:V4SI 9186 (zero_extend:V4SI 9187 (match_operand:V4HI 1 "register_operand" "e")) 9188 (zero_extend:V4SI 9189 (match_operand:V4HI 2 "register_operand" "e"))) 9190 (const_vector:V4SI [(const_int 1) (const_int 1) 9191 (const_int 1) (const_int 1)])) 9192 (const_int 1))))] 9193 "TARGET_VIS3" 9194 "fmean16\t%1, %2, %0" 9195 [(set_attr "type" "fga") 9196 (set_attr "subtype" "fpu")]) 9197 9198(define_insn "fp<plusminus_insn>64_vis" 9199 [(set (match_operand:V1DI 0 "register_operand" "=e") 9200 (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e") 9201 (match_operand:V1DI 2 "register_operand" "e")))] 9202 "TARGET_VIS3" 9203 "fp<plusminus_insn>64\t%1, %2, %0" 9204 [(set_attr "type" "fga") 9205 (set_attr "subtype" "addsub64")]) 9206 9207(define_insn "<plusminus_insn>v8qi3" 9208 [(set (match_operand:V8QI 0 "register_operand" "=e") 9209 (plusminus:V8QI (match_operand:V8QI 1 "register_operand" "e") 9210 (match_operand:V8QI 2 "register_operand" "e")))] 9211 "TARGET_VIS4" 9212 "fp<plusminus_insn>8\t%1, %2, %0" 9213 [(set_attr "type" "fga") 9214 (set_attr "subtype" "other")]) 9215 9216(define_mode_iterator VASS [V4HI V2SI V2HI V1SI]) 9217(define_code_iterator vis3_addsub_ss [ss_plus ss_minus]) 9218(define_code_attr vis3_addsub_ss_insn 9219 [(ss_plus "fpadds") (ss_minus "fpsubs")]) 9220(define_code_attr vis3_addsub_ss_patname 9221 [(ss_plus "ssadd") (ss_minus "sssub")]) 9222 9223(define_insn "<vis3_addsub_ss_patname><VASS:mode>3" 9224 [(set (match_operand:VASS 0 "register_operand" "=<vconstr>") 9225 (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>") 9226 (match_operand:VASS 2 "register_operand" "<vconstr>")))] 9227 "TARGET_VIS3" 9228 "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0" 9229 [(set_attr "type" "fga") 9230 (set_attr "subtype" "other")]) 9231 9232(define_mode_iterator VMMAX [V8QI V4HI V2SI]) 9233(define_code_iterator vis4_minmax [smin smax]) 9234(define_code_attr vis4_minmax_insn 9235 [(smin "fpmin") (smax "fpmax")]) 9236(define_code_attr vis4_minmax_patname 9237 [(smin "min") (smax "max")]) 9238 9239(define_insn "<vis4_minmax_patname><VMMAX:mode>3" 9240 [(set (match_operand:VMMAX 0 "register_operand" "=<vconstr>") 9241 (vis4_minmax:VMMAX (match_operand:VMMAX 1 "register_operand" "<vconstr>") 9242 (match_operand:VMMAX 2 "register_operand" "<vconstr>")))] 9243 "TARGET_VIS4" 9244 "<vis4_minmax_insn><vbits>\t%1, %2, %0" 9245 [(set_attr "type" "fga") 9246 (set_attr "subtype" "maxmin")]) 9247 9248(define_code_iterator vis4_uminmax [umin umax]) 9249(define_code_attr vis4_uminmax_insn 9250 [(umin "fpminu") (umax "fpmaxu")]) 9251(define_code_attr vis4_uminmax_patname 9252 [(umin "minu") (umax "maxu")]) 9253 9254(define_insn "<vis4_uminmax_patname><VMMAX:mode>3" 9255 [(set (match_operand:VMMAX 0 "register_operand" "=<vconstr>") 9256 (vis4_uminmax:VMMAX (match_operand:VMMAX 1 "register_operand" "<vconstr>") 9257 (match_operand:VMMAX 2 "register_operand" "<vconstr>")))] 9258 "TARGET_VIS4" 9259 "<vis4_uminmax_insn><vbits>\t%1, %2, %0" 9260 [(set_attr "type" "fga") 9261 (set_attr "subtype" "maxmin")]) 9262 9263;; The use of vis3_addsub_ss_patname in the VIS4 instruction below is 9264;; intended. 9265(define_insn "<vis3_addsub_ss_patname>v8qi3" 9266 [(set (match_operand:V8QI 0 "register_operand" "=e") 9267 (vis3_addsub_ss:V8QI (match_operand:V8QI 1 "register_operand" "e") 9268 (match_operand:V8QI 2 "register_operand" "e")))] 9269 "TARGET_VIS4" 9270 "<vis3_addsub_ss_insn>8\t%1, %2, %0" 9271 [(set_attr "type" "fga") 9272 (set_attr "subtype" "other")]) 9273 9274(define_mode_iterator VAUS [V4HI V8QI]) 9275(define_code_iterator vis4_addsub_us [us_plus us_minus]) 9276(define_code_attr vis4_addsub_us_insn 9277 [(us_plus "fpaddus") (us_minus "fpsubus")]) 9278(define_code_attr vis4_addsub_us_patname 9279 [(us_plus "usadd") (us_minus "ussub")]) 9280 9281(define_insn "<vis4_addsub_us_patname><VAUS:mode>3" 9282 [(set (match_operand:VAUS 0 "register_operand" "=<vconstr>") 9283 (vis4_addsub_us:VAUS (match_operand:VAUS 1 "register_operand" "<vconstr>") 9284 (match_operand:VAUS 2 "register_operand" "<vconstr>")))] 9285 "TARGET_VIS4" 9286 "<vis4_addsub_us_insn><vbits>\t%1, %2, %0" 9287 [(set_attr "type" "fga") 9288 (set_attr "subtype" "other")]) 9289 9290(define_insn "fucmp<gcond:code>8<P:mode>_vis" 9291 [(set (match_operand:P 0 "register_operand" "=r") 9292 (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e") 9293 (match_operand:V8QI 2 "register_operand" "e"))] 9294 UNSPEC_FUCMP))] 9295 "TARGET_VIS3" 9296 "fucmp<gcond:code>8\t%1, %2, %0" 9297 [(set_attr "type" "viscmp")]) 9298 9299(define_insn "fpcmpu<gcond:code><GCM:gcm_name><P:mode>_vis" 9300 [(set (match_operand:P 0 "register_operand" "=r") 9301 (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e") 9302 (match_operand:GCM 2 "register_operand" "e"))] 9303 UNSPEC_FUCMP))] 9304 "TARGET_VIS4" 9305 "fpcmpu<gcond:code><GCM:gcm_name>\t%1, %2, %0" 9306 [(set_attr "type" "viscmp")]) 9307 9308(define_insn "*naddsf3" 9309 [(set (match_operand:SF 0 "register_operand" "=f") 9310 (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f") 9311 (match_operand:SF 2 "register_operand" "f"))))] 9312 "TARGET_VIS3" 9313 "fnadds\t%1, %2, %0" 9314 [(set_attr "type" "fp")]) 9315 9316(define_insn "*nadddf3" 9317 [(set (match_operand:DF 0 "register_operand" "=e") 9318 (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e") 9319 (match_operand:DF 2 "register_operand" "e"))))] 9320 "TARGET_VIS3" 9321 "fnaddd\t%1, %2, %0" 9322 [(set_attr "type" "fp") 9323 (set_attr "fptype" "double")]) 9324 9325(define_insn "*nmulsf3" 9326 [(set (match_operand:SF 0 "register_operand" "=f") 9327 (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f")) 9328 (match_operand:SF 2 "register_operand" "f")))] 9329 "TARGET_VIS3" 9330 "fnmuls\t%1, %2, %0" 9331 [(set_attr "type" "fpmul")]) 9332 9333(define_insn "*nmuldf3" 9334 [(set (match_operand:DF 0 "register_operand" "=e") 9335 (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e")) 9336 (match_operand:DF 2 "register_operand" "e")))] 9337 "TARGET_VIS3" 9338 "fnmuld\t%1, %2, %0" 9339 [(set_attr "type" "fpmul") 9340 (set_attr "fptype" "double")]) 9341 9342(define_insn "*nmuldf3_extend" 9343 [(set (match_operand:DF 0 "register_operand" "=e") 9344 (mult:DF (neg:DF (float_extend:DF 9345 (match_operand:SF 1 "register_operand" "f"))) 9346 (float_extend:DF 9347 (match_operand:SF 2 "register_operand" "f"))))] 9348 "TARGET_VIS3" 9349 "fnsmuld\t%1, %2, %0" 9350 [(set_attr "type" "fpmul") 9351 (set_attr "fptype" "double")]) 9352 9353(define_insn "fhaddsf_vis" 9354 [(set (match_operand:SF 0 "register_operand" "=f") 9355 (unspec:SF [(match_operand:SF 1 "register_operand" "f") 9356 (match_operand:SF 2 "register_operand" "f")] 9357 UNSPEC_FHADD))] 9358 "TARGET_VIS3" 9359 "fhadds\t%1, %2, %0" 9360 [(set_attr "type" "fp")]) 9361 9362(define_insn "fhadddf_vis" 9363 [(set (match_operand:DF 0 "register_operand" "=f") 9364 (unspec:DF [(match_operand:DF 1 "register_operand" "f") 9365 (match_operand:DF 2 "register_operand" "f")] 9366 UNSPEC_FHADD))] 9367 "TARGET_VIS3" 9368 "fhaddd\t%1, %2, %0" 9369 [(set_attr "type" "fp") 9370 (set_attr "fptype" "double")]) 9371 9372(define_insn "fhsubsf_vis" 9373 [(set (match_operand:SF 0 "register_operand" "=f") 9374 (unspec:SF [(match_operand:SF 1 "register_operand" "f") 9375 (match_operand:SF 2 "register_operand" "f")] 9376 UNSPEC_FHSUB))] 9377 "TARGET_VIS3" 9378 "fhsubs\t%1, %2, %0" 9379 [(set_attr "type" "fp")]) 9380 9381(define_insn "fhsubdf_vis" 9382 [(set (match_operand:DF 0 "register_operand" "=f") 9383 (unspec:DF [(match_operand:DF 1 "register_operand" "f") 9384 (match_operand:DF 2 "register_operand" "f")] 9385 UNSPEC_FHSUB))] 9386 "TARGET_VIS3" 9387 "fhsubd\t%1, %2, %0" 9388 [(set_attr "type" "fp") 9389 (set_attr "fptype" "double")]) 9390 9391(define_insn "fnhaddsf_vis" 9392 [(set (match_operand:SF 0 "register_operand" "=f") 9393 (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f") 9394 (match_operand:SF 2 "register_operand" "f")] 9395 UNSPEC_FHADD)))] 9396 "TARGET_VIS3" 9397 "fnhadds\t%1, %2, %0" 9398 [(set_attr "type" "fp")]) 9399 9400(define_insn "fnhadddf_vis" 9401 [(set (match_operand:DF 0 "register_operand" "=f") 9402 (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f") 9403 (match_operand:DF 2 "register_operand" "f")] 9404 UNSPEC_FHADD)))] 9405 "TARGET_VIS3" 9406 "fnhaddd\t%1, %2, %0" 9407 [(set_attr "type" "fp") 9408 (set_attr "fptype" "double")]) 9409 9410;; VIS4B instructions. 9411 9412(define_mode_iterator DUMODE [V2SI V4HI V8QI]) 9413 9414(define_insn "dictunpack<DUMODE:vbits>" 9415 [(set (match_operand:DUMODE 0 "register_operand" "=e") 9416 (unspec:DUMODE [(match_operand:DF 1 "register_operand" "e") 9417 (match_operand:SI 2 "imm5_operand_dictunpack<DUMODE:vbits>" "t")] 9418 UNSPEC_DICTUNPACK))] 9419 "TARGET_VIS4B" 9420 "dictunpack\t%1, %2, %0" 9421 [(set_attr "type" "fga") 9422 (set_attr "subtype" "other")]) 9423 9424(define_mode_iterator FPCSMODE [V2SI V4HI V8QI]) 9425(define_code_iterator fpcscond [le gt eq ne]) 9426(define_code_iterator fpcsucond [le gt]) 9427 9428(define_insn "fpcmp<fpcscond:code><FPCSMODE:vbits><P:mode>shl" 9429 [(set (match_operand:P 0 "register_operand" "=r") 9430 (unspec:P [(fpcscond:FPCSMODE (match_operand:FPCSMODE 1 "register_operand" "e") 9431 (match_operand:FPCSMODE 2 "register_operand" "e")) 9432 (match_operand:SI 3 "imm2_operand" "q")] 9433 UNSPEC_FPCMPSHL))] 9434 "TARGET_VIS4B" 9435 "fpcmp<fpcscond:code><FPCSMODE:vbits>shl\t%1, %2, %3, %0" 9436 [(set_attr "type" "viscmp")]) 9437 9438(define_insn "fpcmpu<fpcsucond:code><FPCSMODE:vbits><P:mode>shl" 9439 [(set (match_operand:P 0 "register_operand" "=r") 9440 (unspec:P [(fpcsucond:FPCSMODE (match_operand:FPCSMODE 1 "register_operand" "e") 9441 (match_operand:FPCSMODE 2 "register_operand" "e")) 9442 (match_operand:SI 3 "imm2_operand" "q")] 9443 UNSPEC_FPUCMPSHL))] 9444 "TARGET_VIS4B" 9445 "fpcmpu<fpcsucond:code><FPCSMODE:vbits>shl\t%1, %2, %3, %0" 9446 [(set_attr "type" "viscmp")]) 9447 9448(define_insn "fpcmpde<FPCSMODE:vbits><P:mode>shl" 9449 [(set (match_operand:P 0 "register_operand" "=r") 9450 (unspec:P [(match_operand:FPCSMODE 1 "register_operand" "e") 9451 (match_operand:FPCSMODE 2 "register_operand" "e") 9452 (match_operand:SI 3 "imm2_operand" "q")] 9453 UNSPEC_FPCMPDESHL))] 9454 "TARGET_VIS4B" 9455 "fpcmpde<FPCSMODE:vbits>shl\t%1, %2, %3, %0" 9456 [(set_attr "type" "viscmp")]) 9457 9458(define_insn "fpcmpur<FPCSMODE:vbits><P:mode>shl" 9459 [(set (match_operand:P 0 "register_operand" "=r") 9460 (unspec:P [(match_operand:FPCSMODE 1 "register_operand" "e") 9461 (match_operand:FPCSMODE 2 "register_operand" "e") 9462 (match_operand:SI 3 "imm2_operand" "q")] 9463 UNSPEC_FPCMPURSHL))] 9464 "TARGET_VIS4B" 9465 "fpcmpur<FPCSMODE:vbits>shl\t%1, %2, %3, %0" 9466 [(set_attr "type" "viscmp")]) 9467 9468(include "sync.md") 9469