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