|
|
1.1 ! root 1: ;;- Machine description for DEC Alpha for GNU C compiler ! 2: ;; Copyright (C) 1992 Free Software Foundation, Inc. ! 3: ;; Contributed by Richard Kenner ([email protected]) ! 4: ! 5: ;; This file is part of GNU CC. ! 6: ! 7: ;; GNU CC is free software; you can redistribute it and/or modify ! 8: ;; it under the terms of the GNU General Public License as published by ! 9: ;; the Free Software Foundation; either version 2, or (at your option) ! 10: ;; any later version. ! 11: ! 12: ;; GNU CC is distributed in the hope that it will be useful, ! 13: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 15: ;; GNU General Public License for more details. ! 16: ! 17: ;; You should have received a copy of the GNU General Public License ! 18: ;; along with GNU CC; see the file COPYING. If not, write to ! 19: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ! 20: ! 21: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. ! 22: ! 23: ;; Define an insn type attribute. This is used in function unit delay ! 24: ;; computations, among other purposes. For the most part, we use the names ! 25: ;; defined in the EV4 documentation, but add a few that we have to know about ! 26: ;; separately. ! 27: ! 28: (define_attr "type" ! 29: "ld,st,ibr,fbr,jsr,iaddlog,shiftcm,icmp,imull,imulq,fpop,fdivs,fdivt,ldsym,isubr" ! 30: (const_string "shiftcm")) ! 31: ! 32: ;; We include four function units: ABOX, which computes the address, ! 33: ;; BBOX, used for branches, EBOX, used for integer operations, and FBOX, ! 34: ;; used for FP operations. ! 35: ;; ! 36: ;; We assume that we have been successful in getting double issues and ! 37: ;; hence multiply all costs by two insns per cycle. The minimum time in ! 38: ;; a function unit is 2 cycle, which will tend to produce the double ! 39: ;; issues. ! 40: ! 41: ;; Memory delivers its result in three cycles. ! 42: (define_function_unit "abox" 1 0 (eq_attr "type" "ld,ldsym,st") 6 2) ! 43: ! 44: ;; Branches have no delay cost, but do tie up the unit for two cycles. ! 45: (define_function_unit "bbox" 1 1 (eq_attr "type" "ibr,fbr,jsr") 4 4) ! 46: ! 47: ;; Arithmetic insns are normally have their results available after two ! 48: ;; cycles. There are a number of exceptions. They are encoded in ! 49: ;; ADJUST_COST. Some of the other insns have similar exceptions. ! 50: ! 51: (define_function_unit "ebox" 1 0 (eq_attr "type" "iaddlog,shiftcm,icmp") 4 2) ! 52: ! 53: ;; These really don't take up the integer pipeline, but they do occupy ! 54: ;; IBOX1; we approximate here. ! 55: ! 56: (define_function_unit "ebox" 1 0 (eq_attr "type" "imull") 42 2) ! 57: (define_function_unit "ebox" 1 0 (eq_attr "type" "imulq") 46 2) ! 58: ! 59: (define_function_unit "imult" 1 0 (eq_attr "type" "imull") 42 38) ! 60: (define_function_unit "imult" 1 0 (eq_attr "type" "imulq") 46 42) ! 61: ! 62: (define_function_unit "fbox" 1 0 (eq_attr "type" "fpop") 12 2) ! 63: ! 64: (define_function_unit "fbox" 1 0 (eq_attr "type" "fdivs") 68 0) ! 65: (define_function_unit "fbox" 1 0 (eq_attr "type" "fdivt") 126 0) ! 66: ! 67: (define_function_unit "divider" 1 0 (eq_attr "type" "fdivs") 68 60) ! 68: (define_function_unit "divider" 1 0 (eq_attr "type" "fdivt") 126 118) ! 69: ! 70: ;; First define the arithmetic insns. Note that the 32-bit forms also ! 71: ;; sign-extend. ! 72: ! 73: ;; Note that we can do sign extensions in both FP and integer registers. ! 74: ;; However, the result must be in the same type of register as the input. ! 75: ;; The register preferencing code can't handle this case very well, so, for ! 76: ;; now, don't let the FP case show up here for preferencing. Also, ! 77: ;; sign-extends in FP registers take two instructions. ! 78: (define_insn "extendsidi2" ! 79: [(set (match_operand:DI 0 "register_operand" "=r,r,*f") ! 80: (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,*f")))] ! 81: "" ! 82: "@ ! 83: addl %1,$31,%0 ! 84: ldl %0,%1 ! 85: cvtql %1,%0\;cvtlq %0,%0" ! 86: [(set_attr "type" "iaddlog,ld,fpop")]) ! 87: ! 88: (define_insn "addsi3" ! 89: [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") ! 90: (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ") ! 91: (match_operand:SI 2 "add_operand" "rI,O,K,L")))] ! 92: "" ! 93: "@ ! 94: addl %r1,%2,%0 ! 95: subl %r1,%n2,%0 ! 96: lda %0,%2(%r1) ! 97: ldah %0,%h2(%r1)" ! 98: [(set_attr "type" "iaddlog")]) ! 99: ! 100: (define_split ! 101: [(set (match_operand:SI 0 "register_operand" "") ! 102: (plus:SI (match_operand:SI 1 "register_operand" "") ! 103: (match_operand:SI 2 "const_int_operand" "")))] ! 104: "! add_operand (operands[2], SImode)" ! 105: [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3))) ! 106: (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))] ! 107: " ! 108: { ! 109: HOST_WIDE_INT val = INTVAL (operands[2]); ! 110: HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000); ! 111: HOST_WIDE_INT rest = val - low; ! 112: ! 113: operands[3] = GEN_INT (rest); ! 114: operands[4] = GEN_INT (low); ! 115: }") ! 116: ! 117: (define_insn "" ! 118: [(set (match_operand:DI 0 "register_operand" "=r,r") ! 119: (sign_extend:DI ! 120: (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ") ! 121: (match_operand:SI 2 "sext_add_operand" "rI,O"))))] ! 122: "" ! 123: "@ ! 124: addl %r1,%2,%0 ! 125: subl %r1,%n2,%0" ! 126: [(set_attr "type" "iaddlog")]) ! 127: ! 128: (define_split ! 129: [(set (match_operand:DI 0 "register_operand" "") ! 130: (sign_extend:DI ! 131: (plus:SI (match_operand:SI 1 "register_operand" "") ! 132: (match_operand:SI 2 "const_int_operand" "")))) ! 133: (clobber (match_operand:SI 3 "register_operand" ""))] ! 134: "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0 ! 135: && INTVAL (operands[2]) % 4 == 0" ! 136: [(set (match_dup 3) (match_dup 4)) ! 137: (set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3) ! 138: (match_dup 5)) ! 139: (match_dup 1))))] ! 140: " ! 141: { ! 142: HOST_WIDE_INT val = INTVAL (operands[2]) / 4; ! 143: int mult = 4; ! 144: ! 145: if (val % 2 == 0) ! 146: val /= 2, mult = 8; ! 147: ! 148: operands[4] = GEN_INT (val); ! 149: operands[5] = GEN_INT (mult); ! 150: }") ! 151: ! 152: (define_insn "adddi3" ! 153: [(set (match_operand:DI 0 "register_operand" "=r,r,r,r") ! 154: (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ") ! 155: (match_operand:DI 2 "add_operand" "rI,O,K,L")))] ! 156: "" ! 157: "@ ! 158: addq %r1,%2,%0 ! 159: subq %r1,%n2,%0 ! 160: lda %0,%2(%r1) ! 161: ldah %0,%h2(%r1)" ! 162: [(set_attr "type" "iaddlog")]) ! 163: ! 164: ;; Don't do this if we are adjusting SP since we don't want to do ! 165: ;; it in two steps. ! 166: (define_split ! 167: [(set (match_operand:DI 0 "register_operand" "") ! 168: (plus:DI (match_operand:DI 1 "register_operand" "") ! 169: (match_operand:DI 2 "const_int_operand" "")))] ! 170: "! add_operand (operands[2], DImode) ! 171: && REGNO (operands[0]) != STACK_POINTER_REGNUM" ! 172: [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3))) ! 173: (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))] ! 174: " ! 175: { ! 176: HOST_WIDE_INT val = INTVAL (operands[2]); ! 177: HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000); ! 178: HOST_WIDE_INT rest = val - low; ! 179: ! 180: operands[3] = GEN_INT (rest); ! 181: operands[4] = GEN_INT (low); ! 182: }") ! 183: ! 184: (define_insn "" ! 185: [(set (match_operand:SI 0 "register_operand" "=r,r") ! 186: (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ") ! 187: (match_operand:SI 2 "const48_operand" "I,I")) ! 188: (match_operand:SI 3 "sext_add_operand" "rI,O")))] ! 189: "" ! 190: "@ ! 191: s%2addl %r1,%3,%0 ! 192: s%2subl %r1,%n3,%0" ! 193: [(set_attr "type" "iaddlog")]) ! 194: ! 195: (define_insn "" ! 196: [(set (match_operand:DI 0 "register_operand" "=r,r") ! 197: (sign_extend:DI ! 198: (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ") ! 199: (match_operand:SI 2 "const48_operand" "I,I")) ! 200: (match_operand:SI 3 "sext_add_operand" "rI,O"))))] ! 201: "" ! 202: "@ ! 203: s%2addl %r1,%3,%0 ! 204: s%2subl %r1,%n3,%0" ! 205: [(set_attr "type" "iaddlog")]) ! 206: ! 207: (define_insn "" ! 208: [(set (match_operand:DI 0 "register_operand" "=r,r") ! 209: (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ") ! 210: (match_operand:DI 2 "const48_operand" "I,I")) ! 211: (match_operand:DI 3 "reg_or_8bit_operand" "rI,O")))] ! 212: "" ! 213: "@ ! 214: s%2addq %r1,%3,%0 ! 215: s%2subq %1,%n3,%0" ! 216: [(set_attr "type" "iaddlog")]) ! 217: ! 218: ;; These variants of the above insns can occur if the third operand ! 219: ;; is the frame pointer. This is a kludge, but there doesn't ! 220: ;; seem to be a way around it. Only recognize them while reloading. ! 221: ! 222: (define_insn "" ! 223: [(set (match_operand:SI 0 "register_operand" "=&r") ! 224: (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") ! 225: (match_operand:SI 2 "const48_operand" "I")) ! 226: (match_operand:SI 3 "register_operand" "r")) ! 227: (match_operand:SI 4 "const_int_operand" "rI")))] ! 228: "reload_in_progress" ! 229: "s%2addl %r1,%3,%0\;addl %0,%4,%0" ! 230: [(set_attr "type" "iaddlog")]) ! 231: ! 232: (define_insn "" ! 233: [(set (match_operand:DI 0 "register_operand" "=&r") ! 234: (sign_extend:DI ! 235: (plus:SI (plus:SI ! 236: (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") ! 237: (match_operand:SI 2 "const48_operand" "I")) ! 238: (match_operand:SI 3 "register_operand" "r")) ! 239: (match_operand:SI 4 "const_int_operand" "rI"))))] ! 240: "reload_in_progress" ! 241: "s%2addl %r1,%3,%0\;addl %0,%4,%0" ! 242: [(set_attr "type" "iaddlog")]) ! 243: ! 244: (define_insn "" ! 245: [(set (match_operand:DI 0 "register_operand" "=&r") ! 246: (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ! 247: (match_operand:DI 2 "const48_operand" "I")) ! 248: (match_operand:DI 3 "register_operand" "r")) ! 249: (match_operand:DI 4 "const_int_operand" "rI")))] ! 250: "reload_in_progress" ! 251: "s%2addq %r1,%3,%0\;addq %0,%4,%0" ! 252: [(set_attr "type" "iaddlog")]) ! 253: ! 254: (define_insn "negsi2" ! 255: [(set (match_operand:SI 0 "register_operand" "=r") ! 256: (neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))] ! 257: "" ! 258: "subl $31,%1,%0" ! 259: [(set_attr "type" "iaddlog")]) ! 260: ! 261: (define_insn "" ! 262: [(set (match_operand:DI 0 "register_operand" "=r") ! 263: (sign_extend:DI (neg:SI ! 264: (match_operand:SI 1 "reg_or_8bit_operand" "rI"))))] ! 265: "" ! 266: "subl $31,%1,%0" ! 267: [(set_attr "type" "iaddlog")]) ! 268: ! 269: (define_insn "negdi2" ! 270: [(set (match_operand:DI 0 "register_operand" "=r") ! 271: (neg:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))] ! 272: "" ! 273: "subq $31,%1,%0" ! 274: [(set_attr "type" "iaddlog")]) ! 275: ! 276: (define_insn "subsi3" ! 277: [(set (match_operand:SI 0 "register_operand" "=r") ! 278: (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") ! 279: (match_operand:SI 2 "reg_or_8bit_operand" "rI")))] ! 280: "" ! 281: "subl %r1,%2,%0" ! 282: [(set_attr "type" "iaddlog")]) ! 283: ! 284: (define_insn "" ! 285: [(set (match_operand:DI 0 "register_operand" "=r") ! 286: (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") ! 287: (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))] ! 288: "" ! 289: "subl %r1,%2,%0" ! 290: [(set_attr "type" "iaddlog")]) ! 291: ! 292: (define_insn "subdi3" ! 293: [(set (match_operand:DI 0 "register_operand" "=r") ! 294: (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ! 295: (match_operand:DI 2 "reg_or_8bit_operand" "rI")))] ! 296: "" ! 297: "subq %r1,%2,%0" ! 298: [(set_attr "type" "iaddlog")]) ! 299: ! 300: (define_insn "" ! 301: [(set (match_operand:SI 0 "register_operand" "=r") ! 302: (minus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") ! 303: (match_operand:SI 2 "const48_operand" "I")) ! 304: (match_operand:SI 3 "reg_or_8bit_operand" "rI")))] ! 305: "" ! 306: "s%2subl %r1,%3,%0" ! 307: [(set_attr "type" "iaddlog")]) ! 308: ! 309: (define_insn "" ! 310: [(set (match_operand:DI 0 "register_operand" "=r") ! 311: (sign_extend:DI ! 312: (minus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") ! 313: (match_operand:SI 2 "const48_operand" "I")) ! 314: (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))] ! 315: "" ! 316: "s%2subl %r1,%3,%0" ! 317: [(set_attr "type" "iaddlog")]) ! 318: ! 319: (define_insn "" ! 320: [(set (match_operand:DI 0 "register_operand" "=r") ! 321: (minus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ! 322: (match_operand:DI 2 "const48_operand" "I")) ! 323: (match_operand:DI 3 "reg_or_8bit_operand" "rI")))] ! 324: "" ! 325: "s%2subq %r1,%3,%0" ! 326: [(set_attr "type" "iaddlog")]) ! 327: ! 328: (define_insn "mulsi3" ! 329: [(set (match_operand:SI 0 "register_operand" "=r") ! 330: (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") ! 331: (match_operand:SI 2 "reg_or_8bit_operand" "rI")))] ! 332: "" ! 333: "mull %r1,%2,%0" ! 334: [(set_attr "type" "imull")]) ! 335: ! 336: (define_insn "" ! 337: [(set (match_operand:DI 0 "register_operand" "=r") ! 338: (sign_extend:DI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") ! 339: (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))] ! 340: "" ! 341: "mull %r1,%2,%0" ! 342: [(set_attr "type" "imull")]) ! 343: ! 344: (define_insn "muldi3" ! 345: [(set (match_operand:DI 0 "register_operand" "=r") ! 346: (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ") ! 347: (match_operand:DI 2 "reg_or_8bit_operand" "rI")))] ! 348: "" ! 349: "mulq %r1,%2,%0" ! 350: [(set_attr "type" "imulq")]) ! 351: ! 352: ;; The divide and remainder operations always take their inputs from ! 353: ;; r24 and r25, put their output in r27, and clobber r23 and r28. ! 354: ! 355: (define_expand "divsi3" ! 356: [(parallel [(set (reg:SI 27) ! 357: (div:SI (match_operand:SI 1 "general_operand" "") ! 358: (match_operand:SI 2 "general_operand" ""))) ! 359: (clobber (reg:DI 23)) ! 360: (clobber (reg:DI 28))]) ! 361: (set (match_operand:SI 0 "general_operand" "") ! 362: (reg:SI 27))] ! 363: "" ! 364: " ! 365: { rtx in0 = gen_rtx (REG, SImode, 24); ! 366: rtx in1 = gen_rtx (REG, SImode, 25); ! 367: ! 368: emit_move_insn (in0, operands[1]); ! 369: emit_move_insn (in1, operands[2]); ! 370: operands[1] = in0, operands[2] = in1; ! 371: }") ! 372: ! 373: (define_expand "udivsi3" ! 374: [(parallel [(set (reg:SI 27) ! 375: (udiv:SI (match_operand:SI 1 "general_operand" "") ! 376: (match_operand:SI 2 "general_operand" ""))) ! 377: (clobber (reg:DI 23)) ! 378: (clobber (reg:DI 28))]) ! 379: (set (match_operand:SI 0 "general_operand" "") ! 380: (reg:SI 27))] ! 381: "" ! 382: " ! 383: { rtx in0 = gen_rtx (REG, SImode, 24); ! 384: rtx in1 = gen_rtx (REG, SImode, 25); ! 385: ! 386: emit_move_insn (in0, operands[1]); ! 387: emit_move_insn (in1, operands[2]); ! 388: operands[1] = in0, operands[2] = in1; ! 389: }") ! 390: ! 391: (define_expand "modsi3" ! 392: [(parallel [(set (reg:SI 27) ! 393: (mod:SI (match_operand:SI 1 "general_operand" "") ! 394: (match_operand:SI 2 "general_operand" ""))) ! 395: (clobber (reg:DI 23)) ! 396: (clobber (reg:DI 28))]) ! 397: (set (match_operand:SI 0 "general_operand" "") ! 398: (reg:SI 27))] ! 399: "" ! 400: " ! 401: { rtx in0 = gen_rtx (REG, SImode, 24); ! 402: rtx in1 = gen_rtx (REG, SImode, 25); ! 403: ! 404: emit_move_insn (in0, operands[1]); ! 405: emit_move_insn (in1, operands[2]); ! 406: operands[1] = in0, operands[2] = in1; ! 407: }") ! 408: ! 409: (define_expand "umodsi3" ! 410: [(parallel [(set (reg:SI 27) ! 411: (umod:SI (match_operand:SI 1 "general_operand" "") ! 412: (match_operand:SI 2 "general_operand" ""))) ! 413: (clobber (reg:DI 23)) ! 414: (clobber (reg:DI 28))]) ! 415: (set (match_operand:SI 0 "general_operand" "") ! 416: (reg:SI 27))] ! 417: "" ! 418: " ! 419: { rtx in0 = gen_rtx (REG, SImode, 24); ! 420: rtx in1 = gen_rtx (REG, SImode, 25); ! 421: ! 422: emit_move_insn (in0, operands[1]); ! 423: emit_move_insn (in1, operands[2]); ! 424: operands[1] = in0, operands[2] = in1; ! 425: }") ! 426: ! 427: (define_expand "divdi3" ! 428: [(parallel [(set (reg:DI 27) ! 429: (div:DI (match_operand:DI 1 "general_operand" "") ! 430: (match_operand:DI 2 "general_operand" ""))) ! 431: (clobber (reg:DI 23)) ! 432: (clobber (reg:DI 28))]) ! 433: (set (match_operand:DI 0 "general_operand" "") ! 434: (reg:DI 27))] ! 435: "" ! 436: " ! 437: { rtx in0 = gen_rtx (REG, DImode, 24); ! 438: rtx in1 = gen_rtx (REG, DImode, 25); ! 439: ! 440: emit_move_insn (in0, operands[1]); ! 441: emit_move_insn (in1, operands[2]); ! 442: operands[1] = in0, operands[2] = in1; ! 443: }") ! 444: ! 445: (define_expand "udivdi3" ! 446: [(parallel [(set (reg:DI 27) ! 447: (udiv:DI (match_operand:DI 1 "general_operand" "") ! 448: (match_operand:DI 2 "general_operand" ""))) ! 449: (clobber (reg:DI 23)) ! 450: (clobber (reg:DI 28))]) ! 451: (set (match_operand:DI 0 "general_operand" "") ! 452: (reg:DI 27))] ! 453: "" ! 454: " ! 455: { rtx in0 = gen_rtx (REG, DImode, 24); ! 456: rtx in1 = gen_rtx (REG, DImode, 25); ! 457: ! 458: emit_move_insn (in0, operands[1]); ! 459: emit_move_insn (in1, operands[2]); ! 460: operands[1] = in0, operands[2] = in1; ! 461: }") ! 462: ! 463: (define_expand "moddi3" ! 464: [(parallel [(set (reg:DI 27) ! 465: (mod:DI (match_operand:DI 1 "general_operand" "") ! 466: (match_operand:DI 2 "general_operand" ""))) ! 467: (clobber (reg:DI 23)) ! 468: (clobber (reg:DI 28))]) ! 469: (set (match_operand:DI 0 "general_operand" "") ! 470: (reg:DI 27))] ! 471: "" ! 472: " ! 473: { rtx in0 = gen_rtx (REG, DImode, 24); ! 474: rtx in1 = gen_rtx (REG, DImode, 25); ! 475: ! 476: emit_move_insn (in0, operands[1]); ! 477: emit_move_insn (in1, operands[2]); ! 478: operands[1] = in0, operands[2] = in1; ! 479: }") ! 480: ! 481: (define_expand "umoddi3" ! 482: [(parallel [(set (reg:DI 27) ! 483: (umod:DI (match_operand:DI 1 "general_operand" "") ! 484: (match_operand:DI 2 "general_operand" ""))) ! 485: (clobber (reg:DI 23)) ! 486: (clobber (reg:DI 28))]) ! 487: (set (match_operand:DI 0 "general_operand" "") ! 488: (reg:DI 27))] ! 489: "" ! 490: " ! 491: { rtx in0 = gen_rtx (REG, DImode, 24); ! 492: rtx in1 = gen_rtx (REG, DImode, 25); ! 493: ! 494: emit_move_insn (in0, operands[1]); ! 495: emit_move_insn (in1, operands[2]); ! 496: operands[1] = in0, operands[2] = in1; ! 497: }") ! 498: ! 499: (define_insn "" ! 500: [(set (reg:SI 27) ! 501: (match_operator:SI 1 "divmod_operator" ! 502: [(reg:SI 24) (reg:SI 25)])) ! 503: (clobber (reg:DI 23)) ! 504: (clobber (reg:DI 28))] ! 505: "" ! 506: "%E1 $24,$25,$27" ! 507: [(set_attr "type" "isubr")]) ! 508: ! 509: (define_insn "" ! 510: [(set (reg:DI 27) ! 511: (match_operator:DI 1 "divmod_operator" ! 512: [(reg:DI 24) (reg:DI 25)])) ! 513: (clobber (reg:DI 23)) ! 514: (clobber (reg:DI 28))] ! 515: "" ! 516: "%E1 $24,$25,$27" ! 517: [(set_attr "type" "isubr")]) ! 518: ! 519: ;; Next are the basic logical operations. These only exist in DImode. ! 520: ! 521: (define_insn "anddi3" ! 522: [(set (match_operand:DI 0 "register_operand" "=r,r,r") ! 523: (and:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ") ! 524: (match_operand:DI 2 "and_operand" "rI,N,MH")))] ! 525: "" ! 526: "@ ! 527: and %r1,%2,%0 ! 528: bic %r1,%N2,%0 ! 529: zapnot %r1,%m2,%0" ! 530: [(set_attr "type" "iaddlog,iaddlog,shiftcm")]) ! 531: ! 532: ;; There are times when we can split and AND into two AND insns. This occurs ! 533: ;; when we can first clear any bytes and then clear anything else. For ! 534: ;; example "I & 0xffff07" is "(I & 0xffffff) & 0xffffffffffffff07". ! 535: ;; Only to this when running on 64-bit host since the computations are ! 536: ;; too messy otherwise. ! 537: ! 538: (define_split ! 539: [(set (match_operand:DI 0 "register_operand" "") ! 540: (and:DI (match_operand:DI 1 "register_operand" "") ! 541: (match_operand:DI 2 "const_int_operand" "")))] ! 542: "HOST_BITS_PER_WIDE_INT == 64 && ! and_operand (operands[2], DImode)" ! 543: [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3))) ! 544: (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))] ! 545: " ! 546: { ! 547: unsigned HOST_WIDE_INT mask1 = INTVAL (operands[2]); ! 548: unsigned HOST_WIDE_INT mask2 = mask1; ! 549: int i; ! 550: ! 551: /* For each byte that isn't all zeros, make it all ones. */ ! 552: for (i = 0; i < 64; i += 8) ! 553: if ((mask1 & ((HOST_WIDE_INT) 0xff << i)) != 0) ! 554: mask1 |= (HOST_WIDE_INT) 0xff << i; ! 555: ! 556: /* Now turn on any bits we've just turned off. */ ! 557: mask2 |= ~ mask1; ! 558: ! 559: operands[3] = GEN_INT (mask1); ! 560: operands[4] = GEN_INT (mask2); ! 561: }") ! 562: ! 563: (define_insn "zero_extendqihi2" ! 564: [(set (match_operand:HI 0 "register_operand" "=r") ! 565: (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))] ! 566: "" ! 567: "zapnot %1,1,%0" ! 568: [(set_attr "type" "iaddlog")]) ! 569: ! 570: (define_insn "zero_extendqisi2" ! 571: [(set (match_operand:SI 0 "register_operand" "=r") ! 572: (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))] ! 573: "" ! 574: "zapnot %1,1,%0" ! 575: [(set_attr "type" "iaddlog")]) ! 576: ! 577: (define_insn "zero_extendqidi2" ! 578: [(set (match_operand:DI 0 "register_operand" "=r") ! 579: (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))] ! 580: "" ! 581: "zapnot %1,1,%0" ! 582: [(set_attr "type" "iaddlog")]) ! 583: ! 584: (define_insn "zero_extendhisi2" ! 585: [(set (match_operand:SI 0 "register_operand" "=r") ! 586: (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))] ! 587: "" ! 588: "zapnot %1,3,%0" ! 589: [(set_attr "type" "iaddlog")]) ! 590: ! 591: (define_insn "zero_extendhidi2" ! 592: [(set (match_operand:DI 0 "register_operand" "=r") ! 593: (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))] ! 594: "" ! 595: "zapnot %1,3,%0" ! 596: [(set_attr "type" "iaddlog")]) ! 597: ! 598: (define_insn "zero_extendsidi2" ! 599: [(set (match_operand:DI 0 "register_operand" "=r") ! 600: (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))] ! 601: "" ! 602: "zapnot %1,15,%0" ! 603: [(set_attr "type" "iaddlog")]) ! 604: ! 605: (define_insn "" ! 606: [(set (match_operand:DI 0 "register_operand" "=r") ! 607: (and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")) ! 608: (match_operand:DI 2 "reg_or_0_operand" "rJ")))] ! 609: "" ! 610: "bic %r2,%1,%0" ! 611: [(set_attr "type" "iaddlog")]) ! 612: ! 613: (define_insn "iordi3" ! 614: [(set (match_operand:DI 0 "register_operand" "=r") ! 615: (ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ") ! 616: (match_operand:DI 2 "reg_or_8bit_operand" "rI")))] ! 617: "" ! 618: "bis %r1,%2,%0" ! 619: [(set_attr "type" "iaddlog")]) ! 620: ! 621: (define_insn "one_cmpldi2" ! 622: [(set (match_operand:DI 0 "register_operand" "=r") ! 623: (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))] ! 624: "" ! 625: "ornot $31,%1,%0" ! 626: [(set_attr "type" "iaddlog")]) ! 627: ! 628: (define_insn "" ! 629: [(set (match_operand:DI 0 "register_operand" "=r") ! 630: (ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")) ! 631: (match_operand:DI 2 "reg_or_0_operand" "rJ")))] ! 632: "" ! 633: "ornot %r2,%1,%0" ! 634: [(set_attr "type" "iaddlog")]) ! 635: ! 636: (define_insn "xordi3" ! 637: [(set (match_operand:DI 0 "register_operand" "=r") ! 638: (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ") ! 639: (match_operand:DI 2 "reg_or_8bit_operand" "rI")))] ! 640: "" ! 641: "xor %r1,%2,%0" ! 642: [(set_attr "type" "iaddlog")]) ! 643: ! 644: (define_insn "" ! 645: [(set (match_operand:DI 0 "register_operand" "=r") ! 646: (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ") ! 647: (match_operand:DI 2 "reg_or_8bit_operand" "rI"))))] ! 648: "" ! 649: "eqv %r1,%2,%0" ! 650: [(set_attr "type" "iaddlog")]) ! 651: ! 652: ;; Next come the shifts and the various extract and insert operations. ! 653: ! 654: (define_insn "ashldi3" ! 655: [(set (match_operand:DI 0 "register_operand" "=r,r") ! 656: (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ") ! 657: (match_operand:DI 2 "reg_or_6bit_operand" "P,rI")))] ! 658: "" ! 659: "* ! 660: { ! 661: switch (which_alternative) ! 662: { ! 663: case 0: ! 664: if (operands[2] == const1_rtx) ! 665: return \"addq %r1,%r1,%0\"; ! 666: else ! 667: return \"s%P2addq %r1,0,%0\"; ! 668: case 1: ! 669: return \"sll %r1,%2,%0\"; ! 670: } ! 671: }" ! 672: [(set_attr "type" "iaddlog,shiftcm")]) ! 673: ! 674: ;; This is the same as (sign_extend (shift X [123])). ! 675: (define_insn "" ! 676: [(set (match_operand:DI 0 "register_operand" "=r") ! 677: (ashiftrt:DI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ! 678: (match_operand:DI 2 "const_int_operand" "i")) ! 679: (const_int 32)))] ! 680: "INTVAL (operands[2]) >= 33 && INTVAL (operands[2]) <= 35" ! 681: "* ! 682: { ! 683: switch (INTVAL (operands[2])) ! 684: { ! 685: case 33: ! 686: return \"addl %r1,%r1,%0\"; ! 687: case 34: ! 688: return \"s4addl %r1,0,%0\"; ! 689: case 35: ! 690: return \"s8addl %r1,0,%0\"; ! 691: default: ! 692: abort (); ! 693: } ! 694: }" ! 695: [(set_attr "type" "iaddlog")]) ! 696: ! 697: (define_insn "lshrdi3" ! 698: [(set (match_operand:DI 0 "register_operand" "=r") ! 699: (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ! 700: (match_operand:DI 2 "reg_or_6bit_operand" "rI")))] ! 701: "" ! 702: "srl %r1,%2,%0") ! 703: ! 704: (define_insn "ashrdi3" ! 705: [(set (match_operand:DI 0 "register_operand" "=r") ! 706: (ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ! 707: (match_operand:DI 2 "reg_or_6bit_operand" "rI")))] ! 708: "" ! 709: "sra %r1,%2,%0") ! 710: ! 711: (define_expand "extendqihi2" ! 712: [(set (match_dup 2) ! 713: (ashift:DI (match_operand:QI 1 "register_operand" "") ! 714: (const_int 56))) ! 715: (set (match_operand:HI 0 "register_operand" "") ! 716: (ashiftrt:DI (match_dup 2) ! 717: (const_int 56)))] ! 718: "" ! 719: " ! 720: { operands[0] = gen_lowpart (DImode, operands[0]); ! 721: operands[1] = gen_lowpart (DImode, operands[1]); ! 722: operands[2] = gen_reg_rtx (DImode); ! 723: }") ! 724: ! 725: (define_expand "extendqisi2" ! 726: [(set (match_dup 2) ! 727: (ashift:DI (match_operand:QI 1 "register_operand" "") ! 728: (const_int 56))) ! 729: (set (match_operand:SI 0 "register_operand" "") ! 730: (ashiftrt:DI (match_dup 2) ! 731: (const_int 56)))] ! 732: "" ! 733: " ! 734: { operands[0] = gen_lowpart (DImode, operands[0]); ! 735: operands[1] = gen_lowpart (DImode, operands[1]); ! 736: operands[2] = gen_reg_rtx (DImode); ! 737: }") ! 738: ! 739: (define_expand "extendqidi2" ! 740: [(set (match_dup 2) ! 741: (ashift:DI (match_operand:QI 1 "register_operand" "") ! 742: (const_int 56))) ! 743: (set (match_operand:DI 0 "register_operand" "") ! 744: (ashiftrt:DI (match_dup 2) ! 745: (const_int 56)))] ! 746: "" ! 747: " ! 748: { operands[1] = gen_lowpart (DImode, operands[1]); ! 749: operands[2] = gen_reg_rtx (DImode); ! 750: }") ! 751: ! 752: (define_expand "extendhisi2" ! 753: [(set (match_dup 2) ! 754: (ashift:DI (match_operand:HI 1 "register_operand" "") ! 755: (const_int 48))) ! 756: (set (match_operand:SI 0 "register_operand" "") ! 757: (ashiftrt:DI (match_dup 2) ! 758: (const_int 48)))] ! 759: "" ! 760: " ! 761: { operands[0] = gen_lowpart (DImode, operands[0]); ! 762: operands[1] = gen_lowpart (DImode, operands[1]); ! 763: operands[2] = gen_reg_rtx (DImode); ! 764: }") ! 765: ! 766: (define_expand "extendhidi2" ! 767: [(set (match_dup 2) ! 768: (ashift:DI (match_operand:HI 1 "register_operand" "") ! 769: (const_int 48))) ! 770: (set (match_operand:DI 0 "register_operand" "") ! 771: (ashiftrt:DI (match_dup 2) ! 772: (const_int 48)))] ! 773: "" ! 774: " ! 775: { operands[1] = gen_lowpart (DImode, operands[1]); ! 776: operands[2] = gen_reg_rtx (DImode); ! 777: }") ! 778: ! 779: (define_insn "" ! 780: [(set (match_operand:DI 0 "register_operand" "=r") ! 781: (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ! 782: (match_operand:DI 2 "mode_width_operand" "n") ! 783: (match_operand:DI 3 "mul8_operand" "I")))] ! 784: "" ! 785: "ext%M2l %r1,%s3,%0") ! 786: ! 787: (define_insn "" ! 788: [(set (match_operand:DI 0 "register_operand" "=r") ! 789: (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ! 790: (match_operand:DI 2 "mode_width_operand" "n") ! 791: (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI") ! 792: (const_int 3))))] ! 793: "" ! 794: "ext%M2l %r1,%3,%0") ! 795: ! 796: (define_insn "" ! 797: [(set (match_operand:DI 0 "register_operand" "=r") ! 798: (ashift:DI ! 799: (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ! 800: (const_int 8) ! 801: (ashift:DI ! 802: (plus:DI ! 803: (match_operand:DI 2 "reg_or_8bit_operand" "rI") ! 804: (const_int -1)) ! 805: (const_int 3))) ! 806: (const_int 56)))] ! 807: "" ! 808: "extqh %r1,%2,%0") ! 809: ! 810: (define_insn "" ! 811: [(set (match_operand:DI 0 "register_operand" "=r") ! 812: (ashift:DI ! 813: (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ! 814: (const_int 16) ! 815: (ashift:DI ! 816: (plus:DI ! 817: (match_operand:DI 2 "reg_or_8bit_operand" "rI") ! 818: (const_int -2)) ! 819: (const_int 3))) ! 820: (const_int 48)))] ! 821: "" ! 822: "extwh %r1,%2,%0") ! 823: ! 824: (define_insn "" ! 825: [(set (match_operand:DI 0 "register_operand" "=r") ! 826: (ashift:DI ! 827: (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ! 828: (const_int 32) ! 829: (ashift:DI ! 830: (plus:DI ! 831: (match_operand:DI 2 "reg_or_8bit_operand" "rI") ! 832: (const_int -4)) ! 833: (const_int 3))) ! 834: (const_int 32)))] ! 835: "" ! 836: "extlh %r1,%2,%0") ! 837: ! 838: ;; This converts an extXl into an extXh with an appropriate adjustment ! 839: ;; to the address calculation. ! 840: ! 841: (define_split ! 842: [(set (match_operand:DI 0 "register_operand" "") ! 843: (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand" "") ! 844: (match_operand:DI 2 "mode_width_operand" "") ! 845: (ashift:DI (match_operand:DI 3 "" "") ! 846: (const_int 3))) ! 847: (match_operand:DI 4 "const_int_operand" ""))) ! 848: (clobber (match_operand:DI 5 "register_operand" ""))] ! 849: "INTVAL (operands[4]) == 64 - INTVAL (operands[2])" ! 850: [(set (match_dup 5) (match_dup 6)) ! 851: (set (match_dup 0) ! 852: (ashift:DI (zero_extract:DI (match_dup 1) (match_dup 2) ! 853: (ashift:DI (plus:DI (match_dup 5) ! 854: (match_dup 7)) ! 855: (const_int 3))) ! 856: (match_dup 4)))] ! 857: " ! 858: { ! 859: operands[6] = plus_constant (operands[3], ! 860: INTVAL (operands[2]) / BITS_PER_UNIT); ! 861: operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT); ! 862: }") ! 863: ! 864: (define_insn "" ! 865: [(set (match_operand:DI 0 "register_operand" "=r") ! 866: (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r")) ! 867: (match_operand:DI 2 "mul8_operand" "I")))] ! 868: "" ! 869: "insbl %1,%s2,%0") ! 870: ! 871: (define_insn "" ! 872: [(set (match_operand:DI 0 "register_operand" "=r") ! 873: (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r")) ! 874: (match_operand:DI 2 "mul8_operand" "I")))] ! 875: "" ! 876: "inswl %1,%s2,%0") ! 877: ! 878: (define_insn "" ! 879: [(set (match_operand:DI 0 "register_operand" "=r") ! 880: (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) ! 881: (match_operand:DI 2 "mul8_operand" "I")))] ! 882: "" ! 883: "insll %1,%s2,%0") ! 884: ! 885: (define_insn "" ! 886: [(set (match_operand:DI 0 "register_operand" "=r") ! 887: (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r")) ! 888: (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") ! 889: (const_int 3))))] ! 890: "" ! 891: "insbl %1,%2,%0") ! 892: ! 893: (define_insn "" ! 894: [(set (match_operand:DI 0 "register_operand" "=r") ! 895: (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r")) ! 896: (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") ! 897: (const_int 3))))] ! 898: "" ! 899: "inswl %1,%2,%0") ! 900: ! 901: (define_insn "" ! 902: [(set (match_operand:DI 0 "register_operand" "=r") ! 903: (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) ! 904: (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") ! 905: (const_int 3))))] ! 906: "" ! 907: "insll %1,%2,%0") ! 908: ! 909: ;; We do not include the insXh insns because they are complex to express ! 910: ;; and it does not appear that we would ever want to generate them. ! 911: ! 912: (define_insn "" ! 913: [(set (match_operand:DI 0 "register_operand" "=r") ! 914: (and:DI (ashift:DI ! 915: (match_operand:DI 2 "mode_mask_operand" "n") ! 916: (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI") ! 917: (const_int 3))) ! 918: (match_operand:DI 1 "reg_or_0_operand" "rJ")))] ! 919: "" ! 920: "msk%U2l %r1,%3,%0") ! 921: ! 922: ;; We do not include the mskXh insns because it does not appear we would ever ! 923: ;; generate one. ! 924: ! 925: ;; Floating-point operations. All the double-precision insns can extend ! 926: ;; from single, so indicate that. The exception are the ones that simply ! 927: ;; play with the sign bits; it's not clear what to do there. ! 928: ! 929: (define_insn "abssf2" ! 930: [(set (match_operand:SF 0 "register_operand" "=f") ! 931: (abs:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))] ! 932: "TARGET_FP" ! 933: "cpys $f31,%R1,%0" ! 934: [(set_attr "type" "fpop")]) ! 935: ! 936: (define_insn "absdf2" ! 937: [(set (match_operand:DF 0 "register_operand" "=f") ! 938: (abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] ! 939: "TARGET_FP" ! 940: "cpys $f31,%R1,%0" ! 941: [(set_attr "type" "fpop")]) ! 942: ! 943: (define_insn "negsf2" ! 944: [(set (match_operand:SF 0 "register_operand" "=f") ! 945: (neg:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))] ! 946: "TARGET_FP" ! 947: "cpysn %1,%R1,%0" ! 948: [(set_attr "type" "fpop")]) ! 949: ! 950: (define_insn "negdf2" ! 951: [(set (match_operand:DF 0 "register_operand" "=f") ! 952: (neg:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] ! 953: "TARGET_FP" ! 954: "cpysn %1,%R1,%0" ! 955: [(set_attr "type" "fpop")]) ! 956: ! 957: (define_insn "addsf3" ! 958: [(set (match_operand:SF 0 "register_operand" "=f") ! 959: (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG") ! 960: (match_operand:SF 2 "reg_or_fp0_operand" "fG")))] ! 961: "TARGET_FP" ! 962: "adds %R1,%R2,%0" ! 963: [(set_attr "type" "fpop")]) ! 964: ! 965: (define_insn "adddf3" ! 966: [(set (match_operand:DF 0 "register_operand" "=f") ! 967: (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG") ! 968: (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] ! 969: "TARGET_FP" ! 970: "addt %R1,%R2,%0" ! 971: [(set_attr "type" "fpop")]) ! 972: ! 973: (define_insn "" ! 974: [(set (match_operand:DF 0 "register_operand" "=f") ! 975: (plus:DF (float_extend:DF ! 976: (match_operand:SF 1 "reg_or_fp0_operand" "fG")) ! 977: (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] ! 978: "TARGET_FP" ! 979: "addt %R1,%R2,%0" ! 980: [(set_attr "type" "fpop")]) ! 981: ! 982: (define_insn "" ! 983: [(set (match_operand:DF 0 "register_operand" "=f") ! 984: (plus:DF (float_extend:DF ! 985: (match_operand:SF 1 "reg_or_fp0_operand" "%fG")) ! 986: (float_extend:DF ! 987: (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] ! 988: "TARGET_FP" ! 989: "addt %R1,%R2,%0" ! 990: [(set_attr "type" "fpop")]) ! 991: ! 992: (define_insn "fix_truncdfdi2" ! 993: [(set (match_operand:DI 0 "register_operand" "=f") ! 994: (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] ! 995: "TARGET_FP" ! 996: "cvttqc %R1,%0" ! 997: [(set_attr "type" "fpop")]) ! 998: ! 999: (define_insn "fix_truncsfdi2" ! 1000: [(set (match_operand:DI 0 "register_operand" "=f") ! 1001: (fix:DI (float_extend:DF ! 1002: (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))] ! 1003: "TARGET_FP" ! 1004: "cvttqc %R1,%0" ! 1005: [(set_attr "type" "fpop")]) ! 1006: ! 1007: (define_insn "floatdisf2" ! 1008: [(set (match_operand:SF 0 "register_operand" "=f") ! 1009: (float:SF (match_operand:DI 1 "register_operand" "f")))] ! 1010: "TARGET_FP" ! 1011: "cvtqs %1,%0" ! 1012: [(set_attr "type" "fpop")]) ! 1013: ! 1014: (define_insn "floatdidf2" ! 1015: [(set (match_operand:DF 0 "register_operand" "=f") ! 1016: (float:DF (match_operand:DI 1 "register_operand" "f")))] ! 1017: "TARGET_FP" ! 1018: "cvtqt %1,%0" ! 1019: [(set_attr "type" "fpop")]) ! 1020: ! 1021: (define_insn "extendsfdf2" ! 1022: [(set (match_operand:DF 0 "register_operand" "=f,f") ! 1023: (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m")))] ! 1024: "TARGET_FP" ! 1025: "@ ! 1026: addt $f31,%1,%0 ! 1027: lds %0,%1" ! 1028: [(set_attr "type" "fpop,ld")]) ! 1029: ! 1030: (define_insn "truncdfsf2" ! 1031: [(set (match_operand:SF 0 "register_operand" "=f") ! 1032: (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] ! 1033: "TARGET_FP" ! 1034: "cvtts %R1,%0" ! 1035: [(set_attr "type" "fpop")]) ! 1036: ! 1037: (define_insn "divsf3" ! 1038: [(set (match_operand:SF 0 "register_operand" "=f") ! 1039: (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG") ! 1040: (match_operand:SF 2 "reg_or_fp0_operand" "fG")))] ! 1041: "TARGET_FP" ! 1042: "divs %R1,%R2,%0" ! 1043: [(set_attr "type" "fdivs")]) ! 1044: ! 1045: (define_insn "divdf3" ! 1046: [(set (match_operand:DF 0 "register_operand" "=f") ! 1047: (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG") ! 1048: (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] ! 1049: "TARGET_FP" ! 1050: "divt %R1,%R2,%0" ! 1051: [(set_attr "type" "fdivt")]) ! 1052: ! 1053: (define_insn "" ! 1054: [(set (match_operand:DF 0 "register_operand" "=f") ! 1055: (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG")) ! 1056: (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] ! 1057: "TARGET_FP" ! 1058: "divt %R1,%R2,%0" ! 1059: [(set_attr "type" "fdivt")]) ! 1060: ! 1061: (define_insn "" ! 1062: [(set (match_operand:DF 0 "register_operand" "=f") ! 1063: (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG") ! 1064: (float_extend:DF ! 1065: (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] ! 1066: "TARGET_FP" ! 1067: "divt %R1,%R2,%0" ! 1068: [(set_attr "type" "fdivt")]) ! 1069: ! 1070: (define_insn "" ! 1071: [(set (match_operand:DF 0 "register_operand" "=f") ! 1072: (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG")) ! 1073: (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] ! 1074: "TARGET_FP" ! 1075: "divt %R1,%R2,%0" ! 1076: [(set_attr "type" "fdivt")]) ! 1077: ! 1078: (define_insn "mulsf3" ! 1079: [(set (match_operand:SF 0 "register_operand" "=f") ! 1080: (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG") ! 1081: (match_operand:SF 2 "reg_or_fp0_operand" "fG")))] ! 1082: "TARGET_FP" ! 1083: "muls %R1,%R2,%0" ! 1084: [(set_attr "type" "fpop")]) ! 1085: ! 1086: (define_insn "muldf3" ! 1087: [(set (match_operand:DF 0 "register_operand" "=f") ! 1088: (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG") ! 1089: (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] ! 1090: "TARGET_FP" ! 1091: "mult %R1,%R2,%0" ! 1092: [(set_attr "type" "fpop")]) ! 1093: ! 1094: (define_insn "" ! 1095: [(set (match_operand:DF 0 "register_operand" "=f") ! 1096: (mult:DF (float_extend:DF ! 1097: (match_operand:SF 1 "reg_or_fp0_operand" "fG")) ! 1098: (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] ! 1099: "TARGET_FP" ! 1100: "mult %R1,%R2,%0" ! 1101: [(set_attr "type" "fpop")]) ! 1102: ! 1103: (define_insn "" ! 1104: [(set (match_operand:DF 0 "register_operand" "=f") ! 1105: (mult:DF (float_extend:DF ! 1106: (match_operand:SF 1 "reg_or_fp0_operand" "%fG")) ! 1107: (float_extend:DF ! 1108: (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] ! 1109: "TARGET_FP" ! 1110: "mult %R1,%R2,%0" ! 1111: [(set_attr "type" "fpop")]) ! 1112: ! 1113: (define_insn "subsf3" ! 1114: [(set (match_operand:SF 0 "register_operand" "=f") ! 1115: (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG") ! 1116: (match_operand:SF 2 "reg_or_fp0_operand" "fG")))] ! 1117: "TARGET_FP" ! 1118: "subs %R1,%R2,%0" ! 1119: [(set_attr "type" "fpop")]) ! 1120: ! 1121: (define_insn "subdf3" ! 1122: [(set (match_operand:DF 0 "register_operand" "=f") ! 1123: (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG") ! 1124: (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] ! 1125: "TARGET_FP" ! 1126: "subt %R1,%R2,%0" ! 1127: [(set_attr "type" "fpop")]) ! 1128: ! 1129: (define_insn "" ! 1130: [(set (match_operand:DF 0 "register_operand" "=f") ! 1131: (minus:DF (float_extend:DF ! 1132: (match_operand:SF 1 "reg_or_fp0_operand" "fG")) ! 1133: (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] ! 1134: "TARGET_FP" ! 1135: "subt %R1,%R2,%0" ! 1136: [(set_attr "type" "fpop")]) ! 1137: ! 1138: (define_insn "" ! 1139: [(set (match_operand:DF 0 "register_operand" "=f") ! 1140: (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG") ! 1141: (float_extend:DF ! 1142: (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] ! 1143: "TARGET_FP" ! 1144: "subt %R1,%R2,%0" ! 1145: [(set_attr "type" "fpop")]) ! 1146: ! 1147: (define_insn "" ! 1148: [(set (match_operand:DF 0 "register_operand" "=f") ! 1149: (minus:DF (float_extend:DF ! 1150: (match_operand:SF 1 "reg_or_fp0_operand" "fG")) ! 1151: (float_extend:DF ! 1152: (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] ! 1153: "TARGET_FP" ! 1154: "subt %R1,%R2,%0" ! 1155: [(set_attr "type" "fpop")]) ! 1156: ! 1157: ;; Next are all the integer comparisons, and conditional moves and branches ! 1158: ;; and some of the related define_expand's and define_split's. ! 1159: ! 1160: (define_insn "" ! 1161: [(set (match_operand:DI 0 "register_operand" "=r") ! 1162: (match_operator:DI 1 "alpha_comparison_operator" ! 1163: [(match_operand:DI 2 "reg_or_0_operand" "rJ") ! 1164: (match_operand:DI 3 "reg_or_8bit_operand" "rI")]))] ! 1165: "" ! 1166: "cmp%C1 %r2,%3,%0" ! 1167: [(set_attr "type" "icmp")]) ! 1168: ! 1169: ;; There are three important special-case that don't fit the above pattern ! 1170: ;; but which we want to handle here. ! 1171: ! 1172: (define_insn "" ! 1173: [(set (match_operand:DI 0 "register_operand" "=r") ! 1174: (ne:DI (match_operand:DI 1 "register_operand" "r") ! 1175: (const_int 0)))] ! 1176: "" ! 1177: "cmpult $31,%1,%0" ! 1178: [(set_attr "type" "icmp")]) ! 1179: ! 1180: (define_insn "" ! 1181: [(set (match_operand:DI 0 "register_operand" "=r") ! 1182: (gt:DI (match_operand:DI 1 "register_operand" "r") ! 1183: (const_int 0)))] ! 1184: "" ! 1185: "cmplt $31,%1,%0" ! 1186: [(set_attr "type" "icmp")]) ! 1187: ! 1188: (define_insn "" ! 1189: [(set (match_operand:DI 0 "register_operand" "=r") ! 1190: (ge:DI (match_operand:DI 1 "register_operand" "r") ! 1191: (const_int 0)))] ! 1192: "" ! 1193: "cmple $31,%1,%0" ! 1194: [(set_attr "type" "icmp")]) ! 1195: ! 1196: (define_insn "" ! 1197: [(set (match_operand:DI 0 "register_operand" "=r,r") ! 1198: (if_then_else:DI ! 1199: (match_operator 2 "signed_comparison_operator" ! 1200: [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ") ! 1201: (const_int 0)]) ! 1202: (match_operand:DI 1 "reg_or_8bit_operand" "rI,0") ! 1203: (match_operand:DI 4 "reg_or_8bit_operand" "0,rI")))] ! 1204: "" ! 1205: "@ ! 1206: cmov%C2 %r3,%1,%0 ! 1207: cmov%D2 %r3,%4,%0") ! 1208: ! 1209: (define_insn "" ! 1210: [(set (match_operand:DI 0 "register_operand" "=r,r") ! 1211: (if_then_else:DI ! 1212: (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ") ! 1213: (const_int 1) ! 1214: (const_int 0)) ! 1215: (const_int 0)) ! 1216: (match_operand:DI 1 "reg_or_8bit_operand" "rI,0") ! 1217: (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))] ! 1218: "" ! 1219: "@ ! 1220: cmovlbc %r2,%1,%0 ! 1221: cmovlbs %r2,%3,%0") ! 1222: ! 1223: (define_insn "" ! 1224: [(set (match_operand:DI 0 "register_operand" "=r,r") ! 1225: (if_then_else:DI ! 1226: (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ") ! 1227: (const_int 1) ! 1228: (const_int 0)) ! 1229: (const_int 0)) ! 1230: (match_operand:DI 1 "reg_or_8bit_operand" "rI,0") ! 1231: (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))] ! 1232: "" ! 1233: "@ ! 1234: cmovlbs %r2,%1,%0 ! 1235: cmovlbc %r2,%3,%0") ! 1236: ! 1237: ;; This form is added since combine thinks that an IF_THEN_ELSE with both ! 1238: ;; arms constant is a single insn, so it won't try to form it if combine ! 1239: ;; knows they are really two insns. This occurs in divides by powers ! 1240: ;; of two. ! 1241: ! 1242: (define_insn "" ! 1243: [(set (match_operand:DI 0 "register_operand" "=r") ! 1244: (if_then_else:DI ! 1245: (match_operator 2 "signed_comparison_operator" ! 1246: [(match_operand:DI 3 "reg_or_0_operand" "rJ") ! 1247: (const_int 0)]) ! 1248: (plus:DI (match_dup 0) ! 1249: (match_operand:DI 1 "reg_or_8bit_operand" "rI")) ! 1250: (match_dup 0))) ! 1251: (clobber (match_scratch:DI 4 "=&r"))] ! 1252: "" ! 1253: "addq %0,%1,%4\;cmov%C2 %r3,%4,%0") ! 1254: ! 1255: (define_split ! 1256: [(set (match_operand:DI 0 "register_operand" "") ! 1257: (if_then_else:DI ! 1258: (match_operator 2 "signed_comparison_operator" ! 1259: [(match_operand:DI 3 "reg_or_0_operand" "") ! 1260: (const_int 0)]) ! 1261: (plus:DI (match_dup 0) ! 1262: (match_operand:DI 1 "reg_or_8bit_operand" "")) ! 1263: (match_dup 0))) ! 1264: (clobber (match_operand:DI 4 "register_operand" ""))] ! 1265: "" ! 1266: [(set (match_dup 4) (plus:DI (match_dup 0) (match_dup 1))) ! 1267: (set (match_dup 0) (if_then_else:DI (match_op_dup 2 ! 1268: [(match_dup 3) ! 1269: (const_int 0)]) ! 1270: (match_dup 4) (match_dup 0)))] ! 1271: "") ! 1272: ! 1273: (define_split ! 1274: [(parallel ! 1275: [(set (match_operand:DI 0 "register_operand" "") ! 1276: (if_then_else:DI ! 1277: (match_operator 1 "comparison_operator" ! 1278: [(zero_extract:DI (match_operand:DI 2 "register_operand" "") ! 1279: (const_int 1) ! 1280: (match_operand:DI 3 "const_int_operand" "")) ! 1281: (const_int 0)]) ! 1282: (match_operand:DI 4 "reg_or_8bit_operand" "") ! 1283: (match_operand:DI 5 "reg_or_8bit_operand" ""))) ! 1284: (clobber (match_operand:DI 6 "register_operand" ""))])] ! 1285: "INTVAL (operands[3]) != 0" ! 1286: [(set (match_dup 6) ! 1287: (lshiftrt:DI (match_dup 2) (match_dup 3))) ! 1288: (set (match_dup 0) ! 1289: (if_then_else:DI (match_op_dup 1 ! 1290: [(zero_extract:DI (match_dup 6) ! 1291: (const_int 1) ! 1292: (const_int 0)) ! 1293: (const_int 0)]) ! 1294: (match_dup 4) ! 1295: (match_dup 5)))] ! 1296: "") ! 1297: ! 1298: ;; For ABS, we have two choices, depending on whether the input and output ! 1299: ;; registers are the same or not. ! 1300: (define_expand "absdi2" ! 1301: [(set (match_operand:DI 0 "register_operand" "") ! 1302: (abs:DI (match_operand:DI 1 "register_operand" "")))] ! 1303: "" ! 1304: " ! 1305: { if (rtx_equal_p (operands[0], operands[1])) ! 1306: emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode))); ! 1307: else ! 1308: emit_insn (gen_absdi2_diff (operands[0], operands[1])); ! 1309: ! 1310: DONE; ! 1311: }") ! 1312: ! 1313: (define_expand "absdi2_same" ! 1314: [(set (match_operand:DI 1 "register_operand" "") ! 1315: (neg:DI (match_operand:DI 0 "register_operand" ""))) ! 1316: (set (match_dup 0) ! 1317: (if_then_else:DI (ge (match_dup 0) (const_int 0)) ! 1318: (match_dup 0) ! 1319: (match_dup 1)))] ! 1320: "" ! 1321: "") ! 1322: ! 1323: (define_expand "absdi2_diff" ! 1324: [(set (match_operand:DI 0 "register_operand" "") ! 1325: (neg:DI (match_operand:DI 1 "register_operand" ""))) ! 1326: (set (match_dup 0) ! 1327: (if_then_else:DI (lt (match_dup 1) (const_int 0)) ! 1328: (match_dup 0) ! 1329: (match_dup 1)))] ! 1330: "" ! 1331: "") ! 1332: ! 1333: (define_split ! 1334: [(set (match_operand:DI 0 "register_operand" "") ! 1335: (abs:DI (match_dup 0))) ! 1336: (clobber (match_operand:DI 2 "register_operand" ""))] ! 1337: "" ! 1338: [(set (match_dup 1) (neg:DI (match_dup 0))) ! 1339: (set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0)) ! 1340: (match_dup 0) (match_dup 1)))] ! 1341: "") ! 1342: ! 1343: (define_split ! 1344: [(set (match_operand:DI 0 "register_operand" "") ! 1345: (abs:DI (match_operand:DI 1 "register_operand" "")))] ! 1346: "! rtx_equal_p (operands[0], operands[1])" ! 1347: [(set (match_dup 0) (neg:DI (match_dup 1))) ! 1348: (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0)) ! 1349: (match_dup 0) (match_dup 1)))] ! 1350: "") ! 1351: ! 1352: (define_split ! 1353: [(set (match_operand:DI 0 "register_operand" "") ! 1354: (neg:DI (abs:DI (match_dup 0)))) ! 1355: (clobber (match_operand:DI 2 "register_operand" ""))] ! 1356: "" ! 1357: [(set (match_dup 1) (neg:DI (match_dup 0))) ! 1358: (set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0)) ! 1359: (match_dup 0) (match_dup 1)))] ! 1360: "") ! 1361: ! 1362: (define_split ! 1363: [(set (match_operand:DI 0 "register_operand" "") ! 1364: (neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))] ! 1365: "! rtx_equal_p (operands[0], operands[1])" ! 1366: [(set (match_dup 0) (neg:DI (match_dup 1))) ! 1367: (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0)) ! 1368: (match_dup 0) (match_dup 1)))] ! 1369: "") ! 1370: ! 1371: (define_expand "smaxdi3" ! 1372: [(set (match_dup 3) ! 1373: (le:DI (match_operand:DI 1 "reg_or_0_operand" "") ! 1374: (match_operand:DI 2 "reg_or_8bit_operand" ""))) ! 1375: (set (match_operand:DI 0 "register_operand" "") ! 1376: (if_then_else:DI (eq (match_dup 3) (const_int 0)) ! 1377: (match_dup 1) (match_dup 2)))] ! 1378: "" ! 1379: " ! 1380: { operands[3] = gen_reg_rtx (DImode); ! 1381: }") ! 1382: ! 1383: (define_split ! 1384: [(set (match_operand:DI 0 "register_operand" "") ! 1385: (smax:DI (match_operand:DI 1 "reg_or_0_operand" "") ! 1386: (match_operand:DI 2 "reg_or_8bit_operand" ""))) ! 1387: (clobber (match_operand:DI 3 "register_operand" ""))] ! 1388: "operands[2] != const0_rtx" ! 1389: [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2))) ! 1390: (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0)) ! 1391: (match_dup 1) (match_dup 2)))] ! 1392: "") ! 1393: ! 1394: (define_insn "" ! 1395: [(set (match_operand:DI 0 "register_operand" "=r") ! 1396: (smax:DI (match_operand:DI 1 "register_operand" "0") ! 1397: (const_int 0)))] ! 1398: "" ! 1399: "cmovlt %0,0,%0") ! 1400: ! 1401: (define_expand "smindi3" ! 1402: [(set (match_dup 3) ! 1403: (lt:DI (match_operand:DI 1 "reg_or_0_operand" "") ! 1404: (match_operand:DI 2 "reg_or_8bit_operand" ""))) ! 1405: (set (match_operand:DI 0 "register_operand" "") ! 1406: (if_then_else:DI (ne (match_dup 3) (const_int 0)) ! 1407: (match_dup 1) (match_dup 2)))] ! 1408: "" ! 1409: " ! 1410: { operands[3] = gen_reg_rtx (DImode); ! 1411: }") ! 1412: ! 1413: (define_split ! 1414: [(set (match_operand:DI 0 "register_operand" "") ! 1415: (smin:DI (match_operand:DI 1 "reg_or_0_operand" "") ! 1416: (match_operand:DI 2 "reg_or_8bit_operand" ""))) ! 1417: (clobber (match_operand:DI 3 "register_operand" ""))] ! 1418: "operands[2] != const0_rtx" ! 1419: [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2))) ! 1420: (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0)) ! 1421: (match_dup 1) (match_dup 2)))] ! 1422: "") ! 1423: ! 1424: (define_insn "" ! 1425: [(set (match_operand:DI 0 "register_operand" "=r") ! 1426: (smin:DI (match_operand:DI 1 "register_operand" "0") ! 1427: (const_int 0)))] ! 1428: "" ! 1429: "cmovgt %0,0,%0") ! 1430: ! 1431: (define_expand "umaxdi3" ! 1432: [(set (match_dup 3) ! 1433: (leu:DI (match_operand:DI 1 "reg_or_0_operand" "") ! 1434: (match_operand:DI 2 "reg_or_8bit_operand" ""))) ! 1435: (set (match_operand:DI 0 "register_operand" "") ! 1436: (if_then_else:DI (eq (match_dup 3) (const_int 0)) ! 1437: (match_dup 1) (match_dup 2)))] ! 1438: "" ! 1439: " ! 1440: { operands[3] = gen_reg_rtx (DImode); ! 1441: }") ! 1442: ! 1443: (define_split ! 1444: [(set (match_operand:DI 0 "register_operand" "") ! 1445: (umax:DI (match_operand:DI 1 "reg_or_0_operand" "") ! 1446: (match_operand:DI 2 "reg_or_8bit_operand" ""))) ! 1447: (clobber (match_operand:DI 3 "register_operand" ""))] ! 1448: "operands[2] != const0_rtx" ! 1449: [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2))) ! 1450: (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0)) ! 1451: (match_dup 1) (match_dup 2)))] ! 1452: "") ! 1453: ! 1454: (define_expand "umindi3" ! 1455: [(set (match_dup 3) ! 1456: (ltu:DI (match_operand:DI 1 "reg_or_0_operand" "") ! 1457: (match_operand:DI 2 "reg_or_8bit_operand" ""))) ! 1458: (set (match_operand:DI 0 "register_operand" "") ! 1459: (if_then_else:DI (ne (match_dup 3) (const_int 0)) ! 1460: (match_dup 1) (match_dup 2)))] ! 1461: "" ! 1462: " ! 1463: { operands[3] = gen_reg_rtx (DImode); ! 1464: }") ! 1465: ! 1466: (define_split ! 1467: [(set (match_operand:DI 0 "register_operand" "") ! 1468: (umin:DI (match_operand:DI 1 "reg_or_0_operand" "") ! 1469: (match_operand:DI 2 "reg_or_8bit_operand" ""))) ! 1470: (clobber (match_operand:DI 3 "register_operand" ""))] ! 1471: "operands[2] != const0_rtx" ! 1472: [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2))) ! 1473: (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0)) ! 1474: (match_dup 1) (match_dup 2)))] ! 1475: "") ! 1476: ! 1477: (define_insn "" ! 1478: [(set (pc) ! 1479: (if_then_else ! 1480: (match_operator 1 "signed_comparison_operator" ! 1481: [(match_operand:DI 2 "reg_or_0_operand" "rJ") ! 1482: (const_int 0)]) ! 1483: (label_ref (match_operand 0 "" "")) ! 1484: (pc)))] ! 1485: "" ! 1486: "b%C1 %r2,%0" ! 1487: [(set_attr "type" "ibr")]) ! 1488: ! 1489: (define_insn "" ! 1490: [(set (pc) ! 1491: (if_then_else ! 1492: (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ! 1493: (const_int 1) ! 1494: (const_int 0)) ! 1495: (const_int 0)) ! 1496: (label_ref (match_operand 0 "" "")) ! 1497: (pc)))] ! 1498: "" ! 1499: "blbs %r1,%0" ! 1500: [(set_attr "type" "ibr")]) ! 1501: ! 1502: (define_insn "" ! 1503: [(set (pc) ! 1504: (if_then_else ! 1505: (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") ! 1506: (const_int 1) ! 1507: (const_int 0)) ! 1508: (const_int 0)) ! 1509: (label_ref (match_operand 0 "" "")) ! 1510: (pc)))] ! 1511: "" ! 1512: "blbc %r1,%0" ! 1513: [(set_attr "type" "ibr")]) ! 1514: ! 1515: (define_split ! 1516: [(parallel ! 1517: [(set (pc) ! 1518: (if_then_else ! 1519: (match_operator 1 "comparison_operator" ! 1520: [(zero_extract:DI (match_operand:DI 2 "register_operand" "") ! 1521: (const_int 1) ! 1522: (match_operand:DI 3 "const_int_operand" "")) ! 1523: (const_int 0)]) ! 1524: (label_ref (match_operand 0 "" "")) ! 1525: (pc))) ! 1526: (clobber (match_operand:DI 4 "register_operand" ""))])] ! 1527: "INTVAL (operands[3]) != 0" ! 1528: [(set (match_dup 4) ! 1529: (lshiftrt:DI (match_dup 2) (match_dup 3))) ! 1530: (set (pc) ! 1531: (if_then_else (match_op_dup 1 ! 1532: [(zero_extract:DI (match_dup 4) ! 1533: (const_int 1) ! 1534: (const_int 0)) ! 1535: (const_int 0)]) ! 1536: (label_ref (match_dup 0)) ! 1537: (pc)))] ! 1538: "") ! 1539: ! 1540: ;; The following are the corresponding floating-point insns. Recall ! 1541: ;; we need to have variants that expand the arguments from SF mode ! 1542: ;; to DFmode. ! 1543: ! 1544: (define_insn "" ! 1545: [(set (match_operand:DF 0 "register_operand" "=f") ! 1546: (match_operator:DF 1 "alpha_comparison_operator" ! 1547: [(match_operand:DF 2 "reg_or_fp0_operand" "fG") ! 1548: (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))] ! 1549: "TARGET_FP" ! 1550: "cmpt%C1 %R2,%R3,%0" ! 1551: [(set_attr "type" "fpop")]) ! 1552: ! 1553: (define_insn "" ! 1554: [(set (match_operand:DF 0 "register_operand" "=f") ! 1555: (match_operator:DF 1 "alpha_comparison_operator" ! 1556: [(float_extend:DF ! 1557: (match_operand:SF 2 "reg_or_fp0_operand" "fG")) ! 1558: (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))] ! 1559: "TARGET_FP" ! 1560: "cmpt%C1 %R2,%R3,%0" ! 1561: [(set_attr "type" "fpop")]) ! 1562: ! 1563: (define_insn "" ! 1564: [(set (match_operand:DF 0 "register_operand" "=f") ! 1565: (match_operator:DF 1 "alpha_comparison_operator" ! 1566: [(match_operand:DF 2 "reg_or_fp0_operand" "fG") ! 1567: (float_extend:DF ! 1568: (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))] ! 1569: "TARGET_FP" ! 1570: "cmpt%C1 %R2,%R3,%0" ! 1571: [(set_attr "type" "fpop")]) ! 1572: ! 1573: (define_insn "" ! 1574: [(set (match_operand:DF 0 "register_operand" "=f") ! 1575: (match_operator:DF 1 "alpha_comparison_operator" ! 1576: [(float_extend:DF ! 1577: (match_operand:SF 2 "reg_or_fp0_operand" "fG")) ! 1578: (float_extend:DF ! 1579: (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))] ! 1580: "TARGET_FP" ! 1581: "cmpt%C1 %R2,%R3,%0" ! 1582: [(set_attr "type" "fpop")]) ! 1583: ! 1584: (define_insn "" ! 1585: [(set (match_operand:DF 0 "register_operand" "=f,f") ! 1586: (if_then_else:DF ! 1587: (match_operator 3 "signed_comparison_operator" ! 1588: [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG") ! 1589: (match_operand:DF 2 "fp0_operand" "G,G")]) ! 1590: (match_operand:DF 1 "reg_or_fp0_operand" "fG,0") ! 1591: (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))] ! 1592: "TARGET_FP" ! 1593: "@ ! 1594: fcmov%C3 %R4,%R1,%0 ! 1595: fcmov%D3 %R4,%R5,%0" ! 1596: [(set_attr "type" "fpop")]) ! 1597: ! 1598: (define_insn "" ! 1599: [(set (match_operand:SF 0 "register_operand" "=f,f") ! 1600: (if_then_else:SF ! 1601: (match_operator 3 "signed_comparison_operator" ! 1602: [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG") ! 1603: (match_operand:DF 2 "fp0_operand" "G,G")]) ! 1604: (match_operand:SF 1 "reg_or_fp0_operand" "fG,0") ! 1605: (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))] ! 1606: "TARGET_FP" ! 1607: "@ ! 1608: fcmov%C3 %R4,%R1,%0 ! 1609: fcmov%D3 %R4,%R5,%0" ! 1610: [(set_attr "type" "fpop")]) ! 1611: ! 1612: (define_insn "" ! 1613: [(set (match_operand:DF 0 "register_operand" "=f,f") ! 1614: (if_then_else:DF ! 1615: (match_operator 3 "signed_comparison_operator" ! 1616: [(match_operand:DF 1 "reg_or_fp0_operand" "fG,fG") ! 1617: (match_operand:DF 2 "fp0_operand" "G,G")]) ! 1618: (float_extend:DF (match_operand:SF 4 "reg_or_fp0_operand" "fG,0")) ! 1619: (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))] ! 1620: "TARGET_FP" ! 1621: "@ ! 1622: fcmov%C3 %R4,%R1,%0 ! 1623: fcmov%D3 %R4,%R5,%0" ! 1624: [(set_attr "type" "fpop")]) ! 1625: ! 1626: (define_insn "" ! 1627: [(set (match_operand:DF 0 "register_operand" "=f,f") ! 1628: (if_then_else:DF ! 1629: (match_operator 3 "signed_comparison_operator" ! 1630: [(float_extend:DF ! 1631: (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG")) ! 1632: (match_operand:DF 2 "fp0_operand" "G,G")]) ! 1633: (match_operand:DF 1 "reg_or_fp0_operand" "fG,0") ! 1634: (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))] ! 1635: "TARGET_FP" ! 1636: "@ ! 1637: fcmov%C3 %R4,%R1,%0 ! 1638: fcmov%D3 %R4,%R5,%0" ! 1639: [(set_attr "type" "fpop")]) ! 1640: ! 1641: (define_insn "" ! 1642: [(set (match_operand:SF 0 "register_operand" "=f,f") ! 1643: (if_then_else:SF ! 1644: (match_operator 3 "signed_comparison_operator" ! 1645: [(float_extend:DF ! 1646: (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG")) ! 1647: (match_operand:DF 2 "fp0_operand" "G,G")]) ! 1648: (match_operand:SF 1 "reg_or_fp0_operand" "fG,0") ! 1649: (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))] ! 1650: "TARGET_FP" ! 1651: "@ ! 1652: fcmov%C3 %R4,%R1,%0 ! 1653: fcmov%D3 %R4,%R5,%0" ! 1654: [(set_attr "type" "fpop")]) ! 1655: ! 1656: (define_insn "" ! 1657: [(set (match_operand:DF 0 "register_operand" "=f,f") ! 1658: (if_then_else:DF ! 1659: (match_operator 3 "signed_comparison_operator" ! 1660: [(float_extend:DF ! 1661: (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG")) ! 1662: (match_operand:DF 2 "fp0_operand" "G,G")]) ! 1663: (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")) ! 1664: (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))] ! 1665: "TARGET_FP" ! 1666: "@ ! 1667: fcmov%C3 %R4,%R1,%0 ! 1668: fcmov%D3 %R4,%R5,%0" ! 1669: [(set_attr "type" "fpop")]) ! 1670: ! 1671: (define_expand "maxdf3" ! 1672: [(set (match_dup 3) ! 1673: (le:DF (match_operand:DF 1 "reg_or_fp0_operand" "") ! 1674: (match_operand:DF 2 "reg_or_fp0_operand" ""))) ! 1675: (set (match_operand:DF 0 "register_operand" "") ! 1676: (if_then_else:DF (eq (match_dup 3) (const_int 0)) ! 1677: (match_dup 1) (match_dup 2)))] ! 1678: "TARGET_FP" ! 1679: " ! 1680: { operands[3] = gen_reg_rtx (DFmode); ! 1681: }") ! 1682: ! 1683: (define_expand "mindf3" ! 1684: [(set (match_dup 3) ! 1685: (lt:DF (match_operand:DF 1 "reg_or_fp0_operand" "") ! 1686: (match_operand:DF 2 "reg_or_fp0_operand" ""))) ! 1687: (set (match_operand:DF 0 "register_operand" "") ! 1688: (if_then_else:DF (ne (match_dup 3) (const_int 0)) ! 1689: (match_dup 1) (match_dup 2)))] ! 1690: "TARGET_FP" ! 1691: " ! 1692: { operands[3] = gen_reg_rtx (DFmode); ! 1693: }") ! 1694: ! 1695: (define_expand "maxsf3" ! 1696: [(set (match_dup 3) ! 1697: (le:DF (match_operand:SF 1 "reg_or_fp0_operand" "") ! 1698: (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "")))) ! 1699: (set (match_operand:SF 0 "register_operand" "") ! 1700: (if_then_else:SF (eq (match_dup 3) (const_int 0)) ! 1701: (match_dup 1) (match_dup 2)))] ! 1702: "TARGET_FP" ! 1703: " ! 1704: { operands[3] = gen_reg_rtx (SFmode); ! 1705: }") ! 1706: ! 1707: (define_expand "minsf3" ! 1708: [(set (match_dup 3) ! 1709: (lt:DF (match_operand:SF 1 "reg_or_fp0_operand" "") ! 1710: (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "")))) ! 1711: (set (match_operand:SF 0 "register_operand" "") ! 1712: (if_then_else:SF (ne (match_dup 3) (const_int 0)) ! 1713: (match_dup 1) (match_dup 2)))] ! 1714: "TARGET_FP" ! 1715: " ! 1716: { operands[3] = gen_reg_rtx (SFmode); ! 1717: }") ! 1718: ! 1719: (define_insn "" ! 1720: [(set (pc) ! 1721: (if_then_else ! 1722: (match_operator 1 "signed_comparison_operator" ! 1723: [(match_operand:DF 2 "reg_or_fp0_operand" "fG") ! 1724: (match_operand:DF 3 "fp0_operand" "G")]) ! 1725: (label_ref (match_operand 0 "" "")) ! 1726: (pc)))] ! 1727: "TARGET_FP" ! 1728: "fb%C1 %R2,%0" ! 1729: [(set_attr "type" "fbr")]) ! 1730: ! 1731: (define_insn "" ! 1732: [(set (pc) ! 1733: (if_then_else ! 1734: (match_operator 1 "signed_comparison_operator" ! 1735: [(float_extend:DF ! 1736: (match_operand:SF 2 "reg_or_fp0_operand" "fG")) ! 1737: (match_operand:DF 3 "fp0_operand" "G")]) ! 1738: (label_ref (match_operand 0 "" "")) ! 1739: (pc)))] ! 1740: "TARGET_FP" ! 1741: "fb%C1 %R2,%0" ! 1742: [(set_attr "type" "fbr")]) ! 1743: ! 1744: ;; These are the main define_expand's used to make conditional branches ! 1745: ;; and compares. ! 1746: ! 1747: (define_expand "cmpdf" ! 1748: [(set (cc0) (compare (match_operand:DF 0 "reg_or_fp0_operand" "") ! 1749: (match_operand:DF 1 "reg_or_fp0_operand" "")))] ! 1750: "" ! 1751: " ! 1752: { ! 1753: alpha_compare_op0 = operands[0]; ! 1754: alpha_compare_op1 = operands[1]; ! 1755: alpha_compare_fp_p = 1; ! 1756: DONE; ! 1757: }") ! 1758: ! 1759: (define_expand "cmpdi" ! 1760: [(set (cc0) (compare (match_operand:DI 0 "reg_or_0_operand" "") ! 1761: (match_operand:DI 1 "reg_or_8bit_operand" "")))] ! 1762: "" ! 1763: " ! 1764: { ! 1765: alpha_compare_op0 = operands[0]; ! 1766: alpha_compare_op1 = operands[1]; ! 1767: alpha_compare_fp_p = 0; ! 1768: DONE; ! 1769: }") ! 1770: ! 1771: (define_expand "beq" ! 1772: [(set (match_dup 1) (match_dup 2)) ! 1773: (set (pc) ! 1774: (if_then_else (match_dup 3) ! 1775: (label_ref (match_operand 0 "" "")) ! 1776: (pc)))] ! 1777: "" ! 1778: " ! 1779: { ! 1780: enum machine_mode mode; ! 1781: enum rtx_code compare_code, branch_code; ! 1782: ! 1783: if (alpha_compare_fp_p) ! 1784: mode = DFmode, compare_code = EQ, branch_code = NE; ! 1785: else ! 1786: { ! 1787: mode = DImode, compare_code = MINUS, branch_code = EQ; ! 1788: if (GET_CODE (alpha_compare_op1) == CONST_INT) ! 1789: { ! 1790: compare_code = PLUS; ! 1791: alpha_compare_op1 = GEN_INT (- INTVAL (alpha_compare_op1)); ! 1792: } ! 1793: } ! 1794: ! 1795: operands[1] = gen_reg_rtx (mode); ! 1796: operands[2] = gen_rtx (compare_code, mode, ! 1797: alpha_compare_op0, alpha_compare_op1); ! 1798: operands[3] = gen_rtx (branch_code, VOIDmode, ! 1799: operands[1], CONST0_RTX (mode)); ! 1800: }") ! 1801: ! 1802: (define_expand "bne" ! 1803: [(set (match_dup 1) (match_dup 2)) ! 1804: (set (pc) ! 1805: (if_then_else (match_dup 3) ! 1806: (label_ref (match_operand 0 "" "")) ! 1807: (pc)))] ! 1808: "" ! 1809: " ! 1810: { ! 1811: enum machine_mode mode; ! 1812: enum rtx_code compare_code, branch_code; ! 1813: ! 1814: if (alpha_compare_fp_p) ! 1815: mode = DFmode, compare_code = EQ, branch_code = EQ; ! 1816: else ! 1817: { ! 1818: mode = DImode, compare_code = MINUS, branch_code = NE; ! 1819: if (GET_CODE (alpha_compare_op1) == CONST_INT) ! 1820: { ! 1821: compare_code = PLUS; ! 1822: alpha_compare_op1 = GEN_INT (- INTVAL (alpha_compare_op1)); ! 1823: } ! 1824: } ! 1825: ! 1826: operands[1] = gen_reg_rtx (mode); ! 1827: operands[2] = gen_rtx (compare_code, mode, ! 1828: alpha_compare_op0, alpha_compare_op1); ! 1829: operands[3] = gen_rtx (branch_code, VOIDmode, ! 1830: operands[1], CONST0_RTX (mode)); ! 1831: }") ! 1832: ! 1833: (define_expand "blt" ! 1834: [(set (match_dup 1) (match_dup 2)) ! 1835: (set (pc) ! 1836: (if_then_else (match_dup 3) ! 1837: (label_ref (match_operand 0 "" "")) ! 1838: (pc)))] ! 1839: "" ! 1840: " ! 1841: { ! 1842: enum machine_mode mode = alpha_compare_fp_p ? DFmode : DImode; ! 1843: operands[1] = gen_reg_rtx (mode); ! 1844: operands[2] = gen_rtx (LT, mode, alpha_compare_op0, alpha_compare_op1); ! 1845: operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (mode)); ! 1846: }") ! 1847: ! 1848: (define_expand "ble" ! 1849: [(set (match_dup 1) (match_dup 2)) ! 1850: (set (pc) ! 1851: (if_then_else (match_dup 3) ! 1852: (label_ref (match_operand 0 "" "")) ! 1853: (pc)))] ! 1854: "" ! 1855: " ! 1856: { ! 1857: enum machine_mode mode = alpha_compare_fp_p ? DFmode : DImode; ! 1858: operands[1] = gen_reg_rtx (mode); ! 1859: operands[2] = gen_rtx (LE, mode, alpha_compare_op0, alpha_compare_op1); ! 1860: operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (mode)); ! 1861: }") ! 1862: ! 1863: (define_expand "bgt" ! 1864: [(set (match_dup 1) (match_dup 2)) ! 1865: (set (pc) ! 1866: (if_then_else (match_dup 3) ! 1867: (label_ref (match_operand 0 "" "")) ! 1868: (pc)))] ! 1869: "" ! 1870: " ! 1871: { ! 1872: if (alpha_compare_fp_p) ! 1873: { ! 1874: operands[1] = gen_reg_rtx (DFmode); ! 1875: operands[2] = gen_rtx (LT, DFmode, alpha_compare_op1, alpha_compare_op0); ! 1876: operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (DFmode)); ! 1877: } ! 1878: else ! 1879: { ! 1880: operands[1] = gen_reg_rtx (DImode); ! 1881: operands[2] = gen_rtx (LE, DImode, alpha_compare_op0, alpha_compare_op1); ! 1882: operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx); ! 1883: } ! 1884: }") ! 1885: ! 1886: (define_expand "bge" ! 1887: [(set (match_dup 1) (match_dup 2)) ! 1888: (set (pc) ! 1889: (if_then_else (match_dup 3) ! 1890: (label_ref (match_operand 0 "" "")) ! 1891: (pc)))] ! 1892: "" ! 1893: " ! 1894: { ! 1895: if (alpha_compare_fp_p) ! 1896: { ! 1897: operands[1] = gen_reg_rtx (DFmode); ! 1898: operands[2] = gen_rtx (LE, DFmode, alpha_compare_op1, alpha_compare_op0); ! 1899: operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (DFmode)); ! 1900: } ! 1901: else ! 1902: { ! 1903: operands[1] = gen_reg_rtx (DImode); ! 1904: operands[2] = gen_rtx (LT, DImode, alpha_compare_op0, alpha_compare_op1); ! 1905: operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx); ! 1906: } ! 1907: }") ! 1908: ! 1909: (define_expand "bltu" ! 1910: [(set (match_dup 1) (match_dup 2)) ! 1911: (set (pc) ! 1912: (if_then_else (match_dup 3) ! 1913: (label_ref (match_operand 0 "" "")) ! 1914: (pc)))] ! 1915: "" ! 1916: " ! 1917: { ! 1918: operands[1] = gen_reg_rtx (DImode); ! 1919: operands[2] = gen_rtx (LTU, DImode, alpha_compare_op0, alpha_compare_op1); ! 1920: operands[3] = gen_rtx (NE, VOIDmode, operands[1], const0_rtx); ! 1921: }") ! 1922: ! 1923: (define_expand "bleu" ! 1924: [(set (match_dup 1) (match_dup 2)) ! 1925: (set (pc) ! 1926: (if_then_else (match_dup 3) ! 1927: (label_ref (match_operand 0 "" "")) ! 1928: (pc)))] ! 1929: "" ! 1930: " ! 1931: { ! 1932: operands[1] = gen_reg_rtx (DImode); ! 1933: operands[2] = gen_rtx (LEU, DImode, alpha_compare_op0, alpha_compare_op1); ! 1934: operands[3] = gen_rtx (NE, VOIDmode, operands[1], const0_rtx); ! 1935: }") ! 1936: ! 1937: (define_expand "bgtu" ! 1938: [(set (match_dup 1) (match_dup 2)) ! 1939: (set (pc) ! 1940: (if_then_else (match_dup 3) ! 1941: (label_ref (match_operand 0 "" "")) ! 1942: (pc)))] ! 1943: "" ! 1944: " ! 1945: { ! 1946: operands[1] = gen_reg_rtx (DImode); ! 1947: operands[2] = gen_rtx (LEU, DImode, alpha_compare_op0, alpha_compare_op1); ! 1948: operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx); ! 1949: }") ! 1950: ! 1951: (define_expand "bgeu" ! 1952: [(set (match_dup 1) (match_dup 2)) ! 1953: (set (pc) ! 1954: (if_then_else (match_dup 3) ! 1955: (label_ref (match_operand 0 "" "")) ! 1956: (pc)))] ! 1957: "" ! 1958: " ! 1959: { ! 1960: operands[1] = gen_reg_rtx (DImode); ! 1961: operands[2] = gen_rtx (LTU, DImode, alpha_compare_op0, alpha_compare_op1); ! 1962: operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx); ! 1963: }") ! 1964: ! 1965: (define_expand "seq" ! 1966: [(set (match_operand:DI 0 "register_operand" "") ! 1967: (match_dup 1))] ! 1968: "" ! 1969: " ! 1970: { ! 1971: if (alpha_compare_fp_p) ! 1972: FAIL; ! 1973: ! 1974: operands[1] = gen_rtx (EQ, DImode, alpha_compare_op0, alpha_compare_op1); ! 1975: }") ! 1976: ! 1977: (define_expand "sne" ! 1978: [(set (match_operand:DI 0 "register_operand" "") ! 1979: (match_dup 1)) ! 1980: (set (match_dup 0) (xor:DI (match_dup 0) (const_int 1)))] ! 1981: "" ! 1982: " ! 1983: { ! 1984: if (alpha_compare_fp_p) ! 1985: FAIL; ! 1986: ! 1987: operands[1] = gen_rtx (EQ, DImode, alpha_compare_op0, alpha_compare_op1); ! 1988: }") ! 1989: ! 1990: (define_expand "slt" ! 1991: [(set (match_operand:DI 0 "register_operand" "") ! 1992: (match_dup 1))] ! 1993: "" ! 1994: " ! 1995: { ! 1996: if (alpha_compare_fp_p) ! 1997: FAIL; ! 1998: ! 1999: operands[1] = gen_rtx (LT, DImode, alpha_compare_op0, alpha_compare_op1); ! 2000: }") ! 2001: ! 2002: (define_expand "sle" ! 2003: [(set (match_operand:DI 0 "register_operand" "") ! 2004: (match_dup 1))] ! 2005: "" ! 2006: " ! 2007: { ! 2008: if (alpha_compare_fp_p) ! 2009: FAIL; ! 2010: ! 2011: operands[1] = gen_rtx (LE, DImode, alpha_compare_op0, alpha_compare_op1); ! 2012: }") ! 2013: ! 2014: (define_expand "sgt" ! 2015: [(set (match_operand:DI 0 "register_operand" "") ! 2016: (match_dup 1))] ! 2017: "" ! 2018: " ! 2019: { ! 2020: if (alpha_compare_fp_p) ! 2021: FAIL; ! 2022: ! 2023: operands[1] = gen_rtx (LT, DImode, force_reg (DImode, alpha_compare_op1), ! 2024: alpha_compare_op0); ! 2025: }") ! 2026: ! 2027: (define_expand "sge" ! 2028: [(set (match_operand:DI 0 "register_operand" "") ! 2029: (match_dup 1))] ! 2030: "" ! 2031: " ! 2032: { ! 2033: if (alpha_compare_fp_p) ! 2034: FAIL; ! 2035: ! 2036: operands[1] = gen_rtx (LE, DImode, force_reg (DImode, alpha_compare_op1), ! 2037: alpha_compare_op0); ! 2038: }") ! 2039: ! 2040: (define_expand "sltu" ! 2041: [(set (match_operand:DI 0 "register_operand" "") ! 2042: (match_dup 1))] ! 2043: "" ! 2044: " ! 2045: { ! 2046: if (alpha_compare_fp_p) ! 2047: FAIL; ! 2048: ! 2049: operands[1] = gen_rtx (LTU, DImode, alpha_compare_op0, alpha_compare_op1); ! 2050: }") ! 2051: ! 2052: (define_expand "sleu" ! 2053: [(set (match_operand:DI 0 "register_operand" "") ! 2054: (match_dup 1))] ! 2055: "" ! 2056: " ! 2057: { ! 2058: if (alpha_compare_fp_p) ! 2059: FAIL; ! 2060: ! 2061: operands[1] = gen_rtx (LEU, DImode, alpha_compare_op0, alpha_compare_op1); ! 2062: }") ! 2063: ! 2064: (define_expand "sgtu" ! 2065: [(set (match_operand:DI 0 "register_operand" "") ! 2066: (match_dup 1))] ! 2067: "" ! 2068: " ! 2069: { ! 2070: if (alpha_compare_fp_p) ! 2071: FAIL; ! 2072: ! 2073: operands[1] = gen_rtx (LTU, DImode, force_reg (DImode, alpha_compare_op1), ! 2074: alpha_compare_op0); ! 2075: }") ! 2076: ! 2077: (define_expand "sgeu" ! 2078: [(set (match_operand:DI 0 "register_operand" "") ! 2079: (match_dup 1))] ! 2080: "" ! 2081: " ! 2082: { ! 2083: if (alpha_compare_fp_p) ! 2084: FAIL; ! 2085: ! 2086: operands[1] = gen_rtx (LEU, DImode, force_reg (DImode, alpha_compare_op1), ! 2087: alpha_compare_op0); ! 2088: }") ! 2089: ! 2090: ;; These define_split definitions are used in cases when comparisons have ! 2091: ;; not be stated in the correct way and we need to reverse the second ! 2092: ;; comparison. For example, x >= 7 has to be done as x < 6 with the ! 2093: ;; comparison that tests the result being reversed. We have one define_split ! 2094: ;; for each use of a comparison. They do not match valid insns and need ! 2095: ;; not generate valid insns. ! 2096: ;; ! 2097: ;; We can also handle equality comparisons (and inequality comparisons in ! 2098: ;; cases where the resulting add cannot overflow) by doing an add followed by ! 2099: ;; a comparison with zero. This is faster since the addition takes one ! 2100: ;; less cycle than a compare when feeding into a conditional move. ! 2101: ;; For this case, we also have an SImode pattern since we can merge the add ! 2102: ;; and sign extend and the order doesn't matter. ! 2103: ;; ! 2104: ;; We do not do this for floating-point, since it isn't clear how the "wrong" ! 2105: ;; operation could have been generated. ! 2106: ! 2107: (define_split ! 2108: [(set (match_operand:DI 0 "register_operand" "") ! 2109: (if_then_else:DI ! 2110: (match_operator 1 "comparison_operator" ! 2111: [(match_operand:DI 2 "reg_or_0_operand" "") ! 2112: (match_operand:DI 3 "reg_or_cint_operand" "")]) ! 2113: (match_operand:DI 4 "reg_or_cint_operand" "") ! 2114: (match_operand:DI 5 "reg_or_cint_operand" ""))) ! 2115: (clobber (match_operand:DI 6 "register_operand" ""))] ! 2116: "operands[3] != const0_rtx" ! 2117: [(set (match_dup 6) (match_dup 7)) ! 2118: (set (match_dup 0) ! 2119: (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))] ! 2120: " ! 2121: { enum rtx_code code = GET_CODE (operands[1]); ! 2122: int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU); ! 2123: ! 2124: /* If we are comparing for equality with a constant and that constant ! 2125: appears in the arm when the register equals the constant, use the ! 2126: register since that is more likely to match (and to produce better code ! 2127: if both would). */ ! 2128: ! 2129: if (code == EQ && GET_CODE (operands[3]) == CONST_INT ! 2130: && rtx_equal_p (operands[4], operands[3])) ! 2131: operands[4] = operands[2]; ! 2132: ! 2133: else if (code == NE && GET_CODE (operands[3]) == CONST_INT ! 2134: && rtx_equal_p (operands[5], operands[3])) ! 2135: operands[5] = operands[2]; ! 2136: ! 2137: if (code == NE || code == EQ ! 2138: || (extended_count (operands[2], DImode, unsignedp) >= 1 ! 2139: && extended_count (operands[3], DImode, unsignedp) >= 1)) ! 2140: { ! 2141: if (GET_CODE (operands[3]) == CONST_INT) ! 2142: operands[7] = gen_rtx (PLUS, DImode, operands[2], ! 2143: GEN_INT (- INTVAL (operands[3]))); ! 2144: else ! 2145: operands[7] = gen_rtx (MINUS, DImode, operands[2], operands[3]); ! 2146: ! 2147: operands[8] = gen_rtx (code, VOIDmode, operands[6], const0_rtx); ! 2148: } ! 2149: ! 2150: else if (code == EQ || code == LE || code == LT ! 2151: || code == LEU || code == LTU) ! 2152: { ! 2153: operands[7] = gen_rtx (code, DImode, operands[2], operands[3]); ! 2154: operands[8] = gen_rtx (NE, VOIDmode, operands[6], const0_rtx); ! 2155: } ! 2156: else ! 2157: { ! 2158: operands[7] = gen_rtx (reverse_condition (code), DImode, operands[2], ! 2159: operands[3]); ! 2160: operands[8] = gen_rtx (EQ, VOIDmode, operands[6], const0_rtx); ! 2161: } ! 2162: }") ! 2163: ! 2164: (define_split ! 2165: [(set (match_operand:DI 0 "register_operand" "") ! 2166: (if_then_else:DI ! 2167: (match_operator 1 "comparison_operator" ! 2168: [(match_operand:SI 2 "reg_or_0_operand" "") ! 2169: (match_operand:SI 3 "reg_or_cint_operand" "")]) ! 2170: (match_operand:DI 4 "reg_or_8bit_operand" "") ! 2171: (match_operand:DI 5 "reg_or_8bit_operand" ""))) ! 2172: (clobber (match_operand:DI 6 "register_operand" ""))] ! 2173: "operands[3] != const0_rtx ! 2174: && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)" ! 2175: [(set (match_dup 6) (match_dup 7)) ! 2176: (set (match_dup 0) ! 2177: (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))] ! 2178: " ! 2179: { enum rtx_code code = GET_CODE (operands[1]); ! 2180: int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU); ! 2181: rtx tem; ! 2182: ! 2183: if ((code != NE && code != EQ ! 2184: && ! (extended_count (operands[2], DImode, unsignedp) >= 1 ! 2185: && extended_count (operands[3], DImode, unsignedp) >= 1))) ! 2186: FAIL; ! 2187: ! 2188: if (GET_CODE (operands[3]) == CONST_INT) ! 2189: tem = gen_rtx (PLUS, SImode, operands[2], ! 2190: GEN_INT (- INTVAL (operands[3]))); ! 2191: else ! 2192: tem = gen_rtx (MINUS, SImode, operands[2], operands[3]); ! 2193: ! 2194: operands[7] = gen_rtx (SIGN_EXTEND, DImode, tem); ! 2195: operands[8] = gen_rtx (GET_CODE (operands[1]), VOIDmode, operands[6], ! 2196: const0_rtx); ! 2197: }") ! 2198: ! 2199: (define_split ! 2200: [(set (pc) ! 2201: (if_then_else ! 2202: (match_operator 1 "comparison_operator" ! 2203: [(match_operand:DI 2 "reg_or_0_operand" "") ! 2204: (match_operand:DI 3 "reg_or_cint_operand" "")]) ! 2205: (label_ref (match_operand 0 "" "")) ! 2206: (pc))) ! 2207: (clobber (match_operand:DI 4 "register_operand" ""))] ! 2208: "operands[3] != const0_rtx" ! 2209: [(set (match_dup 4) (match_dup 5)) ! 2210: (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))] ! 2211: " ! 2212: { enum rtx_code code = GET_CODE (operands[1]); ! 2213: int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU); ! 2214: ! 2215: if (code == NE || code == EQ ! 2216: || (extended_count (operands[2], DImode, unsignedp) >= 1 ! 2217: && extended_count (operands[3], DImode, unsignedp) >= 1)) ! 2218: { ! 2219: if (GET_CODE (operands[3]) == CONST_INT) ! 2220: operands[5] = gen_rtx (PLUS, DImode, operands[2], ! 2221: GEN_INT (- INTVAL (operands[3]))); ! 2222: else ! 2223: operands[5] = gen_rtx (MINUS, DImode, operands[2], operands[3]); ! 2224: ! 2225: operands[6] = gen_rtx (code, VOIDmode, operands[4], const0_rtx); ! 2226: } ! 2227: ! 2228: else if (code == EQ || code == LE || code == LT ! 2229: || code == LEU || code == LTU) ! 2230: { ! 2231: operands[5] = gen_rtx (code, DImode, operands[2], operands[3]); ! 2232: operands[6] = gen_rtx (NE, VOIDmode, operands[4], const0_rtx); ! 2233: } ! 2234: else ! 2235: { ! 2236: operands[5] = gen_rtx (reverse_condition (code), DImode, operands[2], ! 2237: operands[3]); ! 2238: operands[6] = gen_rtx (EQ, VOIDmode, operands[4], const0_rtx); ! 2239: } ! 2240: }") ! 2241: ! 2242: (define_split ! 2243: [(set (pc) ! 2244: (if_then_else ! 2245: (match_operator 1 "comparison_operator" ! 2246: [(match_operand:SI 2 "reg_or_0_operand" "") ! 2247: (match_operand:SI 3 "const_int_operand" "")]) ! 2248: (label_ref (match_operand 0 "" "")) ! 2249: (pc))) ! 2250: (clobber (match_operand:DI 4 "register_operand" ""))] ! 2251: "operands[3] != const0_rtx ! 2252: && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)" ! 2253: [(set (match_dup 4) (match_dup 5)) ! 2254: (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))] ! 2255: " ! 2256: { rtx tem; ! 2257: ! 2258: if (GET_CODE (operands[3]) == CONST_INT) ! 2259: tem = gen_rtx (PLUS, SImode, operands[2], ! 2260: GEN_INT (- INTVAL (operands[3]))); ! 2261: else ! 2262: tem = gen_rtx (MINUS, SImode, operands[2], operands[3]); ! 2263: ! 2264: operands[5] = gen_rtx (SIGN_EXTEND, DImode, tem); ! 2265: operands[6] = gen_rtx (GET_CODE (operands[1]), VOIDmode, ! 2266: operands[4], const0_rtx); ! 2267: }") ! 2268: ! 2269: ;; Here are the CALL and unconditional branch insns. ! 2270: ! 2271: (define_expand "call" ! 2272: [(parallel [(call (mem:DI (match_dup 2)) ! 2273: (match_operand 1 "" "")) ! 2274: (use (match_operand:DI 0 "" "")) ! 2275: (clobber (reg:DI 26))])] ! 2276: "" ! 2277: " ! 2278: { if (GET_CODE (operands[0]) != MEM) ! 2279: abort (); ! 2280: operands[0] = XEXP (operands[0], 0); ! 2281: ! 2282: operands[2] = gen_rtx (REG, DImode, 27); ! 2283: emit_move_insn (operands[2], operands[0]); ! 2284: ! 2285: if (GET_CODE (operands[0]) != SYMBOL_REF) ! 2286: operands[0] = const0_rtx; ! 2287: }") ! 2288: ! 2289: (define_expand "call_value" ! 2290: [(parallel [(set (match_operand 0 "" "") ! 2291: (call (mem:DI (match_dup 3)) ! 2292: (match_operand 2 "" ""))) ! 2293: (use (match_operand:DI 1 "" "")) ! 2294: (clobber (reg:DI 26))])] ! 2295: "" ! 2296: " ! 2297: { if (GET_CODE (operands[1]) != MEM) ! 2298: abort (); ! 2299: ! 2300: operands[1] = XEXP (operands[1], 0); ! 2301: ! 2302: operands[3] = gen_rtx (REG, DImode, 27); ! 2303: emit_move_insn (operands[3], operands[1]); ! 2304: ! 2305: if (GET_CODE (operands[1]) != SYMBOL_REF) ! 2306: operands[1] = const0_rtx; ! 2307: }") ! 2308: ! 2309: (define_insn "" ! 2310: [(call (mem:DI (reg:DI 27)) ! 2311: (match_operand 0 "" "")) ! 2312: (use (match_operand:DI 1 "" "")) ! 2313: (clobber (reg:DI 26))] ! 2314: "" ! 2315: "jsr $26,($27),%1\;ldgp $29,0($26)" ! 2316: [(set_attr "type" "jsr")]) ! 2317: ! 2318: (define_insn "" ! 2319: [(set (match_operand 0 "register_operand" "=rf") ! 2320: (call (mem:DI (reg:DI 27)) ! 2321: (match_operand 1 "" ""))) ! 2322: (use (match_operand:DI 2 "" "")) ! 2323: (clobber (reg:DI 26))] ! 2324: "" ! 2325: "jsr $26,($27),%2\;ldgp $29,0($26)" ! 2326: [(set_attr "type" "jsr")]) ! 2327: ! 2328: (define_insn "" ! 2329: [(call (mem:DI (match_operand 1 "current_file_function_operand" "i")) ! 2330: (match_operand 0 "" "")) ! 2331: (use (match_dup 1)) ! 2332: (clobber (reg:DI 26))] ! 2333: "" ! 2334: "bsr $26,%1..ng" ! 2335: [(set_attr "type" "ibr")]) ! 2336: ! 2337: (define_insn "" ! 2338: [(set (match_operand 0 "register_operand" "=rf") ! 2339: (call (mem:DI (match_operand 1 "current_file_function_operand" "i")) ! 2340: (match_operand 2 "" ""))) ! 2341: (use (match_dup 1)) ! 2342: (clobber (reg:DI 26))] ! 2343: "" ! 2344: "bsr $26,%1..ng" ! 2345: [(set_attr "type" "ibr")]) ! 2346: ! 2347: ;; Call subroutine returning any type. ! 2348: ! 2349: (define_expand "untyped_call" ! 2350: [(parallel [(call (match_operand 0 "" "") ! 2351: (const_int 0)) ! 2352: (match_operand 1 "" "") ! 2353: (match_operand 2 "" "")])] ! 2354: "" ! 2355: " ! 2356: { ! 2357: int i; ! 2358: ! 2359: emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); ! 2360: ! 2361: for (i = 0; i < XVECLEN (operands[2], 0); i++) ! 2362: { ! 2363: rtx set = XVECEXP (operands[2], 0, i); ! 2364: emit_move_insn (SET_DEST (set), SET_SRC (set)); ! 2365: } ! 2366: ! 2367: /* The optimizer does not know that the call sets the function value ! 2368: registers we stored in the result block. We avoid problems by ! 2369: claiming that all hard registers are used and clobbered at this ! 2370: point. */ ! 2371: emit_insn (gen_blockage ()); ! 2372: ! 2373: DONE; ! 2374: }") ! 2375: ! 2376: ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and ! 2377: ;; all of memory. This blocks insns from being moved across this point. ! 2378: ! 2379: (define_insn "blockage" ! 2380: [(unspec_volatile [(const_int 0)] 1)] ! 2381: "" ! 2382: "") ! 2383: ! 2384: (define_insn "jump" ! 2385: [(set (pc) ! 2386: (label_ref (match_operand 0 "" "")))] ! 2387: "" ! 2388: "br $31,%l0" ! 2389: [(set_attr "type" "ibr")]) ! 2390: ! 2391: (define_insn "return" ! 2392: [(return)] ! 2393: "direct_return ()" ! 2394: "ret $31,($26),1" ! 2395: [(set_attr "type" "ibr")]) ! 2396: ! 2397: (define_insn "indirect_jump" ! 2398: [(set (pc) (match_operand:DI 0 "register_operand" "r"))] ! 2399: "" ! 2400: "jmp $31,(%0),0" ! 2401: [(set_attr "type" "ibr")]) ! 2402: ! 2403: (define_insn "nop" ! 2404: [(const_int 0)] ! 2405: "" ! 2406: "bis $31,$31,$31" ! 2407: [(set_attr "type" "iaddlog")]) ! 2408: ! 2409: (define_expand "tablejump" ! 2410: [(set (match_dup 3) ! 2411: (sign_extend:DI (match_operand:SI 0 "register_operand" ""))) ! 2412: (parallel [(set (pc) (plus:DI (match_dup 3) (reg:DI 29))) ! 2413: (use (label_ref (match_operand 1 "" ""))) ! 2414: (clobber (match_scratch:DI 2 "=r"))])] ! 2415: "" ! 2416: " ! 2417: { operands[3] = gen_reg_rtx (DImode); }") ! 2418: ! 2419: (define_insn "" ! 2420: [(set (pc) ! 2421: (plus:DI (match_operand:DI 0 "register_operand" "r") ! 2422: (reg:DI 29))) ! 2423: (use (label_ref (match_operand 1 "" ""))) ! 2424: (clobber (match_scratch:DI 2 "=r"))] ! 2425: "" ! 2426: "* ! 2427: { rtx best_label = 0; ! 2428: rtx jump_table_insn = next_active_insn (operands[1]); ! 2429: ! 2430: if (GET_CODE (jump_table_insn) == JUMP_INSN ! 2431: && GET_CODE (PATTERN (jump_table_insn)) == ADDR_VEC) ! 2432: { ! 2433: rtx jump_table = PATTERN (jump_table_insn); ! 2434: int n_labels = XVECLEN (jump_table, 0); ! 2435: int best_count = -1; ! 2436: int i, j; ! 2437: ! 2438: for (i = 0; i < n_labels; i++) ! 2439: { ! 2440: int count = 1; ! 2441: ! 2442: for (j = i + 1; j < n_labels; j++) ! 2443: if (XEXP (XVECEXP (jump_table, 0, i), 0) ! 2444: == XEXP (XVECEXP (jump_table, 0, j), 0)) ! 2445: count++; ! 2446: ! 2447: if (count > best_count) ! 2448: best_count = count, best_label = XVECEXP (jump_table, 0, i); ! 2449: } ! 2450: } ! 2451: ! 2452: if (best_label) ! 2453: { ! 2454: operands[3] = best_label; ! 2455: return \"addq %0,$29,%2\;jmp $31,(%2),%3\"; ! 2456: } ! 2457: else ! 2458: return \"addq %0,$29,%2\;jmp $31,(%2),0\"; ! 2459: }" ! 2460: [(set_attr "type" "ibr")]) ! 2461: ! 2462: ;; Cache flush. Used by INITIALIZE_TRAMPOLINE. 0x86 is PAL_imb, but we don't ! 2463: ;; want to have to include pal.h in our .s file. ! 2464: (define_insn "" ! 2465: [(unspec_volatile [(const_int 0)] 0)] ! 2466: "" ! 2467: "call_pal 0x86") ! 2468: ! 2469: ;; Finally, we have the basic data motion insns. The byte and word insns ! 2470: ;; are done via define_expand. Start with the floating-point insns, since ! 2471: ;; they are simpler. ! 2472: ! 2473: (define_insn "" ! 2474: [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m") ! 2475: (match_operand:SF 1 "input_operand" "rG,m,rG,f,G,m,fG"))] ! 2476: "register_operand (operands[0], SFmode) ! 2477: || reg_or_fp0_operand (operands[1], SFmode)" ! 2478: "@ ! 2479: bis %r1,%r1,%0 ! 2480: ldl %0,%1 ! 2481: stl %r1,%0 ! 2482: cpys %1,%1,%0 ! 2483: cpys $f31,$f31,%0 ! 2484: lds %0,%1 ! 2485: sts %R1,%0" ! 2486: [(set_attr "type" "iaddlog,ld,st,fpop,fpop,ld,st")]) ! 2487: ! 2488: (define_insn "" ! 2489: [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m") ! 2490: (match_operand:DF 1 "input_operand" "rG,m,rG,f,G,m,fG"))] ! 2491: "register_operand (operands[0], DFmode) ! 2492: || reg_or_fp0_operand (operands[1], DFmode)" ! 2493: "@ ! 2494: bis %r1,%r1,%0 ! 2495: ldq %0,%1 ! 2496: stq %r1,%0 ! 2497: cpys %1,%1,%0 ! 2498: cpys $f31,$f31,%0 ! 2499: ldt %0,%1 ! 2500: stt %R1,%0" ! 2501: [(set_attr "type" "iaddlog,ld,st,fpop,fpop,ld,st")]) ! 2502: ! 2503: (define_expand "movsf" ! 2504: [(set (match_operand:SF 0 "nonimmediate_operand" "") ! 2505: (match_operand:SF 1 "general_operand" ""))] ! 2506: "" ! 2507: " ! 2508: { ! 2509: if (GET_CODE (operands[0]) == MEM ! 2510: && ! reg_or_fp0_operand (operands[1], SFmode)) ! 2511: operands[1] = force_reg (SFmode, operands[1]); ! 2512: }") ! 2513: ! 2514: (define_expand "movdf" ! 2515: [(set (match_operand:DF 0 "nonimmediate_operand" "") ! 2516: (match_operand:DF 1 "general_operand" ""))] ! 2517: "" ! 2518: " ! 2519: { ! 2520: if (GET_CODE (operands[0]) == MEM ! 2521: && ! reg_or_fp0_operand (operands[1], DFmode)) ! 2522: operands[1] = force_reg (DFmode, operands[1]); ! 2523: }") ! 2524: ! 2525: ;; There is a problem with 32-bit values in FP registers. We keep such ! 2526: ;; values in the register as a quadword. This is done on loads by using ! 2527: ;; the cvtlq instruction. On stores, we can't do anything directly from ! 2528: ;; floating-point registers. Disallow such an operation and let reload ! 2529: ;; use an integer register instead. Don't encourage 32-bit values to ! 2530: ;; be placed in FP registers at all. ! 2531: ! 2532: (define_insn "" ! 2533: [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,*f") ! 2534: (match_operand:SI 1 "input_operand" "r,J,I,K,L,m,rJ,*f,J,m"))] ! 2535: "register_operand (operands[0], SImode) ! 2536: || reg_or_0_operand (operands[1], SImode)" ! 2537: "@ ! 2538: bis %1,%1,%0 ! 2539: bis $31,$31,%0 ! 2540: bis $31,%1,%0 ! 2541: lda %0,%1 ! 2542: ldah %0,%h1 ! 2543: ldl %0,%1 ! 2544: stl %r1,%0 ! 2545: cpys %1,%1,%0 ! 2546: cpys $f31,$f31,%0 ! 2547: lds %0,%1\;cvtlq %0,%0" ! 2548: [(set_attr "type" "iaddlog,iaddlog,iaddlog,iaddlog,iaddlog,ld,st,fpop,fpop,ld")]) ! 2549: ! 2550: (define_insn "" ! 2551: [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,f,f") ! 2552: (match_operand:HI 1 "input_operand" "r,J,I,n,f,J"))] ! 2553: "register_operand (operands[0], HImode) ! 2554: || register_operand (operands[1], HImode)" ! 2555: "@ ! 2556: bis %1,%1,%0 ! 2557: bis $31,$31,%0 ! 2558: bis $31,%1,%0 ! 2559: lda %0,%L1 ! 2560: cpys %1,%1,%0 ! 2561: cpys $f31,$f31,%0" ! 2562: [(set_attr "type" "iaddlog,iaddlog,iaddlog,iaddlog,fpop,fpop")]) ! 2563: ! 2564: (define_insn "" ! 2565: [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,f,f") ! 2566: (match_operand:QI 1 "input_operand" "r,J,I,n,f,J"))] ! 2567: "register_operand (operands[0], QImode) ! 2568: || register_operand (operands[1], QImode)" ! 2569: "@ ! 2570: bis %1,%1,%0 ! 2571: bis $31,$31,%0 ! 2572: bis $31,%1,%0 ! 2573: lda %0,%L1 ! 2574: cpys %1,%1,%0 ! 2575: cpys $f31,$f31,%0" ! 2576: [(set_attr "type" "iaddlog,iaddlog,iaddlog,iaddlog,fpop,fpop")]) ! 2577: ! 2578: ;; We do two major things here: handle mem->mem and construct long ! 2579: ;; constants. ! 2580: ! 2581: (define_expand "movsi" ! 2582: [(set (match_operand:SI 0 "general_operand" "") ! 2583: (match_operand:SI 1 "general_operand" ""))] ! 2584: "" ! 2585: " ! 2586: { ! 2587: if (GET_CODE (operands[0]) == MEM ! 2588: && ! reg_or_0_operand (operands[1], SImode)) ! 2589: operands[1] = force_reg (SImode, operands[1]); ! 2590: ! 2591: if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode)) ! 2592: ; ! 2593: else if (GET_CODE (operands[1]) == CONST_INT) ! 2594: { ! 2595: if (alpha_emit_set_const (operands[0], INTVAL (operands[1]), 3)) ! 2596: DONE; ! 2597: else ! 2598: abort (); ! 2599: } ! 2600: }") ! 2601: ! 2602: ;; Split a load of a large constant into the appropriate two-insn ! 2603: ;; sequence. ! 2604: ! 2605: (define_split ! 2606: [(set (match_operand:SI 0 "register_operand" "") ! 2607: (match_operand:SI 1 "const_int_operand" ""))] ! 2608: "! add_operand (operands[1], SImode)" ! 2609: [(set (match_dup 0) (match_dup 2)) ! 2610: (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))] ! 2611: " ! 2612: { if (alpha_emit_set_const (operands[0], INTVAL (operands[1]), 2)) ! 2613: DONE; ! 2614: else ! 2615: FAIL; ! 2616: }") ! 2617: ! 2618: (define_insn "" ! 2619: [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,r,r,m,f,f,f,Q") ! 2620: (match_operand:DI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,Q,fG"))] ! 2621: "register_operand (operands[0], DImode) ! 2622: || reg_or_0_operand (operands[1], DImode)" ! 2623: "@ ! 2624: bis %1,%1,%0 ! 2625: bis $31,$31,%0 ! 2626: bis $31,%1,%0 ! 2627: lda %0,%1 ! 2628: ldah %0,%h1 ! 2629: lda %0,%1 ! 2630: ldq%A1 %0,%1 ! 2631: stq%A0 %r1,%0 ! 2632: cpys %1,%1,%0 ! 2633: cpys $f31,$f31,%0 ! 2634: ldt %0,%1 ! 2635: stt %R1,%0" ! 2636: [(set_attr "type" "iaddlog,iaddlog,iaddlog,iaddlog,iaddlog,ldsym,ld,st,fpop,fpop,ld,st")]) ! 2637: ! 2638: ;; We do three major things here: handle mem->mem, put 64-bit constants in ! 2639: ;; memory, and construct long 32-bit constants. ! 2640: ! 2641: (define_expand "movdi" ! 2642: [(set (match_operand:DI 0 "general_operand" "") ! 2643: (match_operand:DI 1 "general_operand" ""))] ! 2644: "" ! 2645: " ! 2646: { ! 2647: if (GET_CODE (operands[0]) == MEM ! 2648: && ! reg_or_0_operand (operands[1], DImode)) ! 2649: operands[1] = force_reg (DImode, operands[1]); ! 2650: ! 2651: if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode)) ! 2652: ; ! 2653: else if (GET_CODE (operands[1]) == CONST_INT ! 2654: && alpha_emit_set_const (operands[0], INTVAL (operands[1]), 3)) ! 2655: DONE; ! 2656: else if (CONSTANT_P (operands[1])) ! 2657: { ! 2658: operands[1] = force_const_mem (DImode, operands[1]); ! 2659: if (reload_in_progress) ! 2660: { ! 2661: emit_move_insn (operands[0], XEXP (operands[1], 0)); ! 2662: XEXP (operands[1], 0) = operands[0]; ! 2663: } ! 2664: else ! 2665: operands[1] = validize_mem (operands[1]); ! 2666: } ! 2667: else ! 2668: abort (); ! 2669: }") ! 2670: ! 2671: ;; Split a load of a large constant into the appropriate two-insn ! 2672: ;; sequence. ! 2673: ! 2674: (define_split ! 2675: [(set (match_operand:DI 0 "register_operand" "") ! 2676: (match_operand:DI 1 "const_int_operand" ""))] ! 2677: "! add_operand (operands[1], DImode)" ! 2678: [(set (match_dup 0) (match_dup 2)) ! 2679: (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] ! 2680: " ! 2681: { if (alpha_emit_set_const (operands[0], INTVAL (operands[1]), 2)) ! 2682: DONE; ! 2683: else ! 2684: FAIL; ! 2685: }") ! 2686: ! 2687: ;; These are the partial-word cases. ! 2688: ;; ! 2689: ;; First we have the code to load an aligned word. Operand 0 is the register ! 2690: ;; in which to place the result. It's mode is QImode or HImode. Operand 1 ! 2691: ;; is an SImode MEM at the low-order byte of the proper word. Operand 2 is the ! 2692: ;; number of bits within the word that the value is. Operand 3 is an SImode ! 2693: ;; scratch register. If operand 0 is a hard register, operand 3 may be the ! 2694: ;; same register. It is allowed to conflict with operand 1 as well. ! 2695: ! 2696: (define_expand "aligned_loadqi" ! 2697: [(set (match_operand:SI 3 "register_operand" "") ! 2698: (match_operand:SI 1 "memory_operand" "")) ! 2699: (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0) ! 2700: (zero_extract:DI (subreg:DI (match_dup 3) 0) ! 2701: (const_int 8) ! 2702: (match_operand:DI 2 "const_int_operand" "")))] ! 2703: ! 2704: "" ! 2705: "") ! 2706: ! 2707: (define_expand "aligned_loadhi" ! 2708: [(set (match_operand:SI 3 "register_operand" "") ! 2709: (match_operand:SI 1 "memory_operand" "")) ! 2710: (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0) ! 2711: (zero_extract:DI (subreg:DI (match_dup 3) 0) ! 2712: (const_int 16) ! 2713: (match_operand:DI 2 "const_int_operand" "")))] ! 2714: ! 2715: "" ! 2716: "") ! 2717: ! 2718: ;; Similar for unaligned loads. For QImode, we use the sequence from the ! 2719: ;; Alpha Architecture manual. However, for HImode, we do not. HImode pointers ! 2720: ;; are normally aligned to the byte boundary, so an HImode object cannot ! 2721: ;; cross a longword boundary. We could use a sequence similar to that for ! 2722: ;; QImode, but that would fail if the pointer, was, in fact, not aligned. ! 2723: ;; Instead, we clear bit 1 in the address and do an ldl. If the low-order ! 2724: ;; bit was not aligned, this will trap and the trap handler will do what is ! 2725: ;; needed. ! 2726: ;; ! 2727: ;; Here operand 1 is the address. Operands 2 and 3 are temporaries, where ! 2728: ;; operand 3 can overlap the input and output registers. ! 2729: ! 2730: (define_expand "unaligned_loadqi" ! 2731: [(set (match_operand:DI 2 "register_operand" "") ! 2732: (mem:DI (and:DI (match_operand:DI 1 "address_operand" "") ! 2733: (const_int -8)))) ! 2734: (set (match_operand:DI 3 "register_operand" "") ! 2735: (match_dup 1)) ! 2736: (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0) ! 2737: (zero_extract:DI (match_dup 2) ! 2738: (const_int 8) ! 2739: (ashift:DI (match_dup 3) (const_int 3))))] ! 2740: "" ! 2741: "") ! 2742: ! 2743: ;; For this, the address must already be in a register. We also need two ! 2744: ;; DImode temporaries, neither of which may overlap the input (and hence the ! 2745: ;; output, since they might be the same register), but both of which may ! 2746: ;; be the same. ! 2747: ! 2748: (define_expand "unaligned_loadhi" ! 2749: [(set (match_operand:DI 2 "register_operand" "") ! 2750: (and:DI (match_operand:DI 1 "register_operand" "") ! 2751: (const_int -7))) ! 2752: (set (match_operand:DI 3 "register_operand" "") ! 2753: (mem:DI (match_dup 2))) ! 2754: (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0) ! 2755: (zero_extract:DI (match_dup 3) ! 2756: (const_int 16) ! 2757: (ashift:DI (match_dup 1) (const_int 3))))] ! 2758: "" ! 2759: "") ! 2760: ! 2761: ;; Storing an aligned byte or word requires two temporaries. Operand 0 is the ! 2762: ;; aligned SImode MEM. Operand 1 is the register containing the ! 2763: ;; byte or word to store. Operand 2 is the number of bits within the word that ! 2764: ;; the value should be placed. Operands 3 and 4 are SImode temporaries. ! 2765: ! 2766: (define_expand "aligned_store" ! 2767: [(set (match_operand:SI 3 "register_operand" "") ! 2768: (match_operand:SI 0 "memory_operand" "")) ! 2769: (set (subreg:DI (match_dup 3) 0) ! 2770: (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5))) ! 2771: (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0) ! 2772: (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" "")) ! 2773: (match_operand:DI 2 "const_int_operand" ""))) ! 2774: (set (subreg:DI (match_dup 4) 0) ! 2775: (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0))) ! 2776: (set (match_dup 0) (match_dup 4))] ! 2777: "" ! 2778: " ! 2779: { operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1])) ! 2780: << INTVAL (operands[2]))); ! 2781: }") ! 2782: ! 2783: ;; For the unaligned byte case, we use code similar to that in the ! 2784: ;; Architecture book, but reordered to lower the number of registers ! 2785: ;; required. Operand 0 is the address. Operand 1 is the data to store. ! 2786: ;; Operands 2, 3, and 4 are DImode temporaries, where the last two may ! 2787: ;; be the same temporary, if desired. If the address is in a register, ! 2788: ;; operand 2 can be that register. ! 2789: ! 2790: (define_expand "unaligned_storeqi" ! 2791: [(set (match_operand:DI 3 "register_operand" "") ! 2792: (mem:DI (and:DI (match_operand:DI 0 "address_operand" "") ! 2793: (const_int -8)))) ! 2794: (set (match_operand:DI 2 "register_operand" "") ! 2795: (match_dup 0)) ! 2796: (set (match_dup 3) ! 2797: (and:DI (ashift:DI (const_int 255) ! 2798: (ashift:DI (match_dup 2) (const_int 3))) ! 2799: (match_dup 3))) ! 2800: (set (match_operand:DI 4 "register_operand" "") ! 2801: (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "")) ! 2802: (ashift:DI (match_dup 2) (const_int 3)))) ! 2803: (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3))) ! 2804: (set (mem:DI (and:DI (match_dup 0) (const_int -8))) ! 2805: (match_dup 4))] ! 2806: "" ! 2807: "") ! 2808: ! 2809: ;; This is the code for storing into an unaligned short. It uses the same ! 2810: ;; trick as loading from an unaligned short. It needs lots of temporaries. ! 2811: ;; However, during reload, we only have two registers available. So we ! 2812: ;; repeat code so that only two temporaries are available. During RTL ! 2813: ;; generation, we can use different pseudos for each temporary and CSE ! 2814: ;; will remove the redundancies. During reload, we have to settle with ! 2815: ;; what we get. Luckily, unaligned accesses of this kind produced during ! 2816: ;; reload are quite rare. ! 2817: ;; ! 2818: ;; Operand 0 is the address of the memory location. Operand 1 contains the ! 2819: ;; data to store. The rest of the operands are all temporaries, with ! 2820: ;; various overlap possibilities during reload. See reload_outhi for ! 2821: ;; details of this use. ! 2822: ! 2823: (define_expand "unaligned_storehi" ! 2824: [(set (match_operand:DI 2 "register_operand" "") ! 2825: (match_operand:DI 0 "address_operand" "")) ! 2826: (set (match_operand:DI 3 "register_operand" "") ! 2827: (and:DI (match_dup 2) (const_int -7))) ! 2828: (set (match_operand:DI 4 "register_operand" "") ! 2829: (mem:DI (match_dup 3))) ! 2830: (set (match_operand:DI 5 "register_operand" "") ! 2831: (and:DI (ashift:DI (const_int 65535) ! 2832: (ashift:DI (match_dup 2) (const_int 3))) ! 2833: (match_dup 4))) ! 2834: (set (match_operand:DI 6 "register_operand" "") ! 2835: (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "")) ! 2836: (ashift:DI (match_dup 2) (const_int 3)))) ! 2837: (set (match_operand:DI 7 "register_operand" "") ! 2838: (ior:DI (match_dup 5) (match_dup 6))) ! 2839: (set (match_operand:DI 8 "register_operand" "") (match_dup 0)) ! 2840: (set (match_operand:DI 9 "register_operand" "") ! 2841: (and:DI (match_dup 8) (const_int -7))) ! 2842: (set (mem:DI (match_dup 9)) (match_dup 7))] ! 2843: "" ! 2844: "") ! 2845: ! 2846: ;; Here are the define_expand's for QI and HI moves that use the above ! 2847: ;; patterns. We have the normal sets, plus the ones that need scratch ! 2848: ;; registers for reload. ! 2849: ! 2850: (define_expand "movqi" ! 2851: [(set (match_operand:QI 0 "general_operand" "") ! 2852: (match_operand:QI 1 "general_operand" ""))] ! 2853: "" ! 2854: " ! 2855: { extern rtx get_unaligned_address (); ! 2856: ! 2857: /* If the output is not a register, the input must be. */ ! 2858: if (GET_CODE (operands[0]) == MEM) ! 2859: operands[1] = force_reg (QImode, operands[1]); ! 2860: ! 2861: /* Handle four memory cases, unaligned and aligned for either the input ! 2862: or the output. The only case where we can be called during reload is ! 2863: for aligned loads; all other cases require temporaries. */ ! 2864: ! 2865: if (GET_CODE (operands[1]) == MEM ! 2866: || (GET_CODE (operands[1]) == SUBREG ! 2867: && GET_CODE (SUBREG_REG (operands[1])) == MEM) ! 2868: || (reload_in_progress && GET_CODE (operands[1]) == REG ! 2869: && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER) ! 2870: || (reload_in_progress && GET_CODE (operands[1]) == SUBREG ! 2871: && GET_CODE (SUBREG_REG (operands[1])) == REG ! 2872: && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER)) ! 2873: { ! 2874: if (aligned_memory_operand (operands[1], QImode)) ! 2875: { ! 2876: rtx aligned_mem, bitnum; ! 2877: rtx scratch = (reload_in_progress ! 2878: ? gen_rtx (REG, SImode, REGNO (operands[0])) ! 2879: : gen_reg_rtx (SImode)); ! 2880: ! 2881: get_aligned_mem (operands[1], &aligned_mem, &bitnum); ! 2882: ! 2883: emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum, ! 2884: scratch)); ! 2885: } ! 2886: else ! 2887: { ! 2888: /* Don't pass these as parameters since that makes the generated ! 2889: code depend on parameter evaluation order which will cause ! 2890: bootstrap failures. */ ! 2891: ! 2892: rtx temp1 = gen_reg_rtx (DImode); ! 2893: rtx temp2 = gen_reg_rtx (DImode); ! 2894: rtx seq = gen_unaligned_loadqi (operands[0], ! 2895: get_unaligned_address (operands[1]), ! 2896: temp1, temp2); ! 2897: ! 2898: alpha_set_memflags (seq, operands[1]); ! 2899: emit_insn (seq); ! 2900: } ! 2901: ! 2902: DONE; ! 2903: } ! 2904: ! 2905: else if (GET_CODE (operands[0]) == MEM ! 2906: || (GET_CODE (operands[0]) == SUBREG ! 2907: && GET_CODE (SUBREG_REG (operands[0])) == MEM) ! 2908: || (reload_in_progress && GET_CODE (operands[0]) == REG ! 2909: && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER) ! 2910: || (reload_in_progress && GET_CODE (operands[0]) == SUBREG ! 2911: && GET_CODE (SUBREG_REG (operands[0])) == REG ! 2912: && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)) ! 2913: { ! 2914: if (aligned_memory_operand (operands[0], QImode)) ! 2915: { ! 2916: rtx aligned_mem, bitnum; ! 2917: rtx temp1 = gen_reg_rtx (SImode); ! 2918: rtx temp2 = gen_reg_rtx (SImode); ! 2919: ! 2920: get_aligned_mem (operands[0], &aligned_mem, &bitnum); ! 2921: ! 2922: emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum, ! 2923: temp1, temp2)); ! 2924: } ! 2925: else ! 2926: { ! 2927: rtx temp1 = gen_reg_rtx (DImode); ! 2928: rtx temp2 = gen_reg_rtx (DImode); ! 2929: rtx temp3 = gen_reg_rtx (DImode); ! 2930: rtx seq = gen_unaligned_storeqi (get_unaligned_address (operands[0]), ! 2931: operands[1], temp1, temp2, temp3); ! 2932: ! 2933: alpha_set_memflags (seq, operands[0]); ! 2934: emit_insn (seq); ! 2935: } ! 2936: DONE; ! 2937: } ! 2938: }") ! 2939: ! 2940: (define_expand "movhi" ! 2941: [(set (match_operand:HI 0 "general_operand" "") ! 2942: (match_operand:HI 1 "general_operand" ""))] ! 2943: "" ! 2944: " ! 2945: { extern rtx get_unaligned_address (); ! 2946: ! 2947: /* If the output is not a register, the input must be. */ ! 2948: if (GET_CODE (operands[0]) == MEM) ! 2949: operands[1] = force_reg (HImode, operands[1]); ! 2950: ! 2951: /* Handle four memory cases, unaligned and aligned for either the input ! 2952: or the output. The only case where we can be called during reload is ! 2953: for aligned loads; all other cases require temporaries. */ ! 2954: ! 2955: if (GET_CODE (operands[1]) == MEM ! 2956: || (GET_CODE (operands[1]) == SUBREG ! 2957: && GET_CODE (SUBREG_REG (operands[1])) == MEM) ! 2958: || (reload_in_progress && GET_CODE (operands[1]) == REG ! 2959: && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER) ! 2960: || (reload_in_progress && GET_CODE (operands[1]) == SUBREG ! 2961: && GET_CODE (SUBREG_REG (operands[1])) == REG ! 2962: && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER)) ! 2963: { ! 2964: if (aligned_memory_operand (operands[1], HImode)) ! 2965: { ! 2966: rtx aligned_mem, bitnum; ! 2967: rtx scratch = (reload_in_progress ! 2968: ? gen_rtx (REG, SImode, REGNO (operands[0])) ! 2969: : gen_reg_rtx (SImode)); ! 2970: ! 2971: get_aligned_mem (operands[1], &aligned_mem, &bitnum); ! 2972: ! 2973: emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum, ! 2974: scratch)); ! 2975: } ! 2976: else ! 2977: { ! 2978: rtx addr ! 2979: = force_reg (DImode, ! 2980: force_operand (get_unaligned_address (operands[1]), ! 2981: NULL_RTX)); ! 2982: rtx scratch1 = gen_reg_rtx (DImode); ! 2983: rtx scratch2 = gen_reg_rtx (DImode); ! 2984: rtx seq = gen_unaligned_loadhi (operands[0], addr, scratch1, ! 2985: scratch2); ! 2986: ! 2987: alpha_set_memflags (seq, operands[1]); ! 2988: emit_insn (seq); ! 2989: } ! 2990: ! 2991: DONE; ! 2992: } ! 2993: ! 2994: else if (GET_CODE (operands[0]) == MEM ! 2995: || (GET_CODE (operands[0]) == SUBREG ! 2996: && GET_CODE (SUBREG_REG (operands[0])) == MEM) ! 2997: || (reload_in_progress && GET_CODE (operands[0]) == REG ! 2998: && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER) ! 2999: || (reload_in_progress && GET_CODE (operands[0]) == SUBREG ! 3000: && GET_CODE (SUBREG_REG (operands[0])) == REG ! 3001: && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)) ! 3002: { ! 3003: if (aligned_memory_operand (operands[0], HImode)) ! 3004: { ! 3005: rtx aligned_mem, bitnum; ! 3006: rtx temp1 = gen_reg_rtx (SImode); ! 3007: rtx temp2 = gen_reg_rtx (SImode); ! 3008: ! 3009: get_aligned_mem (operands[0], &aligned_mem, &bitnum); ! 3010: ! 3011: emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum, ! 3012: temp1, temp2)); ! 3013: } ! 3014: else ! 3015: { ! 3016: rtx temp1 = gen_reg_rtx (DImode); ! 3017: rtx temp2 = gen_reg_rtx (DImode); ! 3018: rtx temp3 = gen_reg_rtx (DImode); ! 3019: rtx temp4 = gen_reg_rtx (DImode); ! 3020: rtx temp5 = gen_reg_rtx (DImode); ! 3021: rtx temp6 = gen_reg_rtx (DImode); ! 3022: rtx temp7 = gen_reg_rtx (DImode); ! 3023: rtx temp8 = gen_reg_rtx (DImode); ! 3024: rtx seq = gen_unaligned_storehi (get_unaligned_address (operands[0]), ! 3025: operands[1], temp1, temp2,temp3, ! 3026: temp4, temp5, temp6,temp7, temp8); ! 3027: ! 3028: alpha_set_memflags (seq, operands[0]); ! 3029: emit_insn (seq); ! 3030: } ! 3031: ! 3032: DONE; ! 3033: } ! 3034: }") ! 3035: ! 3036: ;; Here are the versions for reload. Note that in the unaligned cases ! 3037: ;; we know that the operand must not be a pseudo-register because stack ! 3038: ;; slots are always aligned references. ! 3039: ! 3040: (define_expand "reload_inqi" ! 3041: [(parallel [(match_operand:QI 0 "register_operand" "=r") ! 3042: (match_operand:QI 1 "unaligned_memory_operand" "m") ! 3043: (match_operand:DI 2 "register_operand" "=&r")])] ! 3044: "" ! 3045: " ! 3046: { extern rtx get_unaligned_address (); ! 3047: rtx addr = get_unaligned_address (operands[1]); ! 3048: rtx seq = gen_unaligned_loadqi (operands[0], addr, operands[2], ! 3049: gen_rtx (REG, DImode, REGNO (operands[0]))); ! 3050: ! 3051: alpha_set_memflags (seq, operands[1]); ! 3052: emit_insn (seq); ! 3053: DONE; ! 3054: }") ! 3055: ! 3056: (define_expand "reload_inhi" ! 3057: [(parallel [(match_operand:HI 0 "register_operand" "=r") ! 3058: (match_operand:HI 1 "unaligned_memory_operand" "m") ! 3059: (match_operand:TI 2 "register_operand" "=&r")])] ! 3060: "" ! 3061: " ! 3062: { extern rtx get_unaligned_address (); ! 3063: rtx addr = get_unaligned_address (operands[1]); ! 3064: rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2])); ! 3065: rtx scratch2 = gen_rtx (REG, DImode, REGNO (operands[2]) + 1); ! 3066: rtx seq; ! 3067: ! 3068: if (GET_CODE (addr) != REG) ! 3069: { ! 3070: emit_insn (gen_rtx (SET, VOIDmode, scratch2, addr)); ! 3071: addr = scratch2; ! 3072: } ! 3073: ! 3074: seq = gen_unaligned_loadhi (operands[0], addr, scratch1, scratch1); ! 3075: alpha_set_memflags (seq, operands[1]); ! 3076: emit_insn (seq); ! 3077: DONE; ! 3078: }") ! 3079: ! 3080: (define_expand "reload_outqi" ! 3081: [(parallel [(match_operand:QI 0 "any_memory_operand" "=m") ! 3082: (match_operand:QI 1 "register_operand" "r") ! 3083: (match_operand:TI 2 "register_operand" "=&r")])] ! 3084: "" ! 3085: " ! 3086: { extern rtx get_unaligned_address (); ! 3087: ! 3088: if (aligned_memory_operand (operands[0], QImode)) ! 3089: { ! 3090: rtx aligned_mem, bitnum; ! 3091: ! 3092: get_aligned_mem (operands[0], &aligned_mem, &bitnum); ! 3093: ! 3094: emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum, ! 3095: gen_rtx (REG, SImode, REGNO (operands[2])), ! 3096: gen_rtx (REG, SImode, ! 3097: REGNO (operands[2]) + 1))); ! 3098: } ! 3099: else ! 3100: { ! 3101: rtx addr = get_unaligned_address (operands[0]); ! 3102: rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2])); ! 3103: rtx scratch2 = gen_rtx (REG, DImode, REGNO (operands[2]) + 1); ! 3104: rtx seq; ! 3105: ! 3106: if (GET_CODE (addr) == REG) ! 3107: scratch1 = addr; ! 3108: ! 3109: seq = gen_unaligned_storeqi (addr, operands[1], scratch1, ! 3110: scratch2, scratch2); ! 3111: alpha_set_memflags (seq, operands[0]); ! 3112: emit_insn (seq); ! 3113: } ! 3114: ! 3115: DONE; ! 3116: }") ! 3117: ! 3118: (define_expand "reload_outhi" ! 3119: [(parallel [(match_operand:HI 0 "any_memory_operand" "=m") ! 3120: (match_operand:HI 1 "register_operand" "r") ! 3121: (match_operand:TI 2 "register_operand" "=&r")])] ! 3122: "" ! 3123: " ! 3124: { extern rtx get_unaligned_address (); ! 3125: ! 3126: if (aligned_memory_operand (operands[0], HImode)) ! 3127: { ! 3128: rtx aligned_mem, bitnum; ! 3129: ! 3130: get_aligned_mem (operands[0], &aligned_mem, &bitnum); ! 3131: ! 3132: emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum, ! 3133: gen_rtx (REG, SImode, REGNO (operands[2])), ! 3134: gen_rtx (REG, SImode, ! 3135: REGNO (operands[2]) + 1))); ! 3136: } ! 3137: else ! 3138: { ! 3139: rtx addr = get_unaligned_address (operands[0]); ! 3140: rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2])); ! 3141: rtx scratch2 = gen_rtx (REG, DImode, REGNO (operands[2]) + 1); ! 3142: rtx scratch_a = GET_CODE (addr) == REG ? addr : scratch1; ! 3143: rtx seq; ! 3144: ! 3145: seq = gen_unaligned_storehi (addr, operands[1], scratch_a, ! 3146: scratch2, scratch2, scratch2, ! 3147: scratch1, scratch2, scratch_a, ! 3148: scratch1); ! 3149: alpha_set_memflags (seq, operands[0]); ! 3150: emit_insn (seq); ! 3151: } ! 3152: ! 3153: DONE; ! 3154: }") ! 3155: ! 3156: ;; Subroutine of stack space allocation. Perform a stack probe. ! 3157: (define_expand "probe_stack" ! 3158: [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))] ! 3159: "" ! 3160: " ! 3161: { ! 3162: operands[0] = gen_rtx (MEM, DImode, plus_constant (stack_pointer_rtx, ! 3163: INTVAL (operands[0]))); ! 3164: MEM_VOLATILE_P (operands[0]) = 1; ! 3165: ! 3166: operands[1] = gen_reg_rtx (DImode); ! 3167: }") ! 3168: ! 3169: ;; This is how we allocate stack space. If we are allocating a ! 3170: ;; constant amount of space and we know it is less than 4096 ! 3171: ;; bytes, we need do nothing. ! 3172: ;; ! 3173: ;; If it is more than 4096 bytes, we need to probe the stack ! 3174: ;; periodically. ! 3175: (define_expand "allocate_stack" ! 3176: [(set (reg:DI 30) ! 3177: (plus:DI (reg:DI 30) ! 3178: (match_operand:DI 0 "reg_or_cint_operand" "")))] ! 3179: "" ! 3180: " ! 3181: { ! 3182: if (GET_CODE (operands[0]) == CONST_INT ! 3183: && INTVAL (operands[0]) < 32768) ! 3184: { ! 3185: if (INTVAL (operands[0]) >= 4096) ! 3186: { ! 3187: /* We do this the same way as in the prologue and generate explicit ! 3188: probes. Then we update the stack by the constant. */ ! 3189: ! 3190: int probed = 4096; ! 3191: ! 3192: emit_insn (gen_probe_stack (GEN_INT (- probed))); ! 3193: while (probed + 8192 < INTVAL (operands[0])) ! 3194: emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192)))); ! 3195: ! 3196: if (probed + 4096 < INTVAL (operands[0])) ! 3197: emit_insn (gen_probe_stack (GEN_INT (- (probed += 4096)))); ! 3198: } ! 3199: ! 3200: operands[0] = GEN_INT (- INTVAL (operands[0])); ! 3201: } ! 3202: else ! 3203: { ! 3204: rtx out_label = 0; ! 3205: rtx loop_label = gen_label_rtx (); ! 3206: rtx count = gen_reg_rtx (DImode); ! 3207: rtx access = gen_reg_rtx (Pmode); ! 3208: rtx memref = gen_rtx (MEM, DImode, access); ! 3209: ! 3210: MEM_VOLATILE_P (memref) = 1; ! 3211: ! 3212: /* If the amount to be allocated is not a constant, we only need to ! 3213: do something special if it is >= 4096. */ ! 3214: ! 3215: if (GET_CODE (operands[0]) != CONST_INT) ! 3216: { ! 3217: operands[0] = force_reg (DImode, operands[0]); ! 3218: out_label = gen_label_rtx (); ! 3219: emit_insn (gen_cmpdi (operands[0], ! 3220: force_reg (DImode, GEN_INT (4096)))); ! 3221: emit_jump_insn (gen_ble (out_label)); ! 3222: ! 3223: /* Compute COUNT = (N + 4096) / 8192. N is known positive. */ ! 3224: emit_insn (gen_adddi3 (count, operands[0], GEN_INT (4096))); ! 3225: emit_insn (gen_lshrdi3 (count, count, GEN_INT (13))); ! 3226: } ! 3227: else ! 3228: emit_move_insn (count, GEN_INT ((INTVAL (operands[0]) + 4096) >> 13)); ! 3229: ! 3230: /* ACCESS = SP + 4096. */ ! 3231: emit_insn (gen_adddi3 (access, stack_pointer_rtx, GEN_INT (4096))); ! 3232: emit_label (loop_label); ! 3233: ! 3234: /* Each iteration subtracts 8192 from ACCESS and references it. */ ! 3235: emit_insn (gen_adddi3 (count, count, constm1_rtx)); ! 3236: emit_insn (gen_adddi3 (access, access, GEN_INT (-8192))); ! 3237: emit_move_insn (gen_reg_rtx (DImode), memref); ! 3238: emit_insn (gen_cmpdi (count, const0_rtx)); ! 3239: emit_jump_insn (gen_bgt (loop_label)); ! 3240: ! 3241: if (out_label) ! 3242: emit_label (out_label); ! 3243: ! 3244: /* We need to subtract operands[0] from SP. We know it isn't a ! 3245: constant less than 32768, so we know we have to load it into ! 3246: a register. */ ! 3247: ! 3248: emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx, ! 3249: force_reg (Pmode, operands[0]))); ! 3250: ! 3251: /* Now, unless we have a constant and we know that we are within ! 3252: 4096 from the end, we need to access sp + 4096. */ ! 3253: if (! (GET_CODE (operands[0]) == CONST_INT ! 3254: && (INTVAL (operands[0]) % 8192) < 4096)) ! 3255: emit_insn (gen_probe_stack (GEN_INT (4096))); ! 3256: ! 3257: DONE; ! 3258: } ! 3259: }")
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.