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