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