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