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