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