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