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