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