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