|
|
1.1 root 1: ;;- Machine description for HP PA-RISC architecture for GNU C compiler 1.1.1.4 ! root 2: ;; Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. 1.1 root 3: ;; Contributed by the Center for Software Science at the University 4: ;; of Utah. 5: 6: ;; This file is part of GNU CC. 7: 8: ;; GNU CC is free software; you can redistribute it and/or modify 9: ;; it under the terms of the GNU General Public License as published by 10: ;; the Free Software Foundation; either version 2, or (at your option) 11: ;; any later version. 12: 13: ;; GNU CC is distributed in the hope that it will be useful, 14: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16: ;; GNU General Public License for more details. 17: 18: ;; You should have received a copy of the GNU General Public License 19: ;; along with GNU CC; see the file COPYING. If not, write to 1.1.1.4 ! root 20: ;; the Free Software Foundation, 59 Temple Place - Suite 330, ! 21: ;; Boston, MA 02111-1307, USA. 1.1 root 22: 23: ;; This gcc Version 2 machine description is inspired by sparc.md and 24: ;; mips.md. 25: 26: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. 27: 28: ;; Insn type. Used to default other attribute values. 29: 30: ;; type "unary" insns have one input operand (1) and one output operand (0) 31: ;; type "binary" insns have two input operands (1,2) and one output (0) 32: 33: (define_attr "type" 1.1.1.4 ! root 34: "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,branch,cbranch,fbranch,call,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli" 1.1 root 35: (const_string "binary")) 36: 1.1.1.4 ! root 37: ;; Processor type (for scheduling, not code generation) -- this attribute ! 38: ;; must exactly match the processor_type enumeration in pa.h. ! 39: ;; ! 40: ;; FIXME: Add 800 scheduling for completeness? ! 41: ! 42: (define_attr "cpu" "700,7100,7100LC" (const (symbol_ref "pa_cpu_attr"))) ! 43: 1.1 root 44: ;; Length (in # of insns). 45: (define_attr "length" "" 46: (cond [(eq_attr "type" "load,fpload") 47: (if_then_else (match_operand 1 "symbolic_memory_operand" "") 1.1.1.2 root 48: (const_int 8) (const_int 4)) 1.1 root 49: 50: (eq_attr "type" "store,fpstore") 51: (if_then_else (match_operand 0 "symbolic_memory_operand" "") 1.1.1.2 root 52: (const_int 8) (const_int 4)) 1.1 root 53: 1.1.1.4 ! root 54: (eq_attr "type" "binary,shift,nullshift") 1.1 root 55: (if_then_else (match_operand 2 "arith_operand" "") 1.1.1.2 root 56: (const_int 4) (const_int 12)) 1.1 root 57: 1.1.1.4 ! root 58: (eq_attr "type" "move,unary,shift,nullshift") 1.1 root 59: (if_then_else (match_operand 1 "arith_operand" "") 1.1.1.2 root 60: (const_int 4) (const_int 8))] 1.1 root 61: 1.1.1.2 root 62: (const_int 4))) 1.1 root 63: 64: (define_asm_attributes 1.1.1.2 root 65: [(set_attr "length" "4") 1.1 root 66: (set_attr "type" "multi")]) 67: 68: ;; Attributes for instruction and branch scheduling 69: 1.1.1.2 root 70: ;; For conditional branches. 1.1 root 71: (define_attr "in_branch_delay" "false,true" 1.1.1.2 root 72: (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli") 73: (eq_attr "length" "4")) 1.1 root 74: (const_string "true") 75: (const_string "false"))) 76: 77: ;; Disallow instructions which use the FPU since they will tie up the FPU 78: ;; even if the instruction is nullified. 79: (define_attr "in_nullified_branch_delay" "false,true" 1.1.1.4 ! root 80: (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl") 1.1.1.2 root 81: (eq_attr "length" "4")) 1.1 root 82: (const_string "true") 83: (const_string "false"))) 84: 1.1.1.3 root 85: ;; For calls and millicode calls. Allow unconditional branches in the 1.1.1.2 root 86: ;; delay slot. 87: (define_attr "in_call_delay" "false,true" 88: (cond [(and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli") 89: (eq_attr "length" "4")) 90: (const_string "true") 91: (eq_attr "type" "uncond_branch") 92: (if_then_else (ne (symbol_ref "TARGET_JUMP_IN_DELAY") 93: (const_int 0)) 94: (const_string "true") 95: (const_string "false"))] 96: (const_string "false"))) 97: 98: 1.1.1.3 root 99: ;; Unconditional branch and call delay slot description. 100: (define_delay (eq_attr "type" "uncond_branch,branch,call") 1.1.1.2 root 101: [(eq_attr "in_call_delay" "true") (nil) (nil)]) 102: 1.1.1.3 root 103: ;; millicode call delay slot description. Note it disallows delay slot 1.1.1.4 ! root 104: ;; when TARGET_PORTABLE_RUNTIME or TARGET_MILLICODE_LONG_CALLS is true. 1.1.1.3 root 105: (define_delay (eq_attr "type" "milli") 106: [(and (eq_attr "in_call_delay" "true") 1.1.1.4 ! root 107: (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0)) ! 108: (eq (symbol_ref "TARGET_MILLICODE_LONG_CALLS") (const_int 0)))) 1.1.1.3 root 109: (nil) (nil)]) 110: 1.1.1.2 root 111: ;; Unconditional branch, return and other similar instructions. 112: (define_delay (eq_attr "type" "uncond_branch,branch") 1.1 root 113: [(eq_attr "in_branch_delay" "true") (nil) (nil)]) 114: 115: ;; Floating point conditional branch delay slot description and 116: (define_delay (eq_attr "type" "fbranch") 117: [(eq_attr "in_branch_delay" "true") 118: (eq_attr "in_nullified_branch_delay" "true") 119: (nil)]) 120: 121: ;; Integer conditional branch delay slot description. 122: ;; Nullification of conditional branches on the PA is dependent on the 1.1.1.2 root 123: ;; direction of the branch. Forward branches nullify true and 124: ;; backward branches nullify false. If the direction is unknown 125: ;; then nullification is not allowed. 1.1 root 126: (define_delay (eq_attr "type" "cbranch") 1.1.1.3 root 127: [(eq_attr "in_branch_delay" "true") 128: (and (eq_attr "in_nullified_branch_delay" "true") 1.1 root 129: (attr_flag "forward")) 130: (and (eq_attr "in_nullified_branch_delay" "true") 131: (attr_flag "backward"))]) 132: 1.1.1.4 ! root 133: ;; Function units of the HPPA. The following data is for the 700 CPUs ! 134: ;; (Mustang CPU + Timex FPU aka PA-89) because that's what I have the docs for. 1.1 root 135: ;; Scheduling instructions for PA-83 machines according to the Snake 136: ;; constraints shouldn't hurt. 137: 138: ;; (define_function_unit {name} {num-units} {n-users} {test} 139: ;; {ready-delay} {issue-delay} [{conflict-list}]) 140: 141: ;; The integer ALU. 142: ;; (Noted only for documentation; units that take one cycle do not need to 143: ;; be specified.) 144: 145: ;; (define_function_unit "alu" 1 0 1.1.1.4 ! root 146: ;; (and (eq_attr "type" "unary,shift,nullshift,binary,move,address") ! 147: ;; (eq_attr "cpu" "700")) ! 148: ;; 1 0) 1.1 root 149: 150: 151: ;; Memory. Disregarding Cache misses, the Mustang memory times are: 1.1.1.4 ! root 152: ;; load: 2, fpload: 3 1.1 root 153: ;; store, fpstore: 3, no D-cache operations should be scheduled. 154: 1.1.1.4 ! root 155: (define_function_unit "pa700memory" 1 0 ! 156: (and (eq_attr "type" "load,fpload") ! 157: (eq_attr "cpu" "700")) 2 0) ! 158: (define_function_unit "pa700memory" 1 0 ! 159: (and (eq_attr "type" "store,fpstore") ! 160: (eq_attr "cpu" "700")) 3 3) 1.1 root 161: 1.1.1.4 ! root 162: ;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT. 1.1 root 163: ;; Timings: 164: ;; Instruction Time Unit Minimum Distance (unit contention) 165: ;; fcpy 3 ALU 2 166: ;; fabs 3 ALU 2 167: ;; fadd 3 ALU 2 168: ;; fsub 3 ALU 2 169: ;; fcmp 3 ALU 2 170: ;; fcnv 3 ALU 2 171: ;; fmpyadd 3 ALU,MPY 2 172: ;; fmpysub 3 ALU,MPY 2 173: ;; fmpycfxt 3 ALU,MPY 2 174: ;; fmpy 3 MPY 2 175: ;; fmpyi 3 MPY 2 176: ;; fdiv,sgl 10 MPY 10 177: ;; fdiv,dbl 12 MPY 12 178: ;; fsqrt,sgl 14 MPY 14 179: ;; fsqrt,dbl 18 MPY 18 180: 1.1.1.4 ! root 181: (define_function_unit "pa700fp_alu" 1 0 ! 182: (and (eq_attr "type" "fpcc") ! 183: (eq_attr "cpu" "700")) 4 2) ! 184: (define_function_unit "pa700fp_alu" 1 0 ! 185: (and (eq_attr "type" "fpalu") ! 186: (eq_attr "cpu" "700")) 3 2) ! 187: (define_function_unit "pa700fp_mpy" 1 0 ! 188: (and (eq_attr "type" "fpmulsgl,fpmuldbl") ! 189: (eq_attr "cpu" "700")) 3 2) ! 190: (define_function_unit "pa700fp_mpy" 1 0 ! 191: (and (eq_attr "type" "fpdivsgl") ! 192: (eq_attr "cpu" "700")) 10 10) ! 193: (define_function_unit "pa700fp_mpy" 1 0 ! 194: (and (eq_attr "type" "fpdivdbl") ! 195: (eq_attr "cpu" "700")) 12 12) ! 196: (define_function_unit "pa700fp_mpy" 1 0 ! 197: (and (eq_attr "type" "fpsqrtsgl") ! 198: (eq_attr "cpu" "700")) 14 14) ! 199: (define_function_unit "pa700fp_mpy" 1 0 ! 200: (and (eq_attr "type" "fpsqrtdbl") ! 201: (eq_attr "cpu" "700")) 18 18) ! 202: ! 203: ;; Function units for the 7100 and 7150. The 7100/7150 can dual-issue ! 204: ;; floating point computations with non-floating point computations (fp loads ! 205: ;; and stores are not fp computations). ! 206: ;; ! 207: ;; As with the alpha we multiply the ready delay by two to encourage ! 208: ;; schedules which will allow the 7100/7150 to dual issue as many instructions ! 209: ;; as possible. ! 210: ! 211: ;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also ! 212: ;; take two cycles, during which no Dcache operations should be scheduled. ! 213: ;; Any special cases are handled in pa_adjust_cost. The 7100, 7150 and 7100LC ! 214: ;; all have the same memory characteristics if one disregards cache misses. ! 215: (define_function_unit "pa7100memory" 1 0 ! 216: (and (eq_attr "type" "load,fpload") ! 217: (eq_attr "cpu" "7100,7100LC")) 4 0) ! 218: (define_function_unit "pa7100memory" 1 0 ! 219: (and (eq_attr "type" "store,fpstore") ! 220: (eq_attr "cpu" "7100,7100LC")) 4 4) ! 221: ! 222: ;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV. ! 223: ;; Timings: ! 224: ;; Instruction Time Unit Minimum Distance (unit contention) ! 225: ;; fcpy 2 ALU 1 ! 226: ;; fabs 2 ALU 1 ! 227: ;; fadd 2 ALU 1 ! 228: ;; fsub 2 ALU 1 ! 229: ;; fcmp 2 ALU 1 ! 230: ;; fcnv 2 ALU 1 ! 231: ;; fmpyadd 2 ALU,MPY 1 ! 232: ;; fmpysub 2 ALU,MPY 1 ! 233: ;; fmpycfxt 2 ALU,MPY 1 ! 234: ;; fmpy 2 MPY 1 ! 235: ;; fmpyi 2 MPY 1 ! 236: ;; fdiv,sgl 8 DIV 8 ! 237: ;; fdiv,dbl 15 DIV 15 ! 238: ;; fsqrt,sgl 8 DIV 8 ! 239: ;; fsqrt,dbl 15 DIV 15 ! 240: ! 241: (define_function_unit "pa7100fp_alu" 1 0 ! 242: (and (eq_attr "type" "fpcc,fpalu") ! 243: (eq_attr "cpu" "7100")) 4 2) ! 244: (define_function_unit "pa7100fp_mpy" 1 0 ! 245: (and (eq_attr "type" "fpmulsgl,fpmuldbl") ! 246: (eq_attr "cpu" "7100")) 4 2) ! 247: (define_function_unit "pa7100fp_div" 1 0 ! 248: (and (eq_attr "type" "fpdivsgl,fpsqrtsgl") ! 249: (eq_attr "cpu" "7100")) 16 16) ! 250: (define_function_unit "pa7100fp_div" 1 0 ! 251: (and (eq_attr "type" "fpdivdbl,fpsqrtdbl") ! 252: (eq_attr "cpu" "7100")) 30 30) ! 253: ! 254: ;; To encourage dual issue we define function units corresponding to ! 255: ;; the instructions which can be dual issued. This is a rather crude ! 256: ;; approximation, the "pa7100nonflop" test in particular could be refined. ! 257: (define_function_unit "pa7100flop" 1 1 ! 258: (and ! 259: (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl") ! 260: (eq_attr "cpu" "7100,7100LC")) 2 2) ! 261: ! 262: (define_function_unit "pa7100nonflop" 1 1 ! 263: (and ! 264: (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl") ! 265: (eq_attr "cpu" "7100")) 2 2) ! 266: ! 267: ! 268: ;; Memory subsystem works just like 7100/7150 (except for cache miss times which ! 269: ;; we don't model here). ! 270: ! 271: ;; The 7100LC has three floating-point units: ALU, MUL, and DIV. ! 272: ;; Note divides and sqrt flops lock the cpu until the flop is ! 273: ;; finished. fmpy and xmpyu (fmpyi) lock the cpu for one cycle. ! 274: ;; There's no way to avoid the penalty. ! 275: ;; Timings: ! 276: ;; Instruction Time Unit Minimum Distance (unit contention) ! 277: ;; fcpy 2 ALU 1 ! 278: ;; fabs 2 ALU 1 ! 279: ;; fadd 2 ALU 1 ! 280: ;; fsub 2 ALU 1 ! 281: ;; fcmp 2 ALU 1 ! 282: ;; fcnv 2 ALU 1 ! 283: ;; fmpyadd,sgl 2 ALU,MPY 1 ! 284: ;; fmpyadd,dbl 3 ALU,MPY 2 ! 285: ;; fmpysub,sgl 2 ALU,MPY 1 ! 286: ;; fmpysub,dbl 3 ALU,MPY 2 ! 287: ;; fmpycfxt,sgl 2 ALU,MPY 1 ! 288: ;; fmpycfxt,dbl 3 ALU,MPY 2 ! 289: ;; fmpy,sgl 2 MPY 1 ! 290: ;; fmpy,dbl 3 MPY 2 ! 291: ;; fmpyi 3 MPY 2 ! 292: ;; fdiv,sgl 8 DIV 8 ! 293: ;; fdiv,dbl 15 DIV 15 ! 294: ;; fsqrt,sgl 8 DIV 8 ! 295: ;; fsqrt,dbl 15 DIV 15 ! 296: ! 297: (define_function_unit "pa7100LCfp_alu" 1 0 ! 298: (and (eq_attr "type" "fpcc,fpalu") ! 299: (eq_attr "cpu" "7100LC")) 4 2) ! 300: (define_function_unit "pa7100LCfp_mpy" 1 0 ! 301: (and (eq_attr "type" "fpmulsgl") ! 302: (eq_attr "cpu" "7100LC")) 4 2) ! 303: (define_function_unit "pa7100LCfp_mpy" 1 0 ! 304: (and (eq_attr "type" "fpmuldbl") ! 305: (eq_attr "cpu" "7100LC")) 6 4) ! 306: (define_function_unit "pa7100LCfp_div" 1 0 ! 307: (and (eq_attr "type" "fpdivsgl,fpsqrtsgl") ! 308: (eq_attr "cpu" "7100LC")) 16 16) ! 309: (define_function_unit "pa7100LCfp_div" 1 0 ! 310: (and (eq_attr "type" "fpdivdbl,fpsqrtdbl") ! 311: (eq_attr "cpu" "7100LC")) 30 30) ! 312: ! 313: ;; Define the various functional units for dual-issue. ! 314: ;; The 7100LC shares the generic "flop" unit specification with the 7100/7150. ! 315: ! 316: ;; The 7100LC has two basic integer which allow dual issue of most integer ! 317: ;; instructions. This needs further refinement to deal with the nullify, ! 318: ;; carry/borrow possible the ldw/ldw stw/stw special dual issue cases, and ! 319: ;; of course it needs to know about hte 2nd alu. ! 320: (define_function_unit "pa7100LCnonflop" 1 1 ! 321: (and ! 322: (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift") ! 323: (eq_attr "cpu" "7100LC")) 2 2) ! 324: ! 325: (define_function_unit "pa7100LCshifter" 1 1 ! 326: (and ! 327: (eq_attr "type" "shift,nullshift") ! 328: (eq_attr "cpu" "7100LC")) 2 2) ! 329: ! 330: (define_function_unit "pa7100LCmem" 1 1 ! 331: (and ! 332: (eq_attr "type" "load,fpload,store,fpstore") ! 333: (eq_attr "cpu" "7100LC")) 2 2) ! 334: 1.1 root 335: 336: ;; Compare instructions. 337: ;; This controls RTL generation and register allocation. 338: 339: ;; We generate RTL for comparisons and branches by having the cmpxx 340: ;; patterns store away the operands. Then, the scc and bcc patterns 341: ;; emit RTL for both the compare and the branch. 342: ;; 343: 344: (define_expand "cmpsi" 345: [(set (reg:CC 0) 346: (compare:CC (match_operand:SI 0 "reg_or_0_operand" "") 347: (match_operand:SI 1 "arith5_operand" "")))] 348: "" 349: " 350: { 351: hppa_compare_op0 = operands[0]; 352: hppa_compare_op1 = operands[1]; 353: hppa_branch_type = CMP_SI; 354: DONE; 355: }") 356: 357: (define_expand "cmpsf" 358: [(set (reg:CCFP 0) 359: (compare:CCFP (match_operand:SF 0 "reg_or_0_operand" "") 360: (match_operand:SF 1 "reg_or_0_operand" "")))] 1.1.1.4 ! root 361: "! TARGET_SOFT_FLOAT" 1.1 root 362: " 363: { 364: hppa_compare_op0 = operands[0]; 365: hppa_compare_op1 = operands[1]; 366: hppa_branch_type = CMP_SF; 367: DONE; 368: }") 369: 370: (define_expand "cmpdf" 371: [(set (reg:CCFP 0) 372: (compare:CCFP (match_operand:DF 0 "reg_or_0_operand" "") 373: (match_operand:DF 1 "reg_or_0_operand" "")))] 1.1.1.4 ! root 374: "! TARGET_SOFT_FLOAT" 1.1 root 375: " 376: { 377: hppa_compare_op0 = operands[0]; 378: hppa_compare_op1 = operands[1]; 379: hppa_branch_type = CMP_DF; 380: DONE; 381: }") 382: 383: (define_insn "" 1.1.1.3 root 384: [(set (reg:CCFP 0) 385: (match_operator:CCFP 2 "comparison_operator" 386: [(match_operand:SF 0 "reg_or_0_operand" "fG") 387: (match_operand:SF 1 "reg_or_0_operand" "fG")]))] 1.1.1.4 ! root 388: "! TARGET_SOFT_FLOAT" 1.1.1.3 root 389: "fcmp,sgl,%Y2 %r0,%r1" 1.1.1.4 ! root 390: [(set_attr "length" "4") ! 391: (set_attr "type" "fpcc")]) 1.1.1.3 root 392: 393: (define_insn "" 394: [(set (reg:CCFP 0) 395: (match_operator:CCFP 2 "comparison_operator" 396: [(match_operand:DF 0 "reg_or_0_operand" "fG") 397: (match_operand:DF 1 "reg_or_0_operand" "fG")]))] 1.1.1.4 ! root 398: "! TARGET_SOFT_FLOAT" 1.1.1.3 root 399: "fcmp,dbl,%Y2 %r0,%r1" 1.1.1.4 ! root 400: [(set_attr "length" "4") ! 401: (set_attr "type" "fpcc")]) 1.1 root 402: 403: ;; scc insns. 404: 405: (define_expand "seq" 406: [(set (match_operand:SI 0 "register_operand" "") 407: (eq:SI (match_dup 1) 408: (match_dup 2)))] 409: "" 410: " 411: { 412: /* fp scc patterns rarely match, and are not a win on the PA. */ 413: if (hppa_branch_type != CMP_SI) 414: FAIL; 415: /* set up operands from compare. */ 416: operands[1] = hppa_compare_op0; 417: operands[2] = hppa_compare_op1; 418: /* fall through and generate default code */ 419: }") 420: 421: (define_expand "sne" 422: [(set (match_operand:SI 0 "register_operand" "") 423: (ne:SI (match_dup 1) 424: (match_dup 2)))] 425: "" 426: " 427: { 428: /* fp scc patterns rarely match, and are not a win on the PA. */ 429: if (hppa_branch_type != CMP_SI) 430: FAIL; 431: operands[1] = hppa_compare_op0; 432: operands[2] = hppa_compare_op1; 433: }") 434: 435: (define_expand "slt" 436: [(set (match_operand:SI 0 "register_operand" "") 437: (lt:SI (match_dup 1) 438: (match_dup 2)))] 439: "" 440: " 441: { 442: /* fp scc patterns rarely match, and are not a win on the PA. */ 443: if (hppa_branch_type != CMP_SI) 444: FAIL; 445: operands[1] = hppa_compare_op0; 446: operands[2] = hppa_compare_op1; 447: }") 448: 449: (define_expand "sgt" 450: [(set (match_operand:SI 0 "register_operand" "") 451: (gt:SI (match_dup 1) 452: (match_dup 2)))] 453: "" 454: " 455: { 456: /* fp scc patterns rarely match, and are not a win on the PA. */ 457: if (hppa_branch_type != CMP_SI) 458: FAIL; 459: operands[1] = hppa_compare_op0; 460: operands[2] = hppa_compare_op1; 461: }") 462: 463: (define_expand "sle" 464: [(set (match_operand:SI 0 "register_operand" "") 465: (le:SI (match_dup 1) 466: (match_dup 2)))] 467: "" 468: " 469: { 470: /* fp scc patterns rarely match, and are not a win on the PA. */ 471: if (hppa_branch_type != CMP_SI) 472: FAIL; 473: operands[1] = hppa_compare_op0; 474: operands[2] = hppa_compare_op1; 475: }") 476: 477: (define_expand "sge" 478: [(set (match_operand:SI 0 "register_operand" "") 479: (ge:SI (match_dup 1) 480: (match_dup 2)))] 481: "" 482: " 483: { 484: /* fp scc patterns rarely match, and are not a win on the PA. */ 485: if (hppa_branch_type != CMP_SI) 486: FAIL; 487: operands[1] = hppa_compare_op0; 488: operands[2] = hppa_compare_op1; 489: }") 490: 491: (define_expand "sltu" 492: [(set (match_operand:SI 0 "register_operand" "") 493: (ltu:SI (match_dup 1) 494: (match_dup 2)))] 495: "" 496: " 497: { 498: if (hppa_branch_type != CMP_SI) 499: FAIL; 500: operands[1] = hppa_compare_op0; 501: operands[2] = hppa_compare_op1; 502: }") 503: 504: (define_expand "sgtu" 505: [(set (match_operand:SI 0 "register_operand" "") 506: (gtu:SI (match_dup 1) 507: (match_dup 2)))] 508: "" 509: " 510: { 511: if (hppa_branch_type != CMP_SI) 512: FAIL; 513: operands[1] = hppa_compare_op0; 514: operands[2] = hppa_compare_op1; 515: }") 516: 517: (define_expand "sleu" 518: [(set (match_operand:SI 0 "register_operand" "") 519: (leu:SI (match_dup 1) 520: (match_dup 2)))] 521: "" 522: " 523: { 524: if (hppa_branch_type != CMP_SI) 525: FAIL; 526: operands[1] = hppa_compare_op0; 527: operands[2] = hppa_compare_op1; 528: }") 529: 530: (define_expand "sgeu" 531: [(set (match_operand:SI 0 "register_operand" "") 532: (geu:SI (match_dup 1) 533: (match_dup 2)))] 534: "" 535: " 536: { 537: if (hppa_branch_type != CMP_SI) 538: FAIL; 539: operands[1] = hppa_compare_op0; 540: operands[2] = hppa_compare_op1; 541: }") 542: 543: ;; Instruction canonicalization puts immediate operands second, which 544: ;; is the reverse of what we want. 545: 546: (define_insn "scc" 547: [(set (match_operand:SI 0 "register_operand" "=r") 548: (match_operator:SI 3 "comparison_operator" 549: [(match_operand:SI 1 "register_operand" "r") 1.1.1.3 root 550: (match_operand:SI 2 "arith11_operand" "rI")]))] 1.1 root 551: "" 552: "com%I2clr,%B3 %2,%1,%0\;ldi 1,%0" 553: [(set_attr "type" "binary") 1.1.1.2 root 554: (set_attr "length" "8")]) 1.1 root 555: 1.1.1.3 root 556: (define_insn "iorscc" 557: [(set (match_operand:SI 0 "register_operand" "=r") 558: (ior:SI (match_operator:SI 3 "comparison_operator" 559: [(match_operand:SI 1 "register_operand" "r") 560: (match_operand:SI 2 "arith11_operand" "rI")]) 561: (match_operator:SI 6 "comparison_operator" 562: [(match_operand:SI 4 "register_operand" "r") 563: (match_operand:SI 5 "arith11_operand" "rI")])))] 564: "" 565: "com%I2clr,%S3 %2,%1,0\;com%I5clr,%B6 %5,%4,%0\;ldi 1,%0" 566: [(set_attr "type" "binary") 1.1.1.4 ! root 567: (set_attr "length" "12")]) 1.1.1.3 root 568: 1.1 root 569: ;; Combiner patterns for common operations performed with the output 1.1.1.3 root 570: ;; from an scc insn (negscc and incscc). 1.1 root 571: (define_insn "negscc" 572: [(set (match_operand:SI 0 "register_operand" "=r") 1.1.1.2 root 573: (neg:SI (match_operator:SI 3 "comparison_operator" 1.1 root 574: [(match_operand:SI 1 "register_operand" "r") 1.1.1.3 root 575: (match_operand:SI 2 "arith11_operand" "rI")])))] 1.1 root 576: "" 577: "com%I2clr,%B3 %2,%1,%0\;ldi -1,%0" 578: [(set_attr "type" "binary") 1.1.1.2 root 579: (set_attr "length" "8")]) 1.1 root 580: 581: ;; Patterns for adding/subtracting the result of a boolean expression from 582: ;; a register. First we have special patterns that make use of the carry 583: ;; bit, and output only two instructions. For the cases we can't in 584: ;; general do in two instructions, the incscc pattern at the end outputs 585: ;; two or three instructions. 586: 587: (define_insn "" 588: [(set (match_operand:SI 0 "register_operand" "=r") 589: (plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r") 590: (match_operand:SI 3 "arith11_operand" "rI")) 591: (match_operand:SI 1 "register_operand" "r")))] 592: "" 593: "sub%I3 %3,%2,0\;addc 0,%1,%0" 594: [(set_attr "type" "binary") 1.1.1.2 root 595: (set_attr "length" "8")]) 1.1 root 596: 597: ; This need only accept registers for op3, since canonicalization 598: ; replaces geu with gtu when op3 is an integer. 599: (define_insn "" 600: [(set (match_operand:SI 0 "register_operand" "=r") 601: (plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r") 602: (match_operand:SI 3 "register_operand" "r")) 603: (match_operand:SI 1 "register_operand" "r")))] 604: "" 605: "sub %2,%3,0\;addc 0,%1,%0" 606: [(set_attr "type" "binary") 1.1.1.2 root 607: (set_attr "length" "8")]) 1.1 root 608: 609: ; Match only integers for op3 here. This is used as canonical form of the 610: ; geu pattern when op3 is an integer. Don't match registers since we can't 611: ; make better code than the general incscc pattern. 612: (define_insn "" 613: [(set (match_operand:SI 0 "register_operand" "=r") 614: (plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r") 615: (match_operand:SI 3 "int11_operand" "I")) 616: (match_operand:SI 1 "register_operand" "r")))] 617: "" 618: "addi %k3,%2,0\;addc 0,%1,%0" 619: [(set_attr "type" "binary") 1.1.1.2 root 620: (set_attr "length" "8")]) 1.1 root 621: 622: (define_insn "incscc" 623: [(set (match_operand:SI 0 "register_operand" "=r,r") 624: (plus:SI (match_operator:SI 4 "comparison_operator" 625: [(match_operand:SI 2 "register_operand" "r,r") 626: (match_operand:SI 3 "arith11_operand" "rI,rI")]) 627: (match_operand:SI 1 "register_operand" "0,?r")))] 628: "" 629: "@ 630: com%I3clr,%B4 %3,%2,0\;addi 1,%0,%0 631: com%I3clr,%B4 %3,%2,0\;addi,tr 1,%1,%0\;copy %1,%0" 632: [(set_attr "type" "binary,binary") 1.1.1.2 root 633: (set_attr "length" "8,12")]) 1.1 root 634: 635: (define_insn "" 636: [(set (match_operand:SI 0 "register_operand" "=r") 637: (minus:SI (match_operand:SI 1 "register_operand" "r") 638: (gtu:SI (match_operand:SI 2 "register_operand" "r") 639: (match_operand:SI 3 "arith11_operand" "rI"))))] 640: "" 641: "sub%I3 %3,%2,0\;subb %1,0,%0" 642: [(set_attr "type" "binary") 1.1.1.2 root 643: (set_attr "length" "8")]) 1.1 root 644: 1.1.1.3 root 645: (define_insn "" 646: [(set (match_operand:SI 0 "register_operand" "=r") 647: (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r") 648: (gtu:SI (match_operand:SI 2 "register_operand" "r") 649: (match_operand:SI 3 "arith11_operand" "rI"))) 650: (match_operand:SI 4 "register_operand" "r")))] 651: "" 652: "sub%I3 %3,%2,0\;subb %1,%4,%0" 653: [(set_attr "type" "binary") 654: (set_attr "length" "8")]) 655: 1.1 root 656: ; This need only accept registers for op3, since canonicalization 657: ; replaces ltu with leu when op3 is an integer. 658: (define_insn "" 659: [(set (match_operand:SI 0 "register_operand" "=r") 660: (minus:SI (match_operand:SI 1 "register_operand" "r") 661: (ltu:SI (match_operand:SI 2 "register_operand" "r") 662: (match_operand:SI 3 "register_operand" "r"))))] 663: "" 664: "sub %2,%3,0\;subb %1,0,%0" 665: [(set_attr "type" "binary") 1.1.1.2 root 666: (set_attr "length" "8")]) 1.1 root 667: 1.1.1.3 root 668: (define_insn "" 669: [(set (match_operand:SI 0 "register_operand" "=r") 670: (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r") 671: (ltu:SI (match_operand:SI 2 "register_operand" "r") 672: (match_operand:SI 3 "register_operand" "r"))) 673: (match_operand:SI 4 "register_operand" "r")))] 674: "" 675: "sub %2,%3,0\;subb %1,%4,%0" 676: [(set_attr "type" "binary") 677: (set_attr "length" "8")]) 678: 1.1 root 679: ; Match only integers for op3 here. This is used as canonical form of the 680: ; ltu pattern when op3 is an integer. Don't match registers since we can't 681: ; make better code than the general incscc pattern. 682: (define_insn "" 683: [(set (match_operand:SI 0 "register_operand" "=r") 684: (minus:SI (match_operand:SI 1 "register_operand" "r") 685: (leu:SI (match_operand:SI 2 "register_operand" "r") 686: (match_operand:SI 3 "int11_operand" "I"))))] 687: "" 688: "addi %k3,%2,0\;subb %1,0,%0" 689: [(set_attr "type" "binary") 1.1.1.2 root 690: (set_attr "length" "8")]) 1.1 root 691: 1.1.1.3 root 692: (define_insn "" 693: [(set (match_operand:SI 0 "register_operand" "=r") 694: (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r") 695: (leu:SI (match_operand:SI 2 "register_operand" "r") 696: (match_operand:SI 3 "int11_operand" "I"))) 697: (match_operand:SI 4 "register_operand" "r")))] 698: "" 699: "addi %k3,%2,0\;subb %1,%4,%0" 700: [(set_attr "type" "binary") 701: (set_attr "length" "8")]) 702: 1.1 root 703: (define_insn "decscc" 704: [(set (match_operand:SI 0 "register_operand" "=r,r") 705: (minus:SI (match_operand:SI 1 "register_operand" "0,?r") 706: (match_operator:SI 4 "comparison_operator" 707: [(match_operand:SI 2 "register_operand" "r,r") 708: (match_operand:SI 3 "arith11_operand" "rI,rI")])))] 709: "" 710: "@ 711: com%I3clr,%B4 %3,%2,0\;addi -1,%0,%0 712: com%I3clr,%B4 %3,%2,0\;addi,tr -1,%1,%0\;copy %1,%0" 713: [(set_attr "type" "binary,binary") 1.1.1.2 root 714: (set_attr "length" "8,12")]) 1.1 root 715: 716: ; Patterns for max and min. (There is no need for an earlyclobber in the 717: ; last alternative since the middle alternative will match if op0 == op1.) 718: 719: (define_insn "sminsi3" 720: [(set (match_operand:SI 0 "register_operand" "=r,r,r") 721: (smin:SI (match_operand:SI 1 "register_operand" "%0,0,r") 722: (match_operand:SI 2 "arith11_operand" "r,I,M")))] 723: "" 724: "@ 725: comclr,> %2,%0,0\;copy %2,%0 726: comiclr,> %2,%0,0\;ldi %2,%0 727: comclr,> %1,%2,%0\;copy %1,%0" 728: [(set_attr "type" "multi,multi,multi") 1.1.1.2 root 729: (set_attr "length" "8,8,8")]) 1.1 root 730: 731: (define_insn "uminsi3" 732: [(set (match_operand:SI 0 "register_operand" "=r,r") 733: (umin:SI (match_operand:SI 1 "register_operand" "%0,0") 734: (match_operand:SI 2 "arith11_operand" "r,I")))] 735: "" 736: "@ 737: comclr,>> %2,%0,0\;copy %2,%0 738: comiclr,>> %2,%0,0\;ldi %2,%0" 739: [(set_attr "type" "multi,multi") 1.1.1.2 root 740: (set_attr "length" "8,8")]) 1.1 root 741: 742: (define_insn "smaxsi3" 743: [(set (match_operand:SI 0 "register_operand" "=r,r,r") 744: (smax:SI (match_operand:SI 1 "register_operand" "%0,0,r") 745: (match_operand:SI 2 "arith11_operand" "r,I,M")))] 746: "" 747: "@ 748: comclr,< %2,%0,0\;copy %2,%0 749: comiclr,< %2,%0,0\;ldi %2,%0 750: comclr,< %1,%2,%0\;copy %1,%0" 751: [(set_attr "type" "multi,multi,multi") 1.1.1.2 root 752: (set_attr "length" "8,8,8")]) 1.1 root 753: 754: (define_insn "umaxsi3" 755: [(set (match_operand:SI 0 "register_operand" "=r,r") 756: (umax:SI (match_operand:SI 1 "register_operand" "%0,0") 757: (match_operand:SI 2 "arith11_operand" "r,I")))] 758: "" 759: "@ 760: comclr,<< %2,%0,0\;copy %2,%0 761: comiclr,<< %2,%0,0\;ldi %2,%0" 762: [(set_attr "type" "multi,multi") 1.1.1.2 root 763: (set_attr "length" "8,8")]) 1.1 root 764: ;;; Experimental conditional move patterns 765: 1.1.1.4 ! root 766: (define_expand "movsicc" ! 767: [(set (match_operand:SI 0 "register_operand" "") ! 768: (if_then_else:SI ! 769: (match_operator 1 "comparison_operator" ! 770: [(match_dup 4) ! 771: (match_dup 5)]) ! 772: (match_operand:SI 2 "reg_or_cint_move_operand" "") ! 773: (match_operand:SI 3 "reg_or_cint_move_operand" "")))] ! 774: "" ! 775: " ! 776: { ! 777: enum rtx_code code = GET_CODE (operands[1]); ! 778: ! 779: if (hppa_branch_type != CMP_SI) ! 780: FAIL; ! 781: ! 782: /* operands[1] is currently the result of compare_from_rtx. We want to ! 783: emit a compare of the original operands. */ ! 784: operands[1] = gen_rtx (code, SImode, hppa_compare_op0, hppa_compare_op1); ! 785: operands[4] = hppa_compare_op0; ! 786: operands[5] = hppa_compare_op1; ! 787: }") ! 788: 1.1 root 789: ; We need the first constraint alternative in order to avoid 790: ; earlyclobbers on all other alternatives. 791: (define_insn "" 792: [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r") 793: (if_then_else:SI 794: (match_operator 5 "comparison_operator" 795: [(match_operand:SI 3 "register_operand" "r,r,r,r,r") 796: (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI")]) 797: (match_operand:SI 1 "reg_or_cint_move_operand" "0,r,J,N,K") 798: (const_int 0)))] 799: "" 800: "@ 801: com%I4clr,%S5 %4,%3,0\;ldi 0,%0 802: com%I4clr,%B5 %4,%3,%0\;copy %1,%0 803: com%I4clr,%B5 %4,%3,%0\;ldi %1,%0 804: com%I4clr,%B5 %4,%3,%0\;ldil L'%1,%0 805: com%I4clr,%B5 %4,%3,%0\;zdepi %Z1,%0" 1.1.1.4 ! root 806: [(set_attr "type" "multi,multi,multi,multi,nullshift") 1.1.1.2 root 807: (set_attr "length" "8,8,8,8,8")]) 1.1 root 808: 809: (define_insn "" 810: [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r") 811: (if_then_else:SI 812: (match_operator 5 "comparison_operator" 813: [(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r") 814: (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")]) 815: (match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K") 816: (match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))] 817: "" 818: "@ 819: com%I4clr,%S5 %4,%3,0\;copy %2,%0 820: com%I4clr,%S5 %4,%3,0\;ldi %2,%0 821: com%I4clr,%S5 %4,%3,0\;ldil L'%2,%0 822: com%I4clr,%S5 %4,%3,0\;zdepi %Z2,%0 823: com%I4clr,%B5 %4,%3,0\;copy %1,%0 824: com%I4clr,%B5 %4,%3,0\;ldi %1,%0 825: com%I4clr,%B5 %4,%3,0\;ldil L'%1,%0 826: com%I4clr,%B5 %4,%3,0\;zdepi %Z1,%0" 1.1.1.4 ! root 827: [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift") 1.1.1.2 root 828: (set_attr "length" "8,8,8,8,8,8,8,8")]) 1.1 root 829: 830: ;; Conditional Branches 831: 832: (define_expand "beq" 833: [(set (pc) 834: (if_then_else (eq (match_dup 1) (match_dup 2)) 835: (label_ref (match_operand 0 "" "")) 836: (pc)))] 837: "" 838: " 839: { 840: if (hppa_branch_type != CMP_SI) 841: { 842: emit_insn (gen_cmp_fp (EQ, hppa_compare_op0, hppa_compare_op1)); 843: emit_bcond_fp (NE, operands[0]); 844: DONE; 845: } 846: /* set up operands from compare. */ 847: operands[1] = hppa_compare_op0; 848: operands[2] = hppa_compare_op1; 849: /* fall through and generate default code */ 850: }") 851: 852: (define_expand "bne" 853: [(set (pc) 854: (if_then_else (ne (match_dup 1) (match_dup 2)) 855: (label_ref (match_operand 0 "" "")) 856: (pc)))] 857: "" 858: " 859: { 860: if (hppa_branch_type != CMP_SI) 861: { 862: emit_insn (gen_cmp_fp (NE, hppa_compare_op0, hppa_compare_op1)); 863: emit_bcond_fp (NE, operands[0]); 864: DONE; 865: } 866: operands[1] = hppa_compare_op0; 867: operands[2] = hppa_compare_op1; 868: }") 869: 870: (define_expand "bgt" 871: [(set (pc) 872: (if_then_else (gt (match_dup 1) (match_dup 2)) 873: (label_ref (match_operand 0 "" "")) 874: (pc)))] 875: "" 876: " 877: { 878: if (hppa_branch_type != CMP_SI) 879: { 880: emit_insn (gen_cmp_fp (GT, hppa_compare_op0, hppa_compare_op1)); 881: emit_bcond_fp (NE, operands[0]); 882: DONE; 883: } 884: operands[1] = hppa_compare_op0; 885: operands[2] = hppa_compare_op1; 886: }") 887: 888: (define_expand "blt" 889: [(set (pc) 890: (if_then_else (lt (match_dup 1) (match_dup 2)) 891: (label_ref (match_operand 0 "" "")) 892: (pc)))] 893: "" 894: " 895: { 896: if (hppa_branch_type != CMP_SI) 897: { 898: emit_insn (gen_cmp_fp (LT, hppa_compare_op0, hppa_compare_op1)); 899: emit_bcond_fp (NE, operands[0]); 900: DONE; 901: } 902: operands[1] = hppa_compare_op0; 903: operands[2] = hppa_compare_op1; 904: }") 905: 906: (define_expand "bge" 907: [(set (pc) 908: (if_then_else (ge (match_dup 1) (match_dup 2)) 909: (label_ref (match_operand 0 "" "")) 910: (pc)))] 911: "" 912: " 913: { 914: if (hppa_branch_type != CMP_SI) 915: { 916: emit_insn (gen_cmp_fp (GE, hppa_compare_op0, hppa_compare_op1)); 917: emit_bcond_fp (NE, operands[0]); 918: DONE; 919: } 920: operands[1] = hppa_compare_op0; 921: operands[2] = hppa_compare_op1; 922: }") 923: 924: (define_expand "ble" 925: [(set (pc) 926: (if_then_else (le (match_dup 1) (match_dup 2)) 927: (label_ref (match_operand 0 "" "")) 928: (pc)))] 929: "" 930: " 931: { 932: if (hppa_branch_type != CMP_SI) 933: { 934: emit_insn (gen_cmp_fp (LE, hppa_compare_op0, hppa_compare_op1)); 935: emit_bcond_fp (NE, operands[0]); 936: DONE; 937: } 938: operands[1] = hppa_compare_op0; 939: operands[2] = hppa_compare_op1; 940: }") 941: 942: (define_expand "bgtu" 943: [(set (pc) 944: (if_then_else (gtu (match_dup 1) (match_dup 2)) 945: (label_ref (match_operand 0 "" "")) 946: (pc)))] 947: "" 948: " 949: { 950: if (hppa_branch_type != CMP_SI) 951: FAIL; 952: operands[1] = hppa_compare_op0; 953: operands[2] = hppa_compare_op1; 954: }") 955: 956: (define_expand "bltu" 957: [(set (pc) 958: (if_then_else (ltu (match_dup 1) (match_dup 2)) 959: (label_ref (match_operand 0 "" "")) 960: (pc)))] 961: "" 962: " 963: { 964: if (hppa_branch_type != CMP_SI) 965: FAIL; 966: operands[1] = hppa_compare_op0; 967: operands[2] = hppa_compare_op1; 968: }") 969: 970: (define_expand "bgeu" 971: [(set (pc) 972: (if_then_else (geu (match_dup 1) (match_dup 2)) 973: (label_ref (match_operand 0 "" "")) 974: (pc)))] 975: "" 976: " 977: { 978: if (hppa_branch_type != CMP_SI) 979: FAIL; 980: operands[1] = hppa_compare_op0; 981: operands[2] = hppa_compare_op1; 982: }") 983: 984: (define_expand "bleu" 985: [(set (pc) 986: (if_then_else (leu (match_dup 1) (match_dup 2)) 987: (label_ref (match_operand 0 "" "")) 988: (pc)))] 989: "" 990: " 991: { 992: if (hppa_branch_type != CMP_SI) 993: FAIL; 994: operands[1] = hppa_compare_op0; 995: operands[2] = hppa_compare_op1; 996: }") 997: 998: ;; Match the branch patterns. 999: 1000: 1001: ;; Note a long backward conditional branch with an annulled delay slot 1.1.1.3 root 1002: ;; has a length of 12. 1.1 root 1003: (define_insn "" 1004: [(set (pc) 1005: (if_then_else 1006: (match_operator 3 "comparison_operator" 1007: [(match_operand:SI 1 "register_operand" "r") 1008: (match_operand:SI 2 "arith5_operand" "rL")]) 1009: (label_ref (match_operand 0 "" "")) 1010: (pc)))] 1011: "" 1012: "* 1013: { 1.1.1.3 root 1014: return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn), 1.1 root 1015: get_attr_length (insn), 0, insn); 1016: }" 1017: [(set_attr "type" "cbranch") 1.1.1.3 root 1018: (set (attr "length") 1.1.1.2 root 1019: (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) 1020: (const_int 8188)) 1021: (const_int 4) 1022: (const_int 8)))]) 1.1 root 1023: 1024: ;; Match the negated branch. 1025: 1026: (define_insn "" 1027: [(set (pc) 1028: (if_then_else 1029: (match_operator 3 "comparison_operator" 1030: [(match_operand:SI 1 "register_operand" "r") 1031: (match_operand:SI 2 "arith5_operand" "rL")]) 1032: (pc) 1033: (label_ref (match_operand 0 "" ""))))] 1034: "" 1035: "* 1036: { 1.1.1.3 root 1037: return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn), 1.1 root 1038: get_attr_length (insn), 1, insn); 1039: }" 1040: [(set_attr "type" "cbranch") 1.1.1.3 root 1041: (set (attr "length") 1.1.1.2 root 1042: (if_then_else (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) 1043: (const_int 8188)) 1044: (const_int 4) 1045: (const_int 8)))]) 1.1 root 1046: 1047: ;; Branch on Bit patterns. 1048: (define_insn "" 1049: [(set (pc) 1050: (if_then_else 1051: (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r") 1052: (const_int 1) 1053: (match_operand:SI 1 "uint5_operand" "")) 1054: (const_int 0)) 1.1.1.4 ! root 1055: (label_ref (match_operand 2 "" "")) ! 1056: (pc)))] 1.1 root 1057: "" 1058: "* 1059: { 1.1.1.3 root 1060: return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn), 1.1.1.4 ! root 1061: get_attr_length (insn), 0, insn, 0); 1.1 root 1062: }" 1063: [(set_attr "type" "cbranch") 1.1.1.3 root 1064: (set (attr "length") 1.1.1.4 ! root 1065: (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) ! 1066: (const_int 8188)) ! 1067: (const_int 4) ! 1068: (const_int 8)))]) ! 1069: ! 1070: (define_insn "" ! 1071: [(set (pc) ! 1072: (if_then_else ! 1073: (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r") ! 1074: (const_int 1) ! 1075: (match_operand:SI 1 "uint5_operand" "")) ! 1076: (const_int 0)) ! 1077: (pc) ! 1078: (label_ref (match_operand 2 "" ""))))] ! 1079: "" ! 1080: "* ! 1081: { ! 1082: return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn), ! 1083: get_attr_length (insn), 1, insn, 0); ! 1084: }" ! 1085: [(set_attr "type" "cbranch") ! 1086: (set (attr "length") ! 1087: (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) 1.1.1.2 root 1088: (const_int 8188)) 1089: (const_int 4) 1090: (const_int 8)))]) 1.1 root 1091: 1092: (define_insn "" 1093: [(set (pc) 1094: (if_then_else 1095: (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r") 1096: (const_int 1) 1097: (match_operand:SI 1 "uint5_operand" "")) 1098: (const_int 0)) 1.1.1.4 ! root 1099: (label_ref (match_operand 2 "" "")) ! 1100: (pc)))] 1.1 root 1101: "" 1102: "* 1103: { 1.1.1.3 root 1104: return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn), 1.1.1.4 ! root 1105: get_attr_length (insn), 0, insn, 1); 1.1 root 1106: }" 1107: [(set_attr "type" "cbranch") 1.1.1.3 root 1108: (set (attr "length") 1.1.1.4 ! root 1109: (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) ! 1110: (const_int 8188)) ! 1111: (const_int 4) ! 1112: (const_int 8)))]) ! 1113: ! 1114: (define_insn "" ! 1115: [(set (pc) ! 1116: (if_then_else ! 1117: (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r") ! 1118: (const_int 1) ! 1119: (match_operand:SI 1 "uint5_operand" "")) ! 1120: (const_int 0)) ! 1121: (pc) ! 1122: (label_ref (match_operand 2 "" ""))))] ! 1123: "" ! 1124: "* ! 1125: { ! 1126: return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn), ! 1127: get_attr_length (insn), 1, insn, 1); ! 1128: }" ! 1129: [(set_attr "type" "cbranch") ! 1130: (set (attr "length") ! 1131: (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) 1.1.1.2 root 1132: (const_int 8188)) 1133: (const_int 4) 1134: (const_int 8)))]) 1.1 root 1135: 1136: ;; Floating point branches 1137: (define_insn "" 1138: [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0)) 1139: (label_ref (match_operand 0 "" "")) 1140: (pc)))] 1.1.1.4 ! root 1141: "! TARGET_SOFT_FLOAT" 1.1 root 1142: "* 1143: { 1144: if (INSN_ANNULLED_BRANCH_P (insn)) 1145: return \"ftest\;bl,n %0,0\"; 1146: else 1147: return \"ftest\;bl%* %0,0\"; 1148: }" 1149: [(set_attr "type" "fbranch") 1.1.1.2 root 1150: (set_attr "length" "8")]) 1.1 root 1151: 1152: (define_insn "" 1153: [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0)) 1154: (pc) 1155: (label_ref (match_operand 0 "" ""))))] 1.1.1.4 ! root 1156: "! TARGET_SOFT_FLOAT" 1.1 root 1157: "* 1158: { 1159: if (INSN_ANNULLED_BRANCH_P (insn)) 1160: return \"ftest\;add,tr 0,0,0\;bl,n %0,0\"; 1161: else 1162: return \"ftest\;add,tr 0,0,0\;bl%* %0,0\"; 1163: }" 1164: [(set_attr "type" "fbranch") 1.1.1.2 root 1165: (set_attr "length" "12")]) 1.1 root 1166: 1167: ;; Move instructions 1168: 1169: (define_expand "movsi" 1170: [(set (match_operand:SI 0 "general_operand" "") 1171: (match_operand:SI 1 "general_operand" ""))] 1172: "" 1173: " 1174: { 1175: if (emit_move_sequence (operands, SImode, 0)) 1176: DONE; 1177: }") 1178: 1179: ;; Reloading an SImode or DImode value requires a scratch register if 1180: ;; going in to or out of float point registers. 1181: 1182: (define_expand "reload_insi" 1183: [(set (match_operand:SI 0 "register_operand" "=Z") 1.1.1.3 root 1184: (match_operand:SI 1 "non_hard_reg_operand" "")) 1.1 root 1185: (clobber (match_operand:SI 2 "register_operand" "=&r"))] 1186: "" 1187: " 1188: { 1189: if (emit_move_sequence (operands, SImode, operands[2])) 1190: DONE; 1191: 1192: /* We don't want the clobber emitted, so handle this ourselves. */ 1193: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); 1194: DONE; 1195: }") 1196: 1197: (define_expand "reload_outsi" 1.1.1.3 root 1198: [(set (match_operand:SI 0 "non_hard_reg_operand" "") 1.1 root 1199: (match_operand:SI 1 "register_operand" "Z")) 1200: (clobber (match_operand:SI 2 "register_operand" "=&r"))] 1201: "" 1202: " 1203: { 1204: if (emit_move_sequence (operands, SImode, operands[2])) 1205: DONE; 1206: 1207: /* We don't want the clobber emitted, so handle this ourselves. */ 1208: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); 1209: DONE; 1210: }") 1211: 1212: ;;; pic symbol references 1213: 1214: (define_insn "" 1215: [(set (match_operand:SI 0 "register_operand" "=r") 1216: (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") 1217: (match_operand:SI 2 "symbolic_operand" ""))))] 1218: "flag_pic && operands[1] == pic_offset_table_rtx" 1219: "ldw T'%2(%1),%0" 1220: [(set_attr "type" "load") 1.1.1.2 root 1221: (set_attr "length" "4")]) 1.1 root 1222: 1223: (define_insn "" 1.1.1.3 root 1224: [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" 1225: "=r,r,r,r,r,Q,*q,!f,f,*T") 1226: (match_operand:SI 1 "move_operand" 1227: "r,J,N,K,Q,rM,rM,!fM,*T,f"))] 1.1.1.4 ! root 1228: "(register_operand (operands[0], SImode) ! 1229: || reg_or_0_operand (operands[1], SImode)) ! 1230: && ! TARGET_SOFT_FLOAT" 1.1 root 1231: "@ 1.1.1.3 root 1232: copy %1,%0 1.1 root 1233: ldi %1,%0 1234: ldil L'%1,%0 1235: zdepi %Z1,%0 1236: ldw%M1 %1,%0 1237: stw%M0 %r1,%0 1238: mtsar %r1 1239: fcpy,sgl %r1,%0 1240: fldws%F1 %1,%0 1241: fstws%F0 %1,%0" 1.1.1.4 ! root 1242: [(set_attr "type" "move,move,move,shift,load,store,move,fpalu,fpload,fpstore") 1.1.1.2 root 1243: (set_attr "length" "4,4,4,4,4,4,4,4,4,4")]) 1.1 root 1244: 1.1.1.4 ! root 1245: (define_insn "" ! 1246: [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" ! 1247: "=r,r,r,r,r,Q,*q") ! 1248: (match_operand:SI 1 "move_operand" ! 1249: "r,J,N,K,Q,rM,rM"))] ! 1250: "(register_operand (operands[0], SImode) ! 1251: || reg_or_0_operand (operands[1], SImode)) ! 1252: && TARGET_SOFT_FLOAT" ! 1253: "@ ! 1254: copy %1,%0 ! 1255: ldi %1,%0 ! 1256: ldil L'%1,%0 ! 1257: zdepi %Z1,%0 ! 1258: ldw%M1 %1,%0 ! 1259: stw%M0 %r1,%0 ! 1260: mtsar %r1" ! 1261: [(set_attr "type" "move,move,move,move,load,store,move") ! 1262: (set_attr "length" "4,4,4,4,4,4,4")]) ! 1263: 1.1 root 1264: ;; Load indexed. We don't use unscaled modes since they can't be used 1265: ;; unless we can tell which of the registers is the base and which is 1266: ;; the index, due to PA's idea of segment selection using the top bits 1267: ;; of the base register. 1268: 1269: (define_insn "" 1270: [(set (match_operand:SI 0 "register_operand" "=r") 1271: (mem:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") 1272: (const_int 4)) 1273: (match_operand:SI 2 "register_operand" "r"))))] 1274: "! TARGET_DISABLE_INDEXING" 1275: "ldwx,s %1(0,%2),%0" 1276: [(set_attr "type" "load") 1.1.1.2 root 1277: (set_attr "length" "4")]) 1278: 1279: ;; This variant of the above insn can occur if the second operand 1280: ;; is the frame pointer. This is a kludge, but there doesn't 1281: ;; seem to be a way around it. Only recognize it while reloading. 1.1.1.3 root 1282: ;; Note how operand 3 uses a predicate of "const_int_operand", but 1283: ;; has constraints allowing a register. I don't know how this works, 1284: ;; but it somehow makes sure that out-of-range constants are placed 1285: ;; in a register which somehow magically is a "const_int_operand". 1.1.1.4 ! root 1286: ;; (this was stolen from alpha.md, I'm not going to try and change it.) 1.1.1.2 root 1287: (define_insn "" 1288: [(set (match_operand:SI 0 "register_operand" "&=r") 1.1.1.3 root 1289: (mem:SI (plus:SI (plus:SI 1.1.1.2 root 1290: (mult:SI (match_operand:SI 1 "register_operand" "r") 1291: (const_int 4)) 1292: (match_operand:SI 2 "register_operand" "r")) 1293: (match_operand:SI 3 "const_int_operand" "rI"))))] 1294: "! TARGET_DISABLE_INDEXING && reload_in_progress" 1295: "* 1296: { 1297: if (GET_CODE (operands[3]) == CONST_INT) 1.1.1.3 root 1298: return \"sh2addl %1,%2,%0\;ldw %3(0,%0),%0\"; 1.1.1.2 root 1299: else 1.1.1.3 root 1300: return \"sh2addl %1,%2,%0\;ldwx %3(0,%0),%0\"; 1.1.1.2 root 1301: }" 1302: [(set_attr "type" "load") 1303: (set_attr "length" "8")]) 1.1 root 1304: 1305: ;; Load or store with base-register modification. 1306: 1307: (define_insn "pre_ldwm" 1308: [(set (match_operand:SI 3 "register_operand" "=r") 1309: (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "0") 1310: (match_operand:SI 2 "pre_cint_operand" "")))) 1311: (set (match_operand:SI 0 "register_operand" "=r") 1312: (plus:SI (match_dup 1) (match_dup 2)))] 1313: "" 1314: "* 1315: { 1316: if (INTVAL (operands[2]) < 0) 1317: return \"ldwm %2(0,%0),%3\"; 1318: return \"ldws,mb %2(0,%0),%3\"; 1319: }" 1320: [(set_attr "type" "load") 1.1.1.2 root 1321: (set_attr "length" "4")]) 1.1 root 1322: 1323: (define_insn "pre_stwm" 1324: [(set (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "0") 1325: (match_operand:SI 2 "pre_cint_operand" ""))) 1326: (match_operand:SI 3 "reg_or_0_operand" "rM")) 1327: (set (match_operand:SI 0 "register_operand" "=r") 1328: (plus:SI (match_dup 1) (match_dup 2)))] 1329: "" 1330: "* 1331: { 1332: if (INTVAL (operands[2]) < 0) 1333: return \"stwm %r3,%2(0,%0)\"; 1334: return \"stws,mb %r3,%2(0,%0)\"; 1335: }" 1336: [(set_attr "type" "store") 1.1.1.2 root 1337: (set_attr "length" "4")]) 1.1 root 1338: 1339: (define_insn "post_ldwm" 1340: [(set (match_operand:SI 3 "register_operand" "r") 1341: (mem:SI (match_operand:SI 1 "register_operand" "0"))) 1342: (set (match_operand:SI 0 "register_operand" "=r") 1.1.1.3 root 1343: (plus:SI (match_dup 1) 1.1 root 1344: (match_operand:SI 2 "post_cint_operand" "")))] 1345: "" 1346: "* 1347: { 1348: if (INTVAL (operands[2]) > 0) 1349: return \"ldwm %2(0,%0),%3\"; 1350: return \"ldws,ma %2(0,%0),%3\"; 1351: }" 1352: [(set_attr "type" "load") 1.1.1.2 root 1353: (set_attr "length" "4")]) 1.1 root 1354: 1355: (define_insn "post_stwm" 1356: [(set (mem:SI (match_operand:SI 1 "register_operand" "0")) 1357: (match_operand:SI 3 "reg_or_0_operand" "rM")) 1358: (set (match_operand:SI 0 "register_operand" "=r") 1.1.1.3 root 1359: (plus:SI (match_dup 1) 1.1 root 1360: (match_operand:SI 2 "post_cint_operand" "")))] 1361: "" 1362: "* 1363: { 1364: if (INTVAL (operands[2]) > 0) 1365: return \"stwm %r3,%2(0,%0)\"; 1366: return \"stws,ma %r3,%2(0,%0)\"; 1367: }" 1368: [(set_attr "type" "store") 1.1.1.2 root 1369: (set_attr "length" "4")]) 1.1 root 1370: 1371: ;; For pic 1.1.1.4 ! root 1372: ;; Note since this pattern can be created at reload time (via movsi), all ! 1373: ;; the same rules for movsi apply here. (no new pseudos, no temporaries). ! 1374: (define_insn "pic_load_label" ! 1375: [(set (match_operand:SI 0 "register_operand" "=a") ! 1376: (match_operand:SI 1 "pic_label_operand" ""))] 1.1 root 1377: "" 1378: "* 1379: { 1380: rtx label_rtx = gen_label_rtx (); 1381: rtx xoperands[3]; 1382: extern FILE *asm_out_file; 1383: 1384: xoperands[0] = operands[0]; 1385: xoperands[1] = operands[1]; 1386: xoperands[2] = label_rtx; 1.1.1.4 ! root 1387: output_asm_insn (\"bl .+8,%0\", xoperands); ! 1388: output_asm_insn (\"depi 0,31,2,%0\", xoperands); ! 1389: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", ! 1390: CODE_LABEL_NUMBER (label_rtx)); ! 1391: ! 1392: /* If we're trying to load the address of a label that happens to be ! 1393: close, then we can use a shorter sequence. */ ! 1394: if (GET_CODE (operands[1]) == LABEL_REF ! 1395: && insn_addresses ! 1396: && abs (insn_addresses[INSN_UID (XEXP (operands[1], 0))] ! 1397: - insn_current_address) < 8100) ! 1398: { ! 1399: /* Prefixing with R% here is wrong, it extracts just 11 bits and is ! 1400: always non-negative. */ ! 1401: output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands); ! 1402: } ! 1403: else ! 1404: { ! 1405: output_asm_insn (\"addil L%%%1-%2,%0\", xoperands); ! 1406: output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands); ! 1407: } 1.1 root 1408: return \"\"; 1.1.1.4 ! root 1409: }" 1.1 root 1410: [(set_attr "type" "multi") 1.1.1.4 ! root 1411: (set_attr "length" "16")]) ; 12 or 16 ! 1412: ! 1413: (define_insn "pic2_highpart" ! 1414: [(set (match_operand:SI 0 "register_operand" "=a") ! 1415: (plus:SI (match_operand:SI 1 "register_operand" "r") ! 1416: (high:SI (match_operand 2 "" ""))))] ! 1417: "symbolic_operand (operands[2], Pmode) ! 1418: && ! function_label_operand (operands[2]) ! 1419: && flag_pic == 2" ! 1420: "addil LT'%G2,%1" ! 1421: [(set_attr "type" "binary") ! 1422: (set_attr "length" "4")]) ! 1423: ! 1424: ; We need this to make sure CSE doesn't simplify a memory load with a ! 1425: ; symbolic address, whose content it think it knows. For PIC, what CSE ! 1426: ; think is the real value will be the address of that value. ! 1427: (define_insn "pic2_lo_sum" ! 1428: [(set (match_operand:SI 0 "register_operand" "=r") ! 1429: (mem:SI (lo_sum:SI (match_operand:SI 1 "register_operand" "r") ! 1430: (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")] 0))))] ! 1431: "" ! 1432: "* ! 1433: { ! 1434: if (flag_pic != 2) ! 1435: abort (); ! 1436: return \"ldw RT'%G2(%1),%0\"; ! 1437: }" ! 1438: [(set_attr "type" "load") ! 1439: (set_attr "length" "4")]) ! 1440: 1.1 root 1441: 1.1.1.2 root 1442: ;; Always use addil rather than ldil;add sequences. This allows the 1443: ;; HP linker to eliminate the dp relocation if the symbolic operand 1444: ;; lives in the TEXT space. 1.1 root 1445: (define_insn "" 1446: [(set (match_operand:SI 0 "register_operand" "=a") 1447: (high:SI (match_operand 1 "" "")))] 1.1.1.3 root 1448: "symbolic_operand (operands[1], Pmode) 1.1 root 1449: && ! function_label_operand (operands[1]) 1.1.1.4 ! root 1450: && ! read_only_operand (operands[1]) ! 1451: && ! flag_pic" ! 1452: "addil LR'%G1,%%r27" 1.1 root 1453: [(set_attr "type" "binary") 1.1.1.2 root 1454: (set_attr "length" "4")]) 1.1 root 1455: 1.1.1.3 root 1456: ;; This is for use in the prologue/epilogue code. We need it 1.1 root 1457: ;; to add large constants to a stack pointer or frame pointer. 1458: ;; Because of the additional %r1 pressure, we probably do not 1459: ;; want to use this in general code, so make it available 1460: ;; only after reload. 1461: (define_insn "add_high_const" 1462: [(set (match_operand:SI 0 "register_operand" "=!a,*r") 1.1.1.3 root 1463: (plus:SI (match_operand:SI 1 "register_operand" "r,r") 1464: (high:SI (match_operand 2 "const_int_operand" ""))))] 1.1 root 1465: "reload_completed" 1466: "@ 1467: addil L'%G2,%1 1.1.1.3 root 1468: ldil L'%G2,%0\;addl %0,%1,%0" 1.1 root 1469: [(set_attr "type" "binary,binary") 1.1.1.2 root 1470: (set_attr "length" "4,8")]) 1.1 root 1471: 1.1.1.2 root 1472: ;; For function addresses. 1.1 root 1473: (define_insn "" 1474: [(set (match_operand:SI 0 "register_operand" "=r") 1475: (high:SI (match_operand:SI 1 "function_label_operand" "")))] 1.1.1.3 root 1476: "!TARGET_PORTABLE_RUNTIME" 1.1 root 1477: "ldil LP'%G1,%0" 1478: [(set_attr "type" "move") 1.1.1.2 root 1479: (set_attr "length" "4")]) 1.1 root 1480: 1.1.1.3 root 1481: ;; This version is used only for the portable runtime conventions model 1482: ;; (it does not use/support plabels) 1483: (define_insn "" 1484: [(set (match_operand:SI 0 "register_operand" "=r") 1485: (high:SI (match_operand:SI 1 "function_label_operand" "")))] 1486: "TARGET_PORTABLE_RUNTIME" 1487: "ldil L'%G1,%0" 1488: [(set_attr "type" "move") 1489: (set_attr "length" "4")]) 1490: 1.1 root 1491: (define_insn "" 1492: [(set (match_operand:SI 0 "register_operand" "=r") 1493: (high:SI (match_operand 1 "" "")))] 1.1.1.4 ! root 1494: "(!flag_pic || !symbolic_operand (operands[1]), Pmode) ! 1495: && !is_function_label_plus_const (operands[1])" ! 1496: "* ! 1497: { ! 1498: if (symbolic_operand (operands[1], Pmode)) ! 1499: return \"ldil LR'%G1,%0\"; ! 1500: else ! 1501: return \"ldil L'%G1,%0\"; ! 1502: }" 1.1 root 1503: [(set_attr "type" "move") 1.1.1.2 root 1504: (set_attr "length" "4")]) 1.1 root 1505: 1.1.1.2 root 1506: ;; lo_sum of a function address. 1.1.1.3 root 1507: ;; 1508: ;; Note since we are not supporting MPE style external calls we can 1509: ;; use the short ldil;ldo sequence. If one wanted to support 1510: ;; MPE external calls you would want to generate something like 1511: ;; ldil;ldo;extru;ldw;add. See the HP compiler's output for details. 1.1 root 1512: (define_insn "" 1513: [(set (match_operand:SI 0 "register_operand" "=r") 1514: (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 1.1.1.3 root 1515: (match_operand:SI 2 "function_label_operand" "")))] 1516: "!TARGET_PORTABLE_RUNTIME" 1517: "ldo RP'%G2(%1),%0" 1.1.1.4 ! root 1518: [(set_attr "type" "move") ! 1519: (set_attr "length" "4")]) 1.1.1.3 root 1520: 1521: ;; This version is used only for the portable runtime conventions model 1522: ;; (it does not use/support plabels) 1523: (define_insn "" 1524: [(set (match_operand:SI 0 "register_operand" "=r") 1525: (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 1526: (match_operand:SI 2 "function_label_operand" "")))] 1527: "TARGET_PORTABLE_RUNTIME" 1528: "ldo R'%G2(%1),%0" 1.1.1.4 ! root 1529: [(set_attr "type" "move") ! 1530: (set_attr "length" "4")]) 1.1 root 1531: 1532: (define_insn "" 1533: [(set (match_operand:SI 0 "register_operand" "=r") 1534: (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 1535: (match_operand:SI 2 "immediate_operand" "i")))] 1.1.1.3 root 1536: "!is_function_label_plus_const (operands[2])" 1.1.1.4 ! root 1537: "* ! 1538: { ! 1539: if (flag_pic && symbolic_operand (operands[2], Pmode)) ! 1540: abort (); ! 1541: else if (symbolic_operand (operands[2], Pmode)) ! 1542: return \"ldo RR'%G2(%1),%0\"; ! 1543: else ! 1544: return \"ldo R'%G2(%1),%0\"; ! 1545: }" ! 1546: [(set_attr "type" "move") ! 1547: (set_attr "length" "4")]) 1.1 root 1548: 1549: ;; Now that a symbolic_address plus a constant is broken up early 1550: ;; in the compilation phase (for better CSE) we need a special 1551: ;; combiner pattern to load the symbolic address plus the constant 1.1.1.3 root 1552: ;; in only 2 instructions. (For cases where the symbolic address 1.1 root 1553: ;; was not a common subexpression.) 1554: (define_split 1555: [(set (match_operand:SI 0 "register_operand" "") 1.1.1.3 root 1556: (match_operand:SI 1 "symbolic_operand" "")) 1.1 root 1557: (clobber (match_operand:SI 2 "register_operand" ""))] 1.1.1.4 ! root 1558: "! (flag_pic && pic_label_operand (operands[1], SImode))" 1.1 root 1559: [(set (match_dup 2) (high:SI (match_dup 1))) 1560: (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))] 1561: "") 1562: 1563: (define_expand "movhi" 1564: [(set (match_operand:HI 0 "general_operand" "") 1565: (match_operand:HI 1 "general_operand" ""))] 1566: "" 1567: " 1568: { 1569: if (emit_move_sequence (operands, HImode, 0)) 1570: DONE; 1571: }") 1572: 1573: (define_insn "" 1.1.1.3 root 1574: [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!f") 1575: (match_operand:HI 1 "move_operand" "r,J,N,K,Q,rM,rM,!fM"))] 1.1 root 1576: "register_operand (operands[0], HImode) 1577: || reg_or_0_operand (operands[1], HImode)" 1578: "@ 1.1.1.3 root 1579: copy %1,%0 1.1 root 1580: ldi %1,%0 1581: ldil L'%1,%0 1582: zdepi %Z1,%0 1583: ldh%M1 %1,%0 1584: sth%M0 %r1,%0 1585: mtsar %r1 1586: fcpy,sgl %r1,%0" 1.1.1.4 ! root 1587: [(set_attr "type" "move,move,move,shift,load,store,move,fpalu") 1.1.1.2 root 1588: (set_attr "length" "4,4,4,4,4,4,4,4")]) 1.1 root 1589: 1590: (define_insn "" 1591: [(set (match_operand:HI 0 "register_operand" "=r") 1592: (mem:HI (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r") 1593: (const_int 2)) 1594: (match_operand:SI 1 "register_operand" "r"))))] 1595: "! TARGET_DISABLE_INDEXING" 1596: "ldhx,s %2(0,%1),%0" 1597: [(set_attr "type" "load") 1.1.1.2 root 1598: (set_attr "length" "4")]) 1599: 1600: ;; This variant of the above insn can occur if the second operand 1601: ;; is the frame pointer. This is a kludge, but there doesn't 1602: ;; seem to be a way around it. Only recognize it while reloading. 1.1.1.3 root 1603: ;; Note how operand 3 uses a predicate of "const_int_operand", but 1604: ;; has constraints allowing a register. I don't know how this works, 1605: ;; but it somehow makes sure that out-of-range constants are placed 1606: ;; in a register which somehow magically is a "const_int_operand". 1607: ;; (this was stolen from alpha.md, I'm not going to try and change it. 1.1.1.2 root 1608: (define_insn "" 1609: [(set (match_operand:HI 0 "register_operand" "=&r") 1.1.1.3 root 1610: (mem:HI (plus:SI (plus:SI 1.1.1.2 root 1611: (mult:SI (match_operand:SI 2 "register_operand" "r") 1612: (const_int 2)) 1613: (match_operand:SI 1 "register_operand" "r")) 1614: (match_operand:SI 3 "const_int_operand" "rI"))))] 1615: "! TARGET_DISABLE_INDEXING && reload_in_progress" 1616: "* 1617: { 1618: if (GET_CODE (operands[3]) == CONST_INT) 1.1.1.3 root 1619: return \"sh1addl %2,%1,%0\;ldh %3(0,%0),%0\"; 1.1.1.2 root 1620: else 1.1.1.3 root 1621: return \"sh1addl %2,%1,%0\;ldhx %3(0,%0),%0\"; 1.1.1.2 root 1622: }" 1623: [(set_attr "type" "load") 1624: (set_attr "length" "8")]) 1.1 root 1625: 1626: (define_insn "" 1627: [(set (match_operand:HI 3 "register_operand" "=r") 1628: (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "0") 1629: (match_operand:SI 2 "int5_operand" "L")))) 1630: (set (match_operand:SI 0 "register_operand" "=r") 1631: (plus:SI (match_dup 1) (match_dup 2)))] 1632: "" 1633: "ldhs,mb %2(0,%0),%3" 1634: [(set_attr "type" "load") 1.1.1.2 root 1635: (set_attr "length" "4")]) 1.1 root 1636: 1637: (define_insn "" 1638: [(set (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "0") 1639: (match_operand:SI 2 "int5_operand" "L"))) 1640: (match_operand:HI 3 "reg_or_0_operand" "rM")) 1641: (set (match_operand:SI 0 "register_operand" "=r") 1642: (plus:SI (match_dup 1) (match_dup 2)))] 1643: "" 1644: "sths,mb %r3,%2(0,%0)" 1645: [(set_attr "type" "store") 1.1.1.2 root 1646: (set_attr "length" "4")]) 1.1 root 1647: 1648: (define_insn "" 1649: [(set (match_operand:HI 0 "register_operand" "=r") 1.1.1.4 ! root 1650: (high:HI (match_operand 1 "const_int_operand" "")))] ! 1651: "" 1.1 root 1652: "ldil L'%G1,%0" 1653: [(set_attr "type" "move") 1.1.1.2 root 1654: (set_attr "length" "4")]) 1.1 root 1655: 1656: (define_insn "" 1657: [(set (match_operand:HI 0 "register_operand" "=r") 1658: (lo_sum:HI (match_operand:HI 1 "register_operand" "r") 1.1.1.4 ! root 1659: (match_operand 2 "const_int_operand" "")))] 1.1 root 1660: "" 1661: "ldo R'%G2(%1),%0" 1.1.1.4 ! root 1662: [(set_attr "type" "move") ! 1663: (set_attr "length" "4")]) 1.1 root 1664: 1665: (define_expand "movqi" 1666: [(set (match_operand:QI 0 "general_operand" "") 1667: (match_operand:QI 1 "general_operand" ""))] 1668: "" 1669: " 1670: { 1671: if (emit_move_sequence (operands, QImode, 0)) 1672: DONE; 1673: }") 1674: 1675: (define_insn "" 1.1.1.3 root 1676: [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!f") 1677: (match_operand:QI 1 "move_operand" "r,J,N,K,Q,rM,rM,!fM"))] 1.1 root 1678: "register_operand (operands[0], QImode) 1679: || reg_or_0_operand (operands[1], QImode)" 1680: "@ 1.1.1.3 root 1681: copy %1,%0 1.1 root 1682: ldi %1,%0 1683: ldil L'%1,%0 1684: zdepi %Z1,%0 1685: ldb%M1 %1,%0 1686: stb%M0 %r1,%0 1687: mtsar %r1 1688: fcpy,sgl %r1,%0" 1.1.1.4 ! root 1689: [(set_attr "type" "move,move,move,shift,load,store,move,fpalu") 1.1.1.2 root 1690: (set_attr "length" "4,4,4,4,4,4,4,4")]) 1.1 root 1691: 1692: (define_insn "" 1693: [(set (match_operand:QI 3 "register_operand" "=r") 1694: (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "0") 1695: (match_operand:SI 2 "int5_operand" "L")))) 1696: (set (match_operand:SI 0 "register_operand" "=r") 1697: (plus:SI (match_dup 1) (match_dup 2)))] 1698: "" 1699: "ldbs,mb %2(0,%0),%3" 1700: [(set_attr "type" "load") 1.1.1.2 root 1701: (set_attr "length" "4")]) 1.1 root 1702: 1703: (define_insn "" 1704: [(set (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "0") 1705: (match_operand:SI 2 "int5_operand" "L"))) 1706: (match_operand:QI 3 "reg_or_0_operand" "rM")) 1707: (set (match_operand:SI 0 "register_operand" "=r") 1708: (plus:SI (match_dup 1) (match_dup 2)))] 1709: "" 1710: "stbs,mb %r3,%2(0,%0)" 1711: [(set_attr "type" "store") 1.1.1.2 root 1712: (set_attr "length" "4")]) 1.1 root 1713: 1714: ;; The definition of this insn does not really explain what it does, 1715: ;; but it should suffice 1716: ;; that anything generated as this insn will be recognized as one 1717: ;; and that it will not successfully combine with anything. 1718: (define_expand "movstrsi" 1.1.1.3 root 1719: [(parallel [(set (mem:BLK (match_operand:BLK 0 "" "")) 1720: (mem:BLK (match_operand:BLK 1 "" ""))) 1.1 root 1721: (clobber (match_dup 0)) 1722: (clobber (match_dup 1)) 1723: (clobber (match_dup 4)) 1724: (clobber (match_dup 5)) 1725: (use (match_operand:SI 2 "arith_operand" "")) 1726: (use (match_operand:SI 3 "const_int_operand" ""))])] 1727: "" 1728: " 1729: { 1730: /* If the blocks are not at least word-aligned and rather big (>16 items), 1731: or the size is indeterminate, don't inline the copy code. A 1732: procedure call is better since it can check the alignment at 1733: runtime and make the optimal decisions. */ 1734: if (INTVAL (operands[3]) < 4 1735: && (GET_CODE (operands[2]) != CONST_INT 1.1.1.3 root 1736: || (INTVAL (operands[2]) / INTVAL (operands[3]) > 8))) 1.1 root 1737: FAIL; 1738: 1739: operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0)); 1740: operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); 1741: operands[4] = gen_reg_rtx (SImode); 1742: operands[5] = gen_reg_rtx (SImode); 1743: }") 1744: 1745: ;; The operand constraints are written like this to support both compile-time 1746: ;; and run-time determined byte count. If the count is run-time determined, 1747: ;; the register with the byte count is clobbered by the copying code, and 1748: ;; therefore it is forced to operand 2. If the count is compile-time 1749: ;; determined, we need two scratch registers for the unrolled code. 1750: (define_insn "" 1751: [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r")) 1752: (mem:BLK (match_operand:SI 1 "register_operand" "+r,r"))) 1753: (clobber (match_dup 0)) 1754: (clobber (match_dup 1)) 1755: (clobber (match_operand:SI 2 "register_operand" "=r,r")) ;loop cnt/tmp 1756: (clobber (match_operand:SI 3 "register_operand" "=&r,&r")) ;item tmp 1757: (use (match_operand:SI 4 "arith_operand" "J,2")) ;byte count 1758: (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment 1759: "" 1760: "* return output_block_move (operands, !which_alternative);" 1761: [(set_attr "type" "multi,multi")]) 1762: 1763: ;; Floating point move insns 1764: 1765: ;; This pattern forces (set (reg:DF ...) (const_double ...)) 1766: ;; to be reloaded by putting the constant into memory when 1767: ;; reg is a floating point register. 1768: ;; 1769: ;; For integer registers we use ldil;ldo to set the appropriate 1770: ;; value. 1.1.1.3 root 1771: ;; 1.1 root 1772: ;; This must come before the movdf pattern, and it must be present 1773: ;; to handle obscure reloading cases. 1774: (define_insn "" 1.1.1.3 root 1775: [(set (match_operand:DF 0 "general_operand" "=?r,f") 1.1.1.4 ! root 1776: (match_operand:DF 1 "" "?F,m"))] 1.1 root 1777: "GET_CODE (operands[1]) == CONST_DOUBLE 1.1.1.4 ! root 1778: && operands[1] != CONST0_RTX (DFmode) ! 1779: && ! TARGET_SOFT_FLOAT" 1.1 root 1780: "* return (which_alternative == 0 ? output_move_double (operands) 1781: : \" fldds%F1 %1,%0\");" 1782: [(set_attr "type" "move,fpload") 1.1.1.2 root 1783: (set_attr "length" "16,4")]) 1.1 root 1784: 1785: (define_expand "movdf" 1786: [(set (match_operand:DF 0 "general_operand" "") 1787: (match_operand:DF 1 "general_operand" ""))] 1788: "" 1789: " 1790: { 1791: if (emit_move_sequence (operands, DFmode, 0)) 1792: DONE; 1793: }") 1794: 1.1.1.3 root 1795: ;; Reloading an SImode or DImode value requires a scratch register if 1796: ;; going in to or out of float point registers. 1797: 1798: (define_expand "reload_indf" 1799: [(set (match_operand:DF 0 "register_operand" "=Z") 1800: (match_operand:DF 1 "non_hard_reg_operand" "")) 1801: (clobber (match_operand:DF 2 "register_operand" "=&r"))] 1802: "" 1803: " 1804: { 1805: if (emit_move_sequence (operands, DFmode, operands[2])) 1806: DONE; 1807: 1808: /* We don't want the clobber emitted, so handle this ourselves. */ 1809: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); 1810: DONE; 1811: }") 1812: 1813: (define_expand "reload_outdf" 1814: [(set (match_operand:DF 0 "non_hard_reg_operand" "") 1815: (match_operand:DF 1 "register_operand" "Z")) 1816: (clobber (match_operand:DF 2 "register_operand" "=&r"))] 1817: "" 1818: " 1819: { 1820: if (emit_move_sequence (operands, DFmode, operands[2])) 1821: DONE; 1822: 1823: /* We don't want the clobber emitted, so handle this ourselves. */ 1824: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); 1825: DONE; 1826: }") 1827: 1.1 root 1828: (define_insn "" 1829: [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" 1.1.1.3 root 1830: "=f,*r,Q,?o,?Q,f,*&r,*&r") 1.1 root 1831: (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand" 1.1.1.3 root 1832: "fG,*rG,f,*r,*r,Q,o,Q"))] 1.1.1.4 ! root 1833: "(register_operand (operands[0], DFmode) ! 1834: || reg_or_0_operand (operands[1], DFmode)) ! 1835: && ! TARGET_SOFT_FLOAT" 1.1 root 1836: "* 1837: { 1.1.1.3 root 1838: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]) 1.1 root 1839: || operands[1] == CONST0_RTX (DFmode)) 1840: return output_fp_move_double (operands); 1841: return output_move_double (operands); 1842: }" 1.1.1.2 root 1843: [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load") 1844: (set_attr "length" "4,8,4,8,16,4,8,16")]) 1.1 root 1845: 1846: (define_insn "" 1.1.1.4 ! root 1847: [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" ! 1848: "=r,?o,?Q,&r,&r") ! 1849: (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand" ! 1850: "rG,r,r,o,Q"))] ! 1851: "(register_operand (operands[0], DFmode) ! 1852: || reg_or_0_operand (operands[1], DFmode)) ! 1853: && TARGET_SOFT_FLOAT" ! 1854: "* ! 1855: { ! 1856: return output_move_double (operands); ! 1857: }" ! 1858: [(set_attr "type" "move,store,store,load,load") ! 1859: (set_attr "length" "8,8,16,8,16")]) ! 1860: ! 1861: (define_insn "" 1.1.1.3 root 1862: [(set (match_operand:DF 0 "register_operand" "=f") 1.1 root 1863: (mem:DF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") 1864: (const_int 8)) 1865: (match_operand:SI 2 "register_operand" "r"))))] 1.1.1.4 ! root 1866: "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT" 1.1 root 1867: "flddx,s %1(0,%2),%0" 1868: [(set_attr "type" "fpload") 1.1.1.2 root 1869: (set_attr "length" "4")]) 1870: 1871: ;; This variant of the above insn can occur if the second operand 1872: ;; is the frame pointer. This is a kludge, but there doesn't 1873: ;; seem to be a way around it. Only recognize it while reloading. 1.1.1.3 root 1874: ;; Note how operand 3 uses a predicate of "const_int_operand", but 1875: ;; has constraints allowing a register. I don't know how this works, 1876: ;; but it somehow makes sure that out-of-range constants are placed 1877: ;; in a register which somehow magically is a "const_int_operand". 1878: ;; (this was stolen from alpha.md, I'm not going to try and change it. 1.1.1.2 root 1879: ;; Ugh. Output is a FP register; so we need to earlyclobber something 1.1.1.3 root 1880: ;; else as a temporary. 1.1.1.2 root 1881: (define_insn "" 1.1.1.3 root 1882: [(set (match_operand:DF 0 "register_operand" "=f") 1883: (mem:DF (plus:SI 1884: (plus:SI 1.1.1.2 root 1885: (mult:SI (match_operand:SI 1 "register_operand" "+&r") 1886: (const_int 8)) 1887: (match_operand:SI 2 "register_operand" "r")) 1888: (match_operand:SI 3 "const_int_operand" "rL"))))] 1.1.1.4 ! root 1889: "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT && reload_in_progress" 1.1.1.2 root 1890: "* 1891: { 1892: if (GET_CODE (operands[3]) == CONST_INT) 1.1.1.3 root 1893: return \"sh3addl %1,%2,%1\;fldds %3(0,%1),%0\"; 1.1.1.2 root 1894: else 1.1.1.3 root 1895: return \"sh3addl %1,%2,%1\;flddx %3(0,%1),%0\"; 1.1.1.2 root 1896: }" 1897: [(set_attr "type" "fpload") 1898: (set_attr "length" "8")]) 1.1 root 1899: 1900: (define_insn "" 1901: [(set (mem:DF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") 1902: (const_int 8)) 1903: (match_operand:SI 2 "register_operand" "r"))) 1.1.1.3 root 1904: (match_operand:DF 0 "register_operand" "f"))] 1.1.1.4 ! root 1905: "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT" 1.1 root 1906: "fstdx,s %0,%1(0,%2)" 1907: [(set_attr "type" "fpstore") 1.1.1.2 root 1908: (set_attr "length" "4")]) 1909: 1910: ;; This variant of the above insn can occur if the second operand 1911: ;; is the frame pointer. This is a kludge, but there doesn't 1912: ;; seem to be a way around it. Only recognize it while reloading. 1.1.1.3 root 1913: ;; Note how operand 3 uses a predicate of "const_int_operand", but 1914: ;; has constraints allowing a register. I don't know how this works, 1915: ;; but it somehow makes sure that out-of-range constants are placed 1916: ;; in a register which somehow magically is a "const_int_operand". 1917: ;; (this was stolen from alpha.md, I'm not going to try and change it. 1.1.1.2 root 1918: ;; Ugh. Output is a FP register; so we need to earlyclobber something 1.1.1.3 root 1919: ;; else as a temporary. 1.1.1.2 root 1920: (define_insn "" 1.1.1.3 root 1921: [(set (mem:DF (plus:SI 1922: (plus:SI 1.1.1.2 root 1923: (mult:SI (match_operand:SI 1 "register_operand" "+&r") 1924: (const_int 8)) 1925: (match_operand:SI 2 "register_operand" "r")) 1926: (match_operand:SI 3 "const_int_operand" "rL"))) 1.1.1.3 root 1927: (match_operand:DF 0 "register_operand" "f"))] 1.1.1.4 ! root 1928: "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT && reload_in_progress" 1.1.1.2 root 1929: "* 1930: { 1931: if (GET_CODE (operands[3]) == CONST_INT) 1.1.1.3 root 1932: return \"sh3addl %1,%2,%1\;fstds %0,%3(0,%1)\"; 1.1.1.2 root 1933: else 1.1.1.3 root 1934: return \"sh3addl %1,%2,%1\;fstdx %0,%3(0,%1)\"; 1.1.1.2 root 1935: }" 1936: [(set_attr "type" "fpstore") 1937: (set_attr "length" "8")]) 1.1 root 1938: 1939: (define_expand "movdi" 1940: [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "") 1941: (match_operand:DI 1 "general_operand" ""))] 1942: "" 1943: " 1944: { 1945: if (emit_move_sequence (operands, DImode, 0)) 1946: DONE; 1947: }") 1948: 1949: (define_expand "reload_indi" 1.1.1.3 root 1950: [(set (match_operand:DI 0 "register_operand" "=f") 1951: (match_operand:DI 1 "non_hard_reg_operand" "")) 1.1 root 1952: (clobber (match_operand:SI 2 "register_operand" "=&r"))] 1953: "" 1954: " 1955: { 1956: if (emit_move_sequence (operands, DImode, operands[2])) 1957: DONE; 1958: 1959: /* We don't want the clobber emitted, so handle this ourselves. */ 1960: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); 1961: DONE; 1962: }") 1963: 1964: (define_expand "reload_outdi" 1965: [(set (match_operand:DI 0 "general_operand" "") 1.1.1.3 root 1966: (match_operand:DI 1 "register_operand" "f")) 1.1 root 1967: (clobber (match_operand:SI 2 "register_operand" "=&r"))] 1968: "" 1969: " 1970: { 1971: if (emit_move_sequence (operands, DImode, operands[2])) 1972: DONE; 1973: 1974: /* We don't want the clobber emitted, so handle this ourselves. */ 1975: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); 1976: DONE; 1977: }") 1978: 1979: (define_insn "" 1980: [(set (match_operand:DI 0 "register_operand" "=r") 1981: (high:DI (match_operand 1 "" "")))] 1.1.1.4 ! root 1982: "" 1.1 root 1983: "* 1984: { 1985: rtx op0 = operands[0]; 1986: rtx op1 = operands[1]; 1987: 1988: if (GET_CODE (op1) == CONST_INT) 1989: { 1990: operands[0] = operand_subword (op0, 1, 0, DImode); 1991: output_asm_insn (\"ldil L'%1,%0\", operands); 1992: 1993: operands[0] = operand_subword (op0, 0, 0, DImode); 1994: if (INTVAL (op1) < 0) 1995: output_asm_insn (\"ldi -1,%0\", operands); 1996: else 1997: output_asm_insn (\"ldi 0,%0\", operands); 1998: return \"\"; 1999: } 2000: else if (GET_CODE (op1) == CONST_DOUBLE) 2001: { 2002: operands[0] = operand_subword (op0, 1, 0, DImode); 1.1.1.4 ! root 2003: operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1)); 1.1 root 2004: output_asm_insn (\"ldil L'%1,%0\", operands); 2005: 2006: operands[0] = operand_subword (op0, 0, 0, DImode); 1.1.1.4 ! root 2007: operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1)); 1.1 root 2008: output_asm_insn (singlemove_string (operands), operands); 2009: return \"\"; 2010: } 2011: else 2012: abort (); 2013: }" 2014: [(set_attr "type" "move") 1.1.1.2 root 2015: (set_attr "length" "8")]) 1.1 root 2016: 2017: ;;; Experimental 2018: 2019: (define_insn "" 2020: [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" 1.1.1.3 root 2021: "=r,o,Q,&r,&r,&r,f,f,*T") 1.1 root 2022: (match_operand:DI 1 "general_operand" 1.1.1.3 root 2023: "rM,r,r,o,Q,i,fM,*T,f"))] 1.1.1.4 ! root 2024: "(register_operand (operands[0], DImode) ! 2025: || reg_or_0_operand (operands[1], DImode)) ! 2026: && ! TARGET_SOFT_FLOAT" 1.1 root 2027: "* 2028: { 2029: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]) 2030: || (operands[1] == CONST0_RTX (DImode))) 2031: return output_fp_move_double (operands); 2032: return output_move_double (operands); 2033: }" 1.1.1.4 ! root 2034: [(set_attr "type" "move,store,store,load,load,multi,fpalu,fpload,fpstore") 1.1.1.2 root 2035: (set_attr "length" "8,8,16,8,16,16,4,4,4")]) 1.1 root 2036: 2037: (define_insn "" 1.1.1.4 ! root 2038: [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" ! 2039: "=r,o,Q,&r,&r,&r") ! 2040: (match_operand:DI 1 "general_operand" ! 2041: "rM,r,r,o,Q,i"))] ! 2042: "(register_operand (operands[0], DImode) ! 2043: || reg_or_0_operand (operands[1], DImode)) ! 2044: && TARGET_SOFT_FLOAT" ! 2045: "* ! 2046: { ! 2047: return output_move_double (operands); ! 2048: }" ! 2049: [(set_attr "type" "move,store,store,load,load,multi") ! 2050: (set_attr "length" "8,8,16,8,16,16")]) ! 2051: ! 2052: (define_insn "" 1.1.1.3 root 2053: [(set (match_operand:DI 0 "register_operand" "=r,&r") 1.1 root 2054: (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r") 2055: (match_operand:DI 2 "immediate_operand" "i,i")))] 2056: "" 2057: "* 2058: { 2059: /* Don't output a 64 bit constant, since we can't trust the assembler to 2060: handle it correctly. */ 2061: if (GET_CODE (operands[2]) == CONST_DOUBLE) 1.1.1.4 ! root 2062: operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2])); 1.1 root 2063: if (which_alternative == 1) 2064: output_asm_insn (\"copy %1,%0\", operands); 2065: return \"ldo R'%G2(%R1),%R0\"; 2066: }" 1.1.1.4 ! root 2067: [(set_attr "type" "move,move") ! 2068: (set_attr "length" "4,8")]) 1.1 root 2069: 2070: ;; This pattern forces (set (reg:SF ...) (const_double ...)) 2071: ;; to be reloaded by putting the constant into memory when 2072: ;; reg is a floating point register. 2073: ;; 2074: ;; For integer registers we use ldil;ldo to set the appropriate 2075: ;; value. 1.1.1.3 root 2076: ;; 1.1 root 2077: ;; This must come before the movsf pattern, and it must be present 2078: ;; to handle obscure reloading cases. 2079: (define_insn "" 1.1.1.3 root 2080: [(set (match_operand:SF 0 "general_operand" "=?r,f") 1.1.1.4 ! root 2081: (match_operand:SF 1 "" "?F,m"))] 1.1 root 2082: "GET_CODE (operands[1]) == CONST_DOUBLE 1.1.1.4 ! root 2083: && operands[1] != CONST0_RTX (SFmode) ! 2084: && ! TARGET_SOFT_FLOAT" 1.1 root 2085: "* return (which_alternative == 0 ? singlemove_string (operands) 2086: : \" fldws%F1 %1,%0\");" 2087: [(set_attr "type" "move,fpload") 1.1.1.2 root 2088: (set_attr "length" "8,4")]) 1.1 root 2089: 2090: (define_expand "movsf" 2091: [(set (match_operand:SF 0 "general_operand" "") 2092: (match_operand:SF 1 "general_operand" ""))] 2093: "" 2094: " 2095: { 2096: if (emit_move_sequence (operands, SFmode, 0)) 2097: DONE; 2098: }") 2099: 1.1.1.3 root 2100: ;; Reloading an SImode or DImode value requires a scratch register if 2101: ;; going in to or out of float point registers. 2102: 2103: (define_expand "reload_insf" 2104: [(set (match_operand:SF 0 "register_operand" "=Z") 2105: (match_operand:SF 1 "non_hard_reg_operand" "")) 2106: (clobber (match_operand:SF 2 "register_operand" "=&r"))] 2107: "" 2108: " 2109: { 2110: if (emit_move_sequence (operands, SFmode, operands[2])) 2111: DONE; 2112: 2113: /* We don't want the clobber emitted, so handle this ourselves. */ 2114: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); 2115: DONE; 2116: }") 2117: 2118: (define_expand "reload_outsf" 2119: [(set (match_operand:SF 0 "non_hard_reg_operand" "") 2120: (match_operand:SF 1 "register_operand" "Z")) 2121: (clobber (match_operand:SF 2 "register_operand" "=&r"))] 2122: "" 2123: " 2124: { 2125: if (emit_move_sequence (operands, SFmode, operands[2])) 2126: DONE; 2127: 2128: /* We don't want the clobber emitted, so handle this ourselves. */ 2129: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); 2130: DONE; 2131: }") 2132: 1.1 root 2133: (define_insn "" 2134: [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" 1.1.1.3 root 2135: "=f,r,f,r,Q,Q") 1.1 root 2136: (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand" 1.1.1.3 root 2137: "fG,rG,Q,Q,f,rG"))] 1.1.1.4 ! root 2138: "(register_operand (operands[0], SFmode) ! 2139: || reg_or_0_operand (operands[1], SFmode)) ! 2140: && ! TARGET_SOFT_FLOAT" 1.1 root 2141: "@ 2142: fcpy,sgl %r1,%0 2143: copy %r1,%0 2144: fldws%F1 %1,%0 2145: ldw%M1 %1,%0 2146: fstws%F0 %r1,%0 2147: stw%M0 %r1,%0" 2148: [(set_attr "type" "fpalu,move,fpload,load,fpstore,store") 1.1.1.2 root 2149: (set_attr "length" "4,4,4,4,4,4")]) 1.1 root 2150: 2151: (define_insn "" 1.1.1.4 ! root 2152: [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" ! 2153: "=r,r,Q") ! 2154: (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand" ! 2155: "rG,Q,rG"))] ! 2156: "(register_operand (operands[0], SFmode) ! 2157: || reg_or_0_operand (operands[1], SFmode)) ! 2158: && TARGET_SOFT_FLOAT" ! 2159: "@ ! 2160: copy %r1,%0 ! 2161: ldw%M1 %1,%0 ! 2162: stw%M0 %r1,%0" ! 2163: [(set_attr "type" "move,load,store") ! 2164: (set_attr "length" "4,4,4")]) ! 2165: ! 2166: (define_insn "" 1.1.1.3 root 2167: [(set (match_operand:SF 0 "register_operand" "=f") 1.1 root 2168: (mem:SF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") 2169: (const_int 4)) 2170: (match_operand:SI 2 "register_operand" "r"))))] 1.1.1.4 ! root 2171: "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT" 1.1 root 2172: "fldwx,s %1(0,%2),%0" 2173: [(set_attr "type" "fpload") 1.1.1.2 root 2174: (set_attr "length" "4")]) 2175: 2176: ;; This variant of the above insn can occur if the second operand 2177: ;; is the frame pointer. This is a kludge, but there doesn't 2178: ;; seem to be a way around it. Only recognize it while reloading. 1.1.1.3 root 2179: ;; Note how operand 3 uses a predicate of "const_int_operand", but 2180: ;; has constraints allowing a register. I don't know how this works, 2181: ;; but it somehow makes sure that out-of-range constants are placed 2182: ;; in a register which somehow magically is a "const_int_operand". 2183: ;; (this was stolen from alpha.md, I'm not going to try and change it. 1.1.1.2 root 2184: ;; Ugh. Output is a FP register; so we need to earlyclobber something 1.1.1.3 root 2185: ;; else as a temporary. 1.1.1.2 root 2186: (define_insn "" 1.1.1.3 root 2187: [(set (match_operand:SF 0 "register_operand" "=f") 2188: (mem:SF (plus:SI 2189: (plus:SI 1.1.1.2 root 2190: (mult:SI (match_operand:SI 1 "register_operand" "+&r") 2191: (const_int 4)) 2192: (match_operand:SI 2 "register_operand" "r")) 2193: (match_operand:SI 3 "const_int_operand" "rL"))))] 1.1.1.4 ! root 2194: "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT && reload_in_progress" 1.1.1.2 root 2195: "* 2196: { 2197: if (GET_CODE (operands[3]) == CONST_INT) 1.1.1.3 root 2198: return \"sh2addl %1,%2,%1\;fldws %3(0,%1),%0\"; 1.1.1.2 root 2199: else 1.1.1.3 root 2200: return \"sh2addl %1,%2,%1\;fldwx %3(0,%1),%0\"; 1.1.1.2 root 2201: }" 2202: [(set_attr "type" "fpload") 2203: (set_attr "length" "8")]) 1.1 root 2204: 2205: (define_insn "" 2206: [(set (mem:SF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") 2207: (const_int 4)) 2208: (match_operand:SI 2 "register_operand" "r"))) 1.1.1.3 root 2209: (match_operand:SF 0 "register_operand" "f"))] 1.1.1.4 ! root 2210: "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT" 1.1 root 2211: "fstwx,s %0,%1(0,%2)" 2212: [(set_attr "type" "fpstore") 1.1.1.2 root 2213: (set_attr "length" "4")]) 2214: 2215: ;; This variant of the above insn can occur if the second operand 2216: ;; is the frame pointer. This is a kludge, but there doesn't 2217: ;; seem to be a way around it. Only recognize it while reloading. 1.1.1.3 root 2218: ;; Note how operand 3 uses a predicate of "const_int_operand", but 2219: ;; has constraints allowing a register. I don't know how this works, 2220: ;; but it somehow makes sure that out-of-range constants are placed 2221: ;; in a register which somehow magically is a "const_int_operand". 2222: ;; (this was stolen from alpha.md, I'm not going to try and change it. 1.1.1.2 root 2223: ;; Ugh. Output is a FP register; so we need to earlyclobber something 1.1.1.3 root 2224: ;; else as a temporary. 1.1.1.2 root 2225: (define_insn "" 1.1.1.3 root 2226: [(set (mem:SF (plus:SI 2227: (plus:SI 1.1.1.2 root 2228: (mult:SI (match_operand:SI 1 "register_operand" "+&r") 2229: (const_int 4)) 2230: (match_operand:SI 2 "register_operand" "r")) 2231: (match_operand:SI 3 "const_int_operand" "rL"))) 1.1.1.3 root 2232: (match_operand:SF 0 "register_operand" "f"))] 1.1.1.4 ! root 2233: "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT && reload_in_progress" 1.1.1.2 root 2234: "* 2235: { 2236: if (GET_CODE (operands[3]) == CONST_INT) 1.1.1.3 root 2237: return \"sh2addl %1,%2,%1\;fstws %0,%3(0,%1)\"; 1.1.1.2 root 2238: else 1.1.1.3 root 2239: return \"sh2addl %1,%2,%1\;fstwx %0,%3(0,%1)\"; 1.1.1.2 root 2240: }" 2241: [(set_attr "type" "fpstore") 2242: (set_attr "length" "8")]) 1.1 root 2243: 2244: ;;- zero extension instructions 2245: 2246: (define_insn "zero_extendhisi2" 2247: [(set (match_operand:SI 0 "register_operand" "=r,r") 2248: (zero_extend:SI 2249: (match_operand:HI 1 "reg_or_nonsymb_mem_operand" "r,Q")))] 2250: "" 2251: "@ 2252: extru %1,31,16,%0 2253: ldh%M1 %1,%0" 1.1.1.4 ! root 2254: [(set_attr "type" "shift,load") ! 2255: (set_attr "length" "4,4")]) 1.1 root 2256: 2257: (define_insn "zero_extendqihi2" 2258: [(set (match_operand:HI 0 "register_operand" "=r,r") 2259: (zero_extend:HI 2260: (match_operand:QI 1 "reg_or_nonsymb_mem_operand" "r,Q")))] 2261: "" 2262: "@ 2263: extru %1,31,8,%0 2264: ldb%M1 %1,%0" 1.1.1.4 ! root 2265: [(set_attr "type" "shift,load") ! 2266: (set_attr "length" "4,4")]) 1.1 root 2267: 2268: (define_insn "zero_extendqisi2" 2269: [(set (match_operand:SI 0 "register_operand" "=r,r") 2270: (zero_extend:SI 2271: (match_operand:QI 1 "reg_or_nonsymb_mem_operand" "r,Q")))] 2272: "" 2273: "@ 2274: extru %1,31,8,%0 2275: ldb%M1 %1,%0" 1.1.1.4 ! root 2276: [(set_attr "type" "shift,load") ! 2277: (set_attr "length" "4,4")]) 1.1 root 2278: 2279: ;;- sign extension instructions 2280: 2281: (define_insn "extendhisi2" 2282: [(set (match_operand:SI 0 "register_operand" "=r") 2283: (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))] 2284: "" 2285: "extrs %1,31,16,%0" 1.1.1.4 ! root 2286: [(set_attr "type" "shift") ! 2287: (set_attr "length" "4")]) 1.1 root 2288: 2289: (define_insn "extendqihi2" 2290: [(set (match_operand:HI 0 "register_operand" "=r") 2291: (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))] 2292: "" 2293: "extrs %1,31,8,%0" 1.1.1.4 ! root 2294: [(set_attr "type" "shift") ! 2295: (set_attr "length" "4")]) 1.1 root 2296: 2297: (define_insn "extendqisi2" 2298: [(set (match_operand:SI 0 "register_operand" "=r") 2299: (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))] 2300: "" 2301: "extrs %1,31,8,%0" 1.1.1.4 ! root 2302: [(set_attr "type" "shift") ! 2303: (set_attr "length" "4")]) 1.1 root 2304: 2305: ;; Conversions between float and double. 2306: 2307: (define_insn "extendsfdf2" 1.1.1.3 root 2308: [(set (match_operand:DF 0 "register_operand" "=f") 1.1 root 2309: (float_extend:DF 1.1.1.3 root 2310: (match_operand:SF 1 "register_operand" "f")))] 1.1.1.4 ! root 2311: "! TARGET_SOFT_FLOAT" 1.1 root 2312: "fcnvff,sgl,dbl %1,%0" 1.1.1.4 ! root 2313: [(set_attr "type" "fpalu") ! 2314: (set_attr "length" "4")]) 1.1 root 2315: 2316: (define_insn "truncdfsf2" 1.1.1.3 root 2317: [(set (match_operand:SF 0 "register_operand" "=f") 1.1 root 2318: (float_truncate:SF 1.1.1.3 root 2319: (match_operand:DF 1 "register_operand" "f")))] 1.1.1.4 ! root 2320: "! TARGET_SOFT_FLOAT" 1.1 root 2321: "fcnvff,dbl,sgl %1,%0" 1.1.1.4 ! root 2322: [(set_attr "type" "fpalu") ! 2323: (set_attr "length" "4")]) 1.1 root 2324: 2325: ;; Conversion between fixed point and floating point. 2326: ;; Note that among the fix-to-float insns 2327: ;; the ones that start with SImode come first. 2328: ;; That is so that an operand that is a CONST_INT 2329: ;; (and therefore lacks a specific machine mode). 2330: ;; will be recognized as SImode (which is always valid) 2331: ;; rather than as QImode or HImode. 2332: 2333: ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...))) 2334: ;; to be reloaded by putting the constant into memory. 2335: ;; It must come before the more general floatsisf2 pattern. 2336: (define_insn "" 1.1.1.3 root 2337: [(set (match_operand:SF 0 "general_operand" "=f") 1.1 root 2338: (float:SF (match_operand:SI 1 "const_int_operand" "m")))] 1.1.1.4 ! root 2339: "! TARGET_SOFT_FLOAT" 1.1 root 2340: "fldws %1,%0\;fcnvxf,sgl,sgl %0,%0" 2341: [(set_attr "type" "fpalu") 1.1.1.2 root 2342: (set_attr "length" "8")]) 1.1 root 2343: 2344: (define_insn "floatsisf2" 1.1.1.3 root 2345: [(set (match_operand:SF 0 "general_operand" "=f") 2346: (float:SF (match_operand:SI 1 "register_operand" "f")))] 1.1.1.4 ! root 2347: "! TARGET_SOFT_FLOAT" 1.1 root 2348: "fcnvxf,sgl,sgl %1,%0" 1.1.1.4 ! root 2349: [(set_attr "type" "fpalu") ! 2350: (set_attr "length" "4")]) 1.1 root 2351: 2352: ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...))) 2353: ;; to be reloaded by putting the constant into memory. 2354: ;; It must come before the more general floatsidf2 pattern. 2355: (define_insn "" 1.1.1.3 root 2356: [(set (match_operand:DF 0 "general_operand" "=f") 1.1 root 2357: (float:DF (match_operand:SI 1 "const_int_operand" "m")))] 1.1.1.4 ! root 2358: "! TARGET_SOFT_FLOAT" 1.1 root 2359: "fldws %1,%0\;fcnvxf,sgl,dbl %0,%0" 2360: [(set_attr "type" "fpalu") 1.1.1.2 root 2361: (set_attr "length" "8")]) 1.1 root 2362: 2363: (define_insn "floatsidf2" 1.1.1.3 root 2364: [(set (match_operand:DF 0 "general_operand" "=f") 2365: (float:DF (match_operand:SI 1 "register_operand" "f")))] 1.1.1.4 ! root 2366: "! TARGET_SOFT_FLOAT" 1.1 root 2367: "fcnvxf,sgl,dbl %1,%0" 1.1.1.4 ! root 2368: [(set_attr "type" "fpalu") ! 2369: (set_attr "length" "4")]) 1.1 root 2370: 2371: (define_expand "floatunssisf2" 2372: [(set (subreg:SI (match_dup 2) 1) 2373: (match_operand:SI 1 "register_operand" "")) 2374: (set (subreg:SI (match_dup 2) 0) 2375: (const_int 0)) 2376: (set (match_operand:SF 0 "general_operand" "") 2377: (float:SF (match_dup 2)))] 1.1.1.4 ! root 2378: "TARGET_SNAKE && ! TARGET_SOFT_FLOAT" 1.1 root 2379: "operands[2] = gen_reg_rtx (DImode);") 2380: 2381: (define_expand "floatunssidf2" 2382: [(set (subreg:SI (match_dup 2) 1) 2383: (match_operand:SI 1 "register_operand" "")) 2384: (set (subreg:SI (match_dup 2) 0) 2385: (const_int 0)) 2386: (set (match_operand:DF 0 "general_operand" "") 2387: (float:DF (match_dup 2)))] 1.1.1.4 ! root 2388: "TARGET_SNAKE && ! TARGET_SOFT_FLOAT" 1.1 root 2389: "operands[2] = gen_reg_rtx (DImode);") 2390: 2391: (define_insn "floatdisf2" 1.1.1.3 root 2392: [(set (match_operand:SF 0 "general_operand" "=f") 2393: (float:SF (match_operand:DI 1 "register_operand" "f")))] 1.1.1.4 ! root 2394: "TARGET_SNAKE && ! TARGET_SOFT_FLOAT" 1.1 root 2395: "fcnvxf,dbl,sgl %1,%0" 1.1.1.4 ! root 2396: [(set_attr "type" "fpalu") ! 2397: (set_attr "length" "4")]) 1.1 root 2398: 2399: (define_insn "floatdidf2" 1.1.1.3 root 2400: [(set (match_operand:DF 0 "general_operand" "=f") 2401: (float:DF (match_operand:DI 1 "register_operand" "f")))] 1.1.1.4 ! root 2402: "TARGET_SNAKE && ! TARGET_SOFT_FLOAT" 1.1 root 2403: "fcnvxf,dbl,dbl %1,%0" 1.1.1.4 ! root 2404: [(set_attr "type" "fpalu") ! 2405: (set_attr "length" "4")]) 1.1 root 2406: 2407: ;; Convert a float to an actual integer. 2408: ;; Truncation is performed as part of the conversion. 2409: 2410: (define_insn "fix_truncsfsi2" 1.1.1.3 root 2411: [(set (match_operand:SI 0 "register_operand" "=f") 2412: (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] 1.1.1.4 ! root 2413: "! TARGET_SOFT_FLOAT" 1.1 root 2414: "fcnvfxt,sgl,sgl %1,%0" 1.1.1.4 ! root 2415: [(set_attr "type" "fpalu") ! 2416: (set_attr "length" "4")]) 1.1 root 2417: 2418: (define_insn "fix_truncdfsi2" 1.1.1.3 root 2419: [(set (match_operand:SI 0 "register_operand" "=f") 2420: (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))] 1.1.1.4 ! root 2421: "! TARGET_SOFT_FLOAT" 1.1 root 2422: "fcnvfxt,dbl,sgl %1,%0" 1.1.1.4 ! root 2423: [(set_attr "type" "fpalu") ! 2424: (set_attr "length" "4")]) 1.1 root 2425: 2426: (define_insn "fix_truncsfdi2" 1.1.1.3 root 2427: [(set (match_operand:DI 0 "register_operand" "=f") 2428: (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] 1.1.1.4 ! root 2429: "TARGET_SNAKE && ! TARGET_SOFT_FLOAT" 1.1 root 2430: "fcnvfxt,sgl,dbl %1,%0" 1.1.1.4 ! root 2431: [(set_attr "type" "fpalu") ! 2432: (set_attr "length" "4")]) 1.1 root 2433: 2434: (define_insn "fix_truncdfdi2" 1.1.1.3 root 2435: [(set (match_operand:DI 0 "register_operand" "=f") 2436: (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))] 1.1.1.4 ! root 2437: "TARGET_SNAKE && ! TARGET_SOFT_FLOAT" 1.1 root 2438: "fcnvfxt,dbl,dbl %1,%0" 1.1.1.4 ! root 2439: [(set_attr "type" "fpalu") ! 2440: (set_attr "length" "4")]) 1.1 root 2441: 2442: ;;- arithmetic instructions 2443: 2444: (define_insn "adddi3" 2445: [(set (match_operand:DI 0 "register_operand" "=r") 2446: (plus:DI (match_operand:DI 1 "register_operand" "%r") 2447: (match_operand:DI 2 "arith11_operand" "rI")))] 2448: "" 2449: "* 2450: { 2451: if (GET_CODE (operands[2]) == CONST_INT) 2452: { 2453: if (INTVAL (operands[2]) >= 0) 2454: return \"addi %2,%R1,%R0\;addc %1,0,%0\"; 2455: else 2456: return \"addi %2,%R1,%R0\;subb %1,0,%0\"; 2457: } 2458: else 2459: return \"add %R2,%R1,%R0\;addc %2,%1,%0\"; 2460: }" 1.1.1.4 ! root 2461: [(set_attr "type" "binary") ! 2462: (set_attr "length" "8")]) 1.1 root 2463: 2464: (define_insn "" 2465: [(set (match_operand:SI 0 "register_operand" "=r") 2466: (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r")) 2467: (match_operand:SI 2 "register_operand" "r")))] 2468: "" 1.1.1.4 ! root 2469: "uaddcm %2,%1,%0" ! 2470: [(set_attr "type" "binary") ! 2471: (set_attr "length" "4")]) 1.1 root 2472: 2473: ;; define_splits to optimize cases of adding a constant integer 2474: ;; to a register when the constant does not fit in 14 bits. */ 2475: (define_split 2476: [(set (match_operand:SI 0 "register_operand" "") 2477: (plus:SI (match_operand:SI 1 "register_operand" "") 2478: (match_operand:SI 2 "const_int_operand" ""))) 2479: (clobber (match_operand:SI 4 "register_operand" ""))] 1.1.1.3 root 2480: "! cint_ok_for_move (INTVAL (operands[2])) 1.1 root 2481: && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)" 2482: [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2))) 2483: (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))] 2484: " 2485: { 2486: int val = INTVAL (operands[2]); 2487: int low = (val < 0) ? -0x2000 : 0x1fff; 2488: int rest = val - low; 2489: 2490: operands[2] = GEN_INT (rest); 2491: operands[3] = GEN_INT (low); 2492: }") 2493: 2494: (define_split 2495: [(set (match_operand:SI 0 "register_operand" "") 2496: (plus:SI (match_operand:SI 1 "register_operand" "") 2497: (match_operand:SI 2 "const_int_operand" ""))) 2498: (clobber (match_operand:SI 4 "register_operand" ""))] 2499: "! cint_ok_for_move (INTVAL (operands[2]))" 2500: [(set (match_dup 4) (match_dup 2)) 2501: (set (match_dup 0) (plus:SI (mult:SI (match_dup 4) (match_dup 3)) 2502: (match_dup 1)))] 2503: " 2504: { 1.1.1.3 root 2505: HOST_WIDE_INT intval = INTVAL (operands[2]); 1.1 root 2506: 1.1.1.3 root 2507: /* Try dividing the constant by 2, then 4, and finally 8 to see 1.1 root 2508: if we can get a constant which can be loaded into a register 2509: in a single instruction (cint_ok_for_move). */ 2510: if (intval % 2 == 0 && cint_ok_for_move (intval / 2)) 2511: { 1.1.1.3 root 2512: operands[2] = GEN_INT (intval / 2); 1.1 root 2513: operands[3] = GEN_INT (2); 2514: } 2515: else if (intval % 4 == 0 && cint_ok_for_move (intval / 4)) 2516: { 1.1.1.3 root 2517: operands[2] = GEN_INT (intval / 4); 1.1 root 2518: operands[3] = GEN_INT (4); 2519: } 2520: else if (intval % 8 == 0 && cint_ok_for_move (intval / 8)) 2521: { 1.1.1.3 root 2522: operands[2] = GEN_INT (intval / 8); 1.1 root 2523: operands[3] = GEN_INT (8); 2524: } 1.1.1.3 root 2525: else 1.1 root 2526: FAIL; 2527: }") 2528: 2529: (define_insn "addsi3" 2530: [(set (match_operand:SI 0 "register_operand" "=r,r") 2531: (plus:SI (match_operand:SI 1 "register_operand" "%r,r") 2532: (match_operand:SI 2 "arith_operand" "r,J")))] 2533: "" 2534: "@ 1.1.1.3 root 2535: addl %1,%2,%0 1.1.1.4 ! root 2536: ldo %2(%1),%0" ! 2537: [(set_attr "type" "binary,binary") ! 2538: (set_attr "length" "4,4")]) ! 2539: ! 2540: ;; Disgusting kludge to work around reload bugs with frame pointer ! 2541: ;; elimination. Similar to other magic reload patterns in the ! 2542: ;; indexed memory operations. ! 2543: (define_insn "" ! 2544: [(set (match_operand:SI 0 "register_operand" "=&r") ! 2545: (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "%r") ! 2546: (match_operand:SI 2 "register_operand" "r")) ! 2547: (match_operand:SI 3 "const_int_operand" "rL")))] ! 2548: "reload_in_progress" ! 2549: "* ! 2550: { ! 2551: if (GET_CODE (operands[3]) == CONST_INT) ! 2552: return \"ldo %3(%2),%0\;addl %1,%0,%0\"; ! 2553: else ! 2554: return \"addl %3,%2,%0\;addl %1,%0,%0\"; ! 2555: }" ! 2556: [(set_attr "type" "binary") ! 2557: (set_attr "length" "8")]) 1.1 root 2558: 2559: (define_insn "subdi3" 2560: [(set (match_operand:DI 0 "register_operand" "=r") 2561: (minus:DI (match_operand:DI 1 "register_operand" "r") 2562: (match_operand:DI 2 "register_operand" "r")))] 2563: "" 2564: "sub %R1,%R2,%R0\;subb %1,%2,%0" 1.1.1.4 ! root 2565: [(set_attr "type" "binary") ! 2566: (set_attr "length" "8")]) 1.1 root 2567: 2568: (define_insn "subsi3" 2569: [(set (match_operand:SI 0 "register_operand" "=r,r") 2570: (minus:SI (match_operand:SI 1 "arith11_operand" "r,I") 2571: (match_operand:SI 2 "register_operand" "r,r")))] 2572: "" 2573: "@ 2574: sub %1,%2,%0 1.1.1.4 ! root 2575: subi %1,%2,%0" ! 2576: [(set_attr "type" "binary,binary") ! 2577: (set_attr "length" "4,4")]) 1.1 root 2578: 2579: ;; Clobbering a "register_operand" instead of a match_scratch 2580: ;; in operand3 of millicode calls avoids spilling %r1 and 2581: ;; produces better code. 2582: 2583: ;; The mulsi3 insns set up registers for the millicode call. 2584: (define_expand "mulsi3" 2585: [(set (reg:SI 26) (match_operand:SI 1 "move_operand" "")) 2586: (set (reg:SI 25) (match_operand:SI 2 "move_operand" "")) 2587: (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25))) 1.1.1.3 root 2588: (clobber (match_dup 3)) 1.1 root 2589: (clobber (reg:SI 26)) 2590: (clobber (reg:SI 25)) 2591: (clobber (reg:SI 31))]) 2592: (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))] 2593: "" 2594: " 2595: { 1.1.1.4 ! root 2596: if (TARGET_SNAKE && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT) 1.1 root 2597: { 2598: rtx scratch = gen_reg_rtx (DImode); 2599: operands[1] = force_reg (SImode, operands[1]); 2600: operands[2] = force_reg (SImode, operands[2]); 2601: emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2])); 2602: emit_insn (gen_rtx (SET, VOIDmode, 2603: operands[0], 2604: gen_rtx (SUBREG, SImode, scratch, 1))); 2605: DONE; 2606: } 1.1.1.3 root 2607: operands[3] = gen_reg_rtx (SImode); 1.1 root 2608: }") 2609: 2610: (define_insn "umulsidi3" 1.1.1.3 root 2611: [(set (match_operand:DI 0 "nonimmediate_operand" "=f") 2612: (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f")) 2613: (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "f"))))] 1.1.1.4 ! root 2614: "TARGET_SNAKE && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT" 1.1 root 2615: "xmpyu %1,%2,%0" 1.1.1.4 ! root 2616: [(set_attr "type" "fpmuldbl") ! 2617: (set_attr "length" "4")]) 1.1 root 2618: 2619: (define_insn "" 1.1.1.3 root 2620: [(set (match_operand:DI 0 "nonimmediate_operand" "=f") 2621: (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f")) 2622: (match_operand:DI 2 "uint32_operand" "f")))] 1.1.1.4 ! root 2623: "TARGET_SNAKE && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT" 1.1.1.3 root 2624: "xmpyu %1,%R2,%0" 1.1.1.4 ! root 2625: [(set_attr "type" "fpmuldbl") ! 2626: (set_attr "length" "4")]) 1.1.1.3 root 2627: 2628: (define_insn "" 1.1 root 2629: [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25))) 2630: (clobber (match_operand:SI 0 "register_operand" "=a")) 2631: (clobber (reg:SI 26)) 2632: (clobber (reg:SI 25)) 2633: (clobber (reg:SI 31))] 2634: "" 1.1.1.2 root 2635: "* return output_mul_insn (0, insn);" 1.1.1.3 root 2636: [(set_attr "type" "milli") 1.1.1.4 ! root 2637: (set (attr "length") ! 2638: (if_then_else (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME") ! 2639: (const_int 0)) ! 2640: (eq (symbol_ref "TARGET_MILLICODE_LONG_CALLS") ! 2641: (const_int 0))) ! 2642: (const_int 4) ! 2643: (const_int 24)))]) 1.1 root 2644: 2645: ;;; Division and mod. 2646: (define_expand "divsi3" 2647: [(set (reg:SI 26) (match_operand:SI 1 "move_operand" "")) 2648: (set (reg:SI 25) (match_operand:SI 2 "move_operand" "")) 2649: (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25))) 1.1.1.3 root 2650: (clobber (match_dup 3)) 1.1 root 2651: (clobber (reg:SI 26)) 2652: (clobber (reg:SI 25)) 2653: (clobber (reg:SI 31))]) 2654: (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))] 2655: "" 2656: " 2657: { 1.1.1.4 ! root 2658: operands[3] = gen_reg_rtx (SImode); ! 2659: if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 0)) ! 2660: DONE; 1.1 root 2661: }") 2662: 2663: (define_insn "" 2664: [(set (reg:SI 29) 1.1.1.4 ! root 2665: (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" ""))) 1.1 root 2666: (clobber (match_operand:SI 1 "register_operand" "=a")) 2667: (clobber (reg:SI 26)) 2668: (clobber (reg:SI 25)) 2669: (clobber (reg:SI 31))] 1.1.1.3 root 2670: "" 2671: "* 2672: return output_div_insn (operands, 0, insn);" 2673: [(set_attr "type" "milli") 1.1.1.4 ! root 2674: (set (attr "length") ! 2675: (if_then_else (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME") ! 2676: (const_int 0)) ! 2677: (eq (symbol_ref "TARGET_MILLICODE_LONG_CALLS") ! 2678: (const_int 0))) ! 2679: (const_int 4) ! 2680: (const_int 24)))]) 1.1 root 2681: 2682: (define_expand "udivsi3" 2683: [(set (reg:SI 26) (match_operand:SI 1 "move_operand" "")) 2684: (set (reg:SI 25) (match_operand:SI 2 "move_operand" "")) 2685: (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25))) 1.1.1.3 root 2686: (clobber (match_dup 3)) 1.1 root 2687: (clobber (reg:SI 26)) 2688: (clobber (reg:SI 25)) 2689: (clobber (reg:SI 31))]) 2690: (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))] 2691: "" 2692: " 2693: { 1.1.1.4 ! root 2694: operands[3] = gen_reg_rtx (SImode); ! 2695: if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 1)) ! 2696: DONE; 1.1 root 2697: }") 2698: 2699: (define_insn "" 2700: [(set (reg:SI 29) 1.1.1.4 ! root 2701: (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" ""))) 1.1 root 2702: (clobber (match_operand:SI 1 "register_operand" "=a")) 2703: (clobber (reg:SI 26)) 2704: (clobber (reg:SI 25)) 2705: (clobber (reg:SI 31))] 1.1.1.3 root 2706: "" 2707: "* 2708: return output_div_insn (operands, 1, insn);" 2709: [(set_attr "type" "milli") 1.1.1.4 ! root 2710: (set (attr "length") ! 2711: (if_then_else (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME") ! 2712: (const_int 0)) ! 2713: (eq (symbol_ref "TARGET_MILLICODE_LONG_CALLS") ! 2714: (const_int 0))) ! 2715: (const_int 4) ! 2716: (const_int 24)))]) 1.1 root 2717: 2718: (define_expand "modsi3" 2719: [(set (reg:SI 26) (match_operand:SI 1 "move_operand" "")) 2720: (set (reg:SI 25) (match_operand:SI 2 "move_operand" "")) 2721: (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25))) 1.1.1.3 root 2722: (clobber (match_dup 3)) 1.1 root 2723: (clobber (reg:SI 26)) 2724: (clobber (reg:SI 25)) 2725: (clobber (reg:SI 31))]) 2726: (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))] 2727: "" 2728: " 2729: { 1.1.1.4 ! root 2730: operands[3] = gen_reg_rtx (SImode); 1.1 root 2731: }") 2732: 2733: (define_insn "" 2734: [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25))) 2735: (clobber (match_operand:SI 0 "register_operand" "=a")) 2736: (clobber (reg:SI 26)) 2737: (clobber (reg:SI 25)) 2738: (clobber (reg:SI 31))] 2739: "" 2740: "* 1.1.1.2 root 2741: return output_mod_insn (0, insn);" 1.1.1.3 root 2742: [(set_attr "type" "milli") 1.1.1.4 ! root 2743: (set (attr "length") ! 2744: (if_then_else (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME") ! 2745: (const_int 0)) ! 2746: (eq (symbol_ref "TARGET_MILLICODE_LONG_CALLS") ! 2747: (const_int 0))) ! 2748: (const_int 4) ! 2749: (const_int 24)))]) 1.1 root 2750: 2751: (define_expand "umodsi3" 2752: [(set (reg:SI 26) (match_operand:SI 1 "move_operand" "")) 2753: (set (reg:SI 25) (match_operand:SI 2 "move_operand" "")) 2754: (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25))) 1.1.1.3 root 2755: (clobber (match_dup 3)) 1.1 root 2756: (clobber (reg:SI 26)) 2757: (clobber (reg:SI 25)) 2758: (clobber (reg:SI 31))]) 2759: (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))] 2760: "" 2761: " 2762: { 1.1.1.4 ! root 2763: operands[3] = gen_reg_rtx (SImode); 1.1 root 2764: }") 2765: 2766: (define_insn "" 2767: [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25))) 2768: (clobber (match_operand:SI 0 "register_operand" "=a")) 2769: (clobber (reg:SI 26)) 2770: (clobber (reg:SI 25)) 2771: (clobber (reg:SI 31))] 2772: "" 2773: "* 1.1.1.2 root 2774: return output_mod_insn (1, insn);" 1.1.1.3 root 2775: [(set_attr "type" "milli") 1.1.1.4 ! root 2776: (set (attr "length") ! 2777: (if_then_else (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME") ! 2778: (const_int 0)) ! 2779: (eq (symbol_ref "TARGET_MILLICODE_LONG_CALLS") ! 2780: (const_int 0))) ! 2781: (const_int 4) ! 2782: (const_int 24)))]) 1.1 root 2783: 2784: ;;- and instructions 2785: ;; We define DImode `and` so with DImode `not` we can get 2786: ;; DImode `andn`. Other combinations are possible. 2787: 2788: (define_expand "anddi3" 2789: [(set (match_operand:DI 0 "register_operand" "") 2790: (and:DI (match_operand:DI 1 "arith_double_operand" "") 2791: (match_operand:DI 2 "arith_double_operand" "")))] 2792: "" 2793: " 2794: { 2795: if (! register_operand (operands[1], DImode) 2796: || ! register_operand (operands[2], DImode)) 2797: /* Let GCC break this into word-at-a-time operations. */ 2798: FAIL; 2799: }") 2800: 2801: (define_insn "" 2802: [(set (match_operand:DI 0 "register_operand" "=r") 2803: (and:DI (match_operand:DI 1 "register_operand" "%r") 2804: (match_operand:DI 2 "register_operand" "r")))] 2805: "" 2806: "and %1,%2,%0\;and %R1,%R2,%R0" 1.1.1.4 ! root 2807: [(set_attr "type" "binary") ! 2808: (set_attr "length" "8")]) 1.1 root 2809: 1.1.1.3 root 2810: ; The ? for op1 makes reload prefer zdepi instead of loading a huge 2811: ; constant with ldil;ldo. 1.1 root 2812: (define_insn "andsi3" 2813: [(set (match_operand:SI 0 "register_operand" "=r,r") 1.1.1.3 root 2814: (and:SI (match_operand:SI 1 "register_operand" "%?r,0") 1.1 root 2815: (match_operand:SI 2 "and_operand" "rO,P")))] 2816: "" 2817: "* return output_and (operands); " 1.1.1.4 ! root 2818: [(set_attr "type" "binary,shift") ! 2819: (set_attr "length" "4,4")]) 1.1 root 2820: 2821: (define_insn "" 2822: [(set (match_operand:DI 0 "register_operand" "=r") 2823: (and:DI (not:DI (match_operand:DI 1 "register_operand" "r")) 2824: (match_operand:DI 2 "register_operand" "r")))] 2825: "" 2826: "andcm %2,%1,%0\;andcm %R2,%R1,%R0" 1.1.1.4 ! root 2827: [(set_attr "type" "binary") ! 2828: (set_attr "length" "8")]) 1.1 root 2829: 2830: (define_insn "" 2831: [(set (match_operand:SI 0 "register_operand" "=r") 2832: (and:SI (not:SI (match_operand:SI 1 "register_operand" "r")) 2833: (match_operand:SI 2 "register_operand" "r")))] 2834: "" 1.1.1.4 ! root 2835: "andcm %2,%1,%0" ! 2836: [(set_attr "type" "binary") ! 2837: (set_attr "length" "4")]) 1.1 root 2838: 2839: (define_expand "iordi3" 2840: [(set (match_operand:DI 0 "register_operand" "") 2841: (ior:DI (match_operand:DI 1 "arith_double_operand" "") 2842: (match_operand:DI 2 "arith_double_operand" "")))] 2843: "" 2844: " 2845: { 2846: if (! register_operand (operands[1], DImode) 2847: || ! register_operand (operands[2], DImode)) 2848: /* Let GCC break this into word-at-a-time operations. */ 2849: FAIL; 2850: }") 2851: 2852: (define_insn "" 2853: [(set (match_operand:DI 0 "register_operand" "=r") 2854: (ior:DI (match_operand:DI 1 "register_operand" "%r") 2855: (match_operand:DI 2 "register_operand" "r")))] 2856: "" 2857: "or %1,%2,%0\;or %R1,%R2,%R0" 1.1.1.4 ! root 2858: [(set_attr "type" "binary") ! 2859: (set_attr "length" "8")]) 1.1 root 2860: 2861: ;; Need a define_expand because we've run out of CONST_OK... characters. 2862: (define_expand "iorsi3" 2863: [(set (match_operand:SI 0 "register_operand" "") 2864: (ior:SI (match_operand:SI 1 "register_operand" "") 2865: (match_operand:SI 2 "arith32_operand" "")))] 2866: "" 2867: " 2868: { 2869: if (! (ior_operand (operands[2]) || register_operand (operands[2]))) 2870: operands[2] = force_reg (SImode, operands[2]); 2871: }") 2872: 2873: (define_insn "" 1.1.1.4 ! root 2874: [(set (match_operand:SI 0 "register_operand" "=r,r") ! 2875: (ior:SI (match_operand:SI 1 "register_operand" "0,0") ! 2876: (match_operand:SI 2 "ior_operand" "M,i")))] 1.1 root 2877: "" 2878: "* return output_ior (operands); " 1.1.1.4 ! root 2879: [(set_attr "type" "binary,shift") ! 2880: (set_attr "length" "4,4")]) 1.1 root 2881: 2882: (define_insn "" 2883: [(set (match_operand:SI 0 "register_operand" "=r") 2884: (ior:SI (match_operand:SI 1 "register_operand" "%r") 2885: (match_operand:SI 2 "register_operand" "r")))] 2886: "" 1.1.1.4 ! root 2887: "or %1,%2,%0" ! 2888: [(set_attr "type" "binary") ! 2889: (set_attr "length" "4")]) 1.1 root 2890: 2891: (define_expand "xordi3" 2892: [(set (match_operand:DI 0 "register_operand" "") 2893: (xor:DI (match_operand:DI 1 "arith_double_operand" "") 2894: (match_operand:DI 2 "arith_double_operand" "")))] 2895: "" 2896: " 2897: { 2898: if (! register_operand (operands[1], DImode) 2899: || ! register_operand (operands[2], DImode)) 2900: /* Let GCC break this into word-at-a-time operations. */ 2901: FAIL; 2902: }") 2903: 2904: (define_insn "" 2905: [(set (match_operand:DI 0 "register_operand" "=r") 2906: (xor:DI (match_operand:DI 1 "register_operand" "%r") 2907: (match_operand:DI 2 "register_operand" "r")))] 2908: "" 2909: "xor %1,%2,%0\;xor %R1,%R2,%R0" 1.1.1.4 ! root 2910: [(set_attr "type" "binary") ! 2911: (set_attr "length" "8")]) 1.1 root 2912: 2913: (define_insn "xorsi3" 2914: [(set (match_operand:SI 0 "register_operand" "=r") 2915: (xor:SI (match_operand:SI 1 "register_operand" "%r") 2916: (match_operand:SI 2 "register_operand" "r")))] 2917: "" 1.1.1.4 ! root 2918: "xor %1,%2,%0" ! 2919: [(set_attr "type" "binary") ! 2920: (set_attr "length" "4")]) 1.1 root 2921: 2922: (define_insn "negdi2" 2923: [(set (match_operand:DI 0 "register_operand" "=r") 2924: (neg:DI (match_operand:DI 1 "register_operand" "r")))] 2925: "" 2926: "sub 0,%R1,%R0\;subb 0,%1,%0" 2927: [(set_attr "type" "unary") 1.1.1.2 root 2928: (set_attr "length" "8")]) 1.1 root 2929: 2930: (define_insn "negsi2" 2931: [(set (match_operand:SI 0 "register_operand" "=r") 2932: (neg:SI (match_operand:SI 1 "register_operand" "r")))] 2933: "" 2934: "sub 0,%1,%0" 1.1.1.4 ! root 2935: [(set_attr "type" "unary") ! 2936: (set_attr "length" "4")]) 1.1 root 2937: 2938: (define_expand "one_cmpldi2" 2939: [(set (match_operand:DI 0 "register_operand" "") 2940: (not:DI (match_operand:DI 1 "arith_double_operand" "")))] 2941: "" 2942: " 2943: { 2944: if (! register_operand (operands[1], DImode)) 2945: FAIL; 2946: }") 2947: 2948: (define_insn "" 2949: [(set (match_operand:DI 0 "register_operand" "=r") 2950: (not:DI (match_operand:DI 1 "register_operand" "r")))] 2951: "" 2952: "uaddcm 0,%1,%0\;uaddcm 0,%R1,%R0" 2953: [(set_attr "type" "unary") 1.1.1.2 root 2954: (set_attr "length" "8")]) 1.1 root 2955: 2956: (define_insn "one_cmplsi2" 2957: [(set (match_operand:SI 0 "register_operand" "=r") 2958: (not:SI (match_operand:SI 1 "register_operand" "r")))] 2959: "" 2960: "uaddcm 0,%1,%0" 1.1.1.4 ! root 2961: [(set_attr "type" "unary") ! 2962: (set_attr "length" "4")]) 1.1 root 2963: 2964: ;; Floating point arithmetic instructions. 2965: 2966: (define_insn "adddf3" 1.1.1.3 root 2967: [(set (match_operand:DF 0 "register_operand" "=f") 2968: (plus:DF (match_operand:DF 1 "register_operand" "f") 2969: (match_operand:DF 2 "register_operand" "f")))] 1.1.1.4 ! root 2970: "! TARGET_SOFT_FLOAT" 1.1 root 2971: "fadd,dbl %1,%2,%0" 1.1.1.4 ! root 2972: [(set_attr "type" "fpalu") ! 2973: (set_attr "length" "4")]) 1.1 root 2974: 2975: (define_insn "addsf3" 1.1.1.3 root 2976: [(set (match_operand:SF 0 "register_operand" "=f") 2977: (plus:SF (match_operand:SF 1 "register_operand" "f") 2978: (match_operand:SF 2 "register_operand" "f")))] 1.1.1.4 ! root 2979: "! TARGET_SOFT_FLOAT" 1.1 root 2980: "fadd,sgl %1,%2,%0" 1.1.1.4 ! root 2981: [(set_attr "type" "fpalu") ! 2982: (set_attr "length" "4")]) 1.1 root 2983: 2984: (define_insn "subdf3" 1.1.1.3 root 2985: [(set (match_operand:DF 0 "register_operand" "=f") 2986: (minus:DF (match_operand:DF 1 "register_operand" "f") 2987: (match_operand:DF 2 "register_operand" "f")))] 1.1.1.4 ! root 2988: "! TARGET_SOFT_FLOAT" 1.1 root 2989: "fsub,dbl %1,%2,%0" 1.1.1.4 ! root 2990: [(set_attr "type" "fpalu") ! 2991: (set_attr "length" "4")]) 1.1 root 2992: 2993: (define_insn "subsf3" 1.1.1.3 root 2994: [(set (match_operand:SF 0 "register_operand" "=f") 2995: (minus:SF (match_operand:SF 1 "register_operand" "f") 2996: (match_operand:SF 2 "register_operand" "f")))] 1.1.1.4 ! root 2997: "! TARGET_SOFT_FLOAT" 1.1 root 2998: "fsub,sgl %1,%2,%0" 1.1.1.4 ! root 2999: [(set_attr "type" "fpalu") ! 3000: (set_attr "length" "4")]) 1.1 root 3001: 3002: (define_insn "muldf3" 1.1.1.3 root 3003: [(set (match_operand:DF 0 "register_operand" "=f") 3004: (mult:DF (match_operand:DF 1 "register_operand" "f") 3005: (match_operand:DF 2 "register_operand" "f")))] 1.1.1.4 ! root 3006: "! TARGET_SOFT_FLOAT" 1.1 root 3007: "fmpy,dbl %1,%2,%0" 1.1.1.4 ! root 3008: [(set_attr "type" "fpmuldbl") ! 3009: (set_attr "length" "4")]) 1.1 root 3010: 3011: (define_insn "mulsf3" 1.1.1.3 root 3012: [(set (match_operand:SF 0 "register_operand" "=f") 3013: (mult:SF (match_operand:SF 1 "register_operand" "f") 3014: (match_operand:SF 2 "register_operand" "f")))] 1.1.1.4 ! root 3015: "! TARGET_SOFT_FLOAT" 1.1 root 3016: "fmpy,sgl %1,%2,%0" 1.1.1.4 ! root 3017: [(set_attr "type" "fpmulsgl") ! 3018: (set_attr "length" "4")]) 1.1 root 3019: 3020: (define_insn "divdf3" 1.1.1.3 root 3021: [(set (match_operand:DF 0 "register_operand" "=f") 3022: (div:DF (match_operand:DF 1 "register_operand" "f") 3023: (match_operand:DF 2 "register_operand" "f")))] 1.1.1.4 ! root 3024: "! TARGET_SOFT_FLOAT" 1.1 root 3025: "fdiv,dbl %1,%2,%0" 1.1.1.4 ! root 3026: [(set_attr "type" "fpdivdbl") ! 3027: (set_attr "length" "4")]) 1.1 root 3028: 3029: (define_insn "divsf3" 1.1.1.3 root 3030: [(set (match_operand:SF 0 "register_operand" "=f") 3031: (div:SF (match_operand:SF 1 "register_operand" "f") 3032: (match_operand:SF 2 "register_operand" "f")))] 1.1.1.4 ! root 3033: "! TARGET_SOFT_FLOAT" 1.1 root 3034: "fdiv,sgl %1,%2,%0" 1.1.1.4 ! root 3035: [(set_attr "type" "fpdivsgl") ! 3036: (set_attr "length" "4")]) 1.1 root 3037: 3038: (define_insn "negdf2" 1.1.1.3 root 3039: [(set (match_operand:DF 0 "register_operand" "=f") 3040: (neg:DF (match_operand:DF 1 "register_operand" "f")))] 1.1.1.4 ! root 3041: "! TARGET_SOFT_FLOAT" 1.1 root 3042: "fsub,dbl 0,%1,%0" 1.1.1.4 ! root 3043: [(set_attr "type" "fpalu") ! 3044: (set_attr "length" "4")]) 1.1 root 3045: 3046: (define_insn "negsf2" 1.1.1.3 root 3047: [(set (match_operand:SF 0 "register_operand" "=f") 3048: (neg:SF (match_operand:SF 1 "register_operand" "f")))] 1.1.1.4 ! root 3049: "! TARGET_SOFT_FLOAT" 1.1 root 3050: "fsub,sgl 0,%1,%0" 1.1.1.4 ! root 3051: [(set_attr "type" "fpalu") ! 3052: (set_attr "length" "4")]) 1.1 root 3053: 3054: (define_insn "absdf2" 1.1.1.3 root 3055: [(set (match_operand:DF 0 "register_operand" "=f") 3056: (abs:DF (match_operand:DF 1 "register_operand" "f")))] 1.1.1.4 ! root 3057: "! TARGET_SOFT_FLOAT" 1.1 root 3058: "fabs,dbl %1,%0" 1.1.1.4 ! root 3059: [(set_attr "type" "fpalu") ! 3060: (set_attr "length" "4")]) 1.1 root 3061: 3062: (define_insn "abssf2" 1.1.1.3 root 3063: [(set (match_operand:SF 0 "register_operand" "=f") 3064: (abs:SF (match_operand:SF 1 "register_operand" "f")))] 1.1.1.4 ! root 3065: "! TARGET_SOFT_FLOAT" 1.1 root 3066: "fabs,sgl %1,%0" 1.1.1.4 ! root 3067: [(set_attr "type" "fpalu") ! 3068: (set_attr "length" "4")]) 1.1 root 3069: 3070: (define_insn "sqrtdf2" 1.1.1.3 root 3071: [(set (match_operand:DF 0 "register_operand" "=f") 3072: (sqrt:DF (match_operand:DF 1 "register_operand" "f")))] 1.1.1.4 ! root 3073: "! TARGET_SOFT_FLOAT" 1.1 root 3074: "fsqrt,dbl %1,%0" 1.1.1.4 ! root 3075: [(set_attr "type" "fpsqrtdbl") ! 3076: (set_attr "length" "4")]) 1.1 root 3077: 3078: (define_insn "sqrtsf2" 1.1.1.3 root 3079: [(set (match_operand:SF 0 "register_operand" "=f") 3080: (sqrt:SF (match_operand:SF 1 "register_operand" "f")))] 1.1.1.4 ! root 3081: "! TARGET_SOFT_FLOAT" 1.1 root 3082: "fsqrt,sgl %1,%0" 1.1.1.4 ! root 3083: [(set_attr "type" "fpsqrtsgl") ! 3084: (set_attr "length" "4")]) 1.1 root 3085: 3086: ;;- Shift instructions 3087: 3088: ;; Optimized special case of shifting. 3089: 3090: (define_insn "" 3091: [(set (match_operand:SI 0 "register_operand" "=r") 3092: (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") 3093: (const_int 24)))] 3094: "" 3095: "ldb%M1 %1,%0" 3096: [(set_attr "type" "load") 1.1.1.2 root 3097: (set_attr "length" "4")]) 1.1 root 3098: 3099: (define_insn "" 3100: [(set (match_operand:SI 0 "register_operand" "=r") 3101: (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") 3102: (const_int 16)))] 3103: "" 3104: "ldh%M1 %1,%0" 3105: [(set_attr "type" "load") 1.1.1.2 root 3106: (set_attr "length" "4")]) 1.1 root 3107: 3108: (define_insn "" 3109: [(set (match_operand:SI 0 "register_operand" "=r") 3110: (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r") 3111: (match_operand:SI 3 "shadd_operand" "")) 3112: (match_operand:SI 1 "register_operand" "r")))] 3113: "" 1.1.1.4 ! root 3114: "sh%O3addl %2,%1,%0" ! 3115: [(set_attr "type" "binary") ! 3116: (set_attr "length" "4")]) 1.1 root 3117: 3118: ;; This variant of the above insn can occur if the first operand 3119: ;; is the frame pointer. This is a kludge, but there doesn't 1.1.1.2 root 3120: ;; seem to be a way around it. Only recognize it while reloading. 1.1.1.3 root 3121: ;; Note how operand 3 uses a predicate of "const_int_operand", but 3122: ;; has constraints allowing a register. I don't know how this works, 3123: ;; but it somehow makes sure that out-of-range constants are placed 3124: ;; in a register which somehow magically is a "const_int_operand". 3125: ;; (this was stolen from alpha.md, I'm not going to try and change it. 1.1 root 3126: 3127: (define_insn "" 1.1.1.3 root 3128: [(set (match_operand:SI 0 "register_operand" "=&r,r") 3129: (plus:SI (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r,r") 1.1 root 3130: (match_operand:SI 4 "shadd_operand" "")) 1.1.1.3 root 3131: (match_operand:SI 1 "register_operand" "r,r")) 3132: (match_operand:SI 3 "const_int_operand" "r,J")))] 1.1 root 3133: "reload_in_progress" 1.1.1.3 root 3134: "@ 3135: sh%O4addl %2,%1,%0\;addl %3,%0,%0 3136: sh%O4addl %2,%1,%0\;ldo %3(%0),%0" 1.1 root 3137: [(set_attr "type" "multi") 1.1.1.2 root 3138: (set_attr "length" "8")]) 1.1 root 3139: 3140: (define_expand "ashlsi3" 3141: [(set (match_operand:SI 0 "register_operand" "") 3142: (ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "") 3143: (match_operand:SI 2 "arith32_operand" "")))] 3144: "" 3145: " 3146: { 3147: if (GET_CODE (operands[2]) != CONST_INT) 3148: { 3149: rtx temp = gen_reg_rtx (SImode); 3150: emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2])); 1.1.1.4 ! root 3151: if (GET_CODE (operands[1]) == CONST_INT) ! 3152: emit_insn (gen_zvdep_imm (operands[0], operands[1], temp)); ! 3153: else ! 3154: emit_insn (gen_zvdep32 (operands[0], operands[1], temp)); 1.1 root 3155: DONE; 3156: } 1.1.1.3 root 3157: /* Make sure both inputs are not constants, 1.1.1.4 ! root 3158: there are no patterns for that. */ 1.1 root 3159: operands[1] = force_reg (SImode, operands[1]); 3160: }") 3161: 3162: (define_insn "" 3163: [(set (match_operand:SI 0 "register_operand" "=r") 3164: (ashift:SI (match_operand:SI 1 "register_operand" "r") 3165: (match_operand:SI 2 "const_int_operand" "n")))] 3166: "" 3167: "zdep %1,%P2,%L2,%0" 1.1.1.4 ! root 3168: [(set_attr "type" "shift") 1.1.1.2 root 3169: (set_attr "length" "4")]) 1.1 root 3170: 3171: ; Match cases of op1 a CONST_INT here that zvdep_imm doesn't handle. 3172: ; Doing it like this makes slightly better code since reload can 3173: ; replace a register with a known value in range -16..15 with a 3174: ; constant. Ideally, we would like to merge zvdep32 and zvdep_imm, 3175: ; but since we have no more CONST_OK... characters, that is not 3176: ; possible. 3177: (define_insn "zvdep32" 3178: [(set (match_operand:SI 0 "register_operand" "=r,r") 3179: (ashift:SI (match_operand:SI 1 "arith5_operand" "r,L") 3180: (minus:SI (const_int 31) 3181: (match_operand:SI 2 "register_operand" "q,q"))))] 3182: "" 3183: "@ 3184: zvdep %1,32,%0 1.1.1.4 ! root 3185: zvdepi %1,32,%0" ! 3186: [(set_attr "type" "shift,shift") ! 3187: (set_attr "length" "4,4")]) 1.1 root 3188: 3189: (define_insn "zvdep_imm" 3190: [(set (match_operand:SI 0 "register_operand" "=r") 3191: (ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "") 3192: (minus:SI (const_int 31) 3193: (match_operand:SI 2 "register_operand" "q"))))] 3194: "" 3195: "* 3196: { 3197: int x = INTVAL (operands[1]); 3198: operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1)); 3199: operands[1] = GEN_INT ((x & 0xf) - 0x10); 3200: return \"zvdepi %1,%2,%0\"; 1.1.1.4 ! root 3201: }" ! 3202: [(set_attr "type" "shift") ! 3203: (set_attr "length" "4")]) 1.1 root 3204: 1.1.1.3 root 3205: (define_insn "vdepi_ior" 3206: [(set (match_operand:SI 0 "register_operand" "=r") 3207: (ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "") 3208: (minus:SI (const_int 31) 3209: (match_operand:SI 2 "register_operand" "q"))) 3210: (match_operand:SI 3 "register_operand" "0")))] 3211: ; accept ...0001...1, can this be generalized? 3212: "exact_log2 (INTVAL (operands[1]) + 1) >= 0" 3213: "* 3214: { 3215: int x = INTVAL (operands[1]); 3216: operands[2] = GEN_INT (exact_log2 (x + 1)); 3217: return \"vdepi -1,%2,%0\"; 1.1.1.4 ! root 3218: }" ! 3219: [(set_attr "type" "shift") ! 3220: (set_attr "length" "4")]) 1.1.1.3 root 3221: 3222: (define_insn "vdepi_and" 3223: [(set (match_operand:SI 0 "register_operand" "=r") 3224: (and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "") 3225: (minus:SI (const_int 31) 3226: (match_operand:SI 2 "register_operand" "q"))) 3227: (match_operand:SI 3 "register_operand" "0")))] 3228: ; this can be generalized...! 3229: "INTVAL (operands[1]) == -2" 3230: "* 3231: { 3232: int x = INTVAL (operands[1]); 3233: operands[2] = GEN_INT (exact_log2 ((~x) + 1)); 3234: return \"vdepi 0,%2,%0\"; 1.1.1.4 ! root 3235: }" ! 3236: [(set_attr "type" "shift") ! 3237: (set_attr "length" "4")]) 1.1.1.3 root 3238: 1.1 root 3239: (define_expand "ashrsi3" 3240: [(set (match_operand:SI 0 "register_operand" "") 3241: (ashiftrt:SI (match_operand:SI 1 "register_operand" "") 3242: (match_operand:SI 2 "arith32_operand" "")))] 3243: "" 3244: " 3245: { 3246: if (GET_CODE (operands[2]) != CONST_INT) 3247: { 3248: rtx temp = gen_reg_rtx (SImode); 3249: emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2])); 3250: emit_insn (gen_vextrs32 (operands[0], operands[1], temp)); 3251: DONE; 3252: } 3253: }") 3254: 3255: (define_insn "" 3256: [(set (match_operand:SI 0 "register_operand" "=r") 3257: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") 3258: (match_operand:SI 2 "const_int_operand" "n")))] 3259: "" 3260: "extrs %1,%P2,%L2,%0" 1.1.1.4 ! root 3261: [(set_attr "type" "shift") 1.1.1.2 root 3262: (set_attr "length" "4")]) 1.1 root 3263: 3264: (define_insn "vextrs32" 3265: [(set (match_operand:SI 0 "register_operand" "=r") 3266: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") 3267: (minus:SI (const_int 31) 3268: (match_operand:SI 2 "register_operand" "q"))))] 3269: "" 1.1.1.4 ! root 3270: "vextrs %1,32,%0" ! 3271: [(set_attr "type" "shift") ! 3272: (set_attr "length" "4")]) 1.1 root 3273: 3274: (define_insn "lshrsi3" 3275: [(set (match_operand:SI 0 "register_operand" "=r,r") 3276: (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r") 3277: (match_operand:SI 2 "arith32_operand" "q,n")))] 3278: "" 3279: "@ 3280: vshd 0,%1,%0 3281: extru %1,%P2,%L2,%0" 1.1.1.4 ! root 3282: [(set_attr "type" "shift") 1.1.1.2 root 3283: (set_attr "length" "4")]) 1.1 root 3284: 3285: (define_insn "rotrsi3" 3286: [(set (match_operand:SI 0 "register_operand" "=r,r") 3287: (rotatert:SI (match_operand:SI 1 "register_operand" "r,r") 3288: (match_operand:SI 2 "arith32_operand" "q,n")))] 3289: "" 3290: "* 3291: { 3292: if (GET_CODE (operands[2]) == CONST_INT) 3293: { 3294: operands[2] = GEN_INT (INTVAL (operands[2]) & 31); 3295: return \"shd %1,%1,%2,%0\"; 3296: } 3297: else 3298: return \"vshd %1,%1,%0\"; 3299: }" 1.1.1.4 ! root 3300: [(set_attr "type" "shift") 1.1.1.2 root 3301: (set_attr "length" "4")]) 1.1 root 3302: 3303: (define_insn "rotlsi3" 3304: [(set (match_operand:SI 0 "register_operand" "=r") 3305: (rotate:SI (match_operand:SI 1 "register_operand" "r") 3306: (match_operand:SI 2 "const_int_operand" "n")))] 3307: "" 3308: "* 3309: { 3310: operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31); 3311: return \"shd %1,%1,%2,%0\"; 3312: }" 1.1.1.4 ! root 3313: [(set_attr "type" "shift") 1.1.1.2 root 3314: (set_attr "length" "4")]) 1.1 root 3315: 3316: (define_insn "" 3317: [(set (match_operand:SI 0 "register_operand" "=r") 3318: (match_operator:SI 5 "plus_xor_ior_operator" 3319: [(ashift:SI (match_operand:SI 1 "register_operand" "r") 3320: (match_operand:SI 3 "const_int_operand" "n")) 3321: (lshiftrt:SI (match_operand:SI 2 "register_operand" "r") 3322: (match_operand:SI 4 "const_int_operand" "n"))]))] 3323: "INTVAL (operands[3]) + INTVAL (operands[4]) == 32" 3324: "shd %1,%2,%4,%0" 1.1.1.4 ! root 3325: [(set_attr "type" "shift") 1.1.1.2 root 3326: (set_attr "length" "4")]) 1.1 root 3327: 3328: (define_insn "" 3329: [(set (match_operand:SI 0 "register_operand" "=r") 3330: (match_operator:SI 5 "plus_xor_ior_operator" 3331: [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r") 3332: (match_operand:SI 4 "const_int_operand" "n")) 3333: (ashift:SI (match_operand:SI 1 "register_operand" "r") 3334: (match_operand:SI 3 "const_int_operand" "n"))]))] 3335: "INTVAL (operands[3]) + INTVAL (operands[4]) == 32" 3336: "shd %1,%2,%4,%0" 1.1.1.4 ! root 3337: [(set_attr "type" "shift") 1.1.1.2 root 3338: (set_attr "length" "4")]) 1.1 root 3339: 3340: (define_insn "" 3341: [(set (match_operand:SI 0 "register_operand" "=r") 3342: (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r") 3343: (match_operand:SI 2 "const_int_operand" "")) 3344: (match_operand:SI 3 "const_int_operand" "")))] 3345: "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) >= 0" 3346: "* 3347: { 3348: int cnt = INTVAL (operands[2]) & 31; 3349: operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt))); 3350: operands[2] = GEN_INT (31 - cnt); 3351: return \"zdep %1,%2,%3,%0\"; 3352: }" 1.1.1.4 ! root 3353: [(set_attr "type" "shift") 1.1.1.2 root 3354: (set_attr "length" "4")]) 1.1 root 3355: 3356: ;; Unconditional and other jump instructions. 3357: 3358: (define_insn "return" 3359: [(return)] 3360: "hppa_can_use_return_insn_p ()" 3361: "bv%* 0(%%r2)" 1.1.1.4 ! root 3362: [(set_attr "type" "branch") ! 3363: (set_attr "length" "4")]) 1.1 root 3364: 1.1.1.3 root 3365: ;; Use a different pattern for functions which have non-trivial 1.1 root 3366: ;; epilogues so as not to confuse jump and reorg. 3367: (define_insn "return_internal" 3368: [(use (reg:SI 2)) 3369: (return)] 3370: "" 3371: "bv%* 0(%%r2)" 1.1.1.4 ! root 3372: [(set_attr "type" "branch") ! 3373: (set_attr "length" "4")]) 1.1 root 3374: 3375: (define_expand "prologue" 3376: [(const_int 0)] 3377: "" 3378: "hppa_expand_prologue ();DONE;") 3379: 3380: (define_expand "epilogue" 3381: [(return)] 3382: "" 3383: " 3384: { 1.1.1.3 root 3385: /* Try to use the trivial return first. Else use the full 1.1 root 3386: epilogue. */ 3387: if (hppa_can_use_return_insn_p ()) 3388: emit_jump_insn (gen_return ()); 3389: else 3390: { 3391: hppa_expand_epilogue (); 3392: emit_jump_insn (gen_return_internal ()); 3393: } 3394: DONE; 3395: }") 3396: 3397: ;; Special because we use the value placed in %r2 by the bl instruction 3398: ;; from within its delay slot to set the value for the 2nd parameter to 3399: ;; the call. 3400: (define_insn "call_profiler" 3401: [(unspec_volatile [(const_int 0)] 0) 3402: (use (match_operand:SI 0 "const_int_operand" ""))] 3403: "" 3404: "bl _mcount,%%r2\;ldo %0(%%r2),%%r25" 1.1.1.4 ! root 3405: [(set_attr "type" "multi") ! 3406: (set_attr "length" "8")]) 1.1 root 3407: 3408: (define_insn "blockage" 3409: [(unspec_volatile [(const_int 2)] 0)] 3410: "" 3411: "" 3412: [(set_attr "length" "0")]) 3413: 1.1.1.4 ! root 3414: (define_insn "switch_jump" ! 3415: [(set:DI (pc) (label_ref (match_operand 0 "" "")))] ! 3416: "" ! 3417: "bl %l0,0%#" ! 3418: [(set_attr "type" "uncond_branch") ! 3419: (set_attr "length" "4")]) ! 3420: 1.1 root 3421: (define_insn "jump" 3422: [(set (pc) (label_ref (match_operand 0 "" "")))] 3423: "" 3424: "bl%* %l0,0" 1.1.1.2 root 3425: [(set_attr "type" "uncond_branch") 3426: (set (attr "length") 3427: (cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 0)) 3428: (const_int 4) 1.1.1.3 root 3429: ;; If the jump is in the delay slot of a call, then its length depends 1.1.1.2 root 3430: ;; on whether or not we can add the proper offset to %r2 with an ldo 3431: ;; instruction. 3432: (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) 3433: (const_int 8188)) 3434: (const_int 4)] 3435: (const_int 8)))]) 1.1 root 3436: 3437: ;; Subroutines of "casesi". 3438: ;; operand 0 is index 3439: ;; operand 1 is the minimum bound 3440: ;; operand 2 is the maximum bound - minimum bound + 1 3441: ;; operand 3 is CODE_LABEL for the table; 3442: ;; operand 4 is the CODE_LABEL to go to if index out of range. 3443: 3444: (define_expand "casesi" 3445: [(match_operand:SI 0 "general_operand" "") 3446: (match_operand:SI 1 "const_int_operand" "") 3447: (match_operand:SI 2 "const_int_operand" "") 3448: (match_operand 3 "" "") 3449: (match_operand 4 "" "")] 3450: "" 3451: " 3452: { 3453: if (GET_CODE (operands[0]) != REG) 3454: operands[0] = force_reg (SImode, operands[0]); 3455: 3456: if (operands[1] != const0_rtx) 3457: { 3458: rtx reg = gen_reg_rtx (SImode); 3459: 3460: operands[1] = GEN_INT (-INTVAL (operands[1])); 3461: if (!INT_14_BITS (operands[1])) 3462: operands[1] = force_reg (SImode, operands[1]); 3463: emit_insn (gen_addsi3 (reg, operands[0], operands[1])); 3464: 3465: operands[0] = reg; 3466: } 3467: 3468: if (!INT_11_BITS (operands[2])) 3469: operands[2] = force_reg (SImode, operands[2]); 3470: 3471: emit_jump_insn (gen_casesi0 (operands[0], operands[2], 3472: operands[3], operands[4])); 3473: DONE; 3474: }") 3475: 3476: (define_insn "casesi0" 3477: [(set (pc) 3478: (if_then_else (leu (match_operand:SI 0 "register_operand" "r") 3479: (match_operand:SI 1 "arith11_operand" "rI")) 3480: (plus:SI (mem:SI (plus:SI (pc) (match_dup 0))) 3481: (label_ref (match_operand 2 "" ""))) 3482: (pc))) 3483: (use (label_ref (match_operand 3 "" "")))] 3484: "" 3485: "* 3486: { 3487: if (GET_CODE (operands[1]) == CONST_INT) 3488: { 3489: operands[1] = GEN_INT (~INTVAL (operands[1])); 3490: return \"addi,uv %1,%0,0\;blr,n %0,0\;b,n %l3\"; 3491: } 3492: else 3493: { 3494: return \"sub,>> %0,%1,0\;blr,n %0,0\;b,n %l3\"; 3495: } 3496: }" 1.1.1.4 ! root 3497: [(set_attr "type" "multi") ! 3498: (set_attr "length" "12")]) 1.1 root 3499: 3500: ;; Need nops for the calls because execution is supposed to continue 3501: ;; past; we don't want to nullify an instruction that we need. 3502: ;;- jump to subroutine 3503: 3504: (define_expand "call" 1.1.1.3 root 3505: [(parallel [(call (match_operand:SI 0 "" "") 3506: (match_operand 1 "" "")) 3507: (clobber (reg:SI 2))])] 3508: "" 3509: " 1.1 root 3510: { 3511: rtx op; 1.1.1.4 ! root 3512: rtx call_insn; 1.1.1.3 root 3513: 1.1.1.4 ! root 3514: if (TARGET_PORTABLE_RUNTIME) 1.1 root 3515: op = force_reg (SImode, XEXP (operands[0], 0)); 3516: else 3517: op = XEXP (operands[0], 0); 1.1.1.2 root 3518: 3519: /* Use two different patterns for calls to explicitly named functions 3520: and calls through function pointers. This is necessary as these two 3521: types of calls use different calling conventions, and CSE might try 3522: to change the named call into an indirect call in some cases (using 3523: two patterns keeps CSE from performing this optimization). */ 3524: if (GET_CODE (op) == SYMBOL_REF) 1.1.1.4 ! root 3525: call_insn = emit_call_insn (gen_call_internal_symref (op, operands[1])); 1.1.1.2 root 3526: else 1.1.1.4 ! root 3527: call_insn = emit_call_insn (gen_call_internal_reg (force_reg (SImode, op), ! 3528: operands[1])); 1.1.1.2 root 3529: 1.1 root 3530: if (flag_pic) 3531: { 1.1.1.4 ! root 3532: use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx); ! 3533: ! 3534: /* After each call we must restore the PIC register, even if it ! 3535: doesn't appear to be used. ! 3536: ! 3537: This will set regs_ever_live for the callee saved register we ! 3538: stored the PIC register in. */ ! 3539: emit_move_insn (pic_offset_table_rtx, ! 3540: gen_rtx (REG, SImode, PIC_OFFSET_TABLE_REGNUM_SAVED)); ! 3541: emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx)); 1.1 root 3542: } 3543: DONE; 3544: }") 3545: 1.1.1.2 root 3546: (define_insn "call_internal_symref" 1.1.1.3 root 3547: [(call (mem:SI (match_operand:SI 0 "call_operand_address" "")) 3548: (match_operand 1 "" "i")) 3549: (clobber (reg:SI 2)) 3550: (use (const_int 0))] 1.1.1.4 ! root 3551: "! TARGET_PORTABLE_RUNTIME" 1.1.1.3 root 3552: "* 1.1 root 3553: { 1.1.1.2 root 3554: output_arg_descriptor (insn); 3555: return output_call (insn, operands[0], gen_rtx (REG, SImode, 2)); 1.1 root 3556: }" 1.1.1.3 root 3557: [(set_attr "type" "call") 1.1.1.4 ! root 3558: (set (attr "length") ! 3559: (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc)) ! 3560: (const_int 240000)) ! 3561: (const_int 4) ! 3562: (if_then_else (ne (symbol_ref "TARGET_MILLICODE_LONG_CALLS") ! 3563: (const_int 0)) ! 3564: (const_int 64) ! 3565: (const_int 52))))]) 1.1.1.2 root 3566: 3567: (define_insn "call_internal_reg" 1.1.1.3 root 3568: [(call (mem:SI (match_operand:SI 0 "register_operand" "r")) 3569: (match_operand 1 "" "i")) 3570: (clobber (reg:SI 2)) 3571: (use (const_int 1))] 3572: "" 3573: "* 3574: { 1.1.1.4 ! root 3575: if (TARGET_FAST_INDIRECT_CALLS) ! 3576: return \"ble 0(%%sr4,%r0)\;copy %%r31,%%r2\"; ! 3577: 1.1.1.3 root 3578: /* Yuk! bl may not be able to reach $$dyncall. */ 1.1.1.4 ! root 3579: if (TARGET_PORTABLE_RUNTIME || TARGET_MILLICODE_LONG_CALLS) 1.1.1.3 root 3580: return \"copy %r0,%%r22\;ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr 0,%%r2\;bv,n 0(%%r31)\;nop\"; 3581: else 3582: return \"copy %r0,%%r22\;.CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2\"; 3583: }" 3584: [(set_attr "type" "dyncall") 1.1.1.4 ! root 3585: (set (attr "length") ! 3586: (if_then_else (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME") ! 3587: (const_int 0)) ! 3588: (eq (symbol_ref "TARGET_MILLICODE_LONG_CALLS") ! 3589: (const_int 0))) ! 3590: (const_int 12) ! 3591: (const_int 24)))]) 1.1 root 3592: 3593: (define_expand "call_value" 3594: [(parallel [(set (match_operand 0 "" "") 3595: (call (match_operand:SI 1 "" "") 3596: (match_operand 2 "" ""))) 3597: (clobber (reg:SI 2))])] 3598: "" 3599: " 3600: { 3601: rtx op; 1.1.1.4 ! root 3602: rtx call_insn; 1.1.1.3 root 3603: 1.1.1.4 ! root 3604: if (TARGET_PORTABLE_RUNTIME) 1.1 root 3605: op = force_reg (SImode, XEXP (operands[1], 0)); 3606: else 3607: op = XEXP (operands[1], 0); 1.1.1.2 root 3608: 3609: /* Use two different patterns for calls to explicitly named functions 3610: and calls through function pointers. This is necessary as these two 3611: types of calls use different calling conventions, and CSE might try 3612: to change the named call into an indirect call in some cases (using 3613: two patterns keeps CSE from performing this optimization). */ 3614: if (GET_CODE (op) == SYMBOL_REF) 1.1.1.4 ! root 3615: call_insn = emit_call_insn (gen_call_value_internal_symref (operands[0], ! 3616: op, ! 3617: operands[2])); 1.1.1.2 root 3618: else 1.1.1.4 ! root 3619: call_insn = emit_call_insn (gen_call_value_internal_reg (operands[0], ! 3620: force_reg (SImode, op), ! 3621: operands[2])); 1.1.1.2 root 3622: 1.1 root 3623: if (flag_pic) 3624: { 1.1.1.4 ! root 3625: use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx); ! 3626: ! 3627: /* After each call we must restore the PIC register, even if it ! 3628: doesn't appear to be used. ! 3629: ! 3630: This will set regs_ever_live for the callee saved register we ! 3631: stored the PIC register in. */ ! 3632: emit_move_insn (pic_offset_table_rtx, ! 3633: gen_rtx (REG, SImode, PIC_OFFSET_TABLE_REGNUM_SAVED)); ! 3634: emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx)); ! 3635: ! 3636: /* Gross. We have to keep the scheduler from moving the restore ! 3637: of the PIC register away from the call. SCHED_GROUP_P is ! 3638: supposed to do this, but for some reason the compiler will ! 3639: go into an infinite loop when we use that. ! 3640: ! 3641: This method (blockage insn) may make worse code (then again ! 3642: it may not since calls are nearly blockages anyway), but at ! 3643: least it should work. */ ! 3644: emit_insn (gen_blockage ()); ! 3645: ! 3646: /* Gross. We have to keep the scheduler from moving the restore ! 3647: of the PIC register away from the call. SCHED_GROUP_P is ! 3648: supposed to do this, but for some reason the compiler will ! 3649: go into an infinite loop when we use that. ! 3650: ! 3651: This method (blockage insn) may make worse code (then again ! 3652: it may not since calls are nearly blockages anyway), but at ! 3653: least it should work. */ ! 3654: emit_insn (gen_blockage ()); 1.1 root 3655: } 3656: DONE; 3657: }") 3658: 1.1.1.2 root 3659: (define_insn "call_value_internal_symref" 1.1.1.3 root 3660: [(set (match_operand 0 "" "=rf") 1.1.1.2 root 3661: (call (mem:SI (match_operand:SI 1 "call_operand_address" "")) 3662: (match_operand 2 "" "i"))) 3663: (clobber (reg:SI 2)) 3664: (use (const_int 0))] 1.1 root 3665: ;;- Don't use operand 1 for most machines. 1.1.1.4 ! root 3666: "! TARGET_PORTABLE_RUNTIME" 1.1 root 3667: "* 3668: { 1.1.1.2 root 3669: output_arg_descriptor (insn); 3670: return output_call (insn, operands[1], gen_rtx (REG, SImode, 2)); 3671: }" 1.1.1.3 root 3672: [(set_attr "type" "call") 1.1.1.4 ! root 3673: (set (attr "length") ! 3674: (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc)) ! 3675: (const_int 240000)) ! 3676: (const_int 4) ! 3677: (if_then_else (ne (symbol_ref "TARGET_MILLICODE_LONG_CALLS") ! 3678: (const_int 0)) ! 3679: (const_int 64) ! 3680: (const_int 52))))]) 1.1.1.2 root 3681: 3682: (define_insn "call_value_internal_reg" 1.1.1.3 root 3683: [(set (match_operand 0 "" "=rf") 1.1.1.2 root 3684: (call (mem:SI (match_operand:SI 1 "register_operand" "r")) 3685: (match_operand 2 "" "i"))) 3686: (clobber (reg:SI 2)) 3687: (use (const_int 1))] 3688: "" 1.1.1.3 root 3689: "* 3690: { 1.1.1.4 ! root 3691: if (TARGET_FAST_INDIRECT_CALLS) ! 3692: return \"ble 0(%%sr4,%r1)\;copy %%r31,%%r2\"; ! 3693: 1.1.1.3 root 3694: /* Yuk! bl may not be able to reach $$dyncall. */ 1.1.1.4 ! root 3695: if (TARGET_PORTABLE_RUNTIME || TARGET_MILLICODE_LONG_CALLS) 1.1.1.3 root 3696: return \"copy %r1,%%r22\;ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr 0,%%r2\;bv,n 0(%%r31)\;nop\"; 3697: else 3698: return \"copy %r1,%%r22\;.CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2\"; 3699: }" 3700: [(set_attr "type" "dyncall") 1.1.1.4 ! root 3701: (set (attr "length") ! 3702: (if_then_else (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME") ! 3703: (const_int 0)) ! 3704: (eq (symbol_ref "TARGET_MILLICODE_LONG_CALLS") ! 3705: (const_int 0))) ! 3706: (const_int 12) ! 3707: (const_int 24)))]) 1.1.1.2 root 3708: 3709: ;; Call subroutine returning any type. 3710: 3711: (define_expand "untyped_call" 3712: [(parallel [(call (match_operand 0 "" "") 3713: (const_int 0)) 3714: (match_operand 1 "" "") 3715: (match_operand 2 "" "")])] 3716: "" 3717: " 3718: { 3719: int i; 3720: 3721: emit_call_insn (gen_call (operands[0], const0_rtx)); 3722: 3723: for (i = 0; i < XVECLEN (operands[2], 0); i++) 1.1 root 3724: { 1.1.1.2 root 3725: rtx set = XVECEXP (operands[2], 0, i); 3726: emit_move_insn (SET_DEST (set), SET_SRC (set)); 1.1 root 3727: } 3728: 1.1.1.2 root 3729: /* The optimizer does not know that the call sets the function value 3730: registers we stored in the result block. We avoid problems by 3731: claiming that all hard registers are used and clobbered at this 3732: point. */ 3733: emit_insn (gen_blockage ()); 3734: 3735: DONE; 3736: }") 1.1 root 3737: (define_insn "nop" 3738: [(const_int 0)] 3739: "" 1.1.1.4 ! root 3740: "nop" ! 3741: [(set_attr "type" "move") ! 3742: (set_attr "length" "4")]) 1.1 root 3743: 3744: ;;; Hope this is only within a function... 3745: (define_insn "indirect_jump" 3746: [(set (pc) (match_operand:SI 0 "register_operand" "r"))] 3747: "" 1.1.1.3 root 3748: "bv%* 0(%0)" 1.1.1.4 ! root 3749: [(set_attr "type" "branch") ! 3750: (set_attr "length" "4")]) 1.1 root 3751: 3752: (define_insn "extzv" 3753: [(set (match_operand:SI 0 "register_operand" "=r") 3754: (zero_extract:SI (match_operand:SI 1 "register_operand" "r") 3755: (match_operand:SI 2 "uint5_operand" "") 3756: (match_operand:SI 3 "uint5_operand" "")))] 3757: "" 1.1.1.4 ! root 3758: "extru %1,%3+%2-1,%2,%0" ! 3759: [(set_attr "type" "shift") ! 3760: (set_attr "length" "4")]) 1.1 root 3761: 1.1.1.3 root 3762: (define_insn "" 3763: [(set (match_operand:SI 0 "register_operand" "=r") 3764: (zero_extract:SI (match_operand:SI 1 "register_operand" "r") 3765: (const_int 1) 3766: (match_operand:SI 3 "register_operand" "q")))] 3767: "" 1.1.1.4 ! root 3768: "vextru %1,1,%0" ! 3769: [(set_attr "type" "shift") ! 3770: (set_attr "length" "4")]) 1.1.1.3 root 3771: 1.1 root 3772: (define_insn "extv" 3773: [(set (match_operand:SI 0 "register_operand" "=r") 3774: (sign_extract:SI (match_operand:SI 1 "register_operand" "r") 3775: (match_operand:SI 2 "uint5_operand" "") 3776: (match_operand:SI 3 "uint5_operand" "")))] 3777: "" 1.1.1.4 ! root 3778: "extrs %1,%3+%2-1,%2,%0" ! 3779: [(set_attr "type" "shift") ! 3780: (set_attr "length" "4")]) 1.1 root 3781: 1.1.1.3 root 3782: (define_insn "" 3783: [(set (match_operand:SI 0 "register_operand" "=r") 3784: (sign_extract:SI (match_operand:SI 1 "register_operand" "r") 3785: (const_int 1) 3786: (match_operand:SI 3 "register_operand" "q")))] 3787: "" 1.1.1.4 ! root 3788: "vextrs %1,1,%0" ! 3789: [(set_attr "type" "shift") ! 3790: (set_attr "length" "4")]) 1.1.1.3 root 3791: 1.1 root 3792: (define_insn "insv" 3793: [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r") 3794: (match_operand:SI 1 "uint5_operand" "") 3795: (match_operand:SI 2 "uint5_operand" "")) 3796: (match_operand:SI 3 "arith5_operand" "r,L"))] 3797: "" 3798: "@ 3799: dep %3,%2+%1-1,%1,%0 1.1.1.4 ! root 3800: depi %3,%2+%1-1,%1,%0" ! 3801: [(set_attr "type" "shift,shift") ! 3802: (set_attr "length" "4,4")]) 1.1 root 3803: 3804: ;; Optimize insertion of const_int values of type 1...1xxxx. 3805: (define_insn "" 3806: [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") 3807: (match_operand:SI 1 "uint5_operand" "") 3808: (match_operand:SI 2 "uint5_operand" "")) 3809: (match_operand:SI 3 "const_int_operand" ""))] 3810: "(INTVAL (operands[3]) & 0x10) != 0 && 3811: (~INTVAL (operands[3]) & (1L << INTVAL (operands[1])) - 1 & ~0xf) == 0" 3812: "* 3813: { 3814: operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10); 3815: return \"depi %3,%2+%1-1,%1,%0\"; 1.1.1.4 ! root 3816: }" ! 3817: [(set_attr "type" "shift") ! 3818: (set_attr "length" "4")]) 1.1 root 3819: 3820: ;; This insn is used for some loop tests, typically loops reversed when 3821: ;; strength reduction is used. It is actually created when the instruction 3822: ;; combination phase combines the special loop test. Since this insn 3823: ;; is both a jump insn and has an output, it must deal with it's own 3824: ;; reloads, hence the `m' constraints. The `!' constraints direct reload 3825: ;; to not choose the register alternatives in the event a reload is needed. 3826: (define_insn "decrement_and_branch_until_zero" 3827: [(set (pc) 3828: (if_then_else 3829: (match_operator 2 "comparison_operator" 1.1.1.3 root 3830: [(plus:SI (match_operand:SI 0 "register_operand" "+!r,!*f,!*m") 1.1.1.2 root 3831: (match_operand:SI 1 "int5_operand" "L,L,L")) 1.1 root 3832: (const_int 0)]) 3833: (label_ref (match_operand 3 "" "")) 3834: (pc))) 3835: (set (match_dup 0) 3836: (plus:SI (match_dup 0) (match_dup 1))) 1.1.1.2 root 3837: (clobber (match_scratch:SI 4 "=X,r,r"))] 3838: "" 3839: "* return output_dbra (operands, insn, which_alternative); " 1.1.1.3 root 3840: ;; Do not expect to understand this the first time through. 1.1.1.2 root 3841: [(set_attr "type" "cbranch,multi,multi") 1.1 root 3842: (set (attr "length") 1.1.1.2 root 3843: (if_then_else (eq_attr "alternative" "0") 3844: ;; Loop counter in register case 3845: ;; Short branch has length of 4 3846: ;; Long branch has length of 8 3847: (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) 3848: (const_int 8188)) 3849: (const_int 4) 3850: (const_int 8)) 3851: 3852: ;; Loop counter in FP reg case. 3853: ;; Extra goo to deal with additional reload insns. 3854: (if_then_else (eq_attr "alternative" "1") 3855: (if_then_else (lt (match_dup 3) (pc)) 1.1.1.3 root 3856: (if_then_else 1.1.1.2 root 3857: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24)))) 3858: (const_int 8188)) 3859: (const_int 24) 3860: (const_int 28)) 1.1.1.3 root 3861: (if_then_else 1.1.1.2 root 3862: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) 3863: (const_int 8188)) 3864: (const_int 24) 3865: (const_int 28))) 3866: ;; Loop counter in memory case. 3867: ;; Extra goo to deal with additional reload insns. 3868: (if_then_else (lt (match_dup 3) (pc)) 1.1.1.3 root 3869: (if_then_else 1.1.1.2 root 3870: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) 3871: (const_int 8188)) 3872: (const_int 12) 3873: (const_int 16)) 1.1.1.3 root 3874: (if_then_else 1.1.1.2 root 3875: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) 3876: (const_int 8188)) 3877: (const_int 12) 3878: (const_int 16))))))]) 3879: 1.1.1.3 root 3880: ;; Simply another variant of the dbra pattern. More restrictive 1.1.1.2 root 3881: ;; in testing the comparison operator as it must worry about overflow 3882: ;; problems. 3883: (define_insn "" 3884: [(set (pc) 3885: (if_then_else 3886: (match_operator 2 "eq_neq_comparison_operator" 1.1.1.3 root 3887: [(match_operand:SI 0 "register_operand" "+!r,!*f,!*m") 1.1.1.2 root 3888: (match_operand:SI 5 "const_int_operand" "")]) 3889: (label_ref (match_operand 3 "" "")) 3890: (pc))) 3891: (set (match_dup 0) 3892: (plus:SI (match_dup 0) (match_operand:SI 1 "int5_operand" "L,L,L"))) 3893: (clobber (match_scratch:SI 4 "=X,r,r"))] 3894: "INTVAL (operands[5]) == - INTVAL (operands[1])" 3895: "* return output_dbra (operands, insn, which_alternative);" 1.1.1.3 root 3896: ;; Do not expect to understand this the first time through. 1.1.1.2 root 3897: [(set_attr "type" "cbranch,multi,multi") 3898: (set (attr "length") 3899: (if_then_else (eq_attr "alternative" "0") 3900: ;; Loop counter in register case 3901: ;; Short branch has length of 4 3902: ;; Long branch has length of 8 3903: (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) 3904: (const_int 8188)) 3905: (const_int 4) 3906: (const_int 8)) 3907: 3908: ;; Loop counter in FP reg case. 3909: ;; Extra goo to deal with additional reload insns. 3910: (if_then_else (eq_attr "alternative" "1") 3911: (if_then_else (lt (match_dup 3) (pc)) 1.1.1.3 root 3912: (if_then_else 1.1.1.2 root 3913: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24)))) 3914: (const_int 8188)) 3915: (const_int 24) 3916: (const_int 28)) 1.1.1.3 root 3917: (if_then_else 1.1.1.2 root 3918: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) 3919: (const_int 8188)) 3920: (const_int 24) 3921: (const_int 28))) 3922: ;; Loop counter in memory case. 3923: ;; Extra goo to deal with additional reload insns. 3924: (if_then_else (lt (match_dup 3) (pc)) 1.1.1.3 root 3925: (if_then_else 1.1.1.2 root 3926: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) 3927: (const_int 8188)) 3928: (const_int 12) 3929: (const_int 16)) 1.1.1.3 root 3930: (if_then_else 1.1.1.2 root 3931: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) 3932: (const_int 8188)) 3933: (const_int 12) 3934: (const_int 16))))))]) 3935: 3936: (define_insn "" 3937: [(set (pc) 3938: (if_then_else 3939: (match_operator 2 "movb_comparison_operator" 3940: [(match_operand:SI 1 "register_operand" "r,r,r") (const_int 0)]) 3941: (label_ref (match_operand 3 "" "")) 3942: (pc))) 1.1.1.3 root 3943: (set (match_operand:SI 0 "register_operand" "=!r,!*f,!*m") 1.1.1.2 root 3944: (match_dup 1))] 3945: "" 3946: "* return output_movb (operands, insn, which_alternative, 0); " 1.1.1.3 root 3947: ;; Do not expect to understand this the first time through. 1.1.1.2 root 3948: [(set_attr "type" "cbranch,multi,multi") 3949: (set (attr "length") 3950: (if_then_else (eq_attr "alternative" "0") 3951: ;; Loop counter in register case 3952: ;; Short branch has length of 4 3953: ;; Long branch has length of 8 3954: (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) 3955: (const_int 8188)) 3956: (const_int 4) 3957: (const_int 8)) 3958: 3959: ;; Loop counter in FP reg case. 3960: ;; Extra goo to deal with additional reload insns. 3961: (if_then_else (eq_attr "alternative" "1") 3962: (if_then_else (lt (match_dup 3) (pc)) 1.1.1.3 root 3963: (if_then_else 1.1.1.2 root 3964: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) 3965: (const_int 8188)) 3966: (const_int 12) 3967: (const_int 16)) 1.1.1.3 root 3968: (if_then_else 1.1.1.2 root 3969: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) 3970: (const_int 8188)) 3971: (const_int 12) 3972: (const_int 16))) 3973: ;; Loop counter in memory case. 3974: ;; Extra goo to deal with additional reload insns. 1.1.1.3 root 3975: (if_then_else 1.1.1.2 root 3976: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) 3977: (const_int 8188)) 3978: (const_int 8) 3979: (const_int 12)))))]) 1.1 root 3980: 1.1.1.2 root 3981: ;; Handle negated branch. 3982: (define_insn "" 3983: [(set (pc) 3984: (if_then_else 3985: (match_operator 2 "movb_comparison_operator" 3986: [(match_operand:SI 1 "register_operand" "r,r,r") (const_int 0)]) 3987: (pc) 3988: (label_ref (match_operand 3 "" "")))) 1.1.1.3 root 3989: (set (match_operand:SI 0 "register_operand" "=!r,!*f,!*m") 1.1.1.2 root 3990: (match_dup 1))] 3991: "" 3992: "* return output_movb (operands, insn, which_alternative, 1); " 1.1.1.3 root 3993: ;; Do not expect to understand this the first time through. 1.1.1.2 root 3994: [(set_attr "type" "cbranch,multi,multi") 3995: (set (attr "length") 3996: (if_then_else (eq_attr "alternative" "0") 3997: ;; Loop counter in register case 3998: ;; Short branch has length of 4 3999: ;; Long branch has length of 8 4000: (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) 4001: (const_int 8188)) 4002: (const_int 4) 4003: (const_int 8)) 4004: 4005: ;; Loop counter in FP reg case. 4006: ;; Extra goo to deal with additional reload insns. 4007: (if_then_else (eq_attr "alternative" "1") 4008: (if_then_else (lt (match_dup 3) (pc)) 1.1.1.3 root 4009: (if_then_else 1.1.1.2 root 4010: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) 4011: (const_int 8188)) 4012: (const_int 12) 4013: (const_int 16)) 1.1.1.3 root 4014: (if_then_else 1.1.1.2 root 4015: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) 4016: (const_int 8188)) 4017: (const_int 12) 4018: (const_int 16))) 4019: ;; Loop counter in memory case. 4020: ;; Extra goo to deal with additional reload insns. 1.1.1.3 root 4021: (if_then_else 1.1.1.2 root 4022: (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) 4023: (const_int 8188)) 4024: (const_int 8) 4025: (const_int 12)))))]) 1.1 root 4026: 1.1.1.3 root 4027: ;; The next four peepholes take advantage of the new 5 operand 1.1 root 4028: ;; fmpy{add,sub} instructions available on 1.1 CPUS. Basically 4029: ;; fmpyadd performs a multiply and add/sub of independent operands 4030: ;; at the same time. Because the operands must be independent 4031: ;; combine will not try to combine such insns... Thus we have 4032: ;; to use a peephole. 4033: (define_peephole 1.1.1.3 root 4034: [(set (match_operand 0 "register_operand" "=f") 4035: (mult (match_operand 1 "register_operand" "f") 4036: (match_operand 2 "register_operand" "f"))) 4037: (set (match_operand 3 "register_operand" "+f") 4038: (plus (match_operand 4 "register_operand" "f") 4039: (match_operand 5 "register_operand" "f")))] 1.1 root 4040: "TARGET_SNAKE && fmpyaddoperands (operands)" 4041: "* 4042: { 4043: if (GET_MODE (operands[0]) == DFmode) 4044: { 4045: if (rtx_equal_p (operands[5], operands[3])) 4046: return \"fmpyadd,dbl %1,%2,%0,%4,%3\"; 4047: else 4048: return \"fmpyadd,dbl %1,%2,%0,%5,%3\"; 4049: } 4050: else 4051: { 4052: if (rtx_equal_p (operands[5], operands[3])) 4053: return \"fmpyadd,sgl %1,%2,%0,%4,%3\"; 4054: else 4055: return \"fmpyadd,sgl %1,%2,%0,%5,%3\"; 4056: } 4057: }") 4058: 1.1.1.3 root 4059: (define_peephole 4060: [(set (match_operand 3 "register_operand" "+f") 4061: (plus (match_operand 4 "register_operand" "f") 4062: (match_operand 5 "register_operand" "f"))) 4063: (set (match_operand 0 "register_operand" "=f") 4064: (mult (match_operand 1 "register_operand" "f") 4065: (match_operand 2 "register_operand" "f")))] 1.1 root 4066: "TARGET_SNAKE && fmpyaddoperands (operands)" 4067: "* 4068: { 4069: if (GET_MODE (operands[0]) == DFmode) 4070: { 4071: if (rtx_equal_p (operands[3], operands[5])) 4072: return \"fmpyadd,dbl %1,%2,%0,%4,%3\"; 4073: else 4074: return \"fmpyadd,dbl %1,%2,%0,%5,%3\"; 4075: } 4076: else 4077: { 4078: if (rtx_equal_p (operands[3], operands[5])) 4079: return \"fmpyadd,sgl %1,%2,%0,%4,%3\"; 4080: else 4081: return \"fmpyadd,sgl %1,%2,%0,%5,%3\"; 4082: } 4083: }") 4084: 4085: ;; Note fsub subtracts the second operand from the first while fmpysub 4086: ;; does the opposite for the subtraction operands! 4087: (define_peephole 1.1.1.3 root 4088: [(set (match_operand 0 "register_operand" "=f") 4089: (mult (match_operand 1 "register_operand" "f") 4090: (match_operand 2 "register_operand" "f"))) 4091: (set (match_operand 3 "register_operand" "+f") 4092: (minus (match_operand 4 "register_operand" "f") 4093: (match_operand 5 "register_operand" "f")))] 1.1 root 4094: "TARGET_SNAKE && fmpysuboperands (operands)" 4095: "* 4096: { 4097: if (GET_MODE (operands[0]) == DFmode) 4098: return \"fmpysub,dbl %1,%2,%0,%5,%3\"; 4099: else 4100: return \"fmpysub,sgl %1,%2,%0,%5,%3\"; 4101: }") 4102: 4103: (define_peephole 1.1.1.3 root 4104: [(set (match_operand 3 "register_operand" "+f") 4105: (minus (match_operand 4 "register_operand" "f") 4106: (match_operand 5 "register_operand" "f"))) 4107: (set (match_operand 0 "register_operand" "=f") 4108: (mult (match_operand 1 "register_operand" "f") 4109: (match_operand 2 "register_operand" "f")))] 1.1 root 4110: "TARGET_SNAKE && fmpysuboperands (operands)" 4111: "* 4112: { 4113: if (GET_MODE (operands[0]) == DFmode) 4114: return \"fmpysub,dbl %1,%2,%0,%5,%3\"; 4115: else 4116: return \"fmpysub,sgl %1,%2,%0,%5,%3\"; 4117: }") 4118: 4119: ;; Flush the I and D cache line found at the address in operand 0. 4120: ;; This is used by the trampoline code for nested functions. 4121: ;; So long as the trampoline itself is less than 32 bytes this 4122: ;; is sufficient. 1.1.1.2 root 4123: 4124: (define_insn "dcacheflush" 1.1 root 4125: [(unspec_volatile [(const_int 1)] 0) 4126: (use (mem:SI (match_operand:SI 0 "register_operand" "r"))) 4127: (use (mem:SI (match_operand:SI 1 "register_operand" "r")))] 4128: "" 1.1.1.2 root 4129: "fdc 0(0,%0)\;fdc 0(0,%1)\;sync" 1.1.1.4 ! root 4130: [(set_attr "type" "multi") ! 4131: (set_attr "length" "12")]) 1.1.1.2 root 4132: 4133: (define_insn "icacheflush" 4134: [(unspec_volatile [(const_int 2)] 0) 4135: (use (mem:SI (match_operand:SI 0 "register_operand" "r"))) 4136: (use (mem:SI (match_operand:SI 1 "register_operand" "r"))) 4137: (use (match_operand:SI 2 "register_operand" "r")) 4138: (clobber (match_operand:SI 3 "register_operand" "=&r")) 4139: (clobber (match_operand:SI 4 "register_operand" "=&r"))] 4140: "" 4141: "mfsp %%sr0,%4\;ldsid (0,%2),%3\;mtsp %3,%%sr0\;fic 0(%%sr0,%0)\;fic 0(%%sr0,%1)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop" 1.1.1.4 ! root 4142: [(set_attr "type" "multi") ! 4143: (set_attr "length" "52")])
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.