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