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