|
|
1.1 root 1: ;;- Machine description for SPARC chip for GNU C compiler 1.1.1.4 ! root 2: ;; Copyright (C) 1987, 88, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. ! 3: ;; Contributed by Michael Tiemann ([email protected]) ! 4: ;; 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans, ! 5: ;; at Cygnus Support. 1.1 root 6: 7: ;; This file is part of GNU CC. 8: 9: ;; GNU CC is free software; you can redistribute it and/or modify 10: ;; it under the terms of the GNU General Public License as published by 11: ;; the Free Software Foundation; either version 2, or (at your option) 12: ;; any later version. 13: 14: ;; GNU CC is distributed in the hope that it will be useful, 15: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 16: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17: ;; GNU General Public License for more details. 18: 19: ;; You should have received a copy of the GNU General Public License 20: ;; along with GNU CC; see the file COPYING. If not, write to 1.1.1.4 ! root 21: ;; the Free Software Foundation, 59 Temple Place - Suite 330, ! 22: ;; Boston, MA 02111-1307, USA. 1.1 root 23: 24: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. 25: 1.1.1.3 root 26: ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this 27: ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name 28: ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding 29: ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of 30: ;; 'f' for all DF/TFmode values, including those that are specific to the v8. 31: 32: ;; Architecture type. Arch32bit includes v7, sparclite, v8. 33: 34: (define_attr "arch" "arch32bit,arch64bit" 35: (const (symbol_ref "sparc_arch_type"))) 36: 37: ;; CPU type. This is only used for instruction scheduling 38: (define_attr "cpu" "cypress,supersparc" 39: (const 40: (cond [(symbol_ref "TARGET_SUPERSPARC") (const_string "supersparc")] 41: (const_string "cypress")))) 42: 1.1 root 43: ;; Insn type. Used to default other attribute values. 44: 45: ;; type "unary" insns have one input operand (1) and one output operand (0) 46: ;; type "binary" insns have two input operands (1,2) and one output (0) 47: ;; type "compare" insns have one or two input operands (0,1) and no output 48: ;; type "call_no_delay_slot" is a call followed by an unimp instruction. 49: 50: (define_attr "type" 1.1.1.3 root 51: "move,unary,binary,compare,load,store,ialu,shift,uncond_branch,branch,call,call_no_delay_slot,address,imul,fpload,fpstore,fp,fpcmp,fpmul,fpdivs,fpdivd,fpsqrt,cmove,multi,misc" 1.1 root 52: (const_string "binary")) 53: 54: ;; Set true if insn uses call-clobbered intermediate register. 55: (define_attr "use_clobbered" "false,true" 56: (if_then_else (and (eq_attr "type" "address") 57: (match_operand 0 "clobbered_register" "")) 58: (const_string "true") 59: (const_string "false"))) 60: 61: ;; Length (in # of insns). 62: (define_attr "length" "" 63: (cond [(eq_attr "type" "load,fpload") 64: (if_then_else (match_operand 1 "symbolic_memory_operand" "") 65: (const_int 2) (const_int 1)) 66: 67: (eq_attr "type" "store,fpstore") 68: (if_then_else (match_operand 0 "symbolic_memory_operand" "") 69: (const_int 2) (const_int 1)) 70: 71: (eq_attr "type" "address") (const_int 2) 72: 73: (eq_attr "type" "binary") 74: (if_then_else (ior (match_operand 2 "arith_operand" "") 75: (match_operand 2 "arith_double_operand" "")) 76: (const_int 1) (const_int 3)) 77: 78: (eq_attr "type" "multi") (const_int 2) 79: 80: (eq_attr "type" "move,unary") 81: (if_then_else (ior (match_operand 1 "arith_operand" "") 82: (match_operand 1 "arith_double_operand" "")) 83: (const_int 1) (const_int 2))] 84: 85: (const_int 1))) 86: 87: (define_asm_attributes 88: [(set_attr "length" "1") 89: (set_attr "type" "multi")]) 90: 91: ;; Attributes for instruction and branch scheduling 92: 93: (define_attr "in_call_delay" "false,true" 94: (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi") 95: (const_string "false") 96: (eq_attr "type" "load,fpload,store,fpstore") 97: (if_then_else (eq_attr "length" "1") 98: (const_string "true") 99: (const_string "false")) 100: (eq_attr "type" "address") 101: (if_then_else (eq_attr "use_clobbered" "false") 102: (const_string "true") 103: (const_string "false"))] 104: (if_then_else (eq_attr "length" "1") 105: (const_string "true") 106: (const_string "false")))) 107: 108: (define_delay (eq_attr "type" "call") 109: [(eq_attr "in_call_delay" "true") (nil) (nil)]) 110: 111: ;; ??? Should implement the notion of predelay slots for floating point 112: ;; branches. This would allow us to remove the nop always inserted before 113: ;; a floating point branch. 114: 115: ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions 116: ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so. 117: ;; This is because doing so will add several pipeline stalls to the path 118: ;; that the load/store did not come from. Unfortunately, there is no way 119: ;; to prevent fill_eager_delay_slots from using load/store without completely 120: ;; disabling them. For the SPEC benchmark set, this is a serious lose, 121: ;; because it prevents us from moving back the final store of inner loops. 122: 123: (define_attr "in_branch_delay" "false,true" 124: (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi") 125: (eq_attr "length" "1")) 126: (const_string "true") 127: (const_string "false"))) 128: 129: (define_attr "in_uncond_branch_delay" "false,true" 130: (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi") 131: (eq_attr "length" "1")) 132: (const_string "true") 133: (const_string "false"))) 134: 135: (define_attr "in_annul_branch_delay" "false,true" 136: (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi") 137: (eq_attr "length" "1")) 138: (const_string "true") 139: (const_string "false"))) 140: 141: (define_delay (eq_attr "type" "branch") 142: [(eq_attr "in_branch_delay" "true") 143: (nil) (eq_attr "in_annul_branch_delay" "true")]) 144: 145: (define_delay (eq_attr "type" "uncond_branch") 146: [(eq_attr "in_uncond_branch_delay" "true") 147: (nil) (nil)]) 148: 149: ;; Function units of the SPARC 150: 151: ;; (define_function_unit {name} {num-units} {n-users} {test} 152: ;; {ready-delay} {issue-delay} [{conflict-list}]) 153: 154: ;; The integer ALU. 155: ;; (Noted only for documentation; units that take one cycle do not need to 156: ;; be specified.) 157: 158: ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on 159: ;; the inputs. 160: 161: ;; (define_function_unit "alu" 1 0 162: ;; (eq_attr "type" "unary,binary,move,address") 1 0) 163: 1.1.1.3 root 164: ;; ---- cypress CY7C602 scheduling: 1.1 root 165: ;; Memory with load-delay of 1 (i.e., 2 cycle load). 1.1.1.3 root 166: (define_function_unit "memory" 1 0 167: (and (eq_attr "type" "load,fpload") (eq_attr "cpu" "cypress")) 2 2) 1.1 root 168: 169: ;; SPARC has two floating-point units: the FP ALU, 170: ;; and the FP MUL/DIV/SQRT unit. 171: ;; Instruction timings on the CY7C602 are as follows 172: ;; FABSs 4 173: ;; FADDs/d 5/5 174: ;; FCMPs/d 4/4 175: ;; FDIVs/d 23/37 176: ;; FMOVs 4 177: ;; FMULs/d 5/7 178: ;; FNEGs 4 179: ;; FSQRTs/d 34/63 180: ;; FSUBs/d 5/5 181: ;; FdTOi/s 5/5 182: ;; FsTOi/d 5/5 183: ;; FiTOs/d 9/5 184: 185: ;; The CY7C602 can only support 2 fp isnsn simultaneously. 186: ;; More insns cause the chip to stall. 187: 1.1.1.3 root 188: (define_function_unit "fp_alu" 1 0 189: (and (eq_attr "type" "fp") (eq_attr "cpu" "cypress")) 5 5) 190: (define_function_unit "fp_mds" 1 0 191: (and (eq_attr "type" "fpmul") (eq_attr "cpu" "cypress")) 7 7) 192: (define_function_unit "fp_mds" 1 0 193: (and (eq_attr "type" "fpdivs,fpdivd") (eq_attr "cpu" "cypress")) 37 37) 194: (define_function_unit "fp_mds" 1 0 195: (and (eq_attr "type" "fpsqrt") (eq_attr "cpu" "cypress")) 63 63) 196: 197: ;; ----- The TMS390Z55 scheduling 198: ;; The Supersparc can issue 1 - 3 insns per cycle; here we assume 199: ;; three insns/cycle, and hence multiply all costs by three. 200: ;; Combinations up to two integer, one ld/st, one fp. 201: ;; Memory delivers its result in one cycle to IU, zero cycles to FP 202: (define_function_unit "memory" 1 0 203: (and (eq_attr "type" "load") (eq_attr "cpu" "supersparc")) 3 3) 204: (define_function_unit "memory" 1 0 205: (and (eq_attr "type" "fpload") (eq_attr "cpu" "supersparc")) 1 3) 206: ;; at least one in three instructions can be a mem opt. 207: (define_function_unit "memory" 1 0 208: (and (eq_attr "type" "store,fpstore") (eq_attr "cpu" "supersparc")) 1 3) 209: ;; at least one in three instructions can be a shift op. 210: (define_function_unit "shift" 1 0 211: (and (eq_attr "type" "shift") (eq_attr "cpu" "supersparc")) 1 3) 212: 213: ;; There are only two write ports to the integer register file 214: ;; A store also uses a write port 215: (define_function_unit "iwport" 2 0 216: (and (eq_attr "type" "load,store,shift,ialu") (eq_attr "cpu" "supersparc")) 1 3) 217: 218: ;; Timings; throughput/latency 219: ;; FADD 1/3 add/sub, format conv, compar, abs, neg 220: ;; FMUL 1/3 221: ;; FDIVs 4/6 222: ;; FDIVd 7/9 223: ;; FSQRTs 6/8 224: ;; FSQRTd 10/12 225: ;; IMUL 4/4 226: 227: (define_function_unit "fp_alu" 1 0 228: (and (eq_attr "type" "fp,fpcmp") (eq_attr "cpu" "supersparc")) 9 3) 229: (define_function_unit "fp_mds" 1 0 230: (and (eq_attr "type" "fpmul") (eq_attr "cpu" "supersparc")) 9 3) 231: (define_function_unit "fp_mds" 1 0 232: (and (eq_attr "type" "fpdivs") (eq_attr "cpu" "supersparc")) 18 12) 233: (define_function_unit "fp_mds" 1 0 234: (and (eq_attr "type" "fpdivd") (eq_attr "cpu" "supersparc")) 27 21) 235: (define_function_unit "fp_mds" 1 0 236: (and (eq_attr "type" "fpsqrt") (eq_attr "cpu" "supersparc")) 36 30) 237: (define_function_unit "fp_mds" 1 0 238: (and (eq_attr "type" "imul") (eq_attr "cpu" "supersparc")) 12 12) 1.1 root 239: 240: ;; Compare instructions. 241: ;; This controls RTL generation and register allocation. 242: 243: ;; We generate RTL for comparisons and branches by having the cmpxx 244: ;; patterns store away the operands. Then, the scc and bcc patterns 245: ;; emit RTL for both the compare and the branch. 246: ;; 247: ;; We do this because we want to generate different code for an sne and 248: ;; seq insn. In those cases, if the second operand of the compare is not 249: ;; const0_rtx, we want to compute the xor of the two operands and test 250: ;; it against zero. 251: ;; 1.1.1.3 root 252: ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match 1.1 root 253: ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc 254: ;; insns that actually require more than one machine instruction. 255: 256: ;; Put cmpsi first among compare insns so it matches two CONST_INT operands. 257: 258: (define_expand "cmpsi" 259: [(set (reg:CC 0) 260: (compare:CC (match_operand:SI 0 "register_operand" "") 261: (match_operand:SI 1 "arith_operand" "")))] 262: "" 263: " 264: { 265: sparc_compare_op0 = operands[0]; 266: sparc_compare_op1 = operands[1]; 267: DONE; 268: }") 269: 1.1.1.3 root 270: (define_expand "cmpdi" 271: [(set (reg:CCX 0) 272: (compare:CCX (match_operand:DI 0 "register_operand" "") 273: (match_operand:DI 1 "arith_double_operand" "")))] 274: "TARGET_V9" 275: " 276: { 277: sparc_compare_op0 = operands[0]; 278: sparc_compare_op1 = operands[1]; 279: DONE; 280: }") 281: 1.1 root 282: (define_expand "cmpsf" 283: [(set (reg:CCFP 0) 284: (compare:CCFP (match_operand:SF 0 "register_operand" "") 285: (match_operand:SF 1 "register_operand" "")))] 286: "TARGET_FPU" 287: " 288: { 289: sparc_compare_op0 = operands[0]; 290: sparc_compare_op1 = operands[1]; 291: DONE; 292: }") 293: 294: (define_expand "cmpdf" 295: [(set (reg:CCFP 0) 296: (compare:CCFP (match_operand:DF 0 "register_operand" "") 297: (match_operand:DF 1 "register_operand" "")))] 298: "TARGET_FPU" 299: " 300: { 301: sparc_compare_op0 = operands[0]; 302: sparc_compare_op1 = operands[1]; 303: DONE; 304: }") 305: 306: (define_expand "cmptf" 307: [(set (reg:CCFP 0) 308: (compare:CCFP (match_operand:TF 0 "register_operand" "") 309: (match_operand:TF 1 "register_operand" "")))] 310: "TARGET_FPU" 311: " 312: { 313: sparc_compare_op0 = operands[0]; 314: sparc_compare_op1 = operands[1]; 315: DONE; 316: }") 317: 318: ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this 1.1.1.3 root 319: ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use 320: ;; the same code as v8 (the addx/subx method has more applications). The 321: ;; exception to this is "reg != 0" which can be done in one instruction on v9 322: ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do 323: ;; branches. 324: 325: ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they 1.1 root 326: ;; generate addcc/subcc instructions. 327: 1.1.1.3 root 328: (define_expand "seqsi_special" 329: [(set (match_dup 3) 330: (xor:SI (match_operand:SI 1 "register_operand" "") 331: (match_operand:SI 2 "register_operand" ""))) 1.1 root 332: (parallel [(set (match_operand:SI 0 "register_operand" "") 333: (eq:SI (match_dup 3) (const_int 0))) 334: (clobber (reg:CC 0))])] 335: "" 336: "{ operands[3] = gen_reg_rtx (SImode); }") 337: 1.1.1.3 root 338: (define_expand "seqdi_special" 339: [(set (match_dup 3) 340: (xor:DI (match_operand:DI 1 "register_operand" "") 341: (match_operand:DI 2 "register_operand" ""))) 342: (parallel [(set (match_operand:DI 0 "register_operand" "") 343: (eq:DI (match_dup 3) (const_int 0))) 344: (clobber (reg:CCX 0))])] 345: "" 346: "{ operands[3] = gen_reg_rtx (DImode); }") 347: 348: (define_expand "snesi_special" 349: [(set (match_dup 3) 350: (xor:SI (match_operand:SI 1 "register_operand" "") 351: (match_operand:SI 2 "register_operand" ""))) 1.1 root 352: (parallel [(set (match_operand:SI 0 "register_operand" "") 353: (ne:SI (match_dup 3) (const_int 0))) 354: (clobber (reg:CC 0))])] 355: "" 356: "{ operands[3] = gen_reg_rtx (SImode); }") 357: 1.1.1.3 root 358: (define_expand "snedi_special" 359: [(set (match_dup 3) 360: (xor:DI (match_operand:DI 1 "register_operand" "") 361: (match_operand:DI 2 "register_operand" ""))) 362: (parallel [(set (match_operand:DI 0 "register_operand" "") 363: (ne:DI (match_dup 3) (const_int 0))) 364: (clobber (reg:CCX 0))])] 365: "" 366: "{ operands[3] = gen_reg_rtx (DImode); }") 367: 368: (define_expand "seqdi_special_trunc" 369: [(set (match_dup 3) 370: (xor:DI (match_operand:DI 1 "register_operand" "") 371: (match_operand:DI 2 "register_operand" ""))) 372: (parallel [(set (match_operand:SI 0 "register_operand" "") 373: (eq:SI (subreg:SI (match_dup 3) 0) (const_int 0))) 374: (clobber (reg:CC 0))])] 375: "" 376: "{ operands[3] = gen_reg_rtx (DImode); }") 377: 378: (define_expand "snedi_special_trunc" 379: [(set (match_dup 3) 380: (xor:DI (match_operand:DI 1 "register_operand" "") 381: (match_operand:DI 2 "register_operand" ""))) 382: (parallel [(set (match_operand:SI 0 "register_operand" "") 383: (ne:SI (subreg:SI (match_dup 3) 0) (const_int 0))) 384: (clobber (reg:CC 0))])] 385: "" 386: "{ operands[3] = gen_reg_rtx (DImode); }") 387: 388: (define_expand "seqsi_special_extend" 389: [(set (subreg:SI (match_dup 3) 0) 390: (xor:SI (match_operand:SI 1 "register_operand" "") 391: (match_operand:SI 2 "register_operand" ""))) 392: (parallel [(set (match_operand:DI 0 "register_operand" "") 393: (eq:DI (match_dup 3) (const_int 0))) 394: (clobber (reg:CCX 0))])] 395: "" 396: "{ operands[3] = gen_reg_rtx (DImode); }") 397: 398: (define_expand "snesi_special_extend" 399: [(set (subreg:SI (match_dup 3) 0) 400: (xor:SI (match_operand:SI 1 "register_operand" "") 401: (match_operand:SI 2 "register_operand" ""))) 402: (parallel [(set (match_operand:DI 0 "register_operand" "") 403: (ne:DI (match_dup 3) (const_int 0))) 404: (clobber (reg:CCX 0))])] 405: "" 406: "{ operands[3] = gen_reg_rtx (DImode); }") 407: 408: ;; ??? v9: Operand 0 needs a mode, so SImode was chosen. 409: ;; However, the code handles both SImode and DImode. 1.1 root 410: (define_expand "seq" 1.1.1.3 root 411: [(set (match_operand:SI 0 "intreg_operand" "") 1.1 root 412: (eq:SI (match_dup 1) (const_int 0)))] 413: "" 414: " 1.1.1.3 root 415: { 416: if (GET_MODE (sparc_compare_op0) == SImode) 417: { 418: rtx pat; 419: 420: if (GET_MODE (operands[0]) == SImode) 421: pat = gen_seqsi_special (operands[0], sparc_compare_op0, 422: sparc_compare_op1); 423: else if (! TARGET_V9) 424: FAIL; 425: else 426: pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0, 427: sparc_compare_op1); 428: emit_insn (pat); 429: DONE; 430: } 431: else if (GET_MODE (sparc_compare_op0) == DImode) 1.1 root 432: { 1.1.1.3 root 433: rtx pat; 434: 435: if (GET_MODE (operands[0]) == SImode) 436: pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0, 437: sparc_compare_op1); 438: else if (! TARGET_V9) 439: FAIL; 440: else 441: pat = gen_seqdi_special (operands[0], sparc_compare_op0, 442: sparc_compare_op1); 443: emit_insn (pat); 1.1 root 444: DONE; 445: } 1.1.1.3 root 446: else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) 447: { 448: emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ); 449: emit_insn (gen_sne (operands[0])); 450: DONE; 451: } 452: else if (TARGET_V9) 453: { 454: if (gen_v9_scc (EQ, operands)) 455: DONE; 456: /* fall through */ 457: } 458: operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1); 1.1 root 459: }") 460: 1.1.1.3 root 461: ;; ??? v9: Operand 0 needs a mode, so SImode was chosen. 462: ;; However, the code handles both SImode and DImode. 1.1 root 463: (define_expand "sne" 1.1.1.3 root 464: [(set (match_operand:SI 0 "intreg_operand" "") 1.1 root 465: (ne:SI (match_dup 1) (const_int 0)))] 466: "" 467: " 1.1.1.3 root 468: { 469: if (GET_MODE (sparc_compare_op0) == SImode) 1.1 root 470: { 1.1.1.3 root 471: rtx pat; 472: 473: if (GET_MODE (operands[0]) == SImode) 474: pat = gen_snesi_special (operands[0], sparc_compare_op0, 475: sparc_compare_op1); 476: else if (! TARGET_V9) 477: FAIL; 478: else 479: pat = gen_snesi_special_extend (operands[0], sparc_compare_op0, 480: sparc_compare_op1); 481: emit_insn (pat); 1.1 root 482: DONE; 483: } 1.1.1.3 root 484: else if (GET_MODE (sparc_compare_op0) == DImode) 485: { 486: rtx pat; 487: 488: if (GET_MODE (operands[0]) == SImode) 489: pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0, 490: sparc_compare_op1); 491: else if (! TARGET_V9) 492: FAIL; 493: else 494: pat = gen_snedi_special (operands[0], sparc_compare_op0, 495: sparc_compare_op1); 496: emit_insn (pat); 497: DONE; 498: } 499: else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) 500: { 501: emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE); 502: emit_insn (gen_sne (operands[0])); 503: DONE; 504: } 505: else if (TARGET_V9) 506: { 507: if (gen_v9_scc (NE, operands)) 508: DONE; 509: /* fall through */ 510: } 511: operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1); 1.1 root 512: }") 513: 514: (define_expand "sgt" 1.1.1.3 root 515: [(set (match_operand:SI 0 "intreg_operand" "") 1.1 root 516: (gt:SI (match_dup 1) (const_int 0)))] 517: "" 518: " 1.1.1.3 root 519: { 520: if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) 521: { 522: emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT); 523: emit_insn (gen_sne (operands[0])); 524: DONE; 525: } 526: else if (TARGET_V9) 527: { 528: if (gen_v9_scc (GT, operands)) 529: DONE; 530: /* fall through */ 531: } 532: operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); 533: }") 1.1 root 534: 535: (define_expand "slt" 1.1.1.3 root 536: [(set (match_operand:SI 0 "intreg_operand" "") 1.1 root 537: (lt:SI (match_dup 1) (const_int 0)))] 538: "" 539: " 1.1.1.3 root 540: { 541: if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) 542: { 543: emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT); 544: emit_insn (gen_sne (operands[0])); 545: DONE; 546: } 547: else if (TARGET_V9) 548: { 549: if (gen_v9_scc (LT, operands)) 550: DONE; 551: /* fall through */ 552: } 553: operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); 554: }") 1.1 root 555: 556: (define_expand "sge" 1.1.1.3 root 557: [(set (match_operand:SI 0 "intreg_operand" "") 1.1 root 558: (ge:SI (match_dup 1) (const_int 0)))] 559: "" 560: " 1.1.1.3 root 561: { 562: if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) 563: { 564: emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE); 565: emit_insn (gen_sne (operands[0])); 566: DONE; 567: } 568: else if (TARGET_V9) 569: { 570: if (gen_v9_scc (GE, operands)) 571: DONE; 572: /* fall through */ 573: } 574: operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); 575: }") 1.1 root 576: 577: (define_expand "sle" 1.1.1.3 root 578: [(set (match_operand:SI 0 "intreg_operand" "") 1.1 root 579: (le:SI (match_dup 1) (const_int 0)))] 580: "" 581: " 1.1.1.3 root 582: { 583: if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) 584: { 585: emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE); 586: emit_insn (gen_sne (operands[0])); 587: DONE; 588: } 589: else if (TARGET_V9) 590: { 591: if (gen_v9_scc (LE, operands)) 592: DONE; 593: /* fall through */ 594: } 595: operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); 596: }") 1.1 root 597: 598: (define_expand "sgtu" 1.1.1.3 root 599: [(set (match_operand:SI 0 "intreg_operand" "") 1.1 root 600: (gtu:SI (match_dup 1) (const_int 0)))] 601: "" 602: " 603: { 1.1.1.3 root 604: if (! TARGET_V9) 605: { 606: rtx tem; 1.1 root 607: 1.1.1.3 root 608: /* We can do ltu easily, so if both operands are registers, swap them and 609: do a LTU. */ 610: if ((GET_CODE (sparc_compare_op0) == REG 611: || GET_CODE (sparc_compare_op0) == SUBREG) 612: && (GET_CODE (sparc_compare_op1) == REG 613: || GET_CODE (sparc_compare_op1) == SUBREG)) 614: { 615: tem = sparc_compare_op0; 616: sparc_compare_op0 = sparc_compare_op1; 617: sparc_compare_op1 = tem; 618: emit_insn (gen_sltu (operands[0])); 619: DONE; 620: } 1.1 root 621: } 1.1.1.3 root 622: else 623: { 624: if (gen_v9_scc (GTU, operands)) 625: DONE; 626: } 627: operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1); 1.1 root 628: }") 629: 630: (define_expand "sltu" 1.1.1.3 root 631: [(set (match_operand:SI 0 "intreg_operand" "") 1.1 root 632: (ltu:SI (match_dup 1) (const_int 0)))] 633: "" 634: " 1.1.1.3 root 635: { 636: if (TARGET_V9) 637: { 638: if (gen_v9_scc (LTU, operands)) 639: DONE; 640: } 641: operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1); 1.1 root 642: }") 643: 644: (define_expand "sgeu" 1.1.1.3 root 645: [(set (match_operand:SI 0 "intreg_operand" "") 1.1 root 646: (geu:SI (match_dup 1) (const_int 0)))] 647: "" 648: " 1.1.1.3 root 649: { 650: if (TARGET_V9) 651: { 652: if (gen_v9_scc (GEU, operands)) 653: DONE; 654: } 655: operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1); 1.1 root 656: }") 657: 658: (define_expand "sleu" 1.1.1.3 root 659: [(set (match_operand:SI 0 "intreg_operand" "") 1.1 root 660: (leu:SI (match_dup 1) (const_int 0)))] 661: "" 662: " 663: { 1.1.1.3 root 664: if (! TARGET_V9) 665: { 666: rtx tem; 1.1 root 667: 1.1.1.3 root 668: /* We can do geu easily, so if both operands are registers, swap them and 669: do a GEU. */ 670: if ((GET_CODE (sparc_compare_op0) == REG 671: || GET_CODE (sparc_compare_op0) == SUBREG) 672: && (GET_CODE (sparc_compare_op1) == REG 673: || GET_CODE (sparc_compare_op1) == SUBREG)) 674: { 675: tem = sparc_compare_op0; 676: sparc_compare_op0 = sparc_compare_op1; 677: sparc_compare_op1 = tem; 678: emit_insn (gen_sgeu (operands[0])); 679: DONE; 680: } 681: } 682: else 683: { 684: if (gen_v9_scc (LEU, operands)) 685: DONE; 1.1 root 686: } 687: operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1); 688: }") 689: 690: ;; Now the DEFINE_INSNs for the compare and scc cases. First the compares. 691: 1.1.1.4 ! root 692: (define_insn "*cmpsi_insn" 1.1 root 693: [(set (reg:CC 0) 694: (compare:CC (match_operand:SI 0 "register_operand" "r") 695: (match_operand:SI 1 "arith_operand" "rI")))] 696: "" 697: "cmp %r0,%1" 698: [(set_attr "type" "compare")]) 699: 1.1.1.4 ! root 700: (define_insn "*cmpsf_fpe_sp32" 1.1 root 701: [(set (reg:CCFPE 0) 702: (compare:CCFPE (match_operand:SF 0 "register_operand" "f") 703: (match_operand:SF 1 "register_operand" "f")))] 1.1.1.3 root 704: "! TARGET_V9 && TARGET_FPU" 1.1 root 705: "fcmpes %0,%1" 706: [(set_attr "type" "fpcmp")]) 707: 1.1.1.4 ! root 708: (define_insn "*cmpdf_fpe_sp32" 1.1 root 709: [(set (reg:CCFPE 0) 1.1.1.3 root 710: (compare:CCFPE (match_operand:DF 0 "register_operand" "e") 711: (match_operand:DF 1 "register_operand" "e")))] 712: "! TARGET_V9 && TARGET_FPU" 713: "fcmped %0,%1" 1.1 root 714: [(set_attr "type" "fpcmp")]) 715: 1.1.1.4 ! root 716: (define_insn "*cmptf_fpe_sp32" 1.1.1.3 root 717: [(set (reg:CCFPE 0) 718: (compare:CCFPE (match_operand:TF 0 "register_operand" "e") 719: (match_operand:TF 1 "register_operand" "e")))] 720: "! TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" 721: "fcmpeq %0,%1" 1.1 root 722: [(set_attr "type" "fpcmp")]) 723: 1.1.1.4 ! root 724: (define_insn "*cmpsf_fp_sp32" 1.1 root 725: [(set (reg:CCFP 0) 726: (compare:CCFP (match_operand:SF 0 "register_operand" "f") 727: (match_operand:SF 1 "register_operand" "f")))] 1.1.1.3 root 728: "! TARGET_V9 && TARGET_FPU" 1.1 root 729: "fcmps %0,%1" 730: [(set_attr "type" "fpcmp")]) 731: 1.1.1.4 ! root 732: (define_insn "*cmpdf_fp_sp32" 1.1 root 733: [(set (reg:CCFP 0) 1.1.1.3 root 734: (compare:CCFP (match_operand:DF 0 "register_operand" "e") 735: (match_operand:DF 1 "register_operand" "e")))] 736: "! TARGET_V9 && TARGET_FPU" 737: "fcmpd %0,%1" 738: [(set_attr "type" "fpcmp")]) 739: 1.1.1.4 ! root 740: (define_insn "*cmptf_fp_sp32" 1.1.1.3 root 741: [(set (reg:CCFP 0) 742: (compare:CCFP (match_operand:TF 0 "register_operand" "e") 743: (match_operand:TF 1 "register_operand" "e")))] 744: "! TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" 1.1 root 745: "fcmpq %0,%1" 746: [(set_attr "type" "fpcmp")]) 747: 1.1.1.4 ! root 748: (define_insn "*cmpdi_sp64" 1.1.1.3 root 749: [(set (reg:CCX 0) 750: (compare:CCX (match_operand:DI 0 "register_operand" "r") 751: (match_operand:DI 1 "arith_double_operand" "rHI")))] 752: "TARGET_V9" 753: "cmp %r0,%1" 754: [(set_attr "type" "compare")]) 755: 1.1.1.4 ! root 756: (define_insn "*cmpsf_fpe_sp64" 1.1.1.3 root 757: [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c") 758: (compare:CCFPE (match_operand:SF 1 "register_operand" "f") 759: (match_operand:SF 2 "register_operand" "f")))] 760: "TARGET_V9 && TARGET_FPU" 761: "fcmpes %0,%1,%2" 762: [(set_attr "type" "fpcmp")]) 763: 1.1.1.4 ! root 764: (define_insn "*cmpdf_fpe_sp64" 1.1.1.3 root 765: [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c") 766: (compare:CCFPE (match_operand:DF 1 "register_operand" "e") 767: (match_operand:DF 2 "register_operand" "e")))] 768: "TARGET_V9 && TARGET_FPU" 769: "fcmped %0,%1,%2" 770: [(set_attr "type" "fpcmp")]) 771: 1.1.1.4 ! root 772: (define_insn "*cmptf_fpe_sp64" 1.1.1.3 root 773: [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c") 774: (compare:CCFPE (match_operand:TF 1 "register_operand" "e") 775: (match_operand:TF 2 "register_operand" "e")))] 776: "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" 777: "fcmpeq %0,%1,%2" 778: [(set_attr "type" "fpcmp")]) 779: 1.1.1.4 ! root 780: (define_insn "*cmpsf_fp_sp64" 1.1.1.3 root 781: [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c") 782: (compare:CCFP (match_operand:SF 1 "register_operand" "f") 783: (match_operand:SF 2 "register_operand" "f")))] 784: "TARGET_V9 && TARGET_FPU" 785: "fcmps %0,%1,%2" 786: [(set_attr "type" "fpcmp")]) 787: 1.1.1.4 ! root 788: (define_insn "*cmpdf_fp_sp64" 1.1.1.3 root 789: [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c") 790: (compare:CCFP (match_operand:DF 1 "register_operand" "e") 791: (match_operand:DF 2 "register_operand" "e")))] 792: "TARGET_V9 && TARGET_FPU" 793: "fcmpd %0,%1,%2" 794: [(set_attr "type" "fpcmp")]) 795: 1.1.1.4 ! root 796: (define_insn "*cmptf_fp_sp64" 1.1.1.3 root 797: [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c") 798: (compare:CCFP (match_operand:TF 1 "register_operand" "e") 799: (match_operand:TF 2 "register_operand" "e")))] 800: "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" 801: "fcmpq %0,%1,%2" 802: [(set_attr "type" "fpcmp")]) 803: 1.1 root 804: ;; The SEQ and SNE patterns are special because they can be done 805: ;; without any branching and do not involve a COMPARE. 806: 1.1.1.4 ! root 807: (define_insn "*snesi_zero" 1.1 root 808: [(set (match_operand:SI 0 "register_operand" "=r") 1.1.1.3 root 809: (ne:SI (match_operand:SI 1 "register_operand" "r") 810: (const_int 0))) 1.1 root 811: (clobber (reg:CC 0))] 812: "" 813: "subcc %%g0,%1,%%g0\;addx %%g0,0,%0" 814: [(set_attr "type" "unary") 815: (set_attr "length" "2")]) 816: 1.1.1.4 ! root 817: (define_insn "*neg_snesi_zero" 1.1 root 818: [(set (match_operand:SI 0 "register_operand" "=r") 819: (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r") 820: (const_int 0)))) 821: (clobber (reg:CC 0))] 822: "" 823: "subcc %%g0,%1,%%g0\;subx %%g0,0,%0" 824: [(set_attr "type" "unary") 825: (set_attr "length" "2")]) 826: 1.1.1.4 ! root 827: (define_insn "*snedi_zero" 1.1.1.3 root 828: [(set (match_operand:DI 0 "register_operand" "=r") 829: (ne:DI (match_operand:DI 1 "register_operand" "r") 830: (const_int 0))) 831: (clobber (reg:CCX 0))] 832: "TARGET_V9" 833: "mov 0,%0\;movrnz %1,1,%0" 834: [(set_attr "type" "unary") 835: (set_attr "length" "2")]) 836: 1.1.1.4 ! root 837: (define_insn "*neg_snedi_zero" 1.1.1.3 root 838: [(set (match_operand:DI 0 "register_operand" "=r") 839: (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r") 840: (const_int 0)))) 841: (clobber (reg:CCX 0))] 842: "TARGET_V9" 843: "mov 0,%0\;movrnz %1,-1,%0" 844: [(set_attr "type" "unary") 845: (set_attr "length" "2")]) 846: 1.1.1.4 ! root 847: (define_insn "*seqsi_zero" 1.1 root 848: [(set (match_operand:SI 0 "register_operand" "=r") 1.1.1.3 root 849: (eq:SI (match_operand:SI 1 "register_operand" "r") 850: (const_int 0))) 1.1 root 851: (clobber (reg:CC 0))] 852: "" 853: "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0" 854: [(set_attr "type" "unary") 855: (set_attr "length" "2")]) 856: 1.1.1.4 ! root 857: (define_insn "*neg_seqsi_zero" 1.1 root 858: [(set (match_operand:SI 0 "register_operand" "=r") 859: (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r") 860: (const_int 0)))) 861: (clobber (reg:CC 0))] 862: "" 863: "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0" 864: [(set_attr "type" "unary") 865: (set_attr "length" "2")]) 866: 1.1.1.4 ! root 867: (define_insn "*seqdi_zero" 1.1.1.3 root 868: [(set (match_operand:DI 0 "register_operand" "=r") 869: (eq:DI (match_operand:DI 1 "register_operand" "r") 870: (const_int 0))) 871: (clobber (reg:CCX 0))] 872: "TARGET_V9" 873: "mov 0,%0\;movrz %1,1,%0" 874: [(set_attr "type" "unary") 875: (set_attr "length" "2")]) 876: 1.1.1.4 ! root 877: (define_insn "*neg_seqdi_zero" 1.1.1.3 root 878: [(set (match_operand:DI 0 "register_operand" "=r") 879: (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r") 880: (const_int 0)))) 881: (clobber (reg:CCX 0))] 882: "TARGET_V9" 883: "mov 0,%0\;movrz %1,-1,%0" 884: [(set_attr "type" "unary") 885: (set_attr "length" "2")]) 886: 1.1 root 887: ;; We can also do (x + (i == 0)) and related, so put them in. 1.1.1.3 root 888: ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode 889: ;; versions for v9. 1.1 root 890: 1.1.1.4 ! root 891: (define_insn "*x_plus_i_ne_0" 1.1 root 892: [(set (match_operand:SI 0 "register_operand" "=r") 893: (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r") 894: (const_int 0)) 895: (match_operand:SI 2 "register_operand" "r"))) 896: (clobber (reg:CC 0))] 897: "" 898: "subcc %%g0,%1,%%g0\;addx %2,0,%0" 899: [(set_attr "length" "2")]) 900: 1.1.1.4 ! root 901: (define_insn "*x_minus_i_ne_0" 1.1 root 902: [(set (match_operand:SI 0 "register_operand" "=r") 903: (minus:SI (match_operand:SI 2 "register_operand" "r") 904: (ne:SI (match_operand:SI 1 "register_operand" "r") 905: (const_int 0)))) 906: (clobber (reg:CC 0))] 907: "" 908: "subcc %%g0,%1,%%g0\;subx %2,0,%0" 909: [(set_attr "length" "2")]) 910: 1.1.1.4 ! root 911: (define_insn "*x_plus_i_eq_0" 1.1 root 912: [(set (match_operand:SI 0 "register_operand" "=r") 913: (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r") 914: (const_int 0)) 915: (match_operand:SI 2 "register_operand" "r"))) 916: (clobber (reg:CC 0))] 917: "" 918: "subcc %%g0,%1,%%g0\;subx %2,-1,%0" 919: [(set_attr "length" "2")]) 920: 1.1.1.4 ! root 921: (define_insn "*x_minus_i_eq_0" 1.1 root 922: [(set (match_operand:SI 0 "register_operand" "=r") 923: (minus:SI (match_operand:SI 2 "register_operand" "r") 924: (eq:SI (match_operand:SI 1 "register_operand" "r") 925: (const_int 0)))) 926: (clobber (reg:CC 0))] 927: "" 928: "subcc %%g0,%1,%%g0\;addx %2,-1,%0" 929: [(set_attr "length" "2")]) 930: 1.1.1.3 root 931: ;; We can also do GEU and LTU directly, but these operate after a compare. 932: ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode 933: ;; versions for v9. 1.1 root 934: 1.1.1.4 ! root 935: (define_insn "*sltu_insn" 1.1 root 936: [(set (match_operand:SI 0 "register_operand" "=r") 937: (ltu:SI (reg:CC 0) (const_int 0)))] 938: "" 939: "addx %%g0,0,%0" 940: [(set_attr "type" "misc")]) 941: 1.1.1.4 ! root 942: (define_insn "*neg_sltu_insn" 1.1 root 943: [(set (match_operand:SI 0 "register_operand" "=r") 944: (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))] 945: "" 946: "subx %%g0,0,%0" 947: [(set_attr "type" "misc")]) 948: 949: ;; ??? Combine should canonicalize these next two to the same pattern. 1.1.1.4 ! root 950: (define_insn "*neg_sltu_minus_x" 1.1 root 951: [(set (match_operand:SI 0 "register_operand" "=r") 952: (minus:SI (neg:SI (ltu:SI (reg:CC 0) (const_int 0))) 953: (match_operand:SI 1 "arith_operand" "rI")))] 954: "" 955: "subx %%g0,%1,%0" 956: [(set_attr "type" "unary")]) 957: 1.1.1.4 ! root 958: (define_insn "*neg_sltu_plus_x" 1.1 root 959: [(set (match_operand:SI 0 "register_operand" "=r") 960: (neg:SI (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) 961: (match_operand:SI 1 "arith_operand" "rI"))))] 962: "" 963: "subx %%g0,%1,%0" 964: [(set_attr "type" "unary")]) 965: 1.1.1.4 ! root 966: (define_insn "*sgeu_insn" 1.1 root 967: [(set (match_operand:SI 0 "register_operand" "=r") 968: (geu:SI (reg:CC 0) (const_int 0)))] 969: "" 970: "subx %%g0,-1,%0" 971: [(set_attr "type" "misc")]) 972: 1.1.1.4 ! root 973: (define_insn "*neg_sgeu_insn" 1.1 root 974: [(set (match_operand:SI 0 "register_operand" "=r") 975: (neg:SI (geu:SI (reg:CC 0) (const_int 0))))] 976: "" 977: "addx %%g0,-1,%0" 978: [(set_attr "type" "misc")]) 979: 980: ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in. 1.1.1.3 root 981: ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode 982: ;; versions for v9. 1.1 root 983: 1.1.1.4 ! root 984: (define_insn "*sltu_plus_x" 1.1 root 985: [(set (match_operand:SI 0 "register_operand" "=r") 986: (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) 987: (match_operand:SI 1 "arith_operand" "rI")))] 988: "" 989: "addx %%g0,%1,%0" 990: [(set_attr "type" "unary")]) 991: 1.1.1.4 ! root 992: (define_insn "*sltu_plus_x_plus_y" 1.1 root 993: [(set (match_operand:SI 0 "register_operand" "=r") 994: (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) 995: (plus:SI (match_operand:SI 1 "arith_operand" "%r") 996: (match_operand:SI 2 "arith_operand" "rI"))))] 997: "" 998: "addx %1,%2,%0") 999: 1.1.1.4 ! root 1000: (define_insn "*x_minus_sltu" 1.1 root 1001: [(set (match_operand:SI 0 "register_operand" "=r") 1002: (minus:SI (match_operand:SI 1 "register_operand" "r") 1003: (ltu:SI (reg:CC 0) (const_int 0))))] 1004: "" 1005: "subx %1,0,%0" 1006: [(set_attr "type" "unary")]) 1007: 1008: ;; ??? Combine should canonicalize these next two to the same pattern. 1.1.1.4 ! root 1009: (define_insn "*x_minus_y_minus_sltu" 1.1 root 1010: [(set (match_operand:SI 0 "register_operand" "=r") 1011: (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r") 1012: (match_operand:SI 2 "arith_operand" "rI")) 1013: (ltu:SI (reg:CC 0) (const_int 0))))] 1014: "" 1015: "subx %1,%2,%0") 1016: 1.1.1.4 ! root 1017: (define_insn "*x_minus_sltu_plus_y" 1.1 root 1018: [(set (match_operand:SI 0 "register_operand" "=r") 1019: (minus:SI (match_operand:SI 1 "register_operand" "r") 1020: (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) 1021: (match_operand:SI 2 "arith_operand" "rI"))))] 1022: "" 1023: "subx %1,%2,%0") 1024: 1.1.1.4 ! root 1025: (define_insn "*sgeu_plus_x" 1.1 root 1026: [(set (match_operand:SI 0 "register_operand" "=r") 1027: (plus:SI (geu:SI (reg:CC 0) (const_int 0)) 1028: (match_operand:SI 1 "register_operand" "r")))] 1029: "" 1030: "subx %1,-1,%0" 1031: [(set_attr "type" "unary")]) 1032: 1.1.1.4 ! root 1033: (define_insn "*x_minus_sgeu" 1.1 root 1034: [(set (match_operand:SI 0 "register_operand" "=r") 1035: (minus:SI (match_operand:SI 1 "register_operand" "r") 1036: (geu:SI (reg:CC 0) (const_int 0))))] 1037: "" 1038: "addx %1,-1,%0" 1039: [(set_attr "type" "unary")]) 1040: 1.1.1.3 root 1041: ;; Now we have the generic scc insns. 1042: ;; !v9: These will be done using a jump. 1043: ;; v9: Use conditional moves which are defined elsewhere. 1.1 root 1044: ;; We have to exclude the cases above, since we will not want combine to 1045: ;; turn something that does not require a jump into something that does. 1.1.1.3 root 1046: 1.1.1.4 ! root 1047: (define_insn "*scc_si" 1.1 root 1048: [(set (match_operand:SI 0 "register_operand" "=r") 1049: (match_operator:SI 1 "noov_compare_op" [(reg 0) (const_int 0)]))] 1050: "" 1051: "* return output_scc_insn (operands, insn); " 1052: [(set_attr "type" "multi") 1053: (set_attr "length" "3")]) 1.1.1.3 root 1054: 1.1.1.4 ! root 1055: (define_insn "*scc_di" 1.1.1.3 root 1056: [(set (match_operand:DI 0 "register_operand" "=r") 1057: (match_operator:DI 1 "noov_compare_op" [(reg 0) (const_int 0)]))] 1058: "TARGET_V9" 1059: "* return output_scc_insn (operands, insn); " 1060: [(set_attr "type" "multi") 1061: (set_attr "length" "3")]) 1.1 root 1062: 1063: ;; These control RTL generation for conditional jump insns 1064: 1.1.1.3 root 1065: ;; The quad-word fp compare library routines all return nonzero to indicate 1066: ;; true, which is different from the equivalent libgcc routines, so we must 1067: ;; handle them specially here. 1068: 1.1 root 1069: (define_expand "beq" 1070: [(set (pc) 1071: (if_then_else (eq (match_dup 1) (const_int 0)) 1072: (label_ref (match_operand 0 "" "")) 1073: (pc)))] 1074: "" 1075: " 1.1.1.3 root 1076: { 1077: if (TARGET_V9 && sparc_compare_op1 == const0_rtx 1078: && GET_CODE (sparc_compare_op0) == REG 1079: && GET_MODE (sparc_compare_op0) == DImode) 1080: { 1081: emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]); 1082: DONE; 1083: } 1084: else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) 1085: { 1086: emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ); 1087: emit_jump_insn (gen_bne (operands[0])); 1088: DONE; 1089: } 1090: operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1); 1091: }") 1.1 root 1092: 1093: (define_expand "bne" 1094: [(set (pc) 1095: (if_then_else (ne (match_dup 1) (const_int 0)) 1096: (label_ref (match_operand 0 "" "")) 1097: (pc)))] 1098: "" 1099: " 1.1.1.3 root 1100: { 1101: if (TARGET_V9 && sparc_compare_op1 == const0_rtx 1102: && GET_CODE (sparc_compare_op0) == REG 1103: && GET_MODE (sparc_compare_op0) == DImode) 1104: { 1105: emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]); 1106: DONE; 1107: } 1108: else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) 1109: { 1110: emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE); 1111: emit_jump_insn (gen_bne (operands[0])); 1112: DONE; 1113: } 1114: operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1); 1115: }") 1.1 root 1116: 1117: (define_expand "bgt" 1118: [(set (pc) 1119: (if_then_else (gt (match_dup 1) (const_int 0)) 1120: (label_ref (match_operand 0 "" "")) 1121: (pc)))] 1122: "" 1123: " 1.1.1.3 root 1124: { 1125: if (TARGET_V9 && sparc_compare_op1 == const0_rtx 1126: && GET_CODE (sparc_compare_op0) == REG 1127: && GET_MODE (sparc_compare_op0) == DImode) 1128: { 1129: emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]); 1130: DONE; 1131: } 1132: else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) 1133: { 1134: emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT); 1135: emit_jump_insn (gen_bne (operands[0])); 1136: DONE; 1137: } 1138: operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); 1139: }") 1.1 root 1140: 1141: (define_expand "bgtu" 1142: [(set (pc) 1143: (if_then_else (gtu (match_dup 1) (const_int 0)) 1144: (label_ref (match_operand 0 "" "")) 1145: (pc)))] 1146: "" 1147: " 1148: { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1); 1149: }") 1150: 1151: (define_expand "blt" 1152: [(set (pc) 1153: (if_then_else (lt (match_dup 1) (const_int 0)) 1154: (label_ref (match_operand 0 "" "")) 1155: (pc)))] 1156: "" 1157: " 1.1.1.3 root 1158: { 1159: if (TARGET_V9 && sparc_compare_op1 == const0_rtx 1160: && GET_CODE (sparc_compare_op0) == REG 1161: && GET_MODE (sparc_compare_op0) == DImode) 1162: { 1163: emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]); 1164: DONE; 1165: } 1166: else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) 1167: { 1168: emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT); 1169: emit_jump_insn (gen_bne (operands[0])); 1170: DONE; 1171: } 1172: operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); 1173: }") 1.1 root 1174: 1175: (define_expand "bltu" 1176: [(set (pc) 1177: (if_then_else (ltu (match_dup 1) (const_int 0)) 1178: (label_ref (match_operand 0 "" "")) 1179: (pc)))] 1180: "" 1181: " 1182: { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1); 1183: }") 1184: 1185: (define_expand "bge" 1186: [(set (pc) 1187: (if_then_else (ge (match_dup 1) (const_int 0)) 1188: (label_ref (match_operand 0 "" "")) 1189: (pc)))] 1190: "" 1191: " 1.1.1.3 root 1192: { 1193: if (TARGET_V9 && sparc_compare_op1 == const0_rtx 1194: && GET_CODE (sparc_compare_op0) == REG 1195: && GET_MODE (sparc_compare_op0) == DImode) 1196: { 1197: emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]); 1198: DONE; 1199: } 1200: else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) 1201: { 1202: emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE); 1203: emit_jump_insn (gen_bne (operands[0])); 1204: DONE; 1205: } 1206: operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); 1207: }") 1.1 root 1208: 1209: (define_expand "bgeu" 1210: [(set (pc) 1211: (if_then_else (geu (match_dup 1) (const_int 0)) 1212: (label_ref (match_operand 0 "" "")) 1213: (pc)))] 1214: "" 1215: " 1216: { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1); 1217: }") 1218: 1219: (define_expand "ble" 1220: [(set (pc) 1221: (if_then_else (le (match_dup 1) (const_int 0)) 1222: (label_ref (match_operand 0 "" "")) 1223: (pc)))] 1224: "" 1225: " 1.1.1.3 root 1226: { 1227: if (TARGET_V9 && sparc_compare_op1 == const0_rtx 1228: && GET_CODE (sparc_compare_op0) == REG 1229: && GET_MODE (sparc_compare_op0) == DImode) 1230: { 1231: emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]); 1232: DONE; 1233: } 1234: else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) 1235: { 1236: emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE); 1237: emit_jump_insn (gen_bne (operands[0])); 1238: DONE; 1239: } 1240: operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); 1241: }") 1.1 root 1242: 1243: (define_expand "bleu" 1244: [(set (pc) 1245: (if_then_else (leu (match_dup 1) (const_int 0)) 1246: (label_ref (match_operand 0 "" "")) 1247: (pc)))] 1248: "" 1249: " 1250: { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1); 1251: }") 1252: 1253: ;; Now match both normal and inverted jump. 1254: 1.1.1.4 ! root 1255: (define_insn "*normal_branch" 1.1 root 1256: [(set (pc) 1257: (if_then_else (match_operator 0 "noov_compare_op" 1258: [(reg 0) (const_int 0)]) 1259: (label_ref (match_operand 1 "" "")) 1260: (pc)))] 1261: "" 1262: "* 1263: { 1.1.1.3 root 1264: return output_cbranch (operands[0], 0, 1, 0, 1.1 root 1265: final_sequence && INSN_ANNULLED_BRANCH_P (insn), 1266: ! final_sequence); 1267: }" 1268: [(set_attr "type" "branch")]) 1269: 1.1.1.4 ! root 1270: (define_insn "*inverted_branch" 1.1 root 1271: [(set (pc) 1272: (if_then_else (match_operator 0 "noov_compare_op" 1273: [(reg 0) (const_int 0)]) 1274: (pc) 1275: (label_ref (match_operand 1 "" ""))))] 1276: "" 1277: "* 1278: { 1.1.1.3 root 1279: return output_cbranch (operands[0], 0, 1, 1, 1.1 root 1280: final_sequence && INSN_ANNULLED_BRANCH_P (insn), 1281: ! final_sequence); 1282: }" 1283: [(set_attr "type" "branch")]) 1284: 1.1.1.4 ! root 1285: (define_insn "*normal_fp_branch_sp64" 1.1.1.3 root 1286: [(set (pc) 1287: (if_then_else (match_operator 0 "comparison_operator" 1288: [(match_operand:CCFP 1 "ccfp_reg_operand" "c") 1289: (const_int 0)]) 1290: (label_ref (match_operand 2 "" "")) 1291: (pc)))] 1292: "TARGET_V9" 1293: "* 1.1 root 1294: { 1.1.1.3 root 1295: return output_cbranch (operands[0], operands[1], 2, 0, 1296: final_sequence && INSN_ANNULLED_BRANCH_P (insn), 1297: ! final_sequence); 1298: }" 1299: [(set_attr "type" "branch")]) 1.1 root 1300: 1.1.1.4 ! root 1301: (define_insn "*inverted_fp_branch_sp64" 1.1.1.3 root 1302: [(set (pc) 1303: (if_then_else (match_operator 0 "comparison_operator" 1304: [(match_operand:CCFP 1 "ccfp_reg_operand" "c") 1305: (const_int 0)]) 1306: (pc) 1307: (label_ref (match_operand 2 "" ""))))] 1308: "TARGET_V9" 1309: "* 1310: { 1311: return output_cbranch (operands[0], operands[1], 2, 1, 1312: final_sequence && INSN_ANNULLED_BRANCH_P (insn), 1313: ! final_sequence); 1314: }" 1315: [(set_attr "type" "branch")]) 1316: 1.1.1.4 ! root 1317: (define_insn "*normal_fpe_branch_sp64" 1.1.1.3 root 1318: [(set (pc) 1319: (if_then_else (match_operator 0 "comparison_operator" 1320: [(match_operand:CCFPE 1 "ccfp_reg_operand" "c") 1321: (const_int 0)]) 1322: (label_ref (match_operand 2 "" "")) 1323: (pc)))] 1324: "TARGET_V9" 1325: "* 1326: { 1327: return output_cbranch (operands[0], operands[1], 2, 0, 1328: final_sequence && INSN_ANNULLED_BRANCH_P (insn), 1329: ! final_sequence); 1330: }" 1331: [(set_attr "type" "branch")]) 1332: 1.1.1.4 ! root 1333: (define_insn "*inverted_fpe_branch_sp64" 1.1.1.3 root 1334: [(set (pc) 1335: (if_then_else (match_operator 0 "comparison_operator" 1336: [(match_operand:CCFPE 1 "ccfp_reg_operand" "c") 1337: (const_int 0)]) 1338: (pc) 1339: (label_ref (match_operand 2 "" ""))))] 1340: "TARGET_V9" 1341: "* 1342: { 1343: return output_cbranch (operands[0], operands[1], 2, 1, 1344: final_sequence && INSN_ANNULLED_BRANCH_P (insn), 1345: ! final_sequence); 1346: }" 1347: [(set_attr "type" "branch")]) 1348: 1349: ;; Sparc V9-specific jump insns. None of these are guaranteed to be 1350: ;; in the architecture. 1351: 1352: ;; There are no 32 bit brreg insns. 1353: 1.1.1.4 ! root 1354: (define_insn "*normal_int_branch_sp64" 1.1.1.3 root 1355: [(set (pc) 1356: (if_then_else (match_operator 0 "v9_regcmp_op" 1357: [(match_operand:DI 1 "register_operand" "r") 1358: (const_int 0)]) 1359: (label_ref (match_operand 2 "" "")) 1360: (pc)))] 1361: "TARGET_V9" 1362: "* 1363: { 1364: return output_v9branch (operands[0], 1, 2, 0, 1365: final_sequence && INSN_ANNULLED_BRANCH_P (insn), 1366: ! final_sequence); 1367: }" 1368: [(set_attr "type" "branch")]) 1369: 1.1.1.4 ! root 1370: (define_insn "*inverted_int_branch_sp64" 1.1.1.3 root 1371: [(set (pc) 1372: (if_then_else (match_operator 0 "v9_regcmp_op" 1373: [(match_operand:DI 1 "register_operand" "r") 1374: (const_int 0)]) 1375: (pc) 1376: (label_ref (match_operand 2 "" ""))))] 1377: "TARGET_V9" 1378: "* 1379: { 1380: return output_v9branch (operands[0], 1, 2, 1, 1381: final_sequence && INSN_ANNULLED_BRANCH_P (insn), 1382: ! final_sequence); 1383: }" 1384: [(set_attr "type" "branch")]) 1385: 1386: ;; Esoteric move insns (lo_sum, high, pic). 1387: 1.1.1.4 ! root 1388: (define_insn "*lo_sum_si" 1.1.1.3 root 1389: [(set (match_operand:SI 0 "register_operand" "=r") 1390: (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 1391: (match_operand:SI 2 "immediate_operand" "in")))] 1392: "" 1393: ;; V9 needs "add" because of the code models. We still use "or" for v8 1394: ;; so we can compare the old compiler with the new. 1395: "* return TARGET_V9 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";" 1396: ;; Need to set length for this arith insn because operand2 1397: ;; is not an "arith_operand". 1398: [(set_attr "length" "1")]) 1399: 1400: ;; For PIC, symbol_refs are put inside unspec so that the optimizer will not 1401: ;; confuse them with real addresses. 1.1.1.4 ! root 1402: (define_insn "*pic_lo_sum_si" 1.1.1.3 root 1403: [(set (match_operand:SI 0 "register_operand" "=r") 1404: (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 1405: (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))] 1406: "" 1407: ;; V9 needs "add" because of the code models. We still use "or" for v8 1408: ;; so we can compare the old compiler with the new. 1409: "* return TARGET_V9 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";" 1410: ;; Need to set length for this arith insn because operand2 1411: ;; is not an "arith_operand". 1412: [(set_attr "length" "1")]) 1413: 1414: ;; For PIC, symbol_refs are put inside unspec so that the optimizer will not 1415: ;; confuse them with real addresses. 1.1.1.4 ! root 1416: (define_insn "*pic_sethi_si" 1.1.1.3 root 1417: [(set (match_operand:SI 0 "register_operand" "=r") 1418: (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))] 1419: "check_pic (1)" 1420: "sethi %%hi(%a1),%0" 1421: [(set_attr "type" "move") 1422: (set_attr "length" "1")]) 1423: 1.1.1.4 ! root 1424: (define_insn "*sethi_si" 1.1.1.3 root 1425: [(set (match_operand:SI 0 "register_operand" "=r") 1426: (high:SI (match_operand 1 "" "")))] 1427: "check_pic (1)" 1428: "sethi %%hi(%a1),%0" 1429: [(set_attr "type" "move") 1430: (set_attr "length" "1")]) 1431: 1.1.1.4 ! root 1432: (define_insn "*sethi_hi" 1.1.1.3 root 1433: [(set (match_operand:HI 0 "register_operand" "=r") 1434: (high:HI (match_operand 1 "" "")))] 1435: "check_pic (1)" 1436: "sethi %%hi(%a1),%0" 1437: [(set_attr "type" "move") 1438: (set_attr "length" "1")]) 1439: 1440: ;; Special pic pattern, for loading the address of a label into a register. 1441: ;; It clobbers o7 because the call puts the return address (i.e. pc value) 1442: ;; there. 1443: 1.1.1.4 ! root 1444: (define_insn "*move_pic_label_si" 1.1.1.3 root 1445: [(set (match_operand:SI 0 "register_operand" "=r") 1446: (match_operand:SI 1 "move_pic_label" "i")) 1447: (set (reg:SI 15) (pc))] 1448: "" 1449: "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0" 1450: [(set_attr "type" "multi") 1451: (set_attr "length" "4")]) 1452: 1453: ;; v9 special pic pattern, for loading the address of a label into a register. 1454: 1.1.1.4 ! root 1455: (define_insn "*move_pic_label_di" 1.1.1.3 root 1456: [(set (match_operand:DI 0 "register_operand" "=r") 1457: (match_operand:DI 1 "move_pic_label" "i")) 1458: (set (reg:DI 15) (pc))] 1459: "TARGET_V9" 1460: "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0" 1461: [(set_attr "type" "multi") 1462: (set_attr "length" "4")]) 1463: 1.1.1.4 ! root 1464: (define_insn "*lo_sum_di_sp32" 1.1.1.3 root 1465: [(set (match_operand:DI 0 "register_operand" "=r") 1466: (lo_sum:DI (match_operand:DI 1 "register_operand" "0") 1467: (match_operand:DI 2 "immediate_operand" "in")))] 1468: "! TARGET_V9" 1469: "* 1470: { 1471: /* Don't output a 64 bit constant, since we can't trust the assembler to 1472: handle it correctly. */ 1473: if (GET_CODE (operands[2]) == CONST_DOUBLE) 1474: operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2])); 1475: return \"or %R1,%%lo(%a2),%R0\"; 1476: }" 1477: ;; Need to set length for this arith insn because operand2 1478: ;; is not an "arith_operand". 1479: [(set_attr "length" "1")]) 1480: 1481: ;; ??? Gas does not handle %lo(DI), so we use the same code for ! TARGET_V9. 1482: ;; ??? The previous comment is obsolete. 1483: ;; ??? Optimizer does not handle "or %o1,%lo(0),%o1". How about add? 1484: 1.1.1.4 ! root 1485: (define_insn "*lo_sum_di_sp64" 1.1.1.3 root 1486: [(set (match_operand:DI 0 "register_operand" "=r") 1487: (lo_sum:DI (match_operand:DI 1 "register_operand" "0") 1488: (match_operand:DI 2 "immediate_operand" "in")))] 1489: "TARGET_V9" 1490: "* 1491: { 1492: /* Don't output a 64 bit constant, since we can't trust the assembler to 1493: handle it correctly. */ 1494: if (GET_CODE (operands[2]) == CONST_DOUBLE) 1495: operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2])); 1496: /* Note that we use add here. This is important because Medium/Anywhere 1497: code model support depends on it. */ 1498: return \"add %1,%%lo(%a2),%0\"; 1499: }" 1500: ;; Need to set length for this arith insn because operand2 1501: ;; is not an "arith_operand". 1502: [(set_attr "length" "1")]) 1503: 1.1.1.4 ! root 1504: (define_insn "*sethi_di_sp32" 1.1.1.3 root 1505: [(set (match_operand:DI 0 "register_operand" "=r") 1506: (high:DI (match_operand 1 "" "")))] 1507: "! TARGET_V9 && check_pic (1)" 1508: "* 1509: { 1510: rtx op0 = operands[0]; 1511: rtx op1 = operands[1]; 1512: 1513: if (GET_CODE (op1) == CONST_INT) 1514: { 1515: operands[0] = operand_subword (op0, 1, 0, DImode); 1516: output_asm_insn (\"sethi %%hi(%a1),%0\", operands); 1517: 1518: operands[0] = operand_subword (op0, 0, 0, DImode); 1519: if (INTVAL (op1) < 0) 1520: return \"mov -1,%0\"; 1521: else 1522: return \"mov 0,%0\"; 1523: } 1524: else if (GET_CODE (op1) == CONST_DOUBLE) 1525: { 1526: operands[0] = operand_subword (op0, 1, 0, DImode); 1527: operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1)); 1528: output_asm_insn (\"sethi %%hi(%a1),%0\", operands); 1529: 1530: operands[0] = operand_subword (op0, 0, 0, DImode); 1531: operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1)); 1532: return singlemove_string (operands); 1533: } 1534: else 1535: abort (); 1536: return \"\"; 1537: }" 1538: [(set_attr "type" "move") 1539: (set_attr "length" "2")]) 1540: 1541: ;;; ??? This pattern originally clobbered a scratch register. However, this 1.1.1.4 ! root 1542: ;;; is invalid, the movdi pattern may not use a temp register because it 1.1.1.3 root 1543: ;;; may be called from reload to reload a DImode value. In that case, we 1544: ;;; end up with a scratch register that never gets allocated. To avoid this, 1545: ;;; we use global register 1 which is never otherwise used by gcc as a temp. 1546: ;;; The correct solution here might be to force DImode constants to memory, 1547: ;;; e.g. by using a toc like the romp and rs6000 ports do for addresses, reg 1548: ;;; 1 will then no longer need to be considered a fixed reg. 1549: 1550: ;;; Gas doesn't have any 64 bit constant support, so don't use %uhi and %ulo 1551: ;;; on constants. Symbols have to be handled by the linker, so we must use 1552: ;;; %uhi and %ulo for them, but gas will handle these correctly. 1553: ;;; ??? This comment is obsolete, gas handles them now. 1554: 1.1.1.4 ! root 1555: (define_insn "*sethi_di_sp64" 1.1.1.3 root 1556: [(set (match_operand:DI 0 "register_operand" "=r") 1557: (high:DI (match_operand 1 "const_double_operand" ""))) 1558: (clobber (reg:DI 1))] 1559: "TARGET_V9 && check_pic (1)" 1560: "* 1561: { 1562: rtx high, low; 1563: 1564: split_double (operands[1], &high, &low); 1565: 1566: if (high == const0_rtx) 1567: { 1568: operands[1] = low; 1569: output_asm_insn (\"sethi %%hi(%a1),%0\", operands); 1570: } 1571: else 1572: { 1573: operands[1] = high; 1574: output_asm_insn (singlemove_string (operands), operands); 1575: 1576: operands[1] = low; 1577: output_asm_insn (\"sllx %0,32,%0\", operands); 1578: if (low != const0_rtx) 1579: output_asm_insn (\"sethi %%hi(%a1),%%g1; or %0,%%g1,%0\", operands); 1580: } 1.1.1.4 ! root 1581: ! 1582: return \"\"; 1.1.1.3 root 1583: }" 1584: [(set_attr "type" "move") 1585: (set_attr "length" "5")]) 1586: 1587: ;; Most of the required support for the various code models is here. 1588: ;; We can do this because sparcs need the high insn to load the address. We 1589: ;; just need to get high to do the right thing for each code model. Then each 1590: ;; uses the same "%X+%lo(...)" in the load/store insn. 1591: 1592: ;; When TARGET_MEDLOW, assume that the upper 32 bits of symbol addresses are 1593: ;; always 0. 1594: ;; When TARGET_MEDANY, the upper 32 bits of function addresses are 0. 1595: ;; The data segment has a maximum size of 32 bits, but may be located anywhere. 1596: ;; MEDANY_BASE_REG contains the start address, currently %g4. 1597: ;; When TARGET_FULLANY, symbolic addresses are 64 bits. 1598: 1.1.1.4 ! root 1599: (define_insn "*sethi_di_medlow" 1.1.1.3 root 1600: [(set (match_operand:DI 0 "register_operand" "=r") 1601: (high:DI (match_operand 1 "" ""))) 1602: ;; ??? Why the clobber? 1603: (clobber (reg:DI 1))] 1604: "TARGET_MEDLOW && check_pic (1)" 1605: "sethi %%hi(%a1),%0" 1606: [(set_attr "type" "move") 1607: (set_attr "length" "1")]) 1608: 1609: ;; WARNING: %0 gets %hi(%1)+%g4. 1610: ;; You cannot OR in %lo(%1), it must be added in. 1611: 1.1.1.4 ! root 1612: (define_insn "*sethi_di_medany_data" 1.1.1.3 root 1613: [(set (match_operand:DI 0 "register_operand" "=r") 1614: (high:DI (match_operand 1 "data_segment_operand" ""))) 1615: ;; ??? Why the clobber? 1616: (clobber (reg:DI 1))] 1617: "TARGET_MEDANY && check_pic (1)" 1618: "sethi %%hi(%a1),%0; add %0,%%g4,%0" 1619: [(set_attr "type" "move") 1620: (set_attr "length" "2")]) 1621: 1.1.1.4 ! root 1622: (define_insn "*sethi_di_medany_text" 1.1.1.3 root 1623: [(set (match_operand:DI 0 "register_operand" "=r") 1624: (high:DI (match_operand 1 "text_segment_operand" ""))) 1625: ;; ??? Why the clobber? 1626: (clobber (reg:DI 1))] 1627: "TARGET_MEDANY && check_pic (1)" 1628: "sethi %%hi(%a1),%0" 1629: [(set_attr "type" "move") 1630: (set_attr "length" "1")]) 1631: 1.1.1.4 ! root 1632: (define_insn "*sethi_di_fullany" 1.1.1.3 root 1633: [(set (match_operand:DI 0 "register_operand" "=r") 1634: (high:DI (match_operand 1 "" ""))) 1635: (clobber (reg:DI 1))] 1636: "TARGET_FULLANY && check_pic (1)" 1637: "sethi %%uhi(%a1),%%g1; or %%g1,%%ulo(%a1),%%g1; sllx %%g1,32,%%g1; sethi %%hi(%a1),%0; or %0,%%g1,%0" 1638: [(set_attr "type" "move") 1639: (set_attr "length" "5")]) 1640: 1641: ;; Move instructions 1642: 1643: (define_expand "movqi" 1644: [(set (match_operand:QI 0 "general_operand" "") 1645: (match_operand:QI 1 "general_operand" ""))] 1646: "" 1647: " 1648: { 1649: if (emit_move_sequence (operands, QImode)) 1650: DONE; 1651: }") 1652: 1.1.1.4 ! root 1653: (define_insn "*movqi_insn" 1.1.1.3 root 1654: [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q") 1655: (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))] 1656: "register_operand (operands[0], QImode) 1657: || register_operand (operands[1], QImode) 1658: || operands[1] == const0_rtx" 1659: "@ 1660: mov %1,%0 1661: sethi %%hi(%a1),%0 1662: ldub %1,%0 1663: stb %r1,%0" 1.1.1.2 root 1664: [(set_attr "type" "move,move,load,store") 1665: (set_attr "length" "*,1,*,1")]) 1666: 1.1.1.4 ! root 1667: (define_insn "*lo_sum_qi" 1.1.1.2 root 1668: [(set (match_operand:QI 0 "register_operand" "=r") 1669: (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r") 1670: (match_operand 2 "immediate_operand" "in")) 0))] 1671: "" 1672: "or %1,%%lo(%a2),%0" 1673: [(set_attr "length" "1")]) 1674: 1.1.1.4 ! root 1675: (define_insn "*store_qi" 1.1.1.2 root 1676: [(set (mem:QI (match_operand:SI 0 "symbolic_operand" "")) 1677: (match_operand:QI 1 "reg_or_0_operand" "rJ")) 1678: (clobber (match_scratch:SI 2 "=&r"))] 1.1.1.3 root 1679: "(reload_completed || reload_in_progress) && ! TARGET_PTR64" 1.1.1.2 root 1680: "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]" 1681: [(set_attr "type" "store") 1682: (set_attr "length" "2")]) 1683: 1684: (define_expand "movhi" 1685: [(set (match_operand:HI 0 "general_operand" "") 1686: (match_operand:HI 1 "general_operand" ""))] 1.1 root 1687: "" 1688: " 1689: { 1.1.1.2 root 1690: if (emit_move_sequence (operands, HImode)) 1.1 root 1691: DONE; 1.1.1.2 root 1692: }") 1.1 root 1693: 1.1.1.4 ! root 1694: (define_insn "*movhi_insn" 1.1.1.2 root 1695: [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q") 1696: (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))] 1697: "register_operand (operands[0], HImode) 1698: || register_operand (operands[1], HImode) 1699: || operands[1] == const0_rtx" 1700: "@ 1701: mov %1,%0 1702: sethi %%hi(%a1),%0 1703: lduh %1,%0 1704: sth %r1,%0" 1705: [(set_attr "type" "move,move,load,store") 1706: (set_attr "length" "*,1,*,1")]) 1707: 1.1.1.4 ! root 1708: (define_insn "*lo_sum_hi" 1.1.1.2 root 1709: [(set (match_operand:HI 0 "register_operand" "=r") 1710: (lo_sum:HI (match_operand:HI 1 "register_operand" "r") 1711: (match_operand 2 "immediate_operand" "in")))] 1712: "" 1713: "or %1,%%lo(%a2),%0" 1714: [(set_attr "length" "1")]) 1715: 1.1.1.4 ! root 1716: (define_insn "*store_hi" 1.1.1.2 root 1717: [(set (mem:HI (match_operand:SI 0 "symbolic_operand" "")) 1718: (match_operand:HI 1 "reg_or_0_operand" "rJ")) 1719: (clobber (match_scratch:SI 2 "=&r"))] 1.1.1.3 root 1720: "(reload_completed || reload_in_progress) && ! TARGET_PTR64" 1.1.1.2 root 1721: "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]" 1722: [(set_attr "type" "store") 1723: (set_attr "length" "2")]) 1724: 1725: (define_expand "movsi" 1726: [(set (match_operand:SI 0 "general_operand" "") 1727: (match_operand:SI 1 "general_operand" ""))] 1728: "" 1729: " 1730: { 1731: if (emit_move_sequence (operands, SImode)) 1732: DONE; 1.1 root 1733: }") 1734: 1735: ;; We must support both 'r' and 'f' registers here, because combine may 1736: ;; convert SFmode hard registers to SImode hard registers when simplifying 1737: ;; subreg sets. 1738: 1739: ;; We cannot combine the similar 'r' and 'f' constraints, because it causes 1740: ;; problems with register allocation. Reload might try to put an integer 1741: ;; in an fp register, or an fp number is an integer register. 1742: 1.1.1.4 ! root 1743: (define_insn "*movsi_insn" 1.1 root 1744: [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q") 1745: (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f"))] 1746: "register_operand (operands[0], SImode) 1747: || register_operand (operands[1], SImode) 1748: || operands[1] == const0_rtx" 1749: "@ 1750: mov %1,%0 1751: fmovs %1,%0 1752: sethi %%hi(%a1),%0 1753: ld %1,%0 1754: ld %1,%0 1755: st %r1,%0 1756: st %r1,%0" 1757: [(set_attr "type" "move,fp,move,load,load,store,store") 1758: (set_attr "length" "*,*,1,*,*,*,*")]) 1759: 1.1.1.4 ! root 1760: (define_insn "*store_si" 1.1 root 1761: [(set (mem:SI (match_operand:SI 0 "symbolic_operand" "")) 1762: (match_operand:SI 1 "reg_or_0_operand" "rJ")) 1763: (clobber (match_scratch:SI 2 "=&r"))] 1.1.1.3 root 1764: "(reload_completed || reload_in_progress) && ! TARGET_PTR64" 1.1 root 1765: "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]" 1766: [(set_attr "type" "store") 1767: (set_attr "length" "2")]) 1768: 1.1.1.2 root 1769: (define_expand "movdi" 1770: [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "") 1771: (match_operand:DI 1 "general_operand" ""))] 1.1 root 1772: "" 1773: " 1774: { 1.1.1.2 root 1775: if (emit_move_sequence (operands, DImode)) 1.1 root 1776: DONE; 1777: }") 1778: 1.1.1.4 ! root 1779: (define_insn "*movdi_sp32_insn" 1.1.1.3 root 1780: [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,T,U,Q,r,r,?f,?f,?Q") 1781: (match_operand:DI 1 "general_operand" "r,U,T,r,Q,i,f,Q,f"))] 1782: "! TARGET_V9 1783: && (register_operand (operands[0], DImode) 1784: || register_operand (operands[1], DImode) 1785: || operands[1] == const0_rtx)" 1.1.1.2 root 1786: "* 1.1 root 1787: { 1.1.1.2 root 1788: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) 1789: return output_fp_move_double (operands); 1790: return output_move_double (operands); 1791: }" 1.1.1.3 root 1792: [(set_attr "type" "move,store,load,store,load,multi,fp,fpload,fpstore") 1793: (set_attr "length" "2,1,1,3,3,3,2,3,3")]) 1.1 root 1794: 1.1.1.3 root 1795: ;;; ??? The trick used below can be extended to load any negative 32 bit 1796: ;;; constant in two instructions. Currently the compiler will use HIGH/LO_SUM 1797: ;;; for anything not matching the HIK constraints, which results in 5 1798: ;;; instructions. Positive 32 bit constants can be loaded in the obvious way 1799: ;;; with sethi/ori. To extend the trick, in the xor instruction, use 1800: ;;; xor %o0, ((op1 & 0x3ff) | -0x400), %o0 1801: ;;; This needs the original value of operands[1], not the inverted value. 1802: 1.1.1.4 ! root 1803: (define_insn "*movdi_sp64_insn" 1.1.1.3 root 1804: [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q,?f,?f,?Q") 1805: (match_operand:DI 1 "move_operand" "rI,K,Q,rJ,f,Q,f"))] 1806: "TARGET_V9 1807: && (register_operand (operands[0], DImode) 1808: || register_operand (operands[1], DImode) 1809: || operands[1] == const0_rtx)" 1.1.1.2 root 1810: "* 1811: { 1.1.1.3 root 1812: switch (which_alternative) 1813: { 1814: case 0: 1815: return \"mov %1,%0\"; 1816: case 1: 1817: /* Sethi does not sign extend, so we must use a little trickery 1818: to use it for negative numbers. Invert the constant before 1819: loading it in, then use a xor immediate to invert the loaded bits 1820: (along with the upper 32 bits) to the desired constant. This 1821: works because the sethi and immediate fields overlap. */ 1822: 1823: if ((INTVAL (operands[1]) & 0x80000000) == 0) 1824: return \"sethi %%hi(%a1),%0\"; 1825: else 1826: { 1827: operands[1] = gen_rtx (CONST_INT, VOIDmode, 1828: ~ INTVAL (operands[1])); 1829: output_asm_insn (\"sethi %%hi(%a1),%0\", operands); 1830: /* The low 10 bits are already zero, but invert the rest. 1831: Assemblers don't accept 0x1c00, so use -0x400 instead. */ 1832: return \"xor %0,-0x400,%0\"; 1833: } 1834: case 2: 1835: return \"ldx %1,%0\"; 1836: case 3: 1837: return \"stx %r1,%0\"; 1838: case 4: 1839: return \"mov %1,%0\"; 1840: case 5: 1841: return \"ldd %1,%0\"; 1842: case 6: 1843: return \"std %1,%0\"; 1844: } 1.1.1.2 root 1845: }" 1.1.1.3 root 1846: [(set_attr "type" "move,move,load,store,fp,fpload,fpstore") 1847: (set_attr "length" "1,2,1,1,1,1,1")]) 1.1 root 1848: 1.1.1.2 root 1849: ;; ??? There's no symbolic (set (mem:DI ...) ...). 1.1.1.3 root 1850: ;; Experimentation with v9 suggested one isn't needed. 1.1.1.2 root 1851: 1852: ;; Block move insns. 1.1 root 1853: 1854: ;; ??? We get better code without it. See output_block_move in sparc.c. 1855: 1856: ;; The definition of this insn does not really explain what it does, 1857: ;; but it should suffice 1858: ;; that anything generated as this insn will be recognized as one 1859: ;; and that it will not successfully combine with anything. 1860: ;(define_expand "movstrsi" 1861: ; [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" "")) 1862: ; (mem:BLK (match_operand:BLK 1 "general_operand" ""))) 1863: ; (use (match_operand:SI 2 "nonmemory_operand" "")) 1864: ; (use (match_operand:SI 3 "immediate_operand" "")) 1865: ; (clobber (match_dup 0)) 1866: ; (clobber (match_dup 1)) 1867: ; (clobber (match_scratch:SI 4 "")) 1868: ; (clobber (reg:SI 0)) 1869: ; (clobber (reg:SI 1))])] 1870: ; "" 1871: ; " 1872: ;{ 1873: ; /* If the size isn't known, don't emit inline code. output_block_move 1874: ; would output code that's much slower than the library function. 1875: ; Also don't output code for large blocks. */ 1876: ; if (GET_CODE (operands[2]) != CONST_INT 1877: ; || GET_CODE (operands[3]) != CONST_INT 1878: ; || INTVAL (operands[2]) / INTVAL (operands[3]) > 16) 1879: ; FAIL; 1880: ; 1881: ; operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); 1882: ; operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); 1883: ; operands[2] = force_not_mem (operands[2]); 1884: ;}") 1885: 1.1.1.4 ! root 1886: ;(define_insn "*block_move_insn" 1.1 root 1887: ; [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r")) 1888: ; (mem:BLK (match_operand:SI 1 "register_operand" "+r"))) 1889: ; (use (match_operand:SI 2 "nonmemory_operand" "rn")) 1890: ; (use (match_operand:SI 3 "immediate_operand" "i")) 1891: ; (clobber (match_dup 0)) 1892: ; (clobber (match_dup 1)) 1893: ; (clobber (match_scratch:SI 4 "=&r")) 1894: ; (clobber (reg:SI 0)) 1895: ; (clobber (reg:SI 1))] 1896: ; "" 1897: ; "* return output_block_move (operands);" 1898: ; [(set_attr "type" "multi") 1899: ; (set_attr "length" "6")]) 1900: 1901: ;; Floating point move insns 1902: 1.1.1.2 root 1903: ;; This pattern forces (set (reg:SF ...) (const_double ...)) 1.1 root 1904: ;; to be reloaded by putting the constant into memory. 1.1.1.2 root 1905: ;; It must come before the more general movsf pattern. 1.1.1.4 ! root 1906: (define_insn "*movsf_const_insn" 1.1.1.2 root 1907: [(set (match_operand:SF 0 "general_operand" "=?r,f,m") 1.1.1.4 ! root 1908: (match_operand:SF 1 "" "?F,m,G"))] 1.1 root 1909: "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE" 1910: "* 1911: { 1912: switch (which_alternative) 1913: { 1914: case 0: 1.1.1.2 root 1915: return singlemove_string (operands); 1.1 root 1916: case 1: 1.1.1.2 root 1917: return \"ld %1,%0\"; 1.1 root 1918: case 2: 1.1.1.2 root 1919: return \"st %%g0,%0\"; 1.1 root 1920: } 1921: }" 1922: [(set_attr "type" "load,fpload,store") 1.1.1.2 root 1923: (set_attr "length" "2,1,1")]) 1.1 root 1924: 1.1.1.2 root 1925: (define_expand "movsf" 1926: [(set (match_operand:SF 0 "general_operand" "") 1927: (match_operand:SF 1 "general_operand" ""))] 1.1 root 1928: "" 1929: " 1930: { 1.1.1.2 root 1931: if (emit_move_sequence (operands, SFmode)) 1.1 root 1932: DONE; 1933: }") 1934: 1.1.1.4 ! root 1935: (define_insn "*movsf_insn" 1.1.1.2 root 1936: [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,f,r,Q,Q") 1937: (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,Q,Q,f,r"))] 1.1 root 1938: "TARGET_FPU 1.1.1.2 root 1939: && (register_operand (operands[0], SFmode) 1940: || register_operand (operands[1], SFmode))" 1941: "@ 1942: fmovs %1,%0 1943: mov %1,%0 1944: ld %1,%0 1945: ld %1,%0 1946: st %r1,%0 1947: st %r1,%0" 1948: [(set_attr "type" "fp,move,fpload,load,fpstore,store")]) 1.1 root 1949: 1950: ;; Exactly the same as above, except that all `f' cases are deleted. 1951: ;; This is necessary to prevent reload from ever trying to use a `f' reg 1952: ;; when -mno-fpu. 1953: 1.1.1.4 ! root 1954: (define_insn "*movsf_no_f_insn" 1.1.1.2 root 1955: [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q") 1956: (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))] 1.1 root 1957: "! TARGET_FPU 1.1.1.2 root 1958: && (register_operand (operands[0], SFmode) 1959: || register_operand (operands[1], SFmode))" 1960: "@ 1961: mov %1,%0 1962: ld %1,%0 1963: st %r1,%0" 1964: [(set_attr "type" "move,load,store")]) 1.1 root 1965: 1.1.1.4 ! root 1966: (define_insn "*store_sf" 1.1.1.2 root 1967: [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i")) 1968: (match_operand:SF 1 "reg_or_0_operand" "rfG")) 1969: (clobber (match_scratch:SI 2 "=&r"))] 1.1.1.3 root 1970: "(reload_completed || reload_in_progress) && ! TARGET_PTR64" 1.1.1.2 root 1971: "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]" 1.1 root 1972: [(set_attr "type" "store") 1.1.1.2 root 1973: (set_attr "length" "2")]) 1974: 1.1 root 1975: ;; This pattern forces (set (reg:DF ...) (const_double ...)) 1976: ;; to be reloaded by putting the constant into memory. 1977: ;; It must come before the more general movdf pattern. 1978: 1.1.1.4 ! root 1979: (define_insn "*movdf_const_insn" 1.1.1.3 root 1980: [(set (match_operand:DF 0 "general_operand" "=?r,e,o") 1.1.1.4 ! root 1981: (match_operand:DF 1 "" "?F,m,G"))] 1.1 root 1982: "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE" 1983: "* 1984: { 1985: switch (which_alternative) 1986: { 1987: case 0: 1988: return output_move_double (operands); 1989: case 1: 1990: return output_fp_move_double (operands); 1991: case 2: 1.1.1.3 root 1992: if (TARGET_V9) 1993: { 1994: return \"stx %%g0,%0\"; 1995: } 1996: else 1997: { 1998: operands[1] = adj_offsettable_operand (operands[0], 4); 1999: return \"st %%g0,%0\;st %%g0,%1\"; 2000: } 1.1 root 2001: } 2002: }" 2003: [(set_attr "type" "load,fpload,store") 2004: (set_attr "length" "3,3,3")]) 2005: 2006: (define_expand "movdf" 2007: [(set (match_operand:DF 0 "general_operand" "") 2008: (match_operand:DF 1 "general_operand" ""))] 2009: "" 2010: " 2011: { 1.1.1.2 root 2012: if (emit_move_sequence (operands, DFmode)) 1.1 root 2013: DONE; 2014: }") 2015: 1.1.1.4 ! root 2016: (define_insn "*movdf_insn" 1.1.1.3 root 2017: [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,e,r,Q,Q,e,r") 2018: (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,e,r,e,r,Q,Q"))] 1.1 root 2019: "TARGET_FPU 2020: && (register_operand (operands[0], DFmode) 2021: || register_operand (operands[1], DFmode))" 2022: "* 2023: { 2024: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) 2025: return output_fp_move_double (operands); 2026: return output_move_double (operands); 2027: }" 2028: [(set_attr "type" "fpstore,fpload,fp,move,fpstore,store,fpload,load") 2029: (set_attr "length" "1,1,2,2,3,3,3,3")]) 2030: 1.1.1.3 root 2031: ;; Exactly the same as above, except that all `e' cases are deleted. 2032: ;; This is necessary to prevent reload from ever trying to use a `e' reg 1.1 root 2033: ;; when -mno-fpu. 2034: 1.1.1.4 ! root 2035: (define_insn "*movdf_no_e_insn" 1.1 root 2036: [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r") 2037: (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))] 2038: "! TARGET_FPU 2039: && (register_operand (operands[0], DFmode) 2040: || register_operand (operands[1], DFmode))" 2041: "* return output_move_double (operands);" 2042: [(set_attr "type" "store,load,move,store,load") 2043: (set_attr "length" "1,1,2,3,3")]) 2044: 1.1.1.3 root 2045: ;; Must handle overlapping registers here, since parameters can be unaligned 2046: ;; in registers. 2047: ;; ??? Do we need a v9 version of this? 1.1 root 2048: (define_split 2049: [(set (match_operand:DF 0 "register_operand" "") 2050: (match_operand:DF 1 "register_operand" ""))] 1.1.1.3 root 2051: "! TARGET_V9 && reload_completed" 1.1 root 2052: [(set (match_dup 2) (match_dup 3)) 2053: (set (match_dup 4) (match_dup 5))] 2054: " 1.1.1.3 root 2055: { 2056: rtx first_set = operand_subword (operands[0], 0, 0, DFmode); 2057: rtx second_use = operand_subword (operands[1], 1, 0, DFmode); 2058: 2059: if (REGNO (first_set) == REGNO (second_use)) 2060: { 2061: operands[2] = operand_subword (operands[0], 1, 0, DFmode); 2062: operands[3] = second_use; 2063: operands[4] = first_set; 2064: operands[5] = operand_subword (operands[1], 0, 0, DFmode); 2065: } 2066: else 2067: { 2068: operands[2] = first_set; 2069: operands[3] = operand_subword (operands[1], 0, 0, DFmode); 2070: operands[4] = operand_subword (operands[0], 1, 0, DFmode); 2071: operands[5] = second_use; 2072: } 2073: }") 1.1 root 2074: 1.1.1.4 ! root 2075: (define_insn "*store_df" 1.1 root 2076: [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i")) 1.1.1.3 root 2077: (match_operand:DF 1 "reg_or_0_operand" "re,G")) 1.1 root 2078: (clobber (match_scratch:SI 2 "=&r,&r"))] 1.1.1.3 root 2079: "(reload_completed || reload_in_progress) && ! TARGET_PTR64" 1.1 root 2080: "* 2081: { 2082: output_asm_insn (\"sethi %%hi(%a0),%2\", operands); 2083: if (which_alternative == 0) 2084: return \"std %1,[%2+%%lo(%a0)]\"; 2085: else 2086: return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\"; 2087: }" 2088: [(set_attr "type" "store") 2089: (set_attr "length" "3")]) 2090: 1.1.1.2 root 2091: ;; This pattern forces (set (reg:TF ...) (const_double ...)) 1.1 root 2092: ;; to be reloaded by putting the constant into memory. 1.1.1.2 root 2093: ;; It must come before the more general movtf pattern. 1.1.1.4 ! root 2094: (define_insn "*movtf_const_insn" 1.1.1.3 root 2095: [(set (match_operand:TF 0 "general_operand" "=?r,e,o") 1.1.1.4 ! root 2096: (match_operand:TF 1 "" "?F,m,G"))] 1.1 root 2097: "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE" 2098: "* 2099: { 2100: switch (which_alternative) 2101: { 2102: case 0: 1.1.1.2 root 2103: return output_move_quad (operands); 1.1 root 2104: case 1: 1.1.1.2 root 2105: return output_fp_move_quad (operands); 1.1 root 2106: case 2: 1.1.1.3 root 2107: if (TARGET_V9) 2108: { 2109: operands[1] = adj_offsettable_operand (operands[0], 8); 2110: return \"stx %%g0,%0\;stx %%g0,%1\"; 2111: } 2112: else 2113: { 2114: /* ??? Do we run off the end of the array here? */ 2115: operands[1] = adj_offsettable_operand (operands[0], 4); 2116: operands[2] = adj_offsettable_operand (operands[0], 8); 2117: operands[3] = adj_offsettable_operand (operands[0], 12); 2118: return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\"; 2119: } 1.1 root 2120: } 2121: }" 2122: [(set_attr "type" "load,fpload,store") 1.1.1.2 root 2123: (set_attr "length" "5,5,5")]) 1.1 root 2124: 1.1.1.2 root 2125: (define_expand "movtf" 2126: [(set (match_operand:TF 0 "general_operand" "") 2127: (match_operand:TF 1 "general_operand" ""))] 1.1 root 2128: "" 2129: " 2130: { 1.1.1.2 root 2131: if (emit_move_sequence (operands, TFmode)) 1.1 root 2132: DONE; 2133: }") 2134: 1.1.1.4 ! root 2135: (define_insn "*movtf_insn" 1.1.1.3 root 2136: [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=e,r,Q,Q,e,&r") 2137: (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "e,r,e,r,Q,Q"))] 1.1 root 2138: "TARGET_FPU 1.1.1.2 root 2139: && (register_operand (operands[0], TFmode) 2140: || register_operand (operands[1], TFmode))" 2141: "* 2142: { 2143: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) 2144: return output_fp_move_quad (operands); 2145: return output_move_quad (operands); 2146: }" 2147: [(set_attr "type" "fp,move,fpstore,store,fpload,load") 2148: (set_attr "length" "4,4,5,5,5,5")]) 1.1 root 2149: 1.1.1.3 root 2150: ;; Exactly the same as above, except that all `e' cases are deleted. 2151: ;; This is necessary to prevent reload from ever trying to use a `e' reg 1.1 root 2152: ;; when -mno-fpu. 2153: 1.1.1.4 ! root 2154: (define_insn "*movtf_no_e_insn" 1.1.1.2 root 2155: [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r") 2156: (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))] 1.1 root 2157: "! TARGET_FPU 1.1.1.2 root 2158: && (register_operand (operands[0], TFmode) 2159: || register_operand (operands[1], TFmode))" 2160: "* 2161: { 2162: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) 2163: return output_fp_move_quad (operands); 2164: return output_move_quad (operands); 2165: }" 2166: [(set_attr "type" "move,store,load") 2167: (set_attr "length" "4,5,5")]) 1.1 root 2168: 1.1.1.3 root 2169: ;; This is disabled because it does not work. Long doubles have only 8 2170: ;; byte alignment. Adding an offset of 8 or 12 to an 8 byte aligned %lo may 2171: ;; cause it to overflow. See also GO_IF_LEGITIMATE_ADDRESS. 1.1.1.4 ! root 2172: (define_insn "*store_tf" 1.1.1.2 root 2173: [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i")) 1.1.1.3 root 2174: (match_operand:TF 1 "reg_or_0_operand" "re,G")) 1.1.1.2 root 2175: (clobber (match_scratch:SI 2 "=&r,&r"))] 1.1.1.3 root 2176: "0 && (reload_completed || reload_in_progress) && ! TARGET_PTR64" 1.1.1.2 root 2177: "* 2178: { 2179: output_asm_insn (\"sethi %%hi(%a0),%2\", operands); 2180: if (which_alternative == 0) 2181: return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\"; 2182: else 2183: return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\"; 2184: }" 1.1 root 2185: [(set_attr "type" "store") 1.1.1.2 root 2186: (set_attr "length" "5")]) 1.1 root 2187: 1.1.1.3 root 2188: ;; Sparc V9 conditional move instructions. 2189: 1.1.1.4 ! root 2190: ;; We can handle larger constants here for some flavors, but for now we play ! 2191: ;; it safe and only allow those constants supported by all flavours. ! 2192: ! 2193: (define_expand "movsicc" ! 2194: [(set (match_operand:SI 0 "register_operand" "") ! 2195: (if_then_else (match_operand 1 "comparison_operator" "") ! 2196: (match_operand:SI 2 "arith10_operand" "") ! 2197: (match_operand:SI 3 "register_operand" "")))] ! 2198: "TARGET_V9" ! 2199: " ! 2200: { ! 2201: enum rtx_code code = GET_CODE (operands[1]); ! 2202: ! 2203: if (sparc_compare_op1 == const0_rtx ! 2204: && GET_CODE (sparc_compare_op0) == REG ! 2205: && GET_MODE (sparc_compare_op0) == DImode ! 2206: && v9_regcmp_p (code)) ! 2207: { ! 2208: operands[1] = gen_rtx (code, DImode, ! 2209: sparc_compare_op0, sparc_compare_op1); ! 2210: } ! 2211: else ! 2212: { ! 2213: rtx cc_reg = gen_compare_reg (code, ! 2214: sparc_compare_op0, sparc_compare_op1); ! 2215: operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx); ! 2216: } ! 2217: }") ! 2218: ! 2219: (define_expand "movdicc" ! 2220: [(set (match_operand:DI 0 "register_operand" "") ! 2221: (if_then_else (match_operand 1 "comparison_operator" "") ! 2222: (match_operand:DI 2 "arith10_operand" "") ! 2223: (match_operand:DI 3 "register_operand" "")))] ! 2224: "TARGET_V9" ! 2225: " ! 2226: { ! 2227: enum rtx_code code = GET_CODE (operands[1]); ! 2228: ! 2229: if (sparc_compare_op1 == const0_rtx ! 2230: && GET_CODE (sparc_compare_op0) == REG ! 2231: && GET_MODE (sparc_compare_op0) == DImode ! 2232: && v9_regcmp_p (code)) ! 2233: { ! 2234: operands[1] = gen_rtx (code, DImode, ! 2235: sparc_compare_op0, sparc_compare_op1); ! 2236: } ! 2237: else ! 2238: { ! 2239: rtx cc_reg = gen_compare_reg (code, ! 2240: sparc_compare_op0, sparc_compare_op1); ! 2241: operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx); ! 2242: } ! 2243: }") ! 2244: ! 2245: (define_expand "movsfcc" ! 2246: [(set (match_operand:SF 0 "register_operand" "") ! 2247: (if_then_else (match_operand 1 "comparison_operator" "") ! 2248: (match_operand:SF 2 "register_operand" "") ! 2249: (match_operand:SF 3 "register_operand" "")))] ! 2250: "TARGET_V9" ! 2251: " ! 2252: { ! 2253: enum rtx_code code = GET_CODE (operands[1]); ! 2254: ! 2255: if (sparc_compare_op1 == const0_rtx ! 2256: && GET_CODE (sparc_compare_op0) == REG ! 2257: && GET_MODE (sparc_compare_op0) == DImode ! 2258: && v9_regcmp_p (code)) ! 2259: { ! 2260: operands[1] = gen_rtx (code, DImode, ! 2261: sparc_compare_op0, sparc_compare_op1); ! 2262: } ! 2263: else ! 2264: { ! 2265: rtx cc_reg = gen_compare_reg (code, ! 2266: sparc_compare_op0, sparc_compare_op1); ! 2267: operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx); ! 2268: } ! 2269: }") ! 2270: ! 2271: (define_expand "movdfcc" ! 2272: [(set (match_operand:DF 0 "register_operand" "") ! 2273: (if_then_else (match_operand 1 "comparison_operator" "") ! 2274: (match_operand:DF 2 "register_operand" "") ! 2275: (match_operand:DF 3 "register_operand" "")))] ! 2276: "TARGET_V9" ! 2277: " ! 2278: { ! 2279: enum rtx_code code = GET_CODE (operands[1]); ! 2280: ! 2281: if (sparc_compare_op1 == const0_rtx ! 2282: && GET_CODE (sparc_compare_op0) == REG ! 2283: && GET_MODE (sparc_compare_op0) == DImode ! 2284: && v9_regcmp_p (code)) ! 2285: { ! 2286: operands[1] = gen_rtx (code, DImode, ! 2287: sparc_compare_op0, sparc_compare_op1); ! 2288: } ! 2289: else ! 2290: { ! 2291: rtx cc_reg = gen_compare_reg (code, ! 2292: sparc_compare_op0, sparc_compare_op1); ! 2293: operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx); ! 2294: } ! 2295: }") ! 2296: ! 2297: (define_expand "movtfcc" ! 2298: [(set (match_operand:TF 0 "register_operand" "") ! 2299: (if_then_else (match_operand 1 "comparison_operator" "") ! 2300: (match_operand:TF 2 "register_operand" "") ! 2301: (match_operand:TF 3 "register_operand" "")))] ! 2302: "TARGET_V9" ! 2303: " ! 2304: { ! 2305: enum rtx_code code = GET_CODE (operands[1]); ! 2306: ! 2307: if (sparc_compare_op1 == const0_rtx ! 2308: && GET_CODE (sparc_compare_op0) == REG ! 2309: && GET_MODE (sparc_compare_op0) == DImode ! 2310: && v9_regcmp_p (code)) ! 2311: { ! 2312: operands[1] = gen_rtx (code, DImode, ! 2313: sparc_compare_op0, sparc_compare_op1); ! 2314: } ! 2315: else ! 2316: { ! 2317: rtx cc_reg = gen_compare_reg (code, ! 2318: sparc_compare_op0, sparc_compare_op1); ! 2319: operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx); ! 2320: } ! 2321: }") ! 2322: ! 2323: /* Conditional move define_insns. */ ! 2324: ! 2325: (define_insn "*movsi_cc_sp64" 1.1.1.3 root 2326: [(set (match_operand:SI 0 "register_operand" "=r") 2327: (if_then_else (match_operator 1 "comparison_operator" 2328: [(reg:CC 0) (const_int 0)]) 2329: (match_operand:SI 2 "arith11_operand" "ri") 2330: (match_operand:SI 3 "register_operand" "0")))] 2331: "TARGET_V9" 2332: "mov%C1 %%icc,%2,%0" 2333: [(set_attr "type" "cmove")]) 2334: 1.1.1.4 ! root 2335: (define_insn "*movdi_cc_sp64" 1.1.1.3 root 2336: [(set (match_operand:DI 0 "register_operand" "=r") 2337: (if_then_else (match_operator 1 "comparison_operator" 2338: [(reg:CC 0) (const_int 0)]) 2339: (match_operand:DI 2 "arith11_double_operand" "rHI") 2340: (match_operand:DI 3 "register_operand" "0")))] 2341: "TARGET_V9" 2342: "mov%C1 %%icc,%2,%0" 2343: [(set_attr "type" "cmove")]) 2344: 1.1.1.4 ! root 2345: (define_insn "*movsi_ccx_sp64" 1.1.1.3 root 2346: [(set (match_operand:SI 0 "register_operand" "=r") 2347: (if_then_else (match_operator 1 "comparison_operator" 2348: [(reg:CCX 0) (const_int 0)]) 2349: (match_operand:SI 2 "arith11_operand" "ri") 2350: (match_operand:SI 3 "register_operand" "0")))] 2351: "TARGET_V9" 2352: "mov%C1 %%xcc,%2,%0" 2353: [(set_attr "type" "cmove")]) 2354: 1.1.1.4 ! root 2355: (define_insn "*movdi_ccx_sp64" 1.1.1.3 root 2356: [(set (match_operand:DI 0 "register_operand" "=r") 2357: (if_then_else (match_operator 1 "comparison_operator" 2358: [(reg:CCX 0) (const_int 0)]) 2359: (match_operand:DI 2 "arith11_double_operand" "rHI") 2360: (match_operand:DI 3 "register_operand" "0")))] 2361: "TARGET_V9" 2362: "mov%C1 %%xcc,%2,%0" 2363: [(set_attr "type" "cmove")]) 2364: 1.1.1.4 ! root 2365: (define_insn "*movsi_ccfp_sp64" 1.1.1.3 root 2366: [(set (match_operand:SI 0 "register_operand" "=r") 2367: (if_then_else (match_operator 1 "comparison_operator" 2368: [(match_operand:CCFP 2 "ccfp_reg_operand" "c") 2369: (const_int 0)]) 2370: (match_operand:SI 3 "arith11_operand" "ri") 2371: (match_operand:SI 4 "register_operand" "0")))] 2372: "TARGET_V9" 2373: "mov%C1 %2,%3,%0" 2374: [(set_attr "type" "cmove")]) 2375: 1.1.1.4 ! root 2376: (define_insn "*movsi_ccfpe_sp64" 1.1.1.3 root 2377: [(set (match_operand:SI 0 "register_operand" "=r") 2378: (if_then_else (match_operator 1 "comparison_operator" 2379: [(match_operand:CCFPE 2 "ccfp_reg_operand" "c") 2380: (const_int 0)]) 2381: (match_operand:SI 3 "arith11_operand" "ri") 2382: (match_operand:SI 4 "register_operand" "0")))] 2383: "TARGET_V9" 2384: "mov%C1 %2,%3,%0" 2385: [(set_attr "type" "cmove")]) 2386: 1.1.1.4 ! root 2387: (define_insn "*movdi_ccfp_sp64" 1.1.1.3 root 2388: [(set (match_operand:DI 0 "register_operand" "=r") 2389: (if_then_else (match_operator 1 "comparison_operator" 2390: [(match_operand:CCFP 2 "ccfp_reg_operand" "c") 2391: (const_int 0)]) 2392: (match_operand:DI 3 "arith11_double_operand" "rHI") 2393: (match_operand:DI 4 "register_operand" "0")))] 2394: "TARGET_V9" 2395: "mov%C1 %2,%3,%0" 2396: [(set_attr "type" "cmove")]) 2397: 1.1.1.4 ! root 2398: (define_insn "*movdi_ccfpe_sp64" 1.1.1.3 root 2399: [(set (match_operand:DI 0 "register_operand" "=r") 2400: (if_then_else (match_operator 1 "comparison_operator" 2401: [(match_operand:CCFPE 2 "ccfp_reg_operand" "c") 2402: (const_int 0)]) 2403: (match_operand:DI 3 "arith11_double_operand" "rHI") 2404: (match_operand:DI 4 "register_operand" "0")))] 2405: "TARGET_V9" 2406: "mov%C1 %2,%3,%0" 2407: [(set_attr "type" "cmove")]) 2408: 1.1.1.4 ! root 2409: (define_insn "*movsi_cc_reg_sp64" 1.1.1.3 root 2410: [(set (match_operand:SI 0 "register_operand" "=r") 2411: (if_then_else (match_operator 1 "v9_regcmp_op" 2412: [(match_operand:DI 2 "register_operand" "r") 2413: (const_int 0)]) 2414: (match_operand:SI 3 "arith10_operand" "ri") 2415: (match_operand:SI 4 "register_operand" "0")))] 2416: "TARGET_V9" 2417: "movr%D1 %2,%r3,%0" 2418: [(set_attr "type" "cmove")]) 2419: 1.1.1.4 ! root 2420: (define_insn "*movdi_cc_reg_sp64" 1.1.1.3 root 2421: [(set (match_operand:DI 0 "register_operand" "=r") 2422: (if_then_else (match_operator 1 "v9_regcmp_op" 2423: [(match_operand:DI 2 "register_operand" "r") 2424: (const_int 0)]) 2425: (match_operand:DI 3 "arith10_double_operand" "ri") 2426: (match_operand:DI 4 "register_operand" "0")))] 2427: "TARGET_V9" 2428: "movr%D1 %2,%r3,%0" 2429: [(set_attr "type" "cmove")]) 2430: 1.1.1.4 ! root 2431: (define_insn "*movsf_cc_reg_sp64" 1.1.1.3 root 2432: [(set (match_operand:SF 0 "register_operand" "=f") 2433: (if_then_else (match_operator 1 "v9_regcmp_op" 2434: [(match_operand:DI 2 "register_operand" "r") 2435: (const_int 0)]) 2436: (match_operand:SF 3 "register_operand" "f") 2437: (match_operand:SF 4 "register_operand" "0")))] 2438: "TARGET_V9 && TARGET_FPU" 2439: "fmovrs%D1 %2,%r3,%0" 2440: [(set_attr "type" "cmove")]) 2441: 1.1.1.4 ! root 2442: (define_insn "*movdf_cc_reg_sp64" 1.1.1.3 root 2443: [(set (match_operand:DF 0 "register_operand" "=e") 2444: (if_then_else (match_operator 1 "v9_regcmp_op" 2445: [(match_operand:DI 2 "register_operand" "r") 2446: (const_int 0)]) 2447: (match_operand:DF 3 "register_operand" "e") 2448: (match_operand:DF 4 "register_operand" "0")))] 2449: "TARGET_V9 && TARGET_FPU" 2450: "fmovrd%D1 %2,%r3,%0" 2451: [(set_attr "type" "cmove")]) 2452: 1.1.1.4 ! root 2453: (define_insn "*movtf_cc_reg_sp64" 1.1.1.3 root 2454: [(set (match_operand:TF 0 "register_operand" "=e") 2455: (if_then_else (match_operator 1 "v9_regcmp_op" 2456: [(match_operand:DI 2 "register_operand" "r") 2457: (const_int 0)]) 2458: (match_operand:TF 3 "register_operand" "e") 2459: (match_operand:TF 4 "register_operand" "0")))] 2460: "TARGET_V9 && TARGET_FPU" 2461: "fmovrq%D1 %2,%r3,%0" 2462: [(set_attr "type" "cmove")]) 2463: 1.1.1.4 ! root 2464: (define_insn "*movsf_ccfp_sp64" 1.1.1.3 root 2465: [(set (match_operand:SF 0 "register_operand" "=f") 2466: (if_then_else (match_operator 1 "comparison_operator" 2467: [(match_operand:CCFP 2 "ccfp_reg_operand" "c") 2468: (const_int 0)]) 2469: (match_operand:SF 3 "register_operand" "f") 2470: (match_operand:SF 4 "register_operand" "0")))] 2471: "TARGET_V9 && TARGET_FPU" 2472: "fmovs%C1 %2,%3,%0" 2473: [(set_attr "type" "cmove")]) 2474: 1.1.1.4 ! root 2475: (define_insn "*movsf_ccfpe_sp64" 1.1.1.3 root 2476: [(set (match_operand:SF 0 "register_operand" "=f") 2477: (if_then_else (match_operator 1 "comparison_operator" 2478: [(match_operand:CCFPE 2 "ccfp_reg_operand" "c") 2479: (const_int 0)]) 2480: (match_operand:SF 3 "register_operand" "f") 2481: (match_operand:SF 4 "register_operand" "0")))] 2482: "TARGET_V9 && TARGET_FPU" 2483: "fmovs%C1 %2,%3,%0" 2484: [(set_attr "type" "cmove")]) 2485: 1.1.1.4 ! root 2486: (define_insn "*movdf_ccfp_sp64" 1.1.1.3 root 2487: [(set (match_operand:DF 0 "register_operand" "=e") 2488: (if_then_else (match_operator 1 "comparison_operator" 2489: [(match_operand:CCFP 2 "ccfp_reg_operand" "c") 2490: (const_int 0)]) 2491: (match_operand:DF 3 "register_operand" "e") 2492: (match_operand:DF 4 "register_operand" "0")))] 2493: "TARGET_V9 && TARGET_FPU" 2494: "fmovd%C1 %2,%3,%0" 2495: [(set_attr "type" "cmove")]) 2496: 1.1.1.4 ! root 2497: (define_insn "*movdf_ccfpe_sp64" 1.1.1.3 root 2498: [(set (match_operand:DF 0 "register_operand" "=e") 2499: (if_then_else (match_operator 1 "comparison_operator" 2500: [(match_operand:CCFPE 2 "ccfp_reg_operand" "c") 2501: (const_int 0)]) 2502: (match_operand:DF 3 "register_operand" "e") 2503: (match_operand:DF 4 "register_operand" "0")))] 2504: "TARGET_V9 && TARGET_FPU" 2505: "fmovd%C1 %2,%3,%0" 2506: [(set_attr "type" "cmove")]) 2507: 1.1.1.4 ! root 2508: (define_insn "*movtf_ccfp_sp64" 1.1.1.3 root 2509: [(set (match_operand:TF 0 "register_operand" "=e") 2510: (if_then_else (match_operator 1 "comparison_operator" 2511: [(match_operand:CCFP 2 "ccfp_reg_operand" "c") 2512: (const_int 0)]) 2513: (match_operand:TF 3 "register_operand" "e") 2514: (match_operand:TF 4 "register_operand" "0")))] 2515: "TARGET_V9 && TARGET_FPU" 2516: "fmovq%C1 %2,%3,%0" 2517: [(set_attr "type" "cmove")]) 2518: 1.1.1.4 ! root 2519: (define_insn "*movtf_ccfpe_sp64" 1.1.1.3 root 2520: [(set (match_operand:TF 0 "register_operand" "=e") 2521: (if_then_else (match_operator 1 "comparison_operator" 2522: [(match_operand:CCFPE 2 "ccfp_reg_operand" "c") 2523: (const_int 0)]) 2524: (match_operand:TF 3 "register_operand" "e") 2525: (match_operand:TF 4 "register_operand" "0")))] 2526: "TARGET_V9 && TARGET_FPU" 2527: "fmovq%C1 %2,%3,%0" 2528: [(set_attr "type" "cmove")]) 2529: 1.1.1.4 ! root 2530: (define_insn "*movsf_cc_sp64" 1.1.1.3 root 2531: [(set (match_operand:SF 0 "register_operand" "=f") 2532: (if_then_else (match_operator 1 "comparison_operator" 2533: [(reg:CC 0) (const_int 0)]) 2534: (match_operand:SF 2 "register_operand" "f") 2535: (match_operand:SF 3 "register_operand" "0")))] 2536: "TARGET_V9 && TARGET_FPU" 2537: "fmovs%C1 %%icc,%2,%0" 2538: [(set_attr "type" "cmove")]) 2539: 1.1.1.4 ! root 2540: (define_insn "*movdf_cc_sp64" 1.1.1.3 root 2541: [(set (match_operand:DF 0 "register_operand" "=e") 2542: (if_then_else (match_operator 1 "comparison_operator" 2543: [(reg:CC 0) (const_int 0)]) 2544: (match_operand:DF 2 "register_operand" "e") 2545: (match_operand:DF 3 "register_operand" "0")))] 2546: "TARGET_V9 && TARGET_FPU" 2547: "fmovd%C1 %%icc,%2,%0" 2548: [(set_attr "type" "cmove")]) 2549: 1.1.1.4 ! root 2550: (define_insn "*movtf_cc_sp64" 1.1.1.3 root 2551: [(set (match_operand:TF 0 "register_operand" "=e") 2552: (if_then_else (match_operator 1 "comparison_operator" 2553: [(reg:CC 0) (const_int 0)]) 2554: (match_operand:TF 2 "register_operand" "e") 2555: (match_operand:TF 3 "register_operand" "0")))] 2556: "TARGET_V9 && TARGET_FPU" 2557: "fmovq%C1 %%icc,%2,%0" 2558: [(set_attr "type" "cmove")]) 2559: 1.1.1.4 ! root 2560: (define_insn "*movsf_ccx_sp64" 1.1.1.3 root 2561: [(set (match_operand:SF 0 "register_operand" "=f") 2562: (if_then_else (match_operator 1 "comparison_operator" 2563: [(reg:CCX 0) (const_int 0)]) 2564: (match_operand:SF 2 "register_operand" "f") 2565: (match_operand:SF 3 "register_operand" "0")))] 2566: "TARGET_V9 && TARGET_FPU" 2567: "fmovs%C1 %%xcc,%2,%0" 2568: [(set_attr "type" "cmove")]) 2569: 1.1.1.4 ! root 2570: (define_insn "*movdf_ccx_sp64" 1.1.1.3 root 2571: [(set (match_operand:DF 0 "register_operand" "=e") 2572: (if_then_else (match_operator 1 "comparison_operator" 2573: [(reg:CCX 0) (const_int 0)]) 2574: (match_operand:DF 2 "register_operand" "e") 2575: (match_operand:DF 3 "register_operand" "0")))] 2576: "TARGET_V9 && TARGET_FPU" 2577: "fmovd%C1 %%xcc,%2,%0" 2578: [(set_attr "type" "cmove")]) 2579: 1.1.1.4 ! root 2580: (define_insn "*movtf_ccx_sp64" 1.1.1.3 root 2581: [(set (match_operand:TF 0 "register_operand" "=e") 2582: (if_then_else (match_operator 1 "comparison_operator" 2583: [(reg:CCX 0) (const_int 0)]) 2584: (match_operand:TF 2 "register_operand" "e") 2585: (match_operand:TF 3 "register_operand" "0")))] 2586: "TARGET_V9 && TARGET_FPU" 2587: "fmovq%C1 %%xcc,%2,%0" 2588: [(set_attr "type" "cmove")]) 2589: 1.1 root 2590: ;;- zero extension instructions 2591: 2592: ;; These patterns originally accepted general_operands, however, slightly 2593: ;; better code is generated by only accepting register_operands, and then 2594: ;; letting combine generate the ldu[hb] insns. 2595: 2596: (define_expand "zero_extendhisi2" 2597: [(set (match_operand:SI 0 "register_operand" "") 2598: (zero_extend:SI (match_operand:HI 1 "register_operand" "")))] 2599: "" 2600: " 2601: { 2602: rtx temp = gen_reg_rtx (SImode); 2603: rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16); 1.1.1.2 root 2604: int op1_subword = 0; 1.1 root 2605: 2606: if (GET_CODE (operand1) == SUBREG) 1.1.1.2 root 2607: { 2608: op1_subword = SUBREG_WORD (operand1); 2609: operand1 = XEXP (operand1, 0); 2610: } 1.1 root 2611: 1.1.1.2 root 2612: emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 2613: op1_subword), 1.1 root 2614: shift_16)); 2615: emit_insn (gen_lshrsi3 (operand0, temp, shift_16)); 2616: DONE; 2617: }") 2618: 1.1.1.4 ! root 2619: (define_insn "*zero_extendhisi2_insn" 1.1 root 2620: [(set (match_operand:SI 0 "register_operand" "=r") 2621: (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))] 2622: "" 2623: "lduh %1,%0" 2624: [(set_attr "type" "load")]) 2625: 2626: (define_expand "zero_extendqihi2" 2627: [(set (match_operand:HI 0 "register_operand" "") 2628: (zero_extend:HI (match_operand:QI 1 "register_operand" "")))] 2629: "" 2630: "") 2631: 1.1.1.4 ! root 2632: (define_insn "*zero_extendqihi2_insn" 1.1 root 2633: [(set (match_operand:HI 0 "register_operand" "=r,r") 2634: (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,Q")))] 2635: "GET_CODE (operands[1]) != CONST_INT" 2636: "@ 2637: and %1,0xff,%0 2638: ldub %1,%0" 2639: [(set_attr "type" "unary,load") 2640: (set_attr "length" "1")]) 2641: 2642: (define_expand "zero_extendqisi2" 2643: [(set (match_operand:SI 0 "register_operand" "") 2644: (zero_extend:SI (match_operand:QI 1 "register_operand" "")))] 2645: "" 2646: "") 2647: 1.1.1.4 ! root 2648: (define_insn "*zero_extendqisi2_insn" 1.1 root 2649: [(set (match_operand:SI 0 "register_operand" "=r,r") 2650: (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,Q")))] 2651: "GET_CODE (operands[1]) != CONST_INT" 2652: "@ 2653: and %1,0xff,%0 2654: ldub %1,%0" 2655: [(set_attr "type" "unary,load") 2656: (set_attr "length" "1")]) 2657: 1.1.1.3 root 2658: (define_expand "zero_extendqidi2" 2659: [(set (match_operand:DI 0 "register_operand" "") 2660: (zero_extend:DI (match_operand:QI 1 "register_operand" "")))] 2661: "TARGET_V9" 2662: "") 2663: 1.1.1.4 ! root 2664: (define_insn "*zero_extendqidi2_insn" 1.1.1.3 root 2665: [(set (match_operand:DI 0 "register_operand" "=r,r") 2666: (zero_extend:DI (match_operand:QI 1 "sparc_operand" "r,Q")))] 2667: "TARGET_V9 && GET_CODE (operands[1]) != CONST_INT" 2668: "@ 2669: and %1,0xff,%0 2670: ldub %1,%0" 2671: [(set_attr "type" "unary,load") 2672: (set_attr "length" "1")]) 2673: 2674: (define_expand "zero_extendhidi2" 2675: [(set (match_operand:DI 0 "register_operand" "") 2676: (zero_extend:DI (match_operand:HI 1 "register_operand" "")))] 2677: "TARGET_V9" 2678: " 2679: { 2680: rtx temp = gen_reg_rtx (DImode); 2681: rtx shift_48 = gen_rtx (CONST_INT, VOIDmode, 48); 2682: int op1_subword = 0; 2683: 2684: if (GET_CODE (operand1) == SUBREG) 2685: { 2686: op1_subword = SUBREG_WORD (operand1); 2687: operand1 = XEXP (operand1, 0); 2688: } 2689: 2690: emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1, 2691: op1_subword), 2692: shift_48)); 2693: emit_insn (gen_lshrdi3 (operand0, temp, shift_48)); 2694: DONE; 2695: }") 2696: 1.1.1.4 ! root 2697: (define_insn "*zero_extendhidi2_insn" 1.1.1.3 root 2698: [(set (match_operand:DI 0 "register_operand" "=r") 2699: (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))] 2700: "TARGET_V9" 2701: "lduh %1,%0" 2702: [(set_attr "type" "load")]) 2703: 2704: ;; ??? Write truncdisi pattern using sra? 2705: 2706: (define_expand "zero_extendsidi2" 2707: [(set (match_operand:DI 0 "register_operand" "") 2708: (zero_extend:DI (match_operand:SI 1 "register_operand" "")))] 2709: "TARGET_V9" 2710: "") 2711: 1.1.1.4 ! root 2712: (define_insn "*zero_extendsidi2_insn" 1.1.1.3 root 2713: [(set (match_operand:DI 0 "register_operand" "=r,r") 2714: (zero_extend:DI (match_operand:SI 1 "sparc_operand" "r,Q")))] 2715: "TARGET_V9 && GET_CODE (operands[1]) != CONST_INT" 2716: "@ 2717: srl %1,0,%0 2718: lduw %1,%0" 2719: [(set_attr "type" "unary,load") 2720: (set_attr "length" "1")]) 2721: 2722: ;; Simplify comparisons of extended values. 2723: 1.1.1.4 ! root 2724: (define_insn "*cmp_zero_extendqisi2" 1.1 root 2725: [(set (reg:CC 0) 2726: (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r")) 2727: (const_int 0)))] 2728: "" 2729: "andcc %0,0xff,%%g0" 2730: [(set_attr "type" "compare")]) 2731: 1.1.1.4 ! root 2732: (define_insn "*cmp_zero_extendqisi2_set" 1.1 root 2733: [(set (reg:CC 0) 2734: (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) 2735: (const_int 0))) 2736: (set (match_operand:SI 0 "register_operand" "=r") 2737: (zero_extend:SI (match_dup 1)))] 2738: "" 2739: "andcc %1,0xff,%0" 2740: [(set_attr "type" "unary")]) 2741: 2742: ;; Similarly, handle SI->QI mode truncation followed by a compare. 2743: 1.1.1.4 ! root 2744: (define_insn "*cmp_siqi_trunc" 1.1 root 2745: [(set (reg:CC 0) 2746: (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0) 2747: (const_int 0)))] 2748: "" 2749: "andcc %0,0xff,%%g0" 2750: [(set_attr "type" "compare")]) 2751: 1.1.1.4 ! root 2752: (define_insn "*cmp_siqi_trunc_set" 1.1 root 2753: [(set (reg:CC 0) 2754: (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0) 2755: (const_int 0))) 2756: (set (match_operand:QI 0 "register_operand" "=r") 2757: (match_dup 1))] 2758: "" 2759: "andcc %1,0xff,%0" 2760: [(set_attr "type" "unary")]) 2761: 2762: ;;- sign extension instructions 2763: 2764: ;; These patterns originally accepted general_operands, however, slightly 2765: ;; better code is generated by only accepting register_operands, and then 2766: ;; letting combine generate the lds[hb] insns. 2767: 2768: (define_expand "extendhisi2" 2769: [(set (match_operand:SI 0 "register_operand" "") 2770: (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] 2771: "" 2772: " 2773: { 2774: rtx temp = gen_reg_rtx (SImode); 2775: rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16); 1.1.1.2 root 2776: int op1_subword = 0; 1.1 root 2777: 2778: if (GET_CODE (operand1) == SUBREG) 1.1.1.2 root 2779: { 2780: op1_subword = SUBREG_WORD (operand1); 2781: operand1 = XEXP (operand1, 0); 2782: } 1.1 root 2783: 1.1.1.2 root 2784: emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 2785: op1_subword), 1.1 root 2786: shift_16)); 2787: emit_insn (gen_ashrsi3 (operand0, temp, shift_16)); 2788: DONE; 2789: }") 2790: 1.1.1.4 ! root 2791: (define_insn "*sign_extendhisi2_insn" 1.1 root 2792: [(set (match_operand:SI 0 "register_operand" "=r") 2793: (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))] 2794: "" 2795: "ldsh %1,%0" 2796: [(set_attr "type" "load")]) 2797: 2798: (define_expand "extendqihi2" 2799: [(set (match_operand:HI 0 "register_operand" "") 2800: (sign_extend:HI (match_operand:QI 1 "register_operand" "")))] 2801: "" 2802: " 2803: { 2804: rtx temp = gen_reg_rtx (SImode); 2805: rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24); 1.1.1.2 root 2806: int op1_subword = 0; 2807: int op0_subword = 0; 1.1 root 2808: 2809: if (GET_CODE (operand1) == SUBREG) 1.1.1.2 root 2810: { 2811: op1_subword = SUBREG_WORD (operand1); 2812: operand1 = XEXP (operand1, 0); 2813: } 1.1 root 2814: if (GET_CODE (operand0) == SUBREG) 1.1.1.2 root 2815: { 2816: op0_subword = SUBREG_WORD (operand0); 2817: operand0 = XEXP (operand0, 0); 2818: } 2819: emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 2820: op1_subword), 1.1 root 2821: shift_24)); 2822: if (GET_MODE (operand0) != SImode) 1.1.1.2 root 2823: operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subword); 1.1 root 2824: emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); 2825: DONE; 2826: }") 2827: 1.1.1.4 ! root 2828: (define_insn "*sign_extendqihi2_insn" 1.1 root 2829: [(set (match_operand:HI 0 "register_operand" "=r") 2830: (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))] 2831: "" 2832: "ldsb %1,%0" 2833: [(set_attr "type" "load")]) 2834: 2835: (define_expand "extendqisi2" 2836: [(set (match_operand:SI 0 "register_operand" "") 2837: (sign_extend:SI (match_operand:QI 1 "register_operand" "")))] 2838: "" 2839: " 2840: { 2841: rtx temp = gen_reg_rtx (SImode); 2842: rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24); 1.1.1.2 root 2843: int op1_subword = 0; 1.1 root 2844: 2845: if (GET_CODE (operand1) == SUBREG) 1.1.1.2 root 2846: { 2847: op1_subword = SUBREG_WORD (operand1); 2848: operand1 = XEXP (operand1, 0); 2849: } 2850: 2851: emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 2852: op1_subword), 1.1 root 2853: shift_24)); 2854: emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); 2855: DONE; 2856: }") 2857: 1.1.1.4 ! root 2858: (define_insn "*sign_extendqisi2_insn" 1.1 root 2859: [(set (match_operand:SI 0 "register_operand" "=r") 2860: (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))] 2861: "" 2862: "ldsb %1,%0" 2863: [(set_attr "type" "load")]) 1.1.1.3 root 2864: 2865: (define_expand "extendqidi2" 2866: [(set (match_operand:DI 0 "register_operand" "") 2867: (sign_extend:DI (match_operand:QI 1 "register_operand" "")))] 2868: "TARGET_V9" 2869: " 2870: { 2871: rtx temp = gen_reg_rtx (DImode); 2872: rtx shift_56 = gen_rtx (CONST_INT, VOIDmode, 56); 2873: int op1_subword = 0; 2874: 2875: if (GET_CODE (operand1) == SUBREG) 2876: { 2877: op1_subword = SUBREG_WORD (operand1); 2878: operand1 = XEXP (operand1, 0); 2879: } 2880: 2881: emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1, 2882: op1_subword), 2883: shift_56)); 2884: emit_insn (gen_ashrdi3 (operand0, temp, shift_56)); 2885: DONE; 2886: }") 2887: 1.1.1.4 ! root 2888: (define_insn "*sign_extendqidi2_insn" 1.1.1.3 root 2889: [(set (match_operand:DI 0 "register_operand" "=r") 2890: (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))] 2891: "TARGET_V9" 2892: "ldsb %1,%0" 2893: [(set_attr "type" "load")]) 2894: 2895: (define_expand "extendhidi2" 2896: [(set (match_operand:DI 0 "register_operand" "") 2897: (sign_extend:DI (match_operand:HI 1 "register_operand" "")))] 2898: "TARGET_V9" 2899: " 2900: { 2901: rtx temp = gen_reg_rtx (DImode); 2902: rtx shift_48 = gen_rtx (CONST_INT, VOIDmode, 48); 2903: int op1_subword = 0; 2904: 2905: if (GET_CODE (operand1) == SUBREG) 2906: { 2907: op1_subword = SUBREG_WORD (operand1); 2908: operand1 = XEXP (operand1, 0); 2909: } 2910: 2911: emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1, 2912: op1_subword), 2913: shift_48)); 2914: emit_insn (gen_ashrdi3 (operand0, temp, shift_48)); 2915: DONE; 2916: }") 2917: 1.1.1.4 ! root 2918: (define_insn "*sign_extendhidi2_insn" 1.1.1.3 root 2919: [(set (match_operand:DI 0 "register_operand" "=r") 2920: (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))] 2921: "TARGET_V9" 2922: "ldsh %1,%0" 2923: [(set_attr "type" "load")]) 2924: 2925: (define_expand "extendsidi2" 2926: [(set (match_operand:DI 0 "register_operand" "") 2927: (sign_extend:DI (match_operand:SI 1 "register_operand" "")))] 2928: "TARGET_V9" 2929: "") 2930: 1.1.1.4 ! root 2931: (define_insn "*sign_extendsidi2_insn" 1.1.1.3 root 2932: [(set (match_operand:DI 0 "register_operand" "=r,r") 2933: (sign_extend:DI (match_operand:SI 1 "sparc_operand" "r,Q")))] 2934: "TARGET_V9" 2935: "@ 2936: sra %1,0,%0 2937: ldsw %1,%0" 2938: [(set_attr "type" "unary,load") 2939: (set_attr "length" "1")]) 1.1 root 2940: 2941: ;; Special pattern for optimizing bit-field compares. This is needed 2942: ;; because combine uses this as a canonical form. 2943: 1.1.1.4 ! root 2944: (define_insn "*cmp_zero_extract" 1.1 root 2945: [(set (reg:CC 0) 2946: (compare:CC 2947: (zero_extract:SI (match_operand:SI 0 "register_operand" "r") 2948: (match_operand:SI 1 "small_int" "n") 2949: (match_operand:SI 2 "small_int" "n")) 2950: (const_int 0)))] 2951: "INTVAL (operands[2]) > 19" 2952: "* 2953: { 2954: int len = INTVAL (operands[1]); 2955: int pos = 32 - INTVAL (operands[2]) - len; 2956: unsigned mask = ((1 << len) - 1) << pos; 2957: 2958: operands[1] = gen_rtx (CONST_INT, VOIDmode, mask); 2959: return \"andcc %0,%1,%%g0\"; 2960: }") 1.1.1.3 root 2961: 1.1.1.4 ! root 2962: (define_insn "*cmp_zero_extract_sp64" 1.1.1.3 root 2963: [(set (reg:CCX 0) 2964: (compare:CCX 2965: (zero_extract:DI (match_operand:DI 0 "register_operand" "r") 2966: (match_operand:SI 1 "small_int" "n") 2967: (match_operand:SI 2 "small_int" "n")) 2968: (const_int 0)))] 2969: "TARGET_V9 && INTVAL (operands[2]) > 51" 2970: "* 2971: { 2972: int len = INTVAL (operands[1]); 2973: int pos = 64 - INTVAL (operands[2]) - len; 2974: unsigned mask = ((1 << len) - 1) << pos; 2975: 2976: operands[1] = gen_rtx (CONST_INT, VOIDmode, mask); 2977: return \"andcc %0,%1,%%g0\"; 2978: }") 1.1 root 2979: 2980: ;; Conversions between float, double and long double. 2981: 2982: (define_insn "extendsfdf2" 1.1.1.3 root 2983: [(set (match_operand:DF 0 "register_operand" "=e") 1.1 root 2984: (float_extend:DF 2985: (match_operand:SF 1 "register_operand" "f")))] 2986: "TARGET_FPU" 2987: "fstod %1,%0" 2988: [(set_attr "type" "fp")]) 2989: 2990: (define_insn "extendsftf2" 1.1.1.3 root 2991: [(set (match_operand:TF 0 "register_operand" "=e") 1.1 root 2992: (float_extend:TF 2993: (match_operand:SF 1 "register_operand" "f")))] 1.1.1.3 root 2994: "TARGET_FPU && TARGET_HARD_QUAD" 1.1 root 2995: "fstoq %1,%0" 2996: [(set_attr "type" "fp")]) 2997: 2998: (define_insn "extenddftf2" 1.1.1.3 root 2999: [(set (match_operand:TF 0 "register_operand" "=e") 1.1 root 3000: (float_extend:TF 1.1.1.3 root 3001: (match_operand:DF 1 "register_operand" "e")))] 3002: "TARGET_FPU && TARGET_HARD_QUAD" 1.1 root 3003: "fdtoq %1,%0" 3004: [(set_attr "type" "fp")]) 3005: 3006: (define_insn "truncdfsf2" 3007: [(set (match_operand:SF 0 "register_operand" "=f") 3008: (float_truncate:SF 1.1.1.3 root 3009: (match_operand:DF 1 "register_operand" "e")))] 1.1 root 3010: "TARGET_FPU" 3011: "fdtos %1,%0" 3012: [(set_attr "type" "fp")]) 3013: 3014: (define_insn "trunctfsf2" 3015: [(set (match_operand:SF 0 "register_operand" "=f") 3016: (float_truncate:SF 1.1.1.3 root 3017: (match_operand:TF 1 "register_operand" "e")))] 3018: "TARGET_FPU && TARGET_HARD_QUAD" 1.1 root 3019: "fqtos %1,%0" 3020: [(set_attr "type" "fp")]) 3021: 3022: (define_insn "trunctfdf2" 1.1.1.3 root 3023: [(set (match_operand:DF 0 "register_operand" "=e") 1.1 root 3024: (float_truncate:DF 1.1.1.3 root 3025: (match_operand:TF 1 "register_operand" "e")))] 3026: "TARGET_FPU && TARGET_HARD_QUAD" 1.1 root 3027: "fqtod %1,%0" 3028: [(set_attr "type" "fp")]) 3029: 3030: ;; Conversion between fixed point and floating point. 3031: 3032: (define_insn "floatsisf2" 3033: [(set (match_operand:SF 0 "register_operand" "=f") 3034: (float:SF (match_operand:SI 1 "register_operand" "f")))] 3035: "TARGET_FPU" 3036: "fitos %1,%0" 3037: [(set_attr "type" "fp")]) 3038: 1.1.1.3 root 3039: (define_insn "floatsidf2" 3040: [(set (match_operand:DF 0 "register_operand" "=e") 3041: (float:DF (match_operand:SI 1 "register_operand" "f")))] 3042: "TARGET_FPU" 3043: "fitod %1,%0" 3044: [(set_attr "type" "fp")]) 3045: 3046: (define_insn "floatsitf2" 3047: [(set (match_operand:TF 0 "register_operand" "=e") 3048: (float:TF (match_operand:SI 1 "register_operand" "f")))] 3049: "TARGET_FPU && TARGET_HARD_QUAD" 3050: "fitoq %1,%0" 3051: [(set_attr "type" "fp")]) 3052: 3053: ;; Now the same for 64 bit sources. 3054: ;; ??? We cannot put DImode values in fp regs (see below near fix_truncdfsi2). 3055: 3056: (define_expand "floatdisf2" 3057: [(parallel [(set (match_operand:SF 0 "register_operand" "") 3058: (float:SF (match_operand:DI 1 "general_operand" ""))) 3059: (clobber (match_dup 2)) 3060: (clobber (match_dup 3))])] 3061: "TARGET_V9 && TARGET_FPU" 3062: " 3063: { 3064: operands[2] = gen_reg_rtx (DFmode); 3065: operands[3] = sparc64_fpconv_stack_temp (); 3066: }") 3067: 3068: (define_expand "floatdidf2" 3069: [(parallel [(set (match_operand:DF 0 "register_operand" "") 3070: (float:DF (match_operand:DI 1 "general_operand" ""))) 3071: (clobber (match_dup 2)) 3072: (clobber (match_dup 3))])] 3073: "TARGET_V9 && TARGET_FPU" 3074: " 3075: { 3076: operands[2] = gen_reg_rtx (DFmode); 3077: operands[3] = sparc64_fpconv_stack_temp (); 3078: }") 3079: 3080: (define_expand "floatditf2" 3081: [(parallel [(set (match_operand:TF 0 "register_operand" "") 3082: (float:TF (match_operand:DI 1 "general_operand" ""))) 3083: (clobber (match_dup 2)) 3084: (clobber (match_dup 3))])] 3085: "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" 3086: " 3087: { 3088: operands[2] = gen_reg_rtx (DFmode); 3089: operands[3] = sparc64_fpconv_stack_temp (); 3090: }") 3091: 1.1.1.4 ! root 3092: (define_insn "*floatdisf2_insn" 1.1.1.3 root 3093: [(parallel [(set (match_operand:SF 0 "register_operand" "=f") 3094: (float:SF (match_operand:DI 1 "general_operand" "rm"))) 3095: (clobber (match_operand:DF 2 "register_operand" "=&e")) 3096: (clobber (match_operand:DI 3 "memory_operand" "m"))])] 3097: "TARGET_V9 && TARGET_FPU" 3098: "* 3099: { 3100: if (GET_CODE (operands[1]) == MEM) 3101: output_asm_insn (\"ldd %1,%2\", operands); 3102: else 3103: output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands); 3104: return \"fxtos %2,%0\"; 3105: }" 3106: [(set_attr "type" "fp") 3107: (set_attr "length" "3")]) 3108: 1.1.1.4 ! root 3109: (define_insn "*floatdidf2_insn" 1.1.1.3 root 3110: [(parallel [(set (match_operand:DF 0 "register_operand" "=e") 3111: (float:DF (match_operand:DI 1 "general_operand" "rm"))) 3112: (clobber (match_operand:DF 2 "register_operand" "=&e")) 3113: (clobber (match_operand:DI 3 "memory_operand" "m"))])] 3114: "TARGET_V9 && TARGET_FPU" 3115: "* 3116: { 3117: if (GET_CODE (operands[1]) == MEM) 3118: output_asm_insn (\"ldd %1,%2\", operands); 3119: else 3120: output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands); 3121: return \"fxtod %2,%0\"; 3122: }" 3123: [(set_attr "type" "fp") 3124: (set_attr "length" "3")]) 3125: 1.1.1.4 ! root 3126: (define_insn "*floatditf2_insn" 1.1.1.3 root 3127: [(parallel [(set (match_operand:TF 0 "register_operand" "=e") 3128: (float:TF (match_operand:DI 1 "general_operand" "rm"))) 3129: (clobber (match_operand:DF 2 "register_operand" "=&e")) 3130: (clobber (match_operand:DI 3 "memory_operand" "m"))])] 3131: "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" 3132: "* 3133: { 3134: if (GET_CODE (operands[1]) == MEM) 3135: output_asm_insn (\"ldd %1,%2\", operands); 3136: else 3137: output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands); 3138: return \"fxtoq %2,%0\"; 3139: }" 3140: [(set_attr "type" "fp") 3141: (set_attr "length" "3")]) 3142: 3143: ;; ??? Ideally, these are what we would like to use. 3144: 1.1.1.4 ! root 3145: (define_insn "floatdisf2_sp64" 1.1.1.3 root 3146: [(set (match_operand:SF 0 "register_operand" "=f") 3147: (float:SF (match_operand:DI 1 "register_operand" "e")))] 3148: "0 && TARGET_V9 && TARGET_FPU" 3149: "fxtos %1,%0" 3150: [(set_attr "type" "fp")]) 3151: 1.1.1.4 ! root 3152: (define_insn "floatdidf2_sp64" 1.1.1.3 root 3153: [(set (match_operand:DF 0 "register_operand" "=e") 3154: (float:DF (match_operand:DI 1 "register_operand" "e")))] 3155: "0 && TARGET_V9 && TARGET_FPU" 3156: "fxtod %1,%0" 3157: [(set_attr "type" "fp")]) 3158: 1.1.1.4 ! root 3159: (define_insn "floatditf2_sp64" 1.1.1.3 root 3160: [(set (match_operand:TF 0 "register_operand" "=e") 3161: (float:TF (match_operand:DI 1 "register_operand" "e")))] 3162: "0 && TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" 3163: "fxtoq %1,%0" 3164: [(set_attr "type" "fp")]) 3165: 3166: ;; Convert a float to an actual integer. 3167: ;; Truncation is performed as part of the conversion. 3168: 3169: (define_insn "fix_truncsfsi2" 3170: [(set (match_operand:SI 0 "register_operand" "=f") 3171: (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] 3172: "TARGET_FPU" 3173: "fstoi %1,%0" 3174: [(set_attr "type" "fp")]) 3175: 3176: (define_insn "fix_truncdfsi2" 3177: [(set (match_operand:SI 0 "register_operand" "=f") 3178: (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))] 3179: "TARGET_FPU" 3180: "fdtoi %1,%0" 3181: [(set_attr "type" "fp")]) 3182: 3183: (define_insn "fix_trunctfsi2" 3184: [(set (match_operand:SI 0 "register_operand" "=f") 3185: (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))] 3186: "TARGET_FPU && TARGET_HARD_QUAD" 3187: "fqtoi %1,%0" 3188: [(set_attr "type" "fp")]) 3189: 3190: ;; Now the same, for 64-bit targets 3191: ;; ??? We try to work around an interesting problem. 3192: ;; If gcc tries to do a subreg on the result it will get the wrong answer: 3193: ;; "(subreg:SI (reg:DI M int-reg) 0)" is the same as 3194: ;; "(subreg:SI (reg:DI N float-reg) 1)", but gcc does not know how to change 3195: ;; the "0" to a "1". One could enhance alter_subreg but it is not clear how to 3196: ;; do this cleanly. 3197: 3198: (define_expand "fix_truncsfdi2" 3199: [(parallel [(set (match_operand:DI 0 "general_operand" "") 3200: (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "")))) 3201: (clobber (match_dup 2)) 3202: (clobber (match_dup 3))])] 3203: "TARGET_V9 && TARGET_FPU" 3204: " 3205: { 3206: operands[2] = gen_reg_rtx (DFmode); 3207: operands[3] = sparc64_fpconv_stack_temp (); 3208: }") 3209: 3210: (define_expand "fix_truncdfdi2" 3211: [(parallel [(set (match_operand:DI 0 "general_operand" "") 3212: (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "")))) 3213: (clobber (match_dup 2)) 3214: (clobber (match_dup 3))])] 3215: "TARGET_V9 && TARGET_FPU" 3216: " 3217: { 3218: operands[2] = gen_reg_rtx (DFmode); 3219: operands[3] = sparc64_fpconv_stack_temp (); 3220: }") 3221: 3222: (define_expand "fix_trunctfdi2" 3223: [(parallel [(set (match_operand:DI 0 "general_operand" "") 3224: (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "")))) 3225: (clobber (match_dup 2)) 3226: (clobber (match_dup 3))])] 3227: "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" 3228: " 3229: { 3230: operands[2] = gen_reg_rtx (DFmode); 3231: operands[3] = sparc64_fpconv_stack_temp (); 3232: }") 3233: 1.1.1.4 ! root 3234: (define_insn "*fix_truncsfdi2_insn" 1.1.1.3 root 3235: [(parallel [(set (match_operand:DI 0 "general_operand" "=rm") 3236: (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f")))) 3237: (clobber (match_operand:DF 2 "register_operand" "=&e")) 3238: (clobber (match_operand:DI 3 "memory_operand" "m"))])] 3239: "TARGET_V9 && TARGET_FPU" 3240: "* 3241: { 3242: output_asm_insn (\"fstox %1,%2\", operands); 3243: if (GET_CODE (operands[0]) == MEM) 3244: return \"std %2,%0\"; 3245: else 3246: return \"std %2,%3\;ldx %3,%0\"; 3247: }" 3248: [(set_attr "type" "fp") 3249: (set_attr "length" "3")]) 3250: 1.1.1.4 ! root 3251: (define_insn "*fix_truncdfdi2_insn" 1.1.1.3 root 3252: [(parallel [(set (match_operand:DI 0 "general_operand" "=rm") 3253: (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e")))) 3254: (clobber (match_operand:DF 2 "register_operand" "=&e")) 3255: (clobber (match_operand:DI 3 "memory_operand" "m"))])] 3256: "TARGET_V9 && TARGET_FPU" 3257: "* 3258: { 3259: output_asm_insn (\"fdtox %1,%2\", operands); 3260: if (GET_CODE (operands[0]) == MEM) 3261: return \"std %2,%0\"; 3262: else 3263: return \"std %2,%3\;ldx %3,%0\"; 3264: }" 3265: [(set_attr "type" "fp") 3266: (set_attr "length" "3")]) 1.1 root 3267: 1.1.1.4 ! root 3268: (define_insn "*fix_trunctfdi2_insn" 1.1.1.3 root 3269: [(parallel [(set (match_operand:DI 0 "general_operand" "=rm") 3270: (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e")))) 3271: (clobber (match_operand:DF 2 "register_operand" "=&e")) 3272: (clobber (match_operand:DI 3 "memory_operand" "m"))])] 3273: "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" 3274: "* 3275: { 3276: output_asm_insn (\"fqtox %1,%2\", operands); 3277: if (GET_CODE (operands[0]) == MEM) 3278: return \"std %2,%0\"; 3279: else 3280: return \"std %2,%3\;ldx %3,%0\"; 3281: }" 3282: [(set_attr "type" "fp") 3283: (set_attr "length" "3")]) 1.1 root 3284: 1.1.1.3 root 3285: ;; ??? Ideally, these are what we would like to use. 1.1 root 3286: 1.1.1.4 ! root 3287: (define_insn "fix_truncsfdi2_sp64" 1.1.1.3 root 3288: [(set (match_operand:DI 0 "register_operand" "=e") 3289: (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] 3290: "0 && TARGET_V9 && TARGET_FPU" 3291: "fstox %1,%0" 1.1 root 3292: [(set_attr "type" "fp")]) 3293: 1.1.1.4 ! root 3294: (define_insn "fix_truncdfdi2_sp64" 1.1.1.3 root 3295: [(set (match_operand:DI 0 "register_operand" "=e") 3296: (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))] 3297: "0 && TARGET_V9 && TARGET_FPU" 3298: "fdtox %1,%0" 1.1 root 3299: [(set_attr "type" "fp")]) 3300: 1.1.1.4 ! root 3301: (define_insn "fix_trunctfdi2_sp64" 1.1.1.3 root 3302: [(set (match_operand:DI 0 "register_operand" "=e") 3303: (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))] 3304: "0 && TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" 3305: "fqtox %1,%0" 1.1 root 3306: [(set_attr "type" "fp")]) 3307: 3308: ;;- arithmetic instructions 3309: 1.1.1.3 root 3310: (define_expand "adddi3" 3311: [(set (match_operand:DI 0 "register_operand" "=r") 3312: (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") 3313: (match_operand:DI 2 "arith_double_operand" "rHI")))] 3314: "" 3315: " 3316: { 3317: if (! TARGET_V9) 3318: { 3319: emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, 3320: gen_rtx (SET, VOIDmode, operands[0], 3321: gen_rtx (PLUS, DImode, operands[1], 3322: operands[2])), 3323: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0))))); 3324: DONE; 3325: } 3326: }") 3327: 1.1.1.4 ! root 3328: (define_insn "*adddi3_sp32" 1.1 root 3329: [(set (match_operand:DI 0 "register_operand" "=r") 3330: (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") 3331: (match_operand:DI 2 "arith_double_operand" "rHI"))) 3332: (clobber (reg:SI 0))] 1.1.1.3 root 3333: "! TARGET_V9" 1.1 root 3334: "* 3335: { 3336: rtx op2 = operands[2]; 3337: 3338: /* If constant is positive, upper bits zeroed, otherwise unchanged. 3339: Give the assembler a chance to pick the move instruction. */ 3340: if (GET_CODE (op2) == CONST_INT) 3341: { 3342: int sign = INTVAL (op2); 3343: if (sign < 0) 3344: return \"addcc %R1,%2,%R0\;addx %1,-1,%0\"; 3345: return \"addcc %R1,%2,%R0\;addx %1,0,%0\"; 3346: } 3347: else if (GET_CODE (op2) == CONST_DOUBLE) 3348: { 1.1.1.3 root 3349: rtx xoperands[4]; 3350: xoperands[0] = operands[0]; 3351: xoperands[1] = operands[1]; 3352: xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2)); 3353: xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2)); 3354: if (xoperands[2] == const0_rtx && xoperands[0] == xoperands[1]) 3355: output_asm_insn (\"add %1,%3,%0\", xoperands); 3356: else 3357: output_asm_insn (\"addcc %R1,%2,%R0\;addx %1,%3,%0\", xoperands); 3358: return \"\"; 1.1 root 3359: } 3360: return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\"; 3361: }" 3362: [(set_attr "length" "2")]) 3363: 1.1.1.4 ! root 3364: (define_insn "*adddi3_sp64" 1.1.1.3 root 3365: [(set (match_operand:DI 0 "register_operand" "=r") 3366: (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") 3367: (match_operand:DI 2 "arith_double_operand" "rHI")))] 3368: "TARGET_V9" 3369: "add %1,%2,%0") 3370: 1.1 root 3371: (define_insn "addsi3" 3372: [(set (match_operand:SI 0 "register_operand" "=r") 3373: (plus:SI (match_operand:SI 1 "arith_operand" "%r") 3374: (match_operand:SI 2 "arith_operand" "rI")))] 3375: "" 1.1.1.3 root 3376: "add %1,%2,%0" 3377: [(set_attr "type" "ialu")]) 1.1 root 3378: 1.1.1.4 ! root 3379: (define_insn "*cmp_cc_plus" 1.1 root 3380: [(set (reg:CC_NOOV 0) 3381: (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r") 3382: (match_operand:SI 1 "arith_operand" "rI")) 3383: (const_int 0)))] 3384: "" 3385: "addcc %0,%1,%%g0" 3386: [(set_attr "type" "compare")]) 3387: 1.1.1.4 ! root 3388: (define_insn "*cmp_ccx_plus" 1.1.1.3 root 3389: [(set (reg:CCX_NOOV 0) 3390: (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r") 3391: (match_operand:DI 1 "arith_double_operand" "rHI")) 3392: (const_int 0)))] 3393: "TARGET_V9" 3394: "addcc %0,%1,%%g0" 3395: [(set_attr "type" "compare")]) 3396: 1.1.1.4 ! root 3397: (define_insn "*cmp_cc_plus_set" 1.1 root 3398: [(set (reg:CC_NOOV 0) 3399: (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r") 3400: (match_operand:SI 2 "arith_operand" "rI")) 3401: (const_int 0))) 3402: (set (match_operand:SI 0 "register_operand" "=r") 3403: (plus:SI (match_dup 1) (match_dup 2)))] 3404: "" 3405: "addcc %1,%2,%0") 3406: 1.1.1.4 ! root 3407: (define_insn "*cmp_ccx_plus_set" 1.1.1.3 root 3408: [(set (reg:CCX_NOOV 0) 3409: (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") 3410: (match_operand:DI 2 "arith_double_operand" "rHI")) 3411: (const_int 0))) 3412: (set (match_operand:DI 0 "register_operand" "=r") 3413: (plus:DI (match_dup 1) (match_dup 2)))] 3414: "TARGET_V9" 3415: "addcc %1,%2,%0") 3416: 3417: (define_expand "subdi3" 3418: [(set (match_operand:DI 0 "register_operand" "=r") 3419: (minus:DI (match_operand:DI 1 "register_operand" "r") 3420: (match_operand:DI 2 "arith_double_operand" "rHI")))] 3421: "" 3422: " 3423: { 3424: if (! TARGET_V9) 3425: { 3426: emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, 3427: gen_rtx (SET, VOIDmode, operands[0], 3428: gen_rtx (MINUS, DImode, operands[1], 3429: operands[2])), 3430: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0))))); 3431: DONE; 3432: } 3433: }") 3434: 1.1.1.4 ! root 3435: (define_insn "*subdi3_sp32" 1.1 root 3436: [(set (match_operand:DI 0 "register_operand" "=r") 3437: (minus:DI (match_operand:DI 1 "register_operand" "r") 3438: (match_operand:DI 2 "arith_double_operand" "rHI"))) 3439: (clobber (reg:SI 0))] 1.1.1.3 root 3440: "! TARGET_V9" 1.1 root 3441: "* 3442: { 3443: rtx op2 = operands[2]; 3444: 3445: /* If constant is positive, upper bits zeroed, otherwise unchanged. 3446: Give the assembler a chance to pick the move instruction. */ 3447: if (GET_CODE (op2) == CONST_INT) 3448: { 3449: int sign = INTVAL (op2); 3450: if (sign < 0) 3451: return \"subcc %R1,%2,%R0\;subx %1,-1,%0\"; 3452: return \"subcc %R1,%2,%R0\;subx %1,0,%0\"; 3453: } 3454: else if (GET_CODE (op2) == CONST_DOUBLE) 3455: { 1.1.1.3 root 3456: rtx xoperands[4]; 3457: xoperands[0] = operands[0]; 3458: xoperands[1] = operands[1]; 3459: xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2)); 3460: xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2)); 3461: if (xoperands[2] == const0_rtx && xoperands[0] == xoperands[1]) 3462: output_asm_insn (\"sub %1,%3,%0\", xoperands); 3463: else 3464: output_asm_insn (\"subcc %R1,%2,%R0\;subx %1,%3,%0\", xoperands); 3465: return \"\"; 1.1 root 3466: } 3467: return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\"; 3468: }" 3469: [(set_attr "length" "2")]) 3470: 1.1.1.4 ! root 3471: (define_insn "*subdi3_sp64" 1.1.1.3 root 3472: [(set (match_operand:DI 0 "register_operand" "=r") 3473: (minus:DI (match_operand:DI 1 "register_operand" "r") 3474: (match_operand:DI 2 "arith_double_operand" "rHI")))] 3475: "TARGET_V9" 3476: "sub %1,%2,%0") 3477: 1.1 root 3478: (define_insn "subsi3" 3479: [(set (match_operand:SI 0 "register_operand" "=r") 3480: (minus:SI (match_operand:SI 1 "register_operand" "r") 3481: (match_operand:SI 2 "arith_operand" "rI")))] 3482: "" 1.1.1.3 root 3483: "sub %1,%2,%0" 3484: [(set_attr "type" "ialu")]) 1.1 root 3485: 1.1.1.4 ! root 3486: (define_insn "*cmp_minus_cc" 1.1 root 3487: [(set (reg:CC_NOOV 0) 3488: (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r") 3489: (match_operand:SI 1 "arith_operand" "rI")) 3490: (const_int 0)))] 3491: "" 3492: "subcc %0,%1,%%g0" 3493: [(set_attr "type" "compare")]) 3494: 1.1.1.4 ! root 3495: (define_insn "*cmp_minus_ccx" 1.1.1.3 root 3496: [(set (reg:CCX_NOOV 0) 3497: (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r") 3498: (match_operand:DI 1 "arith_double_operand" "rHI")) 3499: (const_int 0)))] 3500: "TARGET_V9" 3501: "subcc %0,%1,%%g0" 3502: [(set_attr "type" "compare")]) 3503: 1.1.1.4 ! root 3504: (define_insn "*cmp_minus_cc_set" 1.1 root 3505: [(set (reg:CC_NOOV 0) 3506: (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r") 3507: (match_operand:SI 2 "arith_operand" "rI")) 3508: (const_int 0))) 3509: (set (match_operand:SI 0 "register_operand" "=r") 3510: (minus:SI (match_dup 1) (match_dup 2)))] 3511: "" 3512: "subcc %1,%2,%0") 3513: 1.1.1.4 ! root 3514: (define_insn "*cmp_minus_ccx_set" 1.1.1.3 root 3515: [(set (reg:CCX_NOOV 0) 3516: (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r") 3517: (match_operand:DI 2 "arith_double_operand" "rHI")) 3518: (const_int 0))) 3519: (set (match_operand:DI 0 "register_operand" "=r") 3520: (minus:DI (match_dup 1) (match_dup 2)))] 3521: "TARGET_V9" 3522: "subcc %1,%2,%0") 3523: 3524: ;; This is anachronistic, and should not be used in v9 software. 3525: ;; The v9 compiler will widen the args and use muldi3. 3526: 1.1 root 3527: (define_insn "mulsi3" 3528: [(set (match_operand:SI 0 "register_operand" "=r") 3529: (mult:SI (match_operand:SI 1 "arith_operand" "%r") 3530: (match_operand:SI 2 "arith_operand" "rI")))] 3531: "TARGET_V8 || TARGET_SPARCLITE" 1.1.1.3 root 3532: "smul %1,%2,%0" 3533: [(set_attr "type" "imul")]) 3534: 3535: (define_insn "muldi3" 3536: [(set (match_operand:DI 0 "register_operand" "=r") 3537: (mult:DI (match_operand:DI 1 "arith_double_operand" "%r") 3538: (match_operand:DI 2 "arith_double_operand" "rHI")))] 3539: "TARGET_V9" 3540: "mulx %1,%2,%0") 1.1 root 3541: 3542: ;; It is not known whether this will match. 3543: 1.1.1.4 ! root 3544: (define_insn "*cmp_mul_set" 1.1 root 3545: [(set (match_operand:SI 0 "register_operand" "=r") 3546: (mult:SI (match_operand:SI 1 "arith_operand" "%r") 3547: (match_operand:SI 2 "arith_operand" "rI"))) 3548: (set (reg:CC_NOOV 0) 3549: (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2)) 3550: (const_int 0)))] 3551: "TARGET_V8 || TARGET_SPARCLITE" 1.1.1.3 root 3552: "smulcc %1,%2,%0" 3553: [(set_attr "type" "imul")]) 1.1 root 3554: 3555: (define_expand "mulsidi3" 3556: [(set (match_operand:DI 0 "register_operand" "") 3557: (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) 3558: (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))] 3559: "TARGET_V8 || TARGET_SPARCLITE" 3560: " 3561: { 3562: if (CONSTANT_P (operands[2])) 3563: { 3564: emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2])); 3565: DONE; 3566: } 3567: }") 3568: 1.1.1.4 ! root 3569: (define_insn "*mulsidi3_sp32" 1.1 root 3570: [(set (match_operand:DI 0 "register_operand" "=r") 3571: (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) 3572: (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))] 3573: "TARGET_V8 || TARGET_SPARCLITE" 3574: "smul %1,%2,%R0\;rd %%y,%0" 3575: [(set_attr "length" "2")]) 3576: 1.1.1.4 ! root 3577: ;; Extra pattern, because sign_extend of a constant isn't valid. 1.1 root 3578: 3579: (define_insn "const_mulsidi3" 3580: [(set (match_operand:DI 0 "register_operand" "=r") 3581: (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) 3582: (match_operand:SI 2 "small_int" "I")))] 3583: "TARGET_V8 || TARGET_SPARCLITE" 3584: "smul %1,%2,%R0\;rd %%y,%0" 3585: [(set_attr "length" "2")]) 3586: 1.1.1.3 root 3587: (define_expand "smulsi3_highpart" 3588: [(set (match_operand:SI 0 "register_operand" "") 3589: (truncate:SI 3590: (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) 3591: (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))) 3592: (const_int 32))))] 3593: "TARGET_V8 || TARGET_SPARCLITE" 3594: " 3595: { 3596: if (CONSTANT_P (operands[2])) 3597: { 3598: emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2])); 3599: DONE; 3600: } 3601: }") 3602: 1.1.1.4 ! root 3603: (define_insn "*smulsidi3_highpart_sp32" 1.1.1.3 root 3604: [(set (match_operand:SI 0 "register_operand" "=r") 3605: (truncate:SI 3606: (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) 3607: (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))) 3608: (const_int 32))))] 3609: "TARGET_V8 || TARGET_SPARCLITE" 3610: "smul %1,%2,%%g0\;rd %%y,%0" 3611: [(set_attr "length" "2")]) 3612: 3613: (define_insn "const_smulsi3_highpart" 3614: [(set (match_operand:SI 0 "register_operand" "=r") 3615: (truncate:SI 3616: (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) 3617: (match_operand:SI 2 "register_operand" "r")) 3618: (const_int 32))))] 3619: "TARGET_V8 || TARGET_SPARCLITE" 3620: "smul %1,%2,%%g0\;rd %%y,%0" 3621: [(set_attr "length" "2")]) 3622: 1.1 root 3623: (define_expand "umulsidi3" 3624: [(set (match_operand:DI 0 "register_operand" "") 3625: (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) 1.1.1.2 root 3626: (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))] 1.1 root 3627: "TARGET_V8 || TARGET_SPARCLITE" 3628: " 3629: { 3630: if (CONSTANT_P (operands[2])) 3631: { 3632: emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2])); 3633: DONE; 3634: } 3635: }") 3636: 1.1.1.4 ! root 3637: (define_insn "*umulsidi3_sp32" 1.1 root 3638: [(set (match_operand:DI 0 "register_operand" "=r") 3639: (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) 3640: (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))] 3641: "TARGET_V8 || TARGET_SPARCLITE" 3642: "umul %1,%2,%R0\;rd %%y,%0" 3643: [(set_attr "length" "2")]) 3644: 1.1.1.4 ! root 3645: ;; Extra pattern, because sign_extend of a constant isn't valid. 1.1 root 3646: 3647: (define_insn "const_umulsidi3" 3648: [(set (match_operand:DI 0 "register_operand" "=r") 3649: (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) 1.1.1.2 root 3650: (match_operand:SI 2 "uns_small_int" "")))] 1.1 root 3651: "TARGET_V8 || TARGET_SPARCLITE" 3652: "umul %1,%2,%R0\;rd %%y,%0" 3653: [(set_attr "length" "2")]) 3654: 1.1.1.3 root 3655: (define_expand "umulsi3_highpart" 3656: [(set (match_operand:SI 0 "register_operand" "") 3657: (truncate:SI 3658: (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) 3659: (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))) 3660: (const_int 32))))] 3661: "TARGET_V8 || TARGET_SPARCLITE" 3662: " 3663: { 3664: if (CONSTANT_P (operands[2])) 3665: { 3666: emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2])); 3667: DONE; 3668: } 3669: }") 3670: 1.1.1.4 ! root 3671: (define_insn "*umulsidi3_highpart_sp32" 1.1.1.3 root 3672: [(set (match_operand:SI 0 "register_operand" "=r") 3673: (truncate:SI 3674: (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) 3675: (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))) 3676: (const_int 32))))] 3677: "TARGET_V8 || TARGET_SPARCLITE" 3678: "umul %1,%2,%%g0\;rd %%y,%0" 3679: [(set_attr "length" "2")]) 3680: 3681: (define_insn "const_umulsi3_highpart" 3682: [(set (match_operand:SI 0 "register_operand" "=r") 3683: (truncate:SI 3684: (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) 3685: (match_operand:SI 2 "uns_small_int" "")) 3686: (const_int 32))))] 3687: "TARGET_V8 || TARGET_SPARCLITE" 3688: "umul %1,%2,%%g0\;rd %%y,%0" 3689: [(set_attr "length" "2")]) 3690: 1.1 root 3691: ;; The architecture specifies that there must be 3 instructions between 3692: ;; a y register write and a use of it for correct results. 3693: 3694: (define_insn "divsi3" 3695: [(set (match_operand:SI 0 "register_operand" "=r") 3696: (div:SI (match_operand:SI 1 "register_operand" "r") 3697: (match_operand:SI 2 "arith_operand" "rI"))) 3698: (clobber (match_scratch:SI 3 "=&r"))] 3699: "TARGET_V8" 3700: "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0" 3701: [(set_attr "length" "6")]) 3702: 1.1.1.3 root 3703: (define_insn "divdi3" 3704: [(set (match_operand:DI 0 "register_operand" "=r") 3705: (div:DI (match_operand:DI 1 "register_operand" "r") 3706: (match_operand:DI 2 "arith_double_operand" "rHI")))] 3707: "TARGET_V9" 3708: "sdivx %1,%2,%0") 3709: 1.1 root 3710: ;; It is not known whether this will match. 3711: 1.1.1.4 ! root 3712: (define_insn "*cmp_sdiv_cc_set" 1.1 root 3713: [(set (match_operand:SI 0 "register_operand" "=r") 3714: (div:SI (match_operand:SI 1 "register_operand" "r") 3715: (match_operand:SI 2 "arith_operand" "rI"))) 3716: (set (reg:CC 0) 3717: (compare:CC (div:SI (match_dup 1) (match_dup 2)) 3718: (const_int 0))) 3719: (clobber (match_scratch:SI 3 "=&r"))] 3720: "TARGET_V8" 3721: "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0" 3722: [(set_attr "length" "6")]) 3723: 3724: (define_insn "udivsi3" 3725: [(set (match_operand:SI 0 "register_operand" "=r") 3726: (udiv:SI (match_operand:SI 1 "register_operand" "r") 3727: (match_operand:SI 2 "arith_operand" "rI")))] 3728: "TARGET_V8" 3729: "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0" 3730: [(set_attr "length" "5")]) 3731: 1.1.1.3 root 3732: (define_insn "udivdi3" 3733: [(set (match_operand:DI 0 "register_operand" "=r") 3734: (udiv:DI (match_operand:DI 1 "register_operand" "r") 3735: (match_operand:DI 2 "arith_double_operand" "rHI")))] 3736: "TARGET_V9" 3737: "udivx %1,%2,%0") 3738: 1.1 root 3739: ;; It is not known whether this will match. 3740: 1.1.1.4 ! root 3741: (define_insn "*cmp_udiv_cc_set" 1.1 root 3742: [(set (match_operand:SI 0 "register_operand" "=r") 3743: (udiv:SI (match_operand:SI 1 "register_operand" "r") 3744: (match_operand:SI 2 "arith_operand" "rI"))) 3745: (set (reg:CC 0) 3746: (compare:CC (udiv:SI (match_dup 1) (match_dup 2)) 3747: (const_int 0)))] 3748: "TARGET_V8" 3749: "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0" 3750: [(set_attr "length" "5")]) 1.1.1.2 root 3751: 3752: ;;- Boolean instructions 1.1 root 3753: ;; We define DImode `and` so with DImode `not` we can get 3754: ;; DImode `andn`. Other combinations are possible. 3755: 3756: (define_expand "anddi3" 3757: [(set (match_operand:DI 0 "register_operand" "") 3758: (and:DI (match_operand:DI 1 "arith_double_operand" "") 3759: (match_operand:DI 2 "arith_double_operand" "")))] 3760: "" 3761: "") 3762: 1.1.1.4 ! root 3763: (define_insn "*anddi3_sp32" 1.1 root 3764: [(set (match_operand:DI 0 "register_operand" "=r") 3765: (and:DI (match_operand:DI 1 "arith_double_operand" "%r") 3766: (match_operand:DI 2 "arith_double_operand" "rHI")))] 1.1.1.3 root 3767: "! TARGET_V9" 1.1 root 3768: "* 3769: { 3770: rtx op2 = operands[2]; 3771: 3772: /* If constant is positive, upper bits zeroed, otherwise unchanged. 3773: Give the assembler a chance to pick the move instruction. */ 3774: if (GET_CODE (op2) == CONST_INT) 3775: { 3776: int sign = INTVAL (op2); 3777: if (sign < 0) 3778: return \"mov %1,%0\;and %R1,%2,%R0\"; 3779: return \"mov 0,%0\;and %R1,%2,%R0\"; 3780: } 3781: else if (GET_CODE (op2) == CONST_DOUBLE) 3782: { 1.1.1.3 root 3783: rtx xoperands[4]; 3784: xoperands[0] = operands[0]; 3785: xoperands[1] = operands[1]; 3786: xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2)); 3787: xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2)); 3788: /* We could optimize then operands[1] == operands[0] 3789: and either half of the constant is -1. */ 3790: output_asm_insn (\"and %R1,%2,%R0\;and %1,%3,%0\", xoperands); 3791: return \"\"; 1.1 root 3792: } 3793: return \"and %1,%2,%0\;and %R1,%R2,%R0\"; 3794: }" 3795: [(set_attr "length" "2")]) 3796: 1.1.1.4 ! root 3797: (define_insn "*anddi3_sp64" 1.1.1.3 root 3798: [(set (match_operand:DI 0 "register_operand" "=r") 3799: (and:DI (match_operand:DI 1 "arith_double_operand" "%r") 3800: (match_operand:DI 2 "arith_double_operand" "rHI")))] 3801: "TARGET_V9" 3802: "and %1,%2,%0") 3803: 1.1 root 3804: (define_insn "andsi3" 3805: [(set (match_operand:SI 0 "register_operand" "=r") 3806: (and:SI (match_operand:SI 1 "arith_operand" "%r") 3807: (match_operand:SI 2 "arith_operand" "rI")))] 3808: "" 1.1.1.3 root 3809: "and %1,%2,%0" 3810: [(set_attr "type" "ialu")]) 1.1 root 3811: 3812: (define_split 3813: [(set (match_operand:SI 0 "register_operand" "") 3814: (and:SI (match_operand:SI 1 "register_operand" "") 3815: (match_operand:SI 2 "" ""))) 3816: (clobber (match_operand:SI 3 "register_operand" ""))] 3817: "GET_CODE (operands[2]) == CONST_INT 3818: && !SMALL_INT (operands[2]) 3819: && (INTVAL (operands[2]) & 0x3ff) == 0x3ff" 3820: [(set (match_dup 3) (match_dup 4)) 3821: (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))] 3822: " 3823: { 3824: operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); 3825: }") 3826: 1.1.1.4 ! root 3827: (define_insn "*and_not_di_sp32" 1.1 root 3828: [(set (match_operand:DI 0 "register_operand" "=r") 3829: (and:DI (not:DI (match_operand:DI 1 "register_operand" "r")) 3830: (match_operand:DI 2 "register_operand" "r")))] 1.1.1.3 root 3831: "! TARGET_V9" 1.1 root 3832: "andn %2,%1,%0\;andn %R2,%R1,%R0" 3833: [(set_attr "length" "2")]) 3834: 1.1.1.4 ! root 3835: (define_insn "*and_not_di_sp64" 1.1.1.3 root 3836: [(set (match_operand:DI 0 "register_operand" "=r") 3837: (and:DI (not:DI (match_operand:DI 1 "register_operand" "r")) 3838: (match_operand:DI 2 "register_operand" "r")))] 3839: "TARGET_V9" 3840: "andn %2,%1,%0") 3841: 1.1.1.4 ! root 3842: (define_insn "*and_not_si" 1.1 root 3843: [(set (match_operand:SI 0 "register_operand" "=r") 3844: (and:SI (not:SI (match_operand:SI 1 "register_operand" "r")) 3845: (match_operand:SI 2 "register_operand" "r")))] 3846: "" 1.1.1.3 root 3847: "andn %2,%1,%0" 3848: [(set_attr "type" "ialu")]) 1.1 root 3849: 3850: (define_expand "iordi3" 3851: [(set (match_operand:DI 0 "register_operand" "") 3852: (ior:DI (match_operand:DI 1 "arith_double_operand" "") 3853: (match_operand:DI 2 "arith_double_operand" "")))] 3854: "" 3855: "") 3856: 1.1.1.4 ! root 3857: (define_insn "*iordi3_sp32" 1.1 root 3858: [(set (match_operand:DI 0 "register_operand" "=r") 3859: (ior:DI (match_operand:DI 1 "arith_double_operand" "%r") 3860: (match_operand:DI 2 "arith_double_operand" "rHI")))] 1.1.1.3 root 3861: "! TARGET_V9" 1.1 root 3862: "* 3863: { 3864: rtx op2 = operands[2]; 3865: 3866: /* If constant is positive, upper bits zeroed, otherwise unchanged. 3867: Give the assembler a chance to pick the move instruction. */ 3868: if (GET_CODE (op2) == CONST_INT) 3869: { 3870: int sign = INTVAL (op2); 3871: if (sign < 0) 3872: return \"mov -1,%0\;or %R1,%2,%R0\"; 3873: return \"mov %1,%0\;or %R1,%2,%R0\"; 3874: } 3875: else if (GET_CODE (op2) == CONST_DOUBLE) 3876: { 1.1.1.3 root 3877: rtx xoperands[4]; 3878: xoperands[0] = operands[0]; 3879: xoperands[1] = operands[1]; 3880: xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2)); 3881: xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2)); 3882: /* We could optimize then operands[1] == operands[0] 3883: and either half of the constant is 0. */ 3884: output_asm_insn (\"or %R1,%2,%R0\;or %1,%3,%0\", xoperands); 3885: return \"\"; 1.1 root 3886: } 3887: return \"or %1,%2,%0\;or %R1,%R2,%R0\"; 3888: }" 3889: [(set_attr "length" "2")]) 3890: 1.1.1.4 ! root 3891: (define_insn "*iordi3_sp64" 1.1.1.3 root 3892: [(set (match_operand:DI 0 "register_operand" "=r") 3893: (ior:DI (match_operand:DI 1 "arith_double_operand" "%r") 3894: (match_operand:DI 2 "arith_double_operand" "rHI")))] 3895: "TARGET_V9" 3896: "or %1,%2,%0") 3897: 1.1 root 3898: (define_insn "iorsi3" 3899: [(set (match_operand:SI 0 "register_operand" "=r") 3900: (ior:SI (match_operand:SI 1 "arith_operand" "%r") 3901: (match_operand:SI 2 "arith_operand" "rI")))] 3902: "" 1.1.1.3 root 3903: "or %1,%2,%0" 3904: [(set_attr "type" "ialu")]) 1.1 root 3905: 3906: (define_split 3907: [(set (match_operand:SI 0 "register_operand" "") 3908: (ior:SI (match_operand:SI 1 "register_operand" "") 3909: (match_operand:SI 2 "" ""))) 3910: (clobber (match_operand:SI 3 "register_operand" ""))] 3911: "GET_CODE (operands[2]) == CONST_INT 3912: && !SMALL_INT (operands[2]) 3913: && (INTVAL (operands[2]) & 0x3ff) == 0x3ff" 3914: [(set (match_dup 3) (match_dup 4)) 3915: (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))] 3916: " 3917: { 3918: operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); 3919: }") 3920: 1.1.1.4 ! root 3921: (define_insn "*or_not_di_sp32" 1.1 root 3922: [(set (match_operand:DI 0 "register_operand" "=r") 3923: (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r")) 3924: (match_operand:DI 2 "register_operand" "r")))] 1.1.1.3 root 3925: "! TARGET_V9" 1.1 root 3926: "orn %2,%1,%0\;orn %R2,%R1,%R0" 3927: [(set_attr "length" "2")]) 3928: 1.1.1.4 ! root 3929: (define_insn "*or_not_di_sp64" 1.1.1.3 root 3930: [(set (match_operand:DI 0 "register_operand" "=r") 3931: (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r")) 3932: (match_operand:DI 2 "register_operand" "r")))] 3933: "TARGET_V9" 3934: "orn %2,%1,%0") 3935: 1.1.1.4 ! root 3936: (define_insn "*or_not_si" 1.1 root 3937: [(set (match_operand:SI 0 "register_operand" "=r") 3938: (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r")) 3939: (match_operand:SI 2 "register_operand" "r")))] 3940: "" 1.1.1.3 root 3941: "orn %2,%1,%0" 3942: [(set_attr "type" "ialu")]) 1.1 root 3943: 3944: (define_expand "xordi3" 3945: [(set (match_operand:DI 0 "register_operand" "") 3946: (xor:DI (match_operand:DI 1 "arith_double_operand" "") 3947: (match_operand:DI 2 "arith_double_operand" "")))] 3948: "" 3949: "") 3950: 1.1.1.4 ! root 3951: (define_insn "*xorsi3_sp32" 1.1 root 3952: [(set (match_operand:DI 0 "register_operand" "=r") 3953: (xor:DI (match_operand:DI 1 "arith_double_operand" "%r") 3954: (match_operand:DI 2 "arith_double_operand" "rHI")))] 1.1.1.3 root 3955: "! TARGET_V9" 1.1 root 3956: "* 3957: { 3958: rtx op2 = operands[2]; 3959: 3960: /* If constant is positive, upper bits zeroed, otherwise unchanged. 3961: Give the assembler a chance to pick the move instruction. */ 3962: if (GET_CODE (op2) == CONST_INT) 3963: { 3964: int sign = INTVAL (op2); 3965: if (sign < 0) 3966: return \"xor %1,-1,%0\;xor %R1,%2,%R0\"; 3967: return \"mov %1,%0\;xor %R1,%2,%R0\"; 3968: } 3969: else if (GET_CODE (op2) == CONST_DOUBLE) 3970: { 1.1.1.3 root 3971: rtx xoperands[4]; 3972: xoperands[0] = operands[0]; 3973: xoperands[1] = operands[1]; 3974: xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2)); 3975: xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2)); 3976: /* We could optimize then operands[1] == operands[0] 3977: and either half of the constant is 0. */ 3978: output_asm_insn (\"xor %R1,%2,%R0\;xor %1,%3,%0\", xoperands); 3979: return \"\"; 1.1 root 3980: } 3981: return \"xor %1,%2,%0\;xor %R1,%R2,%R0\"; 3982: }" 3983: [(set_attr "length" "2")]) 3984: 1.1.1.4 ! root 3985: (define_insn "*xordi3_sp64" 1.1.1.3 root 3986: [(set (match_operand:DI 0 "register_operand" "=r") 3987: (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ") 3988: (match_operand:DI 2 "arith_double_operand" "rHI")))] 3989: "TARGET_V9" 3990: "xor %r1,%2,%0") 3991: 1.1 root 3992: (define_insn "xorsi3" 3993: [(set (match_operand:SI 0 "register_operand" "=r") 3994: (xor:SI (match_operand:SI 1 "arith_operand" "%rJ") 3995: (match_operand:SI 2 "arith_operand" "rI")))] 3996: "" 1.1.1.3 root 3997: "xor %r1,%2,%0" 3998: [(set_attr "type" "ialu")]) 1.1 root 3999: 4000: (define_split 4001: [(set (match_operand:SI 0 "register_operand" "") 4002: (xor:SI (match_operand:SI 1 "register_operand" "") 4003: (match_operand:SI 2 "" ""))) 4004: (clobber (match_operand:SI 3 "register_operand" ""))] 4005: "GET_CODE (operands[2]) == CONST_INT 4006: && !SMALL_INT (operands[2]) 4007: && (INTVAL (operands[2]) & 0x3ff) == 0x3ff" 4008: [(set (match_dup 3) (match_dup 4)) 4009: (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))] 4010: " 4011: { 4012: operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); 4013: }") 4014: 4015: (define_split 4016: [(set (match_operand:SI 0 "register_operand" "") 4017: (not:SI (xor:SI (match_operand:SI 1 "register_operand" "") 4018: (match_operand:SI 2 "" "")))) 4019: (clobber (match_operand:SI 3 "register_operand" ""))] 4020: "GET_CODE (operands[2]) == CONST_INT 4021: && !SMALL_INT (operands[2]) 4022: && (INTVAL (operands[2]) & 0x3ff) == 0x3ff" 4023: [(set (match_dup 3) (match_dup 4)) 4024: (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))] 4025: " 4026: { 4027: operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); 4028: }") 4029: 4030: ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b). 4031: ;; Combine now canonicalizes to the rightmost expression. 1.1.1.4 ! root 4032: (define_insn "*xor_not_di_sp32" 1.1 root 4033: [(set (match_operand:DI 0 "register_operand" "=r") 4034: (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r") 4035: (match_operand:DI 2 "register_operand" "r"))))] 1.1.1.3 root 4036: "! TARGET_V9" 1.1 root 4037: "xnor %1,%2,%0\;xnor %R1,%R2,%R0" 4038: [(set_attr "length" "2")]) 4039: 1.1.1.4 ! root 4040: (define_insn "*xor_not_di_sp64" 1.1.1.3 root 4041: [(set (match_operand:DI 0 "register_operand" "=r") 4042: (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") 4043: (match_operand:DI 2 "arith_double_operand" "rHI"))))] 4044: "TARGET_V9" 4045: "xnor %r1,%2,%0") 4046: 1.1.1.4 ! root 4047: (define_insn "*xor_not_si" 1.1 root 4048: [(set (match_operand:SI 0 "register_operand" "=r") 4049: (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") 4050: (match_operand:SI 2 "arith_operand" "rI"))))] 4051: "" 1.1.1.3 root 4052: "xnor %r1,%2,%0" 4053: [(set_attr "type" "ialu")]) 1.1 root 4054: 4055: ;; These correspond to the above in the case where we also (or only) 4056: ;; want to set the condition code. 4057: 1.1.1.4 ! root 4058: (define_insn "*cmp_cc_arith_op" 1.1 root 4059: [(set (reg:CC 0) 4060: (compare:CC 4061: (match_operator:SI 2 "cc_arithop" 4062: [(match_operand:SI 0 "arith_operand" "%r") 4063: (match_operand:SI 1 "arith_operand" "rI")]) 4064: (const_int 0)))] 4065: "" 4066: "%A2cc %0,%1,%%g0" 4067: [(set_attr "type" "compare")]) 4068: 1.1.1.4 ! root 4069: (define_insn "*cmp_ccx_arith_op" 1.1.1.3 root 4070: [(set (reg:CCX 0) 4071: (compare:CCX 4072: (match_operator:DI 2 "cc_arithop" 4073: [(match_operand:DI 0 "arith_double_operand" "%r") 4074: (match_operand:DI 1 "arith_double_operand" "rHI")]) 4075: (const_int 0)))] 4076: "TARGET_V9" 4077: "%A2cc %0,%1,%%g0" 4078: [(set_attr "type" "compare")]) 4079: 1.1.1.4 ! root 4080: (define_insn "*cmp_cc_arith_op_set" 1.1 root 4081: [(set (reg:CC 0) 4082: (compare:CC 4083: (match_operator:SI 3 "cc_arithop" 4084: [(match_operand:SI 1 "arith_operand" "%r") 4085: (match_operand:SI 2 "arith_operand" "rI")]) 4086: (const_int 0))) 4087: (set (match_operand:SI 0 "register_operand" "=r") 4088: (match_dup 3))] 4089: "" 4090: "%A3cc %1,%2,%0") 4091: 1.1.1.4 ! root 4092: (define_insn "*cmp_ccx_arith_op_set" 1.1.1.3 root 4093: [(set (reg:CCX 0) 4094: (compare:CCX 4095: (match_operator:DI 3 "cc_arithop" 4096: [(match_operand:DI 1 "arith_double_operand" "%r") 4097: (match_operand:DI 2 "arith_double_operand" "rHI")]) 4098: (const_int 0))) 4099: (set (match_operand:DI 0 "register_operand" "=r") 4100: (match_dup 3))] 4101: "TARGET_V9" 4102: "%A3cc %1,%2,%0") 4103: 1.1.1.4 ! root 4104: (define_insn "*cmp_cc_xor_not" 1.1 root 4105: [(set (reg:CC 0) 4106: (compare:CC 4107: (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ") 4108: (match_operand:SI 1 "arith_operand" "rI"))) 4109: (const_int 0)))] 4110: "" 4111: "xnorcc %r0,%1,%%g0" 4112: [(set_attr "type" "compare")]) 4113: 1.1.1.4 ! root 4114: (define_insn "*cmp_ccx_xor_not" 1.1.1.3 root 4115: [(set (reg:CCX 0) 4116: (compare:CCX 4117: (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ") 4118: (match_operand:DI 1 "arith_double_operand" "rHI"))) 4119: (const_int 0)))] 4120: "TARGET_V9" 4121: "xnorcc %r0,%1,%%g0" 4122: [(set_attr "type" "compare")]) 4123: 1.1.1.4 ! root 4124: (define_insn "*cmp_cc_xor_not_set" 1.1 root 4125: [(set (reg:CC 0) 4126: (compare:CC 4127: (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") 4128: (match_operand:SI 2 "arith_operand" "rI"))) 4129: (const_int 0))) 4130: (set (match_operand:SI 0 "register_operand" "=r") 4131: (not:SI (xor:SI (match_dup 1) (match_dup 2))))] 4132: "" 4133: "xnorcc %r1,%2,%0") 4134: 1.1.1.4 ! root 4135: (define_insn "*cmp_ccx_xor_not_set" 1.1.1.3 root 4136: [(set (reg:CCX 0) 4137: (compare:CCX 4138: (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ") 4139: (match_operand:DI 2 "arith_double_operand" "rHI"))) 4140: (const_int 0))) 4141: (set (match_operand:DI 0 "register_operand" "=r") 4142: (not:DI (xor:DI (match_dup 1) (match_dup 2))))] 4143: "TARGET_V9" 4144: "xnorcc %r1,%2,%0") 4145: 1.1.1.4 ! root 4146: (define_insn "*cmp_cc_arith_op_not" 1.1 root 4147: [(set (reg:CC 0) 4148: (compare:CC 4149: (match_operator:SI 2 "cc_arithopn" 4150: [(not:SI (match_operand:SI 0 "arith_operand" "rI")) 4151: (match_operand:SI 1 "reg_or_0_operand" "rJ")]) 4152: (const_int 0)))] 4153: "" 4154: "%B2cc %r1,%0,%%g0" 4155: [(set_attr "type" "compare")]) 4156: 1.1.1.4 ! root 4157: (define_insn "*cmp_ccx_arith_op_not" 1.1.1.3 root 4158: [(set (reg:CCX 0) 4159: (compare:CCX 4160: (match_operator:DI 2 "cc_arithopn" 4161: [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI")) 4162: (match_operand:DI 1 "reg_or_0_operand" "rJ")]) 4163: (const_int 0)))] 4164: "TARGET_V9" 4165: "%B2cc %r1,%0,%%g0" 4166: [(set_attr "type" "compare")]) 4167: 1.1.1.4 ! root 4168: (define_insn "*cmp_cc_arith_op_not_set" 1.1 root 4169: [(set (reg:CC 0) 4170: (compare:CC 4171: (match_operator:SI 3 "cc_arithopn" 4172: [(not:SI (match_operand:SI 1 "arith_operand" "rI")) 4173: (match_operand:SI 2 "reg_or_0_operand" "rJ")]) 4174: (const_int 0))) 4175: (set (match_operand:SI 0 "register_operand" "=r") 4176: (match_dup 3))] 4177: "" 4178: "%B3cc %r2,%1,%0") 4179: 1.1.1.4 ! root 4180: (define_insn "*cmp_ccx_arith_op_not_set" 1.1.1.3 root 4181: [(set (reg:CCX 0) 4182: (compare:CCX 4183: (match_operator:DI 3 "cc_arithopn" 4184: [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI")) 4185: (match_operand:DI 2 "reg_or_0_operand" "rJ")]) 4186: (const_int 0))) 4187: (set (match_operand:DI 0 "register_operand" "=r") 4188: (match_dup 3))] 4189: "TARGET_V9" 4190: "%B3cc %r2,%1,%0") 4191: 1.1 root 4192: ;; We cannot use the "neg" pseudo insn because the Sun assembler 4193: ;; does not know how to make it work for constants. 4194: 1.1.1.3 root 4195: (define_expand "negdi2" 4196: [(set (match_operand:DI 0 "register_operand" "=r") 4197: (neg:DI (match_operand:DI 1 "register_operand" "r")))] 4198: "" 4199: " 4200: { 4201: if (! TARGET_V9) 4202: { 4203: emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, 4204: gen_rtx (SET, VOIDmode, operand0, 4205: gen_rtx (NEG, DImode, operand1)), 4206: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0))))); 4207: DONE; 4208: } 4209: }") 4210: 1.1.1.4 ! root 4211: (define_insn "*negdi2_sp32" 1.1 root 4212: [(set (match_operand:DI 0 "register_operand" "=r") 4213: (neg:DI (match_operand:DI 1 "register_operand" "r"))) 4214: (clobber (reg:SI 0))] 1.1.1.3 root 4215: "! TARGET_V9" 1.1 root 4216: "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0" 4217: [(set_attr "type" "unary") 4218: (set_attr "length" "2")]) 4219: 1.1.1.4 ! root 4220: (define_insn "*negdi2_sp64" 1.1.1.3 root 4221: [(set (match_operand:DI 0 "register_operand" "=r") 4222: (neg:DI (match_operand:DI 1 "register_operand" "r")))] 4223: "TARGET_V9" 4224: "sub %%g0,%1,%0" 4225: [(set_attr "type" "unary") 4226: (set_attr "length" "1")]) 4227: 1.1 root 4228: (define_insn "negsi2" 1.1.1.3 root 4229: [(set (match_operand:SI 0 "register_operand" "=r") 1.1 root 4230: (neg:SI (match_operand:SI 1 "arith_operand" "rI")))] 4231: "" 4232: "sub %%g0,%1,%0" 4233: [(set_attr "type" "unary")]) 4234: 1.1.1.4 ! root 4235: (define_insn "*cmp_cc_neg" 1.1 root 4236: [(set (reg:CC_NOOV 0) 4237: (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI")) 4238: (const_int 0)))] 4239: "" 4240: "subcc %%g0,%0,%%g0" 4241: [(set_attr "type" "compare")]) 4242: 1.1.1.4 ! root 4243: (define_insn "*cmp_ccx_neg" 1.1.1.3 root 4244: [(set (reg:CCX_NOOV 0) 4245: (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI")) 4246: (const_int 0)))] 4247: "TARGET_V9" 4248: "subcc %%g0,%0,%%g0" 4249: [(set_attr "type" "compare")]) 4250: 1.1.1.4 ! root 4251: (define_insn "*cmp_cc_set_neg" 1.1 root 4252: [(set (reg:CC_NOOV 0) 4253: (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI")) 4254: (const_int 0))) 4255: (set (match_operand:SI 0 "register_operand" "=r") 4256: (neg:SI (match_dup 1)))] 4257: "" 4258: "subcc %%g0,%1,%0" 4259: [(set_attr "type" "unary")]) 4260: 1.1.1.4 ! root 4261: (define_insn "*cmp_ccx_set_neg" 1.1.1.3 root 4262: [(set (reg:CCX_NOOV 0) 4263: (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI")) 4264: (const_int 0))) 4265: (set (match_operand:DI 0 "register_operand" "=r") 4266: (neg:DI (match_dup 1)))] 4267: "TARGET_V9" 4268: "subcc %%g0,%1,%0" 4269: [(set_attr "type" "unary")]) 4270: 1.1 root 4271: ;; We cannot use the "not" pseudo insn because the Sun assembler 4272: ;; does not know how to make it work for constants. 4273: (define_expand "one_cmpldi2" 1.1.1.3 root 4274: [(set (match_operand:DI 0 "register_operand" "") 4275: (not:DI (match_operand:DI 1 "register_operand" "")))] 1.1 root 4276: "" 4277: "") 4278: 1.1.1.4 ! root 4279: (define_insn "*one_cmpldi2_sp32" 1.1 root 4280: [(set (match_operand:DI 0 "register_operand" "=r") 1.1.1.3 root 4281: (not:DI (match_operand:DI 1 "register_operand" "r")))] 4282: "! TARGET_V9" 4283: "xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0" 1.1 root 4284: [(set_attr "type" "unary") 4285: (set_attr "length" "2")]) 4286: 1.1.1.4 ! root 4287: (define_insn "*one_cmpldi2_sp64" 1.1.1.3 root 4288: [(set (match_operand:DI 0 "register_operand" "=r") 4289: (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))] 4290: "TARGET_V9" 4291: "xnor %%g0,%1,%0" 4292: [(set_attr "type" "unary")]) 4293: 1.1 root 4294: (define_insn "one_cmplsi2" 4295: [(set (match_operand:SI 0 "register_operand" "=r") 4296: (not:SI (match_operand:SI 1 "arith_operand" "rI")))] 4297: "" 4298: "xnor %%g0,%1,%0" 4299: [(set_attr "type" "unary")]) 4300: 1.1.1.4 ! root 4301: (define_insn "*cmp_cc_not" 1.1 root 4302: [(set (reg:CC 0) 4303: (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI")) 4304: (const_int 0)))] 4305: "" 4306: "xnorcc %%g0,%0,%%g0" 4307: [(set_attr "type" "compare")]) 4308: 1.1.1.4 ! root 4309: (define_insn "*cmp_ccx_not" 1.1.1.3 root 4310: [(set (reg:CCX 0) 4311: (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI")) 4312: (const_int 0)))] 4313: "TARGET_V9" 4314: "xnorcc %%g0,%0,%%g0" 4315: [(set_attr "type" "compare")]) 4316: 1.1.1.4 ! root 4317: (define_insn "*cmp_cc_set_not" 1.1 root 4318: [(set (reg:CC 0) 4319: (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI")) 4320: (const_int 0))) 4321: (set (match_operand:SI 0 "register_operand" "=r") 4322: (not:SI (match_dup 1)))] 4323: "" 4324: "xnorcc %%g0,%1,%0" 4325: [(set_attr "type" "unary")]) 1.1.1.3 root 4326: 1.1.1.4 ! root 4327: (define_insn "*cmp_ccx_set_not" 1.1.1.3 root 4328: [(set (reg:CCX 0) 4329: (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")) 4330: (const_int 0))) 4331: (set (match_operand:DI 0 "register_operand" "=r") 4332: (not:DI (match_dup 1)))] 4333: "TARGET_V9" 4334: "xnorcc %%g0,%1,%0" 4335: [(set_attr "type" "unary")]) 1.1 root 4336: 4337: ;; Floating point arithmetic instructions. 4338: 4339: (define_insn "addtf3" 1.1.1.3 root 4340: [(set (match_operand:TF 0 "register_operand" "=e") 4341: (plus:TF (match_operand:TF 1 "register_operand" "e") 4342: (match_operand:TF 2 "register_operand" "e")))] 4343: "TARGET_FPU && TARGET_HARD_QUAD" 1.1 root 4344: "faddq %1,%2,%0" 4345: [(set_attr "type" "fp")]) 4346: 4347: (define_insn "adddf3" 1.1.1.3 root 4348: [(set (match_operand:DF 0 "register_operand" "=e") 4349: (plus:DF (match_operand:DF 1 "register_operand" "e") 4350: (match_operand:DF 2 "register_operand" "e")))] 1.1 root 4351: "TARGET_FPU" 4352: "faddd %1,%2,%0" 4353: [(set_attr "type" "fp")]) 4354: 4355: (define_insn "addsf3" 4356: [(set (match_operand:SF 0 "register_operand" "=f") 4357: (plus:SF (match_operand:SF 1 "register_operand" "f") 4358: (match_operand:SF 2 "register_operand" "f")))] 4359: "TARGET_FPU" 4360: "fadds %1,%2,%0" 4361: [(set_attr "type" "fp")]) 4362: 4363: (define_insn "subtf3" 1.1.1.3 root 4364: [(set (match_operand:TF 0 "register_operand" "=e") 4365: (minus:TF (match_operand:TF 1 "register_operand" "e") 4366: (match_operand:TF 2 "register_operand" "e")))] 4367: "TARGET_FPU && TARGET_HARD_QUAD" 1.1 root 4368: "fsubq %1,%2,%0" 4369: [(set_attr "type" "fp")]) 4370: 4371: (define_insn "subdf3" 1.1.1.3 root 4372: [(set (match_operand:DF 0 "register_operand" "=e") 4373: (minus:DF (match_operand:DF 1 "register_operand" "e") 4374: (match_operand:DF 2 "register_operand" "e")))] 1.1 root 4375: "TARGET_FPU" 4376: "fsubd %1,%2,%0" 4377: [(set_attr "type" "fp")]) 4378: 4379: (define_insn "subsf3" 4380: [(set (match_operand:SF 0 "register_operand" "=f") 4381: (minus:SF (match_operand:SF 1 "register_operand" "f") 4382: (match_operand:SF 2 "register_operand" "f")))] 4383: "TARGET_FPU" 4384: "fsubs %1,%2,%0" 4385: [(set_attr "type" "fp")]) 4386: 4387: (define_insn "multf3" 1.1.1.3 root 4388: [(set (match_operand:TF 0 "register_operand" "=e") 4389: (mult:TF (match_operand:TF 1 "register_operand" "e") 4390: (match_operand:TF 2 "register_operand" "e")))] 4391: "TARGET_FPU && TARGET_HARD_QUAD" 1.1 root 4392: "fmulq %1,%2,%0" 4393: [(set_attr "type" "fpmul")]) 4394: 4395: (define_insn "muldf3" 1.1.1.3 root 4396: [(set (match_operand:DF 0 "register_operand" "=e") 4397: (mult:DF (match_operand:DF 1 "register_operand" "e") 4398: (match_operand:DF 2 "register_operand" "e")))] 1.1 root 4399: "TARGET_FPU" 4400: "fmuld %1,%2,%0" 4401: [(set_attr "type" "fpmul")]) 4402: 4403: (define_insn "mulsf3" 4404: [(set (match_operand:SF 0 "register_operand" "=f") 4405: (mult:SF (match_operand:SF 1 "register_operand" "f") 4406: (match_operand:SF 2 "register_operand" "f")))] 4407: "TARGET_FPU" 4408: "fmuls %1,%2,%0" 4409: [(set_attr "type" "fpmul")]) 4410: 1.1.1.4 ! root 4411: (define_insn "*muldf3_extend" 1.1.1.3 root 4412: [(set (match_operand:DF 0 "register_operand" "=e") 1.1 root 4413: (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f")) 4414: (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))] 1.1.1.3 root 4415: "(TARGET_V8 || TARGET_V9) && TARGET_FPU" 1.1 root 4416: "fsmuld %1,%2,%0" 4417: [(set_attr "type" "fpmul")]) 4418: 1.1.1.4 ! root 4419: (define_insn "*multf3_extend" 1.1.1.3 root 4420: [(set (match_operand:TF 0 "register_operand" "=e") 4421: (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e")) 4422: (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))] 4423: "(TARGET_V8 || TARGET_V9) && TARGET_FPU" 1.1 root 4424: "fdmulq %1,%2,%0" 4425: [(set_attr "type" "fpmul")]) 4426: 1.1.1.3 root 4427: ;; don't have timing for quad-prec. divide. 1.1 root 4428: (define_insn "divtf3" 1.1.1.3 root 4429: [(set (match_operand:TF 0 "register_operand" "=e") 4430: (div:TF (match_operand:TF 1 "register_operand" "e") 4431: (match_operand:TF 2 "register_operand" "e")))] 4432: "TARGET_FPU && TARGET_HARD_QUAD" 1.1 root 4433: "fdivq %1,%2,%0" 1.1.1.3 root 4434: [(set_attr "type" "fpdivd")]) 1.1 root 4435: 4436: (define_insn "divdf3" 1.1.1.3 root 4437: [(set (match_operand:DF 0 "register_operand" "=e") 4438: (div:DF (match_operand:DF 1 "register_operand" "e") 4439: (match_operand:DF 2 "register_operand" "e")))] 1.1 root 4440: "TARGET_FPU" 4441: "fdivd %1,%2,%0" 1.1.1.3 root 4442: [(set_attr "type" "fpdivd")]) 1.1 root 4443: 4444: (define_insn "divsf3" 4445: [(set (match_operand:SF 0 "register_operand" "=f") 4446: (div:SF (match_operand:SF 1 "register_operand" "f") 4447: (match_operand:SF 2 "register_operand" "f")))] 4448: "TARGET_FPU" 4449: "fdivs %1,%2,%0" 1.1.1.3 root 4450: [(set_attr "type" "fpdivs")]) 1.1 root 4451: 4452: (define_insn "negtf2" 1.1.1.3 root 4453: [(set (match_operand:TF 0 "register_operand" "=e,e") 4454: (neg:TF (match_operand:TF 1 "register_operand" "0,e")))] 1.1 root 4455: "TARGET_FPU" 1.1.1.3 root 4456: "* 4457: { 4458: if (TARGET_V9) 4459: return \"fnegd %1,%0\"; /* Can't use fnegs, won't work with upper regs. */ 4460: else if (which_alternative == 0) 4461: return \"fnegs %0,%0\"; 4462: else 4463: return \"fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\"; 4464: }" 1.1 root 4465: [(set_attr "type" "fp") 1.1.1.3 root 4466: (set_attr_alternative "length" 4467: [(const_int 1) 4468: (if_then_else (eq_attr "arch" "arch32bit") (const_int 4) (const_int 1))])]) 1.1 root 4469: 4470: (define_insn "negdf2" 1.1.1.3 root 4471: [(set (match_operand:DF 0 "register_operand" "=e,e") 4472: (neg:DF (match_operand:DF 1 "register_operand" "0,e")))] 1.1 root 4473: "TARGET_FPU" 1.1.1.3 root 4474: "* 4475: { 4476: if (TARGET_V9) 4477: return \"fnegd %1,%0\"; 4478: else if (which_alternative == 0) 4479: return \"fnegs %0,%0\"; 4480: else 4481: return \"fnegs %1,%0\;fmovs %R1,%R0\"; 4482: }" 1.1 root 4483: [(set_attr "type" "fp") 1.1.1.3 root 4484: (set_attr_alternative "length" 4485: [(const_int 1) 4486: (if_then_else (eq_attr "arch" "arch32bit") (const_int 2) (const_int 1))])]) 1.1 root 4487: 4488: (define_insn "negsf2" 4489: [(set (match_operand:SF 0 "register_operand" "=f") 4490: (neg:SF (match_operand:SF 1 "register_operand" "f")))] 4491: "TARGET_FPU" 4492: "fnegs %1,%0" 4493: [(set_attr "type" "fp")]) 4494: 4495: (define_insn "abstf2" 1.1.1.3 root 4496: [(set (match_operand:TF 0 "register_operand" "=e,e") 4497: (abs:TF (match_operand:TF 1 "register_operand" "0,e")))] 1.1 root 4498: "TARGET_FPU" 1.1.1.3 root 4499: "* 4500: { 4501: if (TARGET_V9) 4502: return \"fabsd %1,%0\"; /* Can't use fabss, won't work with upper regs. */ 4503: else if (which_alternative == 0) 4504: return \"fabss %0,%0\"; 4505: else 4506: return \"fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\"; 4507: }" 1.1 root 4508: [(set_attr "type" "fp") 1.1.1.3 root 4509: (set_attr_alternative "length" 4510: [(const_int 1) 4511: (if_then_else (eq_attr "arch" "arch32bit") (const_int 4) (const_int 1))])]) 1.1 root 4512: 4513: (define_insn "absdf2" 1.1.1.3 root 4514: [(set (match_operand:DF 0 "register_operand" "=e,e") 4515: (abs:DF (match_operand:DF 1 "register_operand" "0,e")))] 1.1 root 4516: "TARGET_FPU" 1.1.1.3 root 4517: "* 4518: { 4519: if (TARGET_V9) 4520: return \"fabsd %1,%0\"; 4521: else if (which_alternative == 0) 4522: return \"fabss %0,%0\"; 4523: else 4524: return \"fabss %1,%0\;fmovs %R1,%R0\"; 4525: }" 1.1 root 4526: [(set_attr "type" "fp") 1.1.1.3 root 4527: (set_attr_alternative "length" 4528: [(const_int 1) 4529: (if_then_else (eq_attr "arch" "arch32bit") (const_int 2) (const_int 1))])]) 1.1 root 4530: 4531: (define_insn "abssf2" 4532: [(set (match_operand:SF 0 "register_operand" "=f") 4533: (abs:SF (match_operand:SF 1 "register_operand" "f")))] 4534: "TARGET_FPU" 4535: "fabss %1,%0" 4536: [(set_attr "type" "fp")]) 4537: 4538: (define_insn "sqrttf2" 1.1.1.3 root 4539: [(set (match_operand:TF 0 "register_operand" "=e") 4540: (sqrt:TF (match_operand:TF 1 "register_operand" "e")))] 4541: "TARGET_FPU && TARGET_HARD_QUAD" 1.1 root 4542: "fsqrtq %1,%0" 4543: [(set_attr "type" "fpsqrt")]) 4544: 4545: (define_insn "sqrtdf2" 1.1.1.3 root 4546: [(set (match_operand:DF 0 "register_operand" "=e") 4547: (sqrt:DF (match_operand:DF 1 "register_operand" "e")))] 1.1 root 4548: "TARGET_FPU" 4549: "fsqrtd %1,%0" 4550: [(set_attr "type" "fpsqrt")]) 4551: 4552: (define_insn "sqrtsf2" 4553: [(set (match_operand:SF 0 "register_operand" "=f") 4554: (sqrt:SF (match_operand:SF 1 "register_operand" "f")))] 4555: "TARGET_FPU" 4556: "fsqrts %1,%0" 4557: [(set_attr "type" "fpsqrt")]) 4558: 4559: ;;- arithmetic shift instructions 4560: 4561: (define_insn "ashlsi3" 4562: [(set (match_operand:SI 0 "register_operand" "=r") 4563: (ashift:SI (match_operand:SI 1 "register_operand" "r") 4564: (match_operand:SI 2 "arith_operand" "rI")))] 4565: "" 1.1.1.2 root 4566: "* 1.1 root 4567: { 1.1.1.2 root 4568: if (GET_CODE (operands[2]) == CONST_INT 4569: && (unsigned) INTVAL (operands[2]) > 31) 4570: operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); 4571: 4572: return \"sll %1,%2,%0\"; 1.1.1.3 root 4573: }" 4574: [(set_attr "type" "shift")]) 4575: 4576: (define_insn "ashldi3" 4577: [(set (match_operand:DI 0 "register_operand" "=r") 4578: (ashift:DI (match_operand:DI 1 "register_operand" "r") 4579: (match_operand:SI 2 "arith_operand" "rI")))] 4580: "TARGET_V9" 4581: "* 4582: { 4583: if (GET_CODE (operands[2]) == CONST_INT 4584: && (unsigned) INTVAL (operands[2]) > 63) 4585: operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); 4586: 4587: return \"sllx %1,%2,%0\"; 1.1 root 4588: }") 4589: 1.1.1.4 ! root 4590: (define_insn "*cmp_cc_ashift_1" 1.1.1.2 root 4591: [(set (reg:CC_NOOV 0) 4592: (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r") 4593: (const_int 1)) 4594: (const_int 0)))] 4595: "" 4596: "addcc %0,%0,%%g0" 4597: [(set_attr "type" "compare")]) 1.1 root 4598: 1.1.1.4 ! root 4599: (define_insn "*cmp_cc_set_ashift_1" 1.1.1.2 root 4600: [(set (reg:CC_NOOV 0) 4601: (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r") 4602: (const_int 1)) 4603: (const_int 0))) 4604: (set (match_operand:SI 0 "register_operand" "=r") 4605: (ashift:SI (match_dup 1) (const_int 1)))] 4606: "" 4607: "addcc %1,%1,%0") 1.1 root 4608: 4609: (define_insn "ashrsi3" 4610: [(set (match_operand:SI 0 "register_operand" "=r") 4611: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") 4612: (match_operand:SI 2 "arith_operand" "rI")))] 4613: "" 1.1.1.2 root 4614: "* 4615: { 4616: if (GET_CODE (operands[2]) == CONST_INT 4617: && (unsigned) INTVAL (operands[2]) > 31) 4618: operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); 4619: 4620: return \"sra %1,%2,%0\"; 1.1.1.3 root 4621: }" 4622: [(set_attr "type" "shift")]) 4623: 4624: (define_insn "ashrdi3" 4625: [(set (match_operand:DI 0 "register_operand" "=r") 4626: (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") 4627: (match_operand:SI 2 "arith_operand" "rI")))] 4628: "TARGET_V9" 4629: "* 4630: { 4631: if (GET_CODE (operands[2]) == CONST_INT 4632: && (unsigned) INTVAL (operands[2]) > 63) 4633: operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); 4634: 4635: return \"srax %1,%2,%0\"; 1.1.1.2 root 4636: }") 1.1 root 4637: 4638: (define_insn "lshrsi3" 4639: [(set (match_operand:SI 0 "register_operand" "=r") 4640: (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") 4641: (match_operand:SI 2 "arith_operand" "rI")))] 4642: "" 4643: "* 4644: { 1.1.1.2 root 4645: if (GET_CODE (operands[2]) == CONST_INT 4646: && (unsigned) INTVAL (operands[2]) > 31) 4647: operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); 1.1 root 4648: 1.1.1.2 root 4649: return \"srl %1,%2,%0\"; 1.1.1.3 root 4650: }" 4651: [(set_attr "type" "shift")]) 4652: 4653: (define_insn "lshrdi3" 4654: [(set (match_operand:DI 0 "register_operand" "=r") 4655: (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") 4656: (match_operand:SI 2 "arith_operand" "rI")))] 4657: "TARGET_V9" 4658: "* 4659: { 4660: if (GET_CODE (operands[2]) == CONST_INT 4661: && (unsigned) INTVAL (operands[2]) > 63) 4662: operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); 4663: 4664: return \"srlx %1,%2,%0\"; 1.1.1.2 root 4665: }") 1.1 root 4666: 4667: ;; Unconditional and other jump instructions 4668: ;; On the Sparc, by setting the annul bit on an unconditional branch, the 4669: ;; following insn is never executed. This saves us a nop. Dbx does not 4670: ;; handle such branches though, so we only use them when optimizing. 4671: (define_insn "jump" 4672: [(set (pc) (label_ref (match_operand 0 "" "")))] 4673: "" 4674: "b%* %l0%(" 4675: [(set_attr "type" "uncond_branch")]) 4676: 4677: (define_expand "tablejump" 1.1.1.3 root 4678: [(parallel [(set (pc) (match_operand 0 "register_operand" "r")) 1.1 root 4679: (use (label_ref (match_operand 1 "" "")))])] 1.1.1.4 ! root 4680: "! TARGET_MEDANY" 1.1 root 4681: " 4682: { 1.1.1.3 root 4683: if (GET_MODE (operands[0]) != Pmode) 4684: abort (); 4685: 1.1 root 4686: /* We need to use the PC value in %o7 that was set up when the address 4687: of the label was loaded into a register, so we need different RTL. */ 4688: if (flag_pic) 4689: { 1.1.1.3 root 4690: if (!TARGET_PTR64) 4691: emit_jump_insn (gen_pic_tablejump_32 (operands[0], operands[1])); 4692: else 4693: emit_jump_insn (gen_pic_tablejump_64 (operands[0], operands[1])); 1.1 root 4694: DONE; 4695: } 4696: }") 4697: 1.1.1.3 root 4698: (define_insn "pic_tablejump_32" 1.1 root 4699: [(set (pc) (match_operand:SI 0 "register_operand" "r")) 4700: (use (label_ref (match_operand 1 "" ""))) 4701: (use (reg:SI 15))] 1.1.1.3 root 4702: "! TARGET_PTR64" 4703: "jmp %%o7+%0%#" 4704: [(set_attr "type" "uncond_branch")]) 4705: 4706: (define_insn "pic_tablejump_64" 4707: [(set (pc) (match_operand:DI 0 "register_operand" "r")) 4708: (use (label_ref (match_operand 1 "" ""))) 4709: (use (reg:DI 15))] 4710: "TARGET_PTR64" 1.1 root 4711: "jmp %%o7+%0%#" 4712: [(set_attr "type" "uncond_branch")]) 4713: 1.1.1.4 ! root 4714: (define_insn "*tablejump_sp32" 1.1 root 4715: [(set (pc) (match_operand:SI 0 "address_operand" "p")) 4716: (use (label_ref (match_operand 1 "" "")))] 1.1.1.3 root 4717: "! TARGET_PTR64" 4718: "jmp %a0%#" 4719: [(set_attr "type" "uncond_branch")]) 4720: 1.1.1.4 ! root 4721: (define_insn "*tablejump_sp64" 1.1.1.3 root 4722: [(set (pc) (match_operand:DI 0 "address_operand" "p")) 4723: (use (label_ref (match_operand 1 "" "")))] 4724: "TARGET_PTR64" 1.1 root 4725: "jmp %a0%#" 4726: [(set_attr "type" "uncond_branch")]) 4727: 1.1.1.4 ! root 4728: (define_insn "*get_pc_sp32" 1.1 root 4729: [(set (pc) (label_ref (match_operand 0 "" ""))) 4730: (set (reg:SI 15) (label_ref (match_dup 0)))] 1.1.1.3 root 4731: "! TARGET_PTR64" 4732: "call %l0%#" 4733: [(set_attr "type" "uncond_branch")]) 4734: 1.1.1.4 ! root 4735: (define_insn "*get_pc_sp64" 1.1.1.3 root 4736: [(set (pc) (label_ref (match_operand 0 "" ""))) 4737: (set (reg:DI 15) (label_ref (match_dup 0)))] 4738: "TARGET_PTR64" 1.1 root 4739: "call %l0%#" 4740: [(set_attr "type" "uncond_branch")]) 4741: 1.1.1.4 ! root 4742: ;; Implement a switch statement for the medium/anywhere code model. ! 4743: ;; This wouldn't be necessary if we could distinguish label refs of the jump ! 4744: ;; table from other label refs. The problem is that jump tables live in the ! 4745: ;; .rodata section and thus we need to add %g4 to get their address. ! 4746: ! 4747: (define_expand "casesi" ! 4748: [(set (match_dup 5) ! 4749: (minus:SI (match_operand:SI 0 "register_operand" "") ! 4750: (match_operand:SI 1 "nonmemory_operand" ""))) ! 4751: (set (reg:CC 0) ! 4752: (compare:CC (match_dup 5) ! 4753: (match_operand:SI 2 "nonmemory_operand" ""))) ! 4754: (set (pc) ! 4755: (if_then_else (gtu (reg:CC 0) ! 4756: (const_int 0)) ! 4757: (label_ref (match_operand 4 "" "")) ! 4758: (pc))) ! 4759: (parallel [(set (match_dup 6) (high:DI (label_ref (match_operand 3 "" "")))) ! 4760: (clobber (reg:DI 1))]) ! 4761: (set (match_dup 6) ! 4762: (lo_sum:DI (match_dup 6) (label_ref (match_dup 3)))) ! 4763: (set (match_dup 6) (plus:DI (match_dup 6) (reg:DI 4))) ! 4764: (set (match_dup 7) (zero_extend:DI (match_dup 5))) ! 4765: (set (match_dup 7) (ashift:DI (match_dup 7) (const_int 3))) ! 4766: (set (match_dup 7) (mem:DI (plus:DI (match_dup 6) (match_dup 7)))) ! 4767: (set (pc) (match_dup 7))] ! 4768: "TARGET_MEDANY" ! 4769: " ! 4770: { ! 4771: operands[5] = gen_reg_rtx (SImode); ! 4772: operands[6] = gen_reg_rtx (DImode); ! 4773: operands[7] = gen_reg_rtx (DImode); ! 4774: }") ! 4775: 1.1 root 4776: ;; This pattern recognizes the "instruction" that appears in 4777: ;; a function call that wants a structure value, 4778: ;; to inform the called function if compiled with Sun CC. 1.1.1.4 ! root 4779: ;(define_insn "*unimp_insn" 1.1 root 4780: ; [(match_operand:SI 0 "immediate_operand" "")] 4781: ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0" 4782: ; "unimp %0" 4783: ; [(set_attr "type" "marker")]) 4784: 4785: ;;- jump to subroutine 4786: (define_expand "call" 4787: ;; Note that this expression is not used for generating RTL. 4788: ;; All the RTL is generated explicitly below. 1.1.1.3 root 4789: [(call (match_operand 0 "call_operand" "") 1.1 root 4790: (match_operand 3 "" "i"))] 4791: ;; operands[2] is next_arg_register 4792: ;; operands[3] is struct_value_size_rtx. 4793: "" 4794: " 4795: { 4796: rtx fn_rtx, nregs_rtx; 4797: 1.1.1.3 root 4798: if (GET_MODE (operands[0]) != FUNCTION_MODE) 4799: abort (); 4800: 4801: if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF) 1.1 root 4802: { 4803: /* This is really a PIC sequence. We want to represent 4804: it as a funny jump so it's delay slots can be filled. 4805: 4806: ??? But if this really *is* a CALL, will not it clobber the 4807: call-clobbered registers? We lose this if it is a JUMP_INSN. 4808: Why cannot we have delay slots filled if it were a CALL? */ 4809: 1.1.1.3 root 4810: if (! TARGET_V9 && INTVAL (operands[3]) != 0) 1.1 root 4811: emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3, 4812: gen_rtx (SET, VOIDmode, pc_rtx, 4813: XEXP (operands[0], 0)), 4814: operands[3], 4815: gen_rtx (CLOBBER, VOIDmode, 1.1.1.3 root 4816: gen_rtx (REG, Pmode, 15))))); 1.1 root 4817: else 4818: emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, 4819: gen_rtx (SET, VOIDmode, pc_rtx, 4820: XEXP (operands[0], 0)), 4821: gen_rtx (CLOBBER, VOIDmode, 1.1.1.3 root 4822: gen_rtx (REG, Pmode, 15))))); 1.1 root 4823: goto finish_call; 4824: } 4825: 4826: fn_rtx = operands[0]; 4827: 4828: /* Count the number of parameter registers being used by this call. 4829: if that argument is NULL, it means we are using them all, which 4830: means 6 on the sparc. */ 4831: #if 0 4832: if (operands[2]) 4833: nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8); 4834: else 4835: nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6); 4836: #else 4837: nregs_rtx = const0_rtx; 4838: #endif 4839: 1.1.1.3 root 4840: if (! TARGET_V9 && INTVAL (operands[3]) != 0) 1.1 root 4841: emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3, 4842: gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx), 4843: operands[3], 4844: gen_rtx (CLOBBER, VOIDmode, 1.1.1.3 root 4845: gen_rtx (REG, Pmode, 15))))); 1.1 root 4846: else 4847: emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, 4848: gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx), 4849: gen_rtx (CLOBBER, VOIDmode, 1.1.1.3 root 4850: gen_rtx (REG, Pmode, 15))))); 1.1 root 4851: 4852: finish_call: 4853: #if 0 4854: /* If this call wants a structure value, 4855: emit an unimp insn to let the called function know about this. */ 1.1.1.3 root 4856: if (! TARGET_V9 && INTVAL (operands[3]) > 0) 1.1 root 4857: { 4858: rtx insn = emit_insn (operands[3]); 4859: SCHED_GROUP_P (insn) = 1; 4860: } 4861: #endif 4862: 4863: DONE; 4864: }") 4865: 1.1.1.2 root 4866: ;; We can't use the same pattern for these two insns, because then registers 4867: ;; in the address may not be properly reloaded. 4868: 1.1.1.4 ! root 4869: (define_insn "*call_address_sp32" 1.1.1.2 root 4870: [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) 4871: (match_operand 1 "" "")) 4872: (clobber (reg:SI 15))] 4873: ;;- Do not use operand 1 for most machines. 1.1.1.3 root 4874: "! TARGET_PTR64" 1.1.1.4 ! root 4875: "call %a0,%1%#" 1.1.1.2 root 4876: [(set_attr "type" "call")]) 4877: 1.1.1.4 ! root 4878: (define_insn "*call_symbolic_sp32" 1.1.1.3 root 4879: [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) 1.1 root 4880: (match_operand 1 "" "")) 4881: (clobber (reg:SI 15))] 4882: ;;- Do not use operand 1 for most machines. 1.1.1.3 root 4883: "! TARGET_PTR64" 1.1.1.4 ! root 4884: "call %a0,%1%#" 1.1.1.3 root 4885: [(set_attr "type" "call")]) 4886: 1.1.1.4 ! root 4887: (define_insn "*call_address_sp64" 1.1.1.3 root 4888: [(call (mem:SI (match_operand:DI 0 "address_operand" "p")) 4889: (match_operand 1 "" "")) 4890: (clobber (reg:DI 15))] 4891: ;;- Do not use operand 1 for most machines. 4892: "TARGET_PTR64" 1.1.1.4 ! root 4893: "call %a0,%1%#" 1.1.1.3 root 4894: [(set_attr "type" "call")]) 4895: 1.1.1.4 ! root 4896: (define_insn "*call_symbolic_sp64" 1.1.1.3 root 4897: [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s")) 4898: (match_operand 1 "" "")) 4899: (clobber (reg:DI 15))] 4900: ;;- Do not use operand 1 for most machines. 4901: "TARGET_PTR64" 1.1.1.4 ! root 4902: "call %a0,%1%#" 1.1 root 4903: [(set_attr "type" "call")]) 4904: 4905: ;; This is a call that wants a structure value. 1.1.1.3 root 4906: ;; There is no such critter for v9 (??? we may need one anyway). 1.1.1.4 ! root 4907: (define_insn "*call_address_struct_value_sp32" 1.1.1.2 root 4908: [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) 4909: (match_operand 1 "" "")) 4910: (match_operand 2 "immediate_operand" "") 4911: (clobber (reg:SI 15))] 4912: ;;- Do not use operand 1 for most machines. 1.1.1.3 root 4913: "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0" 1.1.1.4 ! root 4914: "call %a0,%1\;nop\;unimp %2" 1.1.1.2 root 4915: [(set_attr "type" "call_no_delay_slot")]) 4916: 4917: ;; This is a call that wants a structure value. 1.1.1.3 root 4918: ;; There is no such critter for v9 (??? we may need one anyway). 1.1.1.4 ! root 4919: (define_insn "*call_symbolic_struct_value_sp32" 1.1.1.3 root 4920: [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) 1.1 root 4921: (match_operand 1 "" "")) 4922: (match_operand 2 "immediate_operand" "") 4923: (clobber (reg:SI 15))] 4924: ;;- Do not use operand 1 for most machines. 1.1.1.3 root 4925: "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0" 1.1.1.4 ! root 4926: "call %a0,%1\;nop\;unimp %2" 1.1 root 4927: [(set_attr "type" "call_no_delay_slot")]) 4928: 1.1.1.3 root 4929: ;; This is a call that may want a structure value. This is used for 4930: ;; untyped_calls. 1.1.1.4 ! root 4931: (define_insn "*call_address_untyped_struct_value_sp32" 1.1.1.3 root 4932: [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) 4933: (match_operand 1 "" "")) 4934: (match_operand 2 "immediate_operand" "") 4935: (clobber (reg:SI 15))] 4936: ;;- Do not use operand 1 for most machines. 4937: "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0" 1.1.1.4 ! root 4938: "call %a0,%1\;nop\;nop" 1.1.1.3 root 4939: [(set_attr "type" "call_no_delay_slot")]) 4940: 4941: ;; This is a call that wants a structure value. 1.1.1.4 ! root 4942: (define_insn "*call_symbolic_untyped_struct_value_sp32" 1.1.1.3 root 4943: [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) 4944: (match_operand 1 "" "")) 4945: (match_operand 2 "immediate_operand" "") 4946: (clobber (reg:SI 15))] 4947: ;;- Do not use operand 1 for most machines. 4948: "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0" 1.1.1.4 ! root 4949: "call %a0,%1\;nop\;nop" 1.1.1.3 root 4950: [(set_attr "type" "call_no_delay_slot")]) 4951: 1.1 root 4952: (define_expand "call_value" 1.1.1.3 root 4953: ;; Note that this expression is not used for generating RTL. 4954: ;; All the RTL is generated explicitly below. 1.1 root 4955: [(set (match_operand 0 "register_operand" "=rf") 4956: (call (match_operand:SI 1 "" "") 4957: (match_operand 4 "" "")))] 1.1.1.3 root 4958: ;; operand 2 is stack_size_rtx 1.1 root 4959: ;; operand 3 is next_arg_register 4960: "" 4961: " 4962: { 4963: rtx fn_rtx, nregs_rtx; 4964: rtvec vec; 4965: 1.1.1.3 root 4966: if (GET_MODE (operands[1]) != FUNCTION_MODE) 4967: abort (); 4968: 1.1 root 4969: fn_rtx = operands[1]; 4970: 4971: #if 0 4972: if (operands[3]) 4973: nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8); 4974: else 4975: nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6); 4976: #else 4977: nregs_rtx = const0_rtx; 4978: #endif 4979: 4980: vec = gen_rtvec (2, 4981: gen_rtx (SET, VOIDmode, operands[0], 4982: gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)), 1.1.1.3 root 4983: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, Pmode, 15))); 1.1 root 4984: 4985: emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec)); 4986: 4987: DONE; 4988: }") 4989: 1.1.1.4 ! root 4990: (define_insn "*call_value_address_sp32" 1.1 root 4991: [(set (match_operand 0 "" "=rf") 1.1.1.2 root 4992: (call (mem:SI (match_operand:SI 1 "address_operand" "p")) 4993: (match_operand 2 "" ""))) 4994: (clobber (reg:SI 15))] 4995: ;;- Do not use operand 2 for most machines. 1.1.1.3 root 4996: "! TARGET_PTR64" 1.1.1.4 ! root 4997: "call %a1,%2%#" 1.1.1.2 root 4998: [(set_attr "type" "call")]) 4999: 1.1.1.4 ! root 5000: (define_insn "*call_value_symbolic_sp32" 1.1.1.2 root 5001: [(set (match_operand 0 "" "=rf") 1.1.1.3 root 5002: (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s")) 1.1 root 5003: (match_operand 2 "" ""))) 5004: (clobber (reg:SI 15))] 5005: ;;- Do not use operand 2 for most machines. 1.1.1.3 root 5006: "! TARGET_PTR64" 1.1.1.4 ! root 5007: "call %a1,%2%#" 1.1.1.3 root 5008: [(set_attr "type" "call")]) 5009: 1.1.1.4 ! root 5010: (define_insn "*call_value_address_sp64" 1.1.1.3 root 5011: [(set (match_operand 0 "" "=rf") 5012: (call (mem:SI (match_operand:DI 1 "address_operand" "p")) 5013: (match_operand 2 "" ""))) 5014: (clobber (reg:DI 15))] 5015: ;;- Do not use operand 2 for most machines. 5016: "TARGET_PTR64" 1.1.1.4 ! root 5017: "call %a1,%2%#" 1.1.1.3 root 5018: [(set_attr "type" "call")]) 5019: 1.1.1.4 ! root 5020: (define_insn "*call_value_symbolic_sp64" 1.1.1.3 root 5021: [(set (match_operand 0 "" "=rf") 5022: (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s")) 5023: (match_operand 2 "" ""))) 5024: (clobber (reg:DI 15))] 5025: ;;- Do not use operand 2 for most machines. 5026: "TARGET_PTR64" 1.1.1.4 ! root 5027: "call %a1,%2%#" 1.1 root 5028: [(set_attr "type" "call")]) 5029: 5030: (define_expand "untyped_call" 1.1.1.3 root 5031: [(parallel [(call (match_operand 0 "" "") 1.1 root 5032: (const_int 0)) 1.1.1.3 root 5033: (match_operand 1 "" "") 5034: (match_operand 2 "" "")])] 1.1 root 5035: "" 5036: " 5037: { 1.1.1.3 root 5038: int i; 1.1 root 5039: 1.1.1.3 root 5040: /* Pass constm1 to indicate that it may expect a structure value, but 5041: we don't know what size it is. */ 5042: emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx)); 1.1 root 5043: 1.1.1.3 root 5044: for (i = 0; i < XVECLEN (operands[2], 0); i++) 5045: { 5046: rtx set = XVECEXP (operands[2], 0, i); 5047: emit_move_insn (SET_DEST (set), SET_SRC (set)); 5048: } 1.1.1.2 root 5049: 1.1.1.3 root 5050: /* The optimizer does not know that the call sets the function value 5051: registers we stored in the result block. We avoid problems by 5052: claiming that all hard registers are used and clobbered at this 5053: point. */ 5054: emit_insn (gen_blockage ()); 1.1.1.2 root 5055: 1.1.1.3 root 5056: DONE; 5057: }") 5058: 5059: ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 5060: ;; all of memory. This blocks insns from being moved across this point. 5061: 5062: (define_insn "blockage" 5063: [(unspec_volatile [(const_int 0)] 0)] 1.1 root 5064: "" 1.1.1.3 root 5065: "") 1.1 root 5066: 5067: ;; Prepare to return any type including a structure value. 5068: 5069: (define_expand "untyped_return" 5070: [(match_operand:BLK 0 "memory_operand" "") 5071: (match_operand 1 "" "")] 5072: "" 5073: " 5074: { 5075: rtx valreg1 = gen_rtx (REG, DImode, 24); 1.1.1.3 root 5076: rtx valreg2 = gen_rtx (REG, TARGET_V9 ? TFmode : DFmode, 32); 1.1 root 5077: rtx result = operands[0]; 5078: 1.1.1.3 root 5079: if (! TARGET_V9) 5080: { 5081: rtx rtnreg = gen_rtx (REG, SImode, (leaf_function ? 15 : 31)); 5082: rtx value = gen_reg_rtx (SImode); 5083: 5084: /* Fetch the instruction where we will return to and see if it's an unimp 5085: instruction (the most significant 10 bits will be zero). If so, 5086: update the return address to skip the unimp instruction. */ 5087: emit_move_insn (value, 5088: gen_rtx (MEM, SImode, plus_constant (rtnreg, 8))); 5089: emit_insn (gen_lshrsi3 (value, value, GEN_INT (22))); 5090: emit_insn (gen_update_return (rtnreg, value)); 5091: } 1.1 root 5092: 5093: /* Reload the function value registers. */ 5094: emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0))); 5095: emit_move_insn (valreg2, 1.1.1.3 root 5096: change_address (result, TARGET_V9 ? TFmode : DFmode, 1.1 root 5097: plus_constant (XEXP (result, 0), 8))); 5098: 5099: /* Put USE insns before the return. */ 5100: emit_insn (gen_rtx (USE, VOIDmode, valreg1)); 5101: emit_insn (gen_rtx (USE, VOIDmode, valreg2)); 5102: 5103: /* Construct the return. */ 5104: expand_null_return (); 5105: 5106: DONE; 5107: }") 5108: 5109: ;; This is a bit of a hack. We're incrementing a fixed register (%i7), 5110: ;; and parts of the compiler don't want to believe that the add is needed. 5111: 5112: (define_insn "update_return" 5113: [(unspec:SI [(match_operand:SI 0 "register_operand" "r") 5114: (match_operand:SI 1 "register_operand" "r")] 0)] 1.1.1.3 root 5115: "! TARGET_V9" 1.1 root 5116: "cmp %1,0\;be,a .+8\;add %0,4,%0" 5117: [(set_attr "type" "multi")]) 5118: 5119: (define_insn "return" 5120: [(return)] 5121: "! TARGET_EPILOGUE" 5122: "* return output_return (operands);" 5123: [(set_attr "type" "multi")]) 5124: 5125: (define_insn "nop" 5126: [(const_int 0)] 5127: "" 5128: "nop") 5129: 1.1.1.3 root 5130: (define_expand "indirect_jump" 5131: [(set (pc) (match_operand 0 "address_operand" "p"))] 1.1 root 5132: "" 1.1.1.3 root 5133: "") 5134: 1.1.1.4 ! root 5135: (define_insn "*branch_sp32" 1.1.1.3 root 5136: [(set (pc) (match_operand:SI 0 "address_operand" "p"))] 5137: "! TARGET_PTR64" 1.1 root 5138: "jmp %a0%#" 5139: [(set_attr "type" "uncond_branch")]) 5140: 1.1.1.4 ! root 5141: (define_insn "*branch_sp64" 1.1.1.3 root 5142: [(set (pc) (match_operand:DI 0 "address_operand" "p"))] 5143: "TARGET_PTR64" 5144: "jmp %a0%#" 5145: [(set_attr "type" "uncond_branch")]) 5146: 1.1.1.4 ! root 5147: ;; ??? Doesn't work with -mflat. 1.1 root 5148: (define_expand "nonlocal_goto" 5149: [(match_operand:SI 0 "general_operand" "") 5150: (match_operand:SI 1 "general_operand" "") 5151: (match_operand:SI 2 "general_operand" "") 5152: (match_operand:SI 3 "" "")] 5153: "" 5154: " 5155: { 1.1.1.3 root 5156: /* Trap instruction to flush all the register windows. */ 1.1 root 5157: emit_insn (gen_flush_register_windows ()); 5158: /* Load the fp value for the containing fn into %fp. 5159: This is needed because operands[2] refers to %fp. 5160: Virtual register instantiation fails if the virtual %fp isn't set from a 5161: register. Thus we must copy operands[0] into a register if it isn't 5162: already one. */ 5163: if (GET_CODE (operands[0]) != REG) 1.1.1.4 ! root 5164: operands[0] = force_reg (Pmode, operands[0]); 1.1 root 5165: emit_move_insn (virtual_stack_vars_rtx, operands[0]); 5166: /* Find the containing function's current nonlocal goto handler, 5167: which will do any cleanups and then jump to the label. */ 1.1.1.4 ! root 5168: emit_move_insn (gen_rtx (REG, Pmode, 8), operands[1]); 1.1 root 5169: /* Restore %fp from stack pointer value for containing function. 5170: The restore insn that follows will move this to %sp, 5171: and reload the appropriate value into %fp. */ 5172: emit_move_insn (frame_pointer_rtx, operands[2]); 5173: /* Put in the static chain register the nonlocal label address. */ 5174: emit_move_insn (static_chain_rtx, operands[3]); 5175: /* USE of frame_pointer_rtx added for consistency; not clear if 5176: really needed. */ 5177: emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx)); 5178: emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx)); 5179: emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx)); 1.1.1.4 ! root 5180: emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, Pmode, 8))); 1.1 root 5181: /* Return, restoring reg window and jumping to goto handler. */ 5182: emit_insn (gen_goto_handler_and_restore ()); 5183: DONE; 5184: }") 5185: 5186: ;; Special trap insn to flush register windows. 5187: (define_insn "flush_register_windows" 1.1.1.3 root 5188: [(unspec_volatile [(const_int 0)] 1)] 1.1 root 5189: "" 1.1.1.3 root 5190: "* return TARGET_V9 ? \"flushw\" : \"ta 3\";" 1.1 root 5191: [(set_attr "type" "misc")]) 5192: 5193: (define_insn "goto_handler_and_restore" 1.1.1.3 root 5194: [(unspec_volatile [(const_int 0)] 2)] 1.1 root 5195: "" 5196: "jmp %%o0+0\;restore" 5197: [(set_attr "type" "misc") 5198: (set_attr "length" "2")]) 1.1.1.2 root 5199: 5200: ;; Special pattern for the FLUSH instruction. 5201: 5202: (define_insn "flush" 1.1.1.4 ! root 5203: [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 3)] 1.1.1.2 root 5204: "" 1.1.1.4 ! root 5205: "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";" 1.1.1.2 root 5206: [(set_attr "type" "misc")]) 1.1 root 5207: 5208: ;; find first set. 5209: 5210: ;; The scan instruction searches from the most significant bit while ffs 5211: ;; searches from the least significant bit. The bit index and treatment of 5212: ;; zero also differ. It takes at least 7 instructions to get the proper 1.1.1.4 ! root 5213: ;; result. Here is an obvious 8 instruction sequence. 1.1 root 5214: 5215: (define_insn "ffssi2" 5216: [(set (match_operand:SI 0 "register_operand" "=&r") 5217: (ffs:SI (match_operand:SI 1 "register_operand" "r"))) 5218: (clobber (match_scratch:SI 2 "=&r"))] 5219: "TARGET_SPARCLITE" 5220: "sub %%g0,%1,%0\;and %0,%1,%0\;scan %0,0,%0\;mov 32,%2\;sub %2,%0,%0\;sra %0,31,%2\;and %2,31,%2\;add %2,%0,%0" 5221: [(set_attr "type" "multi") 5222: (set_attr "length" "8")]) 1.1.1.3 root 5223: 5224: ;; ??? This should be a define expand, so that the extra instruction have 5225: ;; a chance of being optimized away. 5226: 5227: (define_insn "ffsdi2" 5228: [(set (match_operand:DI 0 "register_operand" "=&r") 5229: (ffs:DI (match_operand:DI 1 "register_operand" "r"))) 5230: (clobber (match_scratch:DI 2 "=&r"))] 5231: "TARGET_V9" 5232: "neg %1,%2\;not %2,%2\;xor %1,%2,%2\;popc %2,%0\;movrz %1,%%g0,%0" 5233: [(set_attr "type" "multi") 5234: (set_attr "length" "5")]) 1.1 root 5235: 5236: ;; Split up troublesome insns for better scheduling. */ 5237: 5238: ;; The following patterns are straightforward. They can be applied 5239: ;; either before or after register allocation. 5240: 5241: (define_split 1.1.1.4 ! root 5242: [(set (match_operand 0 "splittable_symbolic_memory_operand" "") ! 5243: (match_operand 1 "reg_or_0_operand" "")) ! 5244: (clobber (match_operand:SI 2 "register_operand" ""))] 1.1 root 5245: "! flag_pic" 1.1.1.4 ! root 5246: [(set (match_dup 2) (high:SI (match_dup 3))) ! 5247: (set (match_dup 4) (match_dup 1))] ! 5248: " ! 5249: { ! 5250: operands[3] = XEXP (operands[0], 0); ! 5251: operands[4] = gen_rtx (MEM, GET_MODE (operands[0]), ! 5252: gen_rtx (LO_SUM, SImode, operands[2], operands[3])); ! 5253: MEM_IN_STRUCT_P (operands[4]) = MEM_IN_STRUCT_P (operands[0]); ! 5254: MEM_VOLATILE_P (operands[4]) = MEM_VOLATILE_P (operands[0]); ! 5255: RTX_UNCHANGING_P (operands[4]) = RTX_UNCHANGING_P (operands[0]); ! 5256: }") 1.1 root 5257: 5258: (define_split 1.1.1.4 ! root 5259: [(set (match_operand 0 "splittable_immediate_memory_operand" "") ! 5260: (match_operand 1 "general_operand" "")) ! 5261: (clobber (match_operand:SI 2 "register_operand" ""))] 1.1 root 5262: "flag_pic" 1.1.1.4 ! root 5263: [(set (match_dup 3) (match_dup 1))] 1.1 root 5264: " 5265: { 1.1.1.4 ! root 5266: rtx addr = legitimize_pic_address (XEXP (operands[0], 0), ! 5267: GET_MODE (operands[0]), ! 5268: operands[2]); ! 5269: operands[3] = gen_rtx (MEM, GET_MODE (operands[0]), addr); ! 5270: MEM_IN_STRUCT_P (operands[3]) = MEM_IN_STRUCT_P (operands[0]); ! 5271: MEM_VOLATILE_P (operands[3]) = MEM_VOLATILE_P (operands[0]); ! 5272: RTX_UNCHANGING_P (operands[3]) = RTX_UNCHANGING_P (operands[0]); 1.1 root 5273: }") 5274: 5275: (define_split 5276: [(set (match_operand 0 "register_operand" "") 1.1.1.4 ! root 5277: (match_operand 1 "splittable_immediate_memory_operand" ""))] 1.1 root 5278: "flag_pic" 1.1.1.4 ! root 5279: [(set (match_dup 0) (match_dup 2))] 1.1 root 5280: " 5281: { 1.1.1.4 ! root 5282: rtx addr = legitimize_pic_address (XEXP (operands[1], 0), ! 5283: GET_MODE (operands[1]), ! 5284: operands[0]); ! 5285: operands[2] = gen_rtx (MEM, GET_MODE (operands[1]), addr); ! 5286: MEM_IN_STRUCT_P (operands[2]) = MEM_IN_STRUCT_P (operands[1]); ! 5287: MEM_VOLATILE_P (operands[2]) = MEM_VOLATILE_P (operands[1]); ! 5288: RTX_UNCHANGING_P (operands[2]) = RTX_UNCHANGING_P (operands[1]); 1.1 root 5289: }") 5290: 5291: ;; Sign- and Zero-extend operations can have symbolic memory operands. 5292: 5293: (define_split 5294: [(set (match_operand 0 "register_operand" "") 1.1.1.4 ! root 5295: (match_operator 1 "extend_op" [(match_operand 2 "splittable_immediate_memory_operand" "")]))] 1.1 root 5296: "flag_pic" 1.1.1.4 ! root 5297: [(set (match_dup 0) (match_op_dup 1 [(match_dup 3)]))] 1.1 root 5298: " 5299: { 1.1.1.4 ! root 5300: rtx addr = legitimize_pic_address (XEXP (operands[2], 0), ! 5301: GET_MODE (operands[2]), ! 5302: operands[0]); ! 5303: operands[3] = gen_rtx (MEM, GET_MODE (operands[2]), addr); ! 5304: MEM_IN_STRUCT_P (operands[3]) = MEM_IN_STRUCT_P (operands[2]); ! 5305: MEM_VOLATILE_P (operands[3]) = MEM_VOLATILE_P (operands[2]); ! 5306: RTX_UNCHANGING_P (operands[3]) = RTX_UNCHANGING_P (operands[2]); 1.1 root 5307: }") 5308: 5309: (define_split 5310: [(set (match_operand:SI 0 "register_operand" "") 5311: (match_operand:SI 1 "immediate_operand" ""))] 5312: "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF 5313: || GET_CODE (operands[1]) == CONST 5314: || GET_CODE (operands[1]) == LABEL_REF)" 5315: [(set (match_dup 0) (high:SI (match_dup 1))) 5316: (set (match_dup 0) 5317: (lo_sum:SI (match_dup 0) (match_dup 1)))] 5318: "") 5319: 5320: ;; LABEL_REFs are not modified by `legitimize_pic_address` 5321: ;; so do not recurse infinitely in the PIC case. 5322: (define_split 5323: [(set (match_operand:SI 0 "register_operand" "") 5324: (match_operand:SI 1 "immediate_operand" ""))] 5325: "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF 5326: || GET_CODE (operands[1]) == CONST)" 5327: [(set (match_dup 0) (match_dup 1))] 5328: " 5329: { 1.1.1.2 root 5330: operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0]); 1.1 root 5331: }") 5332: 5333: ;; These split sne/seq insns. The forms of the resulting insns are 5334: ;; somewhat bogus, but they avoid extra patterns and show data dependency. 5335: ;; Nothing will look at these in detail after splitting has occurred. 5336: 1.1.1.3 root 5337: ;; ??? v9 DImode versions are missing because addc and subc use %icc. 5338: 1.1 root 5339: (define_split 5340: [(set (match_operand:SI 0 "register_operand" "") 1.1.1.3 root 5341: (ne:SI (match_operand:SI 1 "register_operand" "") 5342: (const_int 0))) 1.1 root 5343: (clobber (reg:CC 0))] 5344: "" 5345: [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) 5346: (const_int 0))) 5347: (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))] 5348: "") 5349: 5350: (define_split 5351: [(set (match_operand:SI 0 "register_operand" "") 5352: (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "") 5353: (const_int 0)))) 5354: (clobber (reg:CC 0))] 5355: "" 5356: [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) 5357: (const_int 0))) 5358: (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))] 5359: "") 5360: 5361: (define_split 5362: [(set (match_operand:SI 0 "register_operand" "") 1.1.1.3 root 5363: (eq:SI (match_operand:SI 1 "register_operand" "") 5364: (const_int 0))) 1.1 root 5365: (clobber (reg:CC 0))] 5366: "" 5367: [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) 5368: (const_int 0))) 5369: (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))] 5370: "") 5371: 5372: (define_split 5373: [(set (match_operand:SI 0 "register_operand" "") 5374: (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "") 5375: (const_int 0)))) 5376: (clobber (reg:CC 0))] 5377: "" 5378: [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) 5379: (const_int 0))) 5380: (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))] 5381: "") 5382: 5383: (define_split 5384: [(set (match_operand:SI 0 "register_operand" "") 5385: (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "") 5386: (const_int 0)) 5387: (match_operand:SI 2 "register_operand" ""))) 5388: (clobber (reg:CC 0))] 5389: "" 5390: [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) 5391: (const_int 0))) 5392: (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) 5393: (match_dup 2)))] 5394: "") 5395: 5396: (define_split 5397: [(set (match_operand:SI 0 "register_operand" "") 5398: (minus:SI (match_operand:SI 2 "register_operand" "") 5399: (ne:SI (match_operand:SI 1 "register_operand" "") 5400: (const_int 0)))) 5401: (clobber (reg:CC 0))] 5402: "" 5403: [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) 5404: (const_int 0))) 5405: (set (match_dup 0) (minus:SI (match_dup 2) 5406: (ltu:SI (reg:CC 0) (const_int 0))))] 5407: "") 5408: 5409: (define_split 5410: [(set (match_operand:SI 0 "register_operand" "") 5411: (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "") 5412: (const_int 0)) 5413: (match_operand:SI 2 "register_operand" ""))) 5414: (clobber (reg:CC 0))] 5415: "" 5416: [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) 5417: (const_int 0))) 5418: (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0)) 5419: (match_dup 2)))] 5420: "") 5421: 5422: (define_split 5423: [(set (match_operand:SI 0 "register_operand" "") 5424: (minus:SI (match_operand:SI 2 "register_operand" "") 5425: (eq:SI (match_operand:SI 1 "register_operand" "") 5426: (const_int 0)))) 5427: (clobber (reg:CC 0))] 5428: "" 5429: [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) 5430: (const_int 0))) 5431: (set (match_dup 0) (minus:SI (match_dup 2) 5432: (geu:SI (reg:CC 0) (const_int 0))))] 5433: "") 5434: 5435: ;; Peepholes go at the end. 5436: 5437: ;; Optimize consecutive loads or stores into ldd and std when possible. 5438: ;; The conditions in which we do this are very restricted and are 5439: ;; explained in the code for {registers,memory}_ok_for_ldd functions. 5440: 5441: (define_peephole 5442: [(set (match_operand:SI 0 "register_operand" "=rf") 5443: (match_operand:SI 1 "memory_operand" "")) 5444: (set (match_operand:SI 2 "register_operand" "=rf") 5445: (match_operand:SI 3 "memory_operand" ""))] 1.1.1.3 root 5446: "! TARGET_V9 5447: && registers_ok_for_ldd_peep (operands[0], operands[2]) 1.1 root 5448: && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3]) 5449: && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" 5450: "ldd %1,%0") 5451: 5452: (define_peephole 5453: [(set (match_operand:SI 0 "memory_operand" "") 5454: (match_operand:SI 1 "register_operand" "rf")) 5455: (set (match_operand:SI 2 "memory_operand" "") 5456: (match_operand:SI 3 "register_operand" "rf"))] 1.1.1.3 root 5457: "! TARGET_V9 5458: && registers_ok_for_ldd_peep (operands[1], operands[3]) 1.1 root 5459: && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2]) 5460: && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))" 5461: "std %1,%0") 5462: 5463: (define_peephole 5464: [(set (match_operand:SF 0 "register_operand" "=fr") 5465: (match_operand:SF 1 "memory_operand" "")) 5466: (set (match_operand:SF 2 "register_operand" "=fr") 5467: (match_operand:SF 3 "memory_operand" ""))] 1.1.1.3 root 5468: "! TARGET_V9 5469: && registers_ok_for_ldd_peep (operands[0], operands[2]) 1.1 root 5470: && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3]) 5471: && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" 5472: "ldd %1,%0") 5473: 5474: (define_peephole 5475: [(set (match_operand:SF 0 "memory_operand" "") 5476: (match_operand:SF 1 "register_operand" "fr")) 5477: (set (match_operand:SF 2 "memory_operand" "") 5478: (match_operand:SF 3 "register_operand" "fr"))] 1.1.1.3 root 5479: "! TARGET_V9 5480: && registers_ok_for_ldd_peep (operands[1], operands[3]) 1.1 root 5481: && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2]) 5482: && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))" 5483: "std %1,%0") 5484: 5485: (define_peephole 5486: [(set (match_operand:SI 0 "register_operand" "=rf") 5487: (match_operand:SI 1 "memory_operand" "")) 5488: (set (match_operand:SI 2 "register_operand" "=rf") 5489: (match_operand:SI 3 "memory_operand" ""))] 1.1.1.3 root 5490: "! TARGET_V9 5491: && registers_ok_for_ldd_peep (operands[2], operands[0]) 1.1 root 5492: && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1]) 5493: && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))" 5494: "ldd %3,%2") 5495: 5496: (define_peephole 5497: [(set (match_operand:SI 0 "memory_operand" "") 5498: (match_operand:SI 1 "register_operand" "rf")) 5499: (set (match_operand:SI 2 "memory_operand" "") 5500: (match_operand:SI 3 "register_operand" "rf"))] 1.1.1.3 root 5501: "! TARGET_V9 5502: && registers_ok_for_ldd_peep (operands[3], operands[1]) 1.1 root 5503: && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0]) 5504: && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" 5505: "std %3,%2") 5506: 5507: (define_peephole 5508: [(set (match_operand:SF 0 "register_operand" "=fr") 5509: (match_operand:SF 1 "memory_operand" "")) 5510: (set (match_operand:SF 2 "register_operand" "=fr") 5511: (match_operand:SF 3 "memory_operand" ""))] 1.1.1.3 root 5512: "! TARGET_V9 5513: && registers_ok_for_ldd_peep (operands[2], operands[0]) 1.1 root 5514: && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1]) 5515: && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))" 5516: "ldd %3,%2") 5517: 5518: (define_peephole 5519: [(set (match_operand:SF 0 "memory_operand" "") 5520: (match_operand:SF 1 "register_operand" "fr")) 5521: (set (match_operand:SF 2 "memory_operand" "") 5522: (match_operand:SF 3 "register_operand" "fr"))] 1.1.1.3 root 5523: "! TARGET_V9 5524: && registers_ok_for_ldd_peep (operands[3], operands[1]) 1.1 root 5525: && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0]) 5526: && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" 5527: "std %3,%2") 5528: 5529: ;; Optimize the case of following a reg-reg move with a test 5530: ;; of reg just moved. Don't allow floating point regs for operand 0 or 1. 5531: ;; This can result from a float to fix conversion. 5532: 5533: (define_peephole 5534: [(set (match_operand:SI 0 "register_operand" "=r") 5535: (match_operand:SI 1 "register_operand" "r")) 5536: (set (reg:CC 0) 5537: (compare:CC (match_operand:SI 2 "register_operand" "r") 5538: (const_int 0)))] 5539: "(rtx_equal_p (operands[2], operands[0]) 5540: || rtx_equal_p (operands[2], operands[1])) 5541: && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])" 5542: "orcc %1,%%g0,%0") 5543: 1.1.1.3 root 5544: (define_peephole 5545: [(set (match_operand:DI 0 "register_operand" "=r") 5546: (match_operand:DI 1 "register_operand" "r")) 5547: (set (reg:CCX 0) 5548: (compare:CCX (match_operand:DI 2 "register_operand" "r") 5549: (const_int 0)))] 5550: "TARGET_V9 5551: && (rtx_equal_p (operands[2], operands[0]) 5552: || rtx_equal_p (operands[2], operands[1])) 5553: && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])" 5554: "orcc %1,%%g0,%0") 5555: 1.1 root 5556: ;; Do {sign,zero}-extended compares somewhat more efficiently. 5557: ;; ??? Is this now the Right Way to do this? Or will SCRATCH 5558: ;; eventually have some impact here? 5559: 5560: (define_peephole 5561: [(set (match_operand:HI 0 "register_operand" "") 5562: (match_operand:HI 1 "memory_operand" "")) 5563: (set (match_operand:SI 2 "register_operand" "") 5564: (sign_extend:SI (match_dup 0))) 5565: (set (reg:CC 0) 5566: (compare:CC (match_dup 2) 5567: (const_int 0)))] 5568: "" 5569: "ldsh %1,%0\;orcc %0,%%g0,%2") 5570: 5571: (define_peephole 1.1.1.3 root 5572: [(set (match_operand:HI 0 "register_operand" "") 5573: (match_operand:HI 1 "memory_operand" "")) 5574: (set (match_operand:DI 2 "register_operand" "") 5575: (sign_extend:DI (match_dup 0))) 5576: (set (reg:CCX 0) 5577: (compare:CCX (match_dup 2) 5578: (const_int 0)))] 5579: "TARGET_V9" 5580: "ldsh %1,%0\;orcc %0,%%g0,%2") 5581: 5582: (define_peephole 1.1 root 5583: [(set (match_operand:QI 0 "register_operand" "") 5584: (match_operand:QI 1 "memory_operand" "")) 5585: (set (match_operand:SI 2 "register_operand" "") 5586: (sign_extend:SI (match_dup 0))) 5587: (set (reg:CC 0) 5588: (compare:CC (match_dup 2) 5589: (const_int 0)))] 5590: "" 5591: "ldsb %1,%0\;orcc %0,%%g0,%2") 5592: 5593: (define_peephole 1.1.1.3 root 5594: [(set (match_operand:QI 0 "register_operand" "") 5595: (match_operand:QI 1 "memory_operand" "")) 5596: (set (match_operand:DI 2 "register_operand" "") 5597: (sign_extend:DI (match_dup 0))) 5598: (set (reg:CCX 0) 5599: (compare:CCX (match_dup 2) 5600: (const_int 0)))] 5601: "TARGET_V9" 5602: "ldsb %1,%0\;orcc %0,%%g0,%2") 5603: 1.1 root 5604: ;; Floating-point move peepholes 1.1.1.3 root 5605: ;; ??? v9: Do we want similar ones? 1.1 root 5606: 5607: (define_peephole 5608: [(set (match_operand:SI 0 "register_operand" "=r") 5609: (lo_sum:SI (match_dup 0) 5610: (match_operand:SI 1 "immediate_operand" "i"))) 1.1.1.3 root 5611: (set (match_operand:DF 2 "register_operand" "=er") 1.1 root 5612: (mem:DF (match_dup 0)))] 5613: "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)" 5614: "* 5615: { 5616: /* Go by way of output_move_double in case the register in operand 2 5617: is not properly aligned for ldd. */ 5618: operands[1] = gen_rtx (MEM, DFmode, 5619: gen_rtx (LO_SUM, SImode, operands[0], operands[1])); 5620: operands[0] = operands[2]; 5621: return output_move_double (operands); 5622: }") 5623: 5624: (define_peephole 5625: [(set (match_operand:SI 0 "register_operand" "=r") 5626: (lo_sum:SI (match_dup 0) 5627: (match_operand:SI 1 "immediate_operand" "i"))) 5628: (set (match_operand:SF 2 "register_operand" "=fr") 5629: (mem:SF (match_dup 0)))] 5630: "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)" 5631: "ld [%0+%%lo(%a1)],%2") 5632: 5633: ;; Return peepholes. First the "normal" ones 5634: 5635: ;; ??? There are QImode, HImode, and SImode versions of this pattern. 5636: ;; It might be possible to write one more general pattern instead of three. 5637: 1.1.1.4 ! root 5638: (define_insn "*return_qi" 1.1 root 5639: [(set (match_operand:QI 0 "restore_operand" "") 5640: (match_operand:QI 1 "arith_operand" "rI")) 5641: (return)] 5642: "! TARGET_EPILOGUE" 5643: "* 5644: { 1.1.1.3 root 5645: if (! TARGET_V9 && current_function_returns_struct) 1.1 root 5646: return \"jmp %%i7+12\;restore %%g0,%1,%Y0\"; 5647: else 5648: return \"ret\;restore %%g0,%1,%Y0\"; 5649: }" 5650: [(set_attr "type" "multi")]) 5651: 1.1.1.4 ! root 5652: (define_insn "*return_hi" 1.1 root 5653: [(set (match_operand:HI 0 "restore_operand" "") 5654: (match_operand:HI 1 "arith_operand" "rI")) 5655: (return)] 5656: "! TARGET_EPILOGUE" 5657: "* 5658: { 1.1.1.3 root 5659: if (! TARGET_V9 && current_function_returns_struct) 1.1 root 5660: return \"jmp %%i7+12\;restore %%g0,%1,%Y0\"; 5661: else 5662: return \"ret\;restore %%g0,%1,%Y0\"; 5663: }" 5664: [(set_attr "type" "multi")]) 5665: 1.1.1.4 ! root 5666: (define_insn "*return_si" 1.1 root 5667: [(set (match_operand:SI 0 "restore_operand" "") 5668: (match_operand:SI 1 "arith_operand" "rI")) 5669: (return)] 5670: "! TARGET_EPILOGUE" 5671: "* 5672: { 1.1.1.3 root 5673: if (! TARGET_V9 && current_function_returns_struct) 1.1 root 5674: return \"jmp %%i7+12\;restore %%g0,%1,%Y0\"; 5675: else 5676: return \"ret\;restore %%g0,%1,%Y0\"; 5677: }" 5678: [(set_attr "type" "multi")]) 5679: 5680: ;; The following pattern is only generated by delayed-branch scheduling, 5681: ;; when the insn winds up in the epilogue. This can only happen when 5682: ;; ! TARGET_FPU because otherwise fp return values are in %f0. 1.1.1.4 ! root 5683: (define_insn "*return_sf_no_fpu" 1.1 root 5684: [(set (match_operand:SF 0 "restore_operand" "r") 5685: (match_operand:SF 1 "register_operand" "r")) 5686: (return)] 5687: "! TARGET_FPU && ! TARGET_EPILOGUE" 5688: "* 5689: { 1.1.1.3 root 5690: if (! TARGET_V9 && current_function_returns_struct) 1.1 root 5691: return \"jmp %%i7+12\;restore %%g0,%1,%Y0\"; 5692: else 5693: return \"ret\;restore %%g0,%1,%Y0\"; 5694: }" 5695: [(set_attr "type" "multi")]) 5696: 1.1.1.4 ! root 5697: (define_insn "*return_addsi" 1.1 root 5698: [(set (match_operand:SI 0 "restore_operand" "") 5699: (plus:SI (match_operand:SI 1 "arith_operand" "%r") 5700: (match_operand:SI 2 "arith_operand" "rI"))) 5701: (return)] 5702: "! TARGET_EPILOGUE" 5703: "* 5704: { 1.1.1.3 root 5705: if (! TARGET_V9 && current_function_returns_struct) 1.1 root 5706: return \"jmp %%i7+12\;restore %r1,%2,%Y0\"; 5707: else 5708: return \"ret\;restore %r1,%2,%Y0\"; 5709: }" 5710: [(set_attr "type" "multi")]) 5711: 1.1.1.4 ! root 5712: (define_insn "*return_di" 1.1.1.3 root 5713: [(set (match_operand:DI 0 "restore_operand" "") 5714: (match_operand:DI 1 "arith_double_operand" "rHI")) 5715: (return)] 5716: "TARGET_V9 && ! TARGET_EPILOGUE" 5717: "ret\;restore %%g0,%1,%Y0" 5718: [(set_attr "type" "multi")]) 5719: 1.1.1.4 ! root 5720: (define_insn "*return_adddi" 1.1.1.3 root 5721: [(set (match_operand:DI 0 "restore_operand" "") 5722: (plus:DI (match_operand:DI 1 "arith_operand" "%r") 5723: (match_operand:DI 2 "arith_double_operand" "rHI"))) 5724: (return)] 5725: "TARGET_V9 && ! TARGET_EPILOGUE" 5726: "ret\;restore %r1,%2,%Y0" 5727: [(set_attr "type" "multi")]) 5728: 1.1 root 5729: ;; Turned off because it should never match (subtracting a constant 5730: ;; is turned into addition) and because it would do the wrong thing 5731: ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate). 1.1.1.4 ! root 5732: ;;(define_insn "*minus_const" 1.1 root 5733: ;; [(set (match_operand:SI 0 "restore_operand" "") 5734: ;; (minus:SI (match_operand:SI 1 "register_operand" "r") 5735: ;; (match_operand:SI 2 "small_int" "I"))) 5736: ;; (return)] 5737: ;; "! TARGET_EPILOGUE" 5738: ;; "ret\;restore %1,-(%2),%Y0" 5739: ;; [(set_attr "type" "multi")]) 5740: 5741: ;; The following pattern is only generated by delayed-branch scheduling, 5742: ;; when the insn winds up in the epilogue. 1.1.1.4 ! root 5743: (define_insn "*return_sf" 1.1 root 5744: [(set (reg:SF 32) 5745: (match_operand:SF 0 "register_operand" "f")) 5746: (return)] 5747: "! TARGET_EPILOGUE" 5748: "ret\;fmovs %0,%%f0" 5749: [(set_attr "type" "multi")]) 5750: 1.1.1.3 root 5751: ;; Now peepholes to do a call followed by a jump. 1.1 root 5752: 5753: (define_peephole 5754: [(parallel [(set (match_operand 0 "" "") 1.1.1.3 root 5755: (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps")) 1.1 root 5756: (match_operand 2 "" ""))) 5757: (clobber (reg:SI 15))]) 5758: (set (pc) (label_ref (match_operand 3 "" "")))] 5759: "short_branch (INSN_UID (insn), INSN_UID (operands[3]))" 1.1.1.4 ! root 5760: "call %a1,%2\;add %%o7,(%l3-.-4),%%o7") 1.1 root 5761: 5762: (define_peephole 1.1.1.3 root 5763: [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps")) 1.1 root 5764: (match_operand 1 "" "")) 5765: (clobber (reg:SI 15))]) 5766: (set (pc) (label_ref (match_operand 2 "" "")))] 5767: "short_branch (INSN_UID (insn), INSN_UID (operands[2]))" 5768: "* 5769: { 5770: return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\"; 5771: }") 5772: 5773: (define_peephole 1.1.1.3 root 5774: [(parallel [(set (match_operand 0 "" "") 5775: (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps")) 5776: (match_operand 2 "" ""))) 5777: (clobber (reg:DI 15))]) 5778: (set (pc) (label_ref (match_operand 3 "" "")))] 5779: "TARGET_V9 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))" 1.1.1.4 ! root 5780: "call %a1,%2\;add %%o7,(%l3-.-4),%%o7") 1.1.1.3 root 5781: 5782: (define_peephole 5783: [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps")) 5784: (match_operand 1 "" "")) 5785: (clobber (reg:DI 15))]) 5786: (set (pc) (label_ref (match_operand 2 "" "")))] 5787: "TARGET_V9 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))" 1.1.1.4 ! root 5788: "call %a0,%1\;add %%o7,(%l2-.-4),%%o7") 1.1.1.3 root 5789: 5790: ;; Other miscellaneous peepholes. 5791: 5792: (define_peephole 1.1 root 5793: [(parallel [(set (match_operand:SI 0 "register_operand" "=r") 5794: (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") 5795: (reg:SI 0))) 5796: (clobber (reg:CC 0))]) 5797: (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))] 5798: "" 5799: "subxcc %r1,0,%0")
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.