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