|
|
1.1 ! root 1: ;;- Machine description for the Motorola 88000 for GNU C compiler ! 2: ;; Copyright (C) 1988, 1989, 1990, 1991 Free Software Foundation, Inc. ! 3: ;; Contributed by Michael Tiemann ([email protected]) ! 4: ;; Additional changes by Michael Meissner ([email protected]) ! 5: ;; Version 2 port by Tom Wood ([email protected]) ! 6: ! 7: ;; This file is part of GNU CC. ! 8: ! 9: ;; GNU CC is free software; you can redistribute it and/or modify ! 10: ;; it under the terms of the GNU General Public License as published by ! 11: ;; the Free Software Foundation; either version 2, or (at your option) ! 12: ;; any later version. ! 13: ! 14: ;; GNU CC is distributed in the hope that it will be useful, ! 15: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ! 16: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 17: ;; GNU General Public License for more details. ! 18: ! 19: ;; You should have received a copy of the GNU General Public License ! 20: ;; along with GNU CC; see the file COPYING. If not, write to ! 21: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ! 22: ! 23: ! 24: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. ! 25: ! 26: ;; SCCS rev field. This is a NOP, just to get the SCCS id into the ! 27: ;; program image. ! 28: (define_expand "m88k_sccs_id" ! 29: [(match_operand:SI 0 "" "")] ! 30: "" ! 31: "{ static char sccs_id[] = \"@(#)m88k.md 2.3.3.2 12/16/92 08:26:12\"; ! 32: FAIL; }") ! 33: ! 34: ;; Attribute specifications ! 35: ! 36: ; Target CPU. ! 37: (define_attr "cpu" "m88100,m88110,m88000" ! 38: (const (symbol_ref "m88k_cpu"))) ! 39: ! 40: ; Type of each instruction. Default is arithmetic. ! 41: ; I'd like to write the list as this, but genattrtab won't accept it. ! 42: ; ! 43: ; "branch,jump,call, ; flow-control instructions ! 44: ; load,store,loadd,loada, ; data unit instructions ! 45: ; spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv, ; FPU add instructions ! 46: ; spmul,dpmul,imul, ; FPU multiply instructions ! 47: ; arith,bit,mov ; integer unit instructions ! 48: ; marith,weird" ; multi-word instructions ! 49: ! 50: ; Classification of each insn. Some insns of TYPE_BRANCH are multi-word. ! 51: (define_attr "type" ! 52: "branch,jump,call,load,store,loadd,loada,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv,spmul,dpmul,imul,arith,bit,mov,marith,weird" ! 53: (const_string "arith")) ! 54: ! 55: (define_attr "fpu" "yes,no" ! 56: (if_then_else ! 57: (eq_attr "type" "spmul,dpmul,imul,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv") ! 58: (const_string "yes") (const_string "no"))) ! 59: ! 60: ; Length in # of instructions of each insn. The values are not exact, but ! 61: ; are safe. ! 62: (define_attr "length" "" ! 63: (cond [(eq_attr "type" "marith,weird,branch") ! 64: (const_int 2)] ! 65: (const_int 1))) ! 66: ! 67: ; Describe a user's asm statement. ! 68: (define_asm_attributes ! 69: [(set_attr "type" "weird")]) ! 70: ! 71: ; Define the delay slot requirements for branches and calls. ! 72: ; The m88100 annuls instructions if a conditional branch is taken. ! 73: ; For insns of TYPE_BRANCH that are multi-word instructions, the ! 74: ; delay slot applies to the first instruction. ! 75: ! 76: ; @@ For the moment, reorg.c requires that the delay slot of a branch not ! 77: ; be a call or branch. ! 78: ! 79: (define_delay (eq_attr "type" "branch,jump") ! 80: [(and ! 81: (and ! 82: (eq_attr "type" "!branch,jump,call,marith,weird") ; required. ! 83: (eq_attr "type" "!load,loadd")) ; issue as-soon-as-possible. ! 84: (eq_attr "fpu" "no")) ; issue as-soon-as-possible. ! 85: (eq_attr "type" "!call,branch,jump") (nil)]) ; @@ was (const_int 1) ! 86: ! 87: ; output_call supports an unconditional branch in the delay slot of ! 88: ; a call. (@@ Support for this case is expected in reorg.c soon.) ! 89: ! 90: (define_delay (eq_attr "type" "call") ! 91: [(eq_attr "type" "!branch,call,marith,weird") ; required. ! 92: (nil) (nil)]) ! 93: ! 94: ; An abstract block diagram of the function units for the m88100. ! 95: ; ! 96: ; * ! 97: ; | ! 98: ; +---v----+ ! 99: ; | decode | ! 100: ; +-vv-v-v-+ fpu ! 101: ; ,----------'| | `----------------------. ! 102: ; | | | | ,-----. ! 103: ; load | store | | arith | | | ! 104: ; | | | +-v-v-+ | dp source ! 105: ; | | | | fp1 |---' ! 106: ; store | | | div +-v-v-+ ! 107: ; ,------. | | | ,-----. ,-----------' `-----------. ! 108: ; | | | | | | | | | ! 109: ; | +--v---v--+ ,---' | | +-v-v---+ +---v---+ ! 110: ; | | stage 2 | | | `---| add 2 | | mul 2 | ! 111: ; | +---------+ | +--v--+ +-------+ imul +-------+ ! 112: ; | | stage 1 | | | alu | | add 3 | ,--------| mul 3 | ! 113: ; | +---------+ | +--v--+ +-------+ | +-------+ ! 114: ; | | stage 0 | | | | add 4 | | | mul 4 | ! 115: ; | +--v---v--+ | | +---v---+ | +-------+ ! 116: ; | | | | | | | | mul 5 | ! 117: ; | * | | | | | +---v---+ ! 118: ; | | | | | +----v----+ | ! 119: ; | load | | | fp add `------>| fp last |<------' fp mul ! 120: ; | | | | +---v-v--^+ ! 121: ; | | | | | | | ! 122: ; | | | | | `--' dp dest ! 123: ; | | +--v-----v--+ | ! 124: ; | `--->| writeback |<--------------------' ! 125: ; | +--v-----v--+ ! 126: ; | | | ! 127: ; `------------------' * ! 128: ; ! 129: ; The decode unit need not be specified. ! 130: ; Consideration of writeback contention is critical to superb scheduling. ! 131: ; ! 132: ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY ! 133: ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST]) ! 134: ! 135: ; Describing the '100 alu is currently not useful. ! 136: ;(define_function_unit "alu" 1 0 (eq_attr "type" ! 137: ; "!store,marith,weird") 1 0) ! 138: ;(define_function_unit "alu" 1 0 (eq_attr "type" "marith,weird") 2 0) ! 139: ! 140: (define_function_unit "alu" 1 0 ! 141: (and (eq_attr "type" "loada,arith,mov") (eq_attr "cpu" "!m88100")) 2 0) ! 142: (define_function_unit "alu" 1 0 ! 143: (and (eq_attr "type" "marith,weird") (eq_attr "cpu" "!m88100")) 4 0) ! 144: ! 145: (define_function_unit "bit" 1 0 ! 146: (and (eq_attr "type" "bit") (eq_attr "cpu" "!m88100")) 2 2) ! 147: ! 148: (define_function_unit "mem100" 1 0 ! 149: (and (eq_attr "type" "store,loada") (eq_attr "cpu" "m88100")) 1 0) ! 150: (define_function_unit "mem100" 1 0 ! 151: (and (eq_attr "type" "load") (eq_attr "cpu" "m88100")) 3 0) ! 152: (define_function_unit "mem100" 1 0 ! 153: (and (eq_attr "type" "loadd") (eq_attr "cpu" "m88100")) 3 2) ! 154: ! 155: (define_function_unit "mem110" 1 0 ! 156: (and (eq_attr "type" "load,loadd") (eq_attr "cpu" "!m88100")) 3 2) ! 157: (define_function_unit "mem110" 1 0 ! 158: (and (eq_attr "type" "store") (eq_attr "cpu" "!m88100")) 1 2) ! 159: ! 160: ; The times are adjusted to include fp1 and fplast, but then are further ! 161: ; adjusted based on the actual generated code. The notation to the right ! 162: ; is the total latency. A range denotes a group of instructions and/or ! 163: ; conditions (the extra clock of fplast time with some sequences). ! 164: ! 165: (define_function_unit "fpmul100" 1 0 ! 166: (and (eq_attr "type" "spmul") (eq_attr "cpu" "m88100")) 4 0) ; 6-8 ! 167: (define_function_unit "fpmul100" 1 0 ! 168: (and (eq_attr "type" "dpmul") (eq_attr "cpu" "m88100")) 7 0) ; 9-10 ! 169: (define_function_unit "fpmul100" 1 0 ! 170: (and (eq_attr "type" "imul") (eq_attr "cpu" "m88100")) 3 0) ; 4 ! 171: ! 172: (define_function_unit "fpmul110" 1 0 ! 173: (and (eq_attr "type" "imul,spmul,dpmul") ! 174: (eq_attr "cpu" "!m88100")) 5 2) ; 3 ! 175: ! 176: (define_function_unit "fpadd100" 1 5 ! 177: (and (eq_attr "type" "spadd,spcmp") (eq_attr "cpu" "m88100")) 3 0) ; 5-6 ! 178: (define_function_unit "fpadd100" 1 5 ! 179: (and (eq_attr "type" "dpadd,dpcmp") (eq_attr "cpu" "m88100")) 4 0) ; 6-7 ! 180: ! 181: (define_function_unit "fpadd110" 1 0 ! 182: (and (eq_attr "type" "spadd,dpadd") (eq_attr "cpu" "!m88100")) 5 2) ; 3 ! 183: (define_function_unit "fpadd110" 1 0 ! 184: (and (eq_attr "type" "spcmp,dpcmp") (eq_attr "cpu" "!m88100")) 2 2) ; 1 ! 185: ! 186: (define_function_unit "fpadd100" 1 5 ! 187: (and (eq_attr "type" "spdiv") (eq_attr "cpu" "m88100")) 30 0) ; 30-31 ! 188: (define_function_unit "fpadd100" 1 5 ! 189: (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "m88100")) 60 0) ; 60-61 ! 190: (define_function_unit "fpadd100" 1 5 ! 191: (and (eq_attr "type" "idiv") (eq_attr "cpu" "m88100")) 38 0) ; 38 ! 192: ! 193: (define_function_unit "div" 1 1 ! 194: (and (eq_attr "type" "spdiv") (eq_attr "cpu" "!m88100")) 25 2) ; 13 ! 195: (define_function_unit "div" 1 1 ! 196: (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "!m88100")) 45 2) ; 23 ! 197: (define_function_unit "div" 1 1 ! 198: (and (eq_attr "type" "idiv") (eq_attr "cpu" "!m88100")) 35 2) ; 18 ! 199: ! 200: ;; Superoptimizer sequences ! 201: ! 202: ;; geu+: { r = ((unsigned_word) v0 >= (unsigned_word) v1) + v2; } ! 203: ;; subu.co r5,r2,r3 ! 204: ;; addu.cio r6,r4,r0 ! 205: ! 206: (define_split ! 207: [(set (match_operand:SI 0 "register_operand" "=r") ! 208: (minus:SI (match_operand:SI 1 "register_operand" "r") ! 209: (geu:SI (match_operand:SI 2 "register_operand" "r") ! 210: (match_operand:SI 3 "register_operand" "r"))))] ! 211: "" ! 212: [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1)) ! 213: (set (match_dup 0) ! 214: (plus:SI (match_dup 1) ! 215: (unspec:SI [(const_int 0) ! 216: (reg:CC 0)] 0)))] ! 217: "") ! 218: ! 219: ;; leu+: { r = ((unsigned_word) v0 <= (unsigned_word) v1) + v2; } ! 220: ;; subu.co r5,r3,r2 ! 221: ;; addu.cio r6,r4,r0 ! 222: ! 223: (define_split ! 224: [(set (match_operand:SI 0 "register_operand" "=r") ! 225: (minus:SI (match_operand:SI 1 "register_operand" "r") ! 226: (leu:SI (match_operand:SI 3 "register_operand" "r") ! 227: (match_operand:SI 2 "register_operand" "r"))))] ! 228: "" ! 229: [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1)) ! 230: (set (match_dup 0) ! 231: (plus:SI (match_dup 1) ! 232: (unspec:SI [(const_int 0) ! 233: (reg:CC 0)] 0)))] ! 234: "") ! 235: ! 236: ;; eq0+: { r = (v0 == 0) + v1; } ! 237: ;; subu.co r4,r0,r2 ! 238: ;; addu.cio r5,r3,r0 ! 239: ! 240: (define_split ! 241: [(set (match_operand:SI 0 "register_operand" "=r") ! 242: (minus:SI (match_operand:SI 1 "register_operand" "r") ! 243: (eq:SI (match_operand:SI 2 "register_operand" "r") ! 244: (const_int 0))))] ! 245: "" ! 246: [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1)) ! 247: (set (match_dup 0) ! 248: (plus:SI (match_dup 1) ! 249: (unspec:SI [(const_int 0) ! 250: (reg:CC 0)] 0)))] ! 251: "") ! 252: ! 253: ;; ltu-: { r = v2 - ((unsigned_word) v0 < (unsigned_word) v1); } ! 254: ;; subu.co r5,r2,r3 ! 255: ;; subu.cio r6,r4,r0 ! 256: ! 257: (define_split ! 258: [(set (match_operand:SI 0 "register_operand" "=r") ! 259: (plus:SI (ltu:SI (match_operand:SI 2 "register_operand" "r") ! 260: (match_operand:SI 3 "register_operand" "r")) ! 261: (match_operand:SI 1 "register_operand" "r")))] ! 262: "" ! 263: [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1)) ! 264: (set (match_dup 0) ! 265: (minus:SI (match_dup 1) ! 266: (unspec:SI [(const_int 0) ! 267: (reg:CC 0)] 1)))] ! 268: "") ! 269: ! 270: ;; gtu-: { r = v2 - ((unsigned_word) v0 > (unsigned_word) v1); } ! 271: ;; subu.co r5,r3,r2 ! 272: ;; subu.cio r6,r4,r0 ! 273: ! 274: (define_split ! 275: [(set (match_operand:SI 0 "register_operand" "=r") ! 276: (plus:SI (gtu:SI (match_operand:SI 3 "register_operand" "r") ! 277: (match_operand:SI 2 "register_operand" "r")) ! 278: (match_operand:SI 1 "register_operand" "r")))] ! 279: "" ! 280: [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1)) ! 281: (set (match_dup 0) ! 282: (minus:SI (match_dup 1) ! 283: (unspec:SI [(const_int 0) ! 284: (reg:CC 0)] 1)))] ! 285: "") ! 286: ! 287: ;; ne0-: { r = v1 - (v0 != 0); } ! 288: ;; subu.co r4,r0,r2 ! 289: ;; subu.cio r5,r3,r0 ! 290: ! 291: (define_split ! 292: [(set (match_operand:SI 0 "register_operand" "=r") ! 293: (plus:SI (ne:SI (match_operand:SI 2 "register_operand" "r") ! 294: (const_int 0)) ! 295: (match_operand:SI 1 "register_operand" "r")))] ! 296: "" ! 297: [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1)) ! 298: (set (match_dup 0) ! 299: (minus:SI (match_dup 1) ! 300: (unspec:SI [(const_int 0) ! 301: (reg:CC 0)] 1)))] ! 302: "") ! 303: ! 304: ;; ges0-: { r = v1 - ((signed_word) v0 >= 0); } ! 305: ;; addu.co r4,r2,r2 ! 306: ;; subu.cio r5,r3,r0 ! 307: ! 308: (define_split ! 309: [(set (match_operand:SI 0 "register_operand" "=r") ! 310: (minus:SI (match_operand:SI 1 "register_operand" "r") ! 311: (xor:SI (lshiftrt:SI ! 312: (match_operand:SI 2 "register_operand" "r") ! 313: (const_int 31)) ! 314: (const_int 1))))] ! 315: "" ! 316: [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 2)] 0)) ! 317: (set (match_dup 0) ! 318: (minus:SI (match_dup 1) ! 319: (unspec:SI [(const_int 0) ! 320: (reg:CC 0)] 1)))] ! 321: "") ! 322: ! 323: ;; This rich set of complex patterns are mostly due to Torbjorn Granlund ! 324: ;; ([email protected]). They've changed since then, so don't complain to him ! 325: ;; if they don't work right. ! 326: ! 327: ;; Regarding shifts, gen_lshlsi3 generates ASHIFT. LSHIFT opcodes are ! 328: ;; not produced and should not normally occur. Also, the gen functions ! 329: ;; produce the necessary insns to support TARGET_*_LARGE_SHIFT, so nothing ! 330: ;; special needs to be done here. ! 331: ! 332: ;; Optimize possible cases of the set instruction. ! 333: ! 334: (define_insn "" ! 335: [(set (match_operand:SI 0 "register_operand" "=r") ! 336: (ashift:SI (const_int -1) ! 337: (match_operand:SI 1 "register_operand" "r")))] ! 338: "" ! 339: "set %0,%#r0,%1" ! 340: [(set_attr "type" "bit")]) ! 341: ! 342: (define_insn "" ! 343: [(set (match_operand:SI 0 "register_operand" "=r") ! 344: (ior:SI (ashift:SI (const_int -1) ! 345: (match_operand:SI 1 "register_operand" "r")) ! 346: (match_operand:SI 2 "register_operand" "r")))] ! 347: "" ! 348: "set %0,%2,%1" ! 349: [(set_attr "type" "bit")]) ! 350: ! 351: (define_insn "" ! 352: [(set (match_operand:SI 0 "register_operand" "=r") ! 353: (ior:SI (match_operand:SI 1 "register_operand" "r") ! 354: (ashift:SI (const_int -1) ! 355: (match_operand:SI 2 "register_operand" "r"))))] ! 356: "" ! 357: "set %0,%1,%2" ! 358: [(set_attr "type" "bit")]) ! 359: ! 360: ;; Optimize possible cases of the mak instruction. ! 361: ! 362: (define_insn "" ! 363: [(set (match_operand:SI 0 "register_operand" "=r") ! 364: (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r") ! 365: (match_operand:SI 2 "int5_operand" "")) ! 366: (match_operand:SI 3 "immediate_operand" "n")))] ! 367: "mak_mask_p (INTVAL (operands[3]) >> INTVAL (operands[2]))" ! 368: "* ! 369: { ! 370: operands[4] = gen_rtx (CONST_INT, SImode, ! 371: exact_log2 (1 + (INTVAL (operands[3]) ! 372: >> INTVAL(operands[2])))); ! 373: return \"mak %0,%1,%4<%2>\"; ! 374: }" ! 375: [(set_attr "type" "bit")]) ! 376: ! 377: ;; Optimize possible cases of output_and. ! 378: ! 379: (define_insn "" ! 380: [(set (match_operand:SI 0 "register_operand" "=r") ! 381: (ashift:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r") ! 382: (match_operand:SI 2 "int5_operand" "") ! 383: (match_operand:SI 3 "int5_operand" "")) ! 384: (match_operand:SI 4 "int5_operand" "")))] ! 385: "INTVAL (operands[2]) + INTVAL (operands[3]) + INTVAL (operands[4]) == 32" ! 386: "* ! 387: { ! 388: operands[2] ! 389: = gen_rtx (CONST_INT, SImode, ! 390: ((1 << INTVAL (operands[2])) - 1) << INTVAL (operands[4])); ! 391: return output_and (operands); ! 392: }" ! 393: [(set_attr "type" "marith")]) ; arith,bit,marith. length is 1 or 2. ! 394: ! 395: ;; Improve logical operations on compare words ! 396: ;; ! 397: ;; We define all logical operations on CCmode values to preserve the pairwise ! 398: ;; relationship of the compare bits. This allows a future branch prediction ! 399: ;; pass the degree of freedom needed to change and/bb0-le into or/bb1-gt. ! 400: ;; ! 401: ;; Opportunities arise when conditional expressions using && and || are made ! 402: ;; unconditional. When these are used to branch, the sequence is ! 403: ;; cmp/cmp/extu/extu/{and,or}/bcnd-{eq0,ne0}. When these are used to create ! 404: ;; a value, the sequence is cmp/cmp/extu/extu/{and,or} for 1 or 0 or ! 405: ;; cmp/cmp/ext/ext/{and,or} for -1 or 0. ! 406: ;; ! 407: ;; When the extracted conditions are the same, the define_split patterns ! 408: ;; below change extu/extu/{and,or} into {and,or}/extu. If the reversed ! 409: ;; conditions match, one compare word can be complimented, resulting in ! 410: ;; {and.c,or.c}/extu. These changes are done for ext/ext/{and,or} as well. ! 411: ;; If the conditions don't line up, one can be rotated. To keep the pairwise ! 412: ;; relationship, it may be necessary to both rotate and compliment. Rotating ! 413: ;; makes branching cheaper, but doesn't help (or hurt) creating a value, so ! 414: ;; we don't do this for ext/ext/{and,or}. ! 415: ;; ! 416: ;; These changes result in the sequence extu/bcnd-{eq0,ne0} which is combined ! 417: ;; into an alternate form of bb0 and bb1. ! 418: ! 419: (define_split ! 420: [(set (match_operand:SI 0 "register_operand" "=r") ! 421: (ior:SI (neg:SI ! 422: (match_operator 1 "relop" ! 423: [(match_operand:CC 2 "register_operand" "%r") ! 424: (const_int 0)])) ! 425: (neg:SI ! 426: (match_operator 3 "relop" ! 427: [(match_operand:CC 4 "register_operand" "r") ! 428: (const_int 0)])))) ! 429: (clobber (match_operand:SI 5 "register_operand" "=r"))] ! 430: "" ! 431: [(set (match_dup 5) ! 432: (ior:CC (match_dup 4) ! 433: (match_dup 2))) ! 434: (set (match_dup 0) ! 435: (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))] ! 436: "operands[5] = gen_rtx (SUBREG, CCmode, operands[5], 0); ! 437: if (GET_CODE (operands[1]) == GET_CODE (operands[3])) ! 438: ; /* The conditions match. */ ! 439: else if (GET_CODE (operands[1]) ! 440: == reverse_condition (GET_CODE (operands[3]))) ! 441: /* Reverse the condition by complimenting the compare word. */ ! 442: operands[4] = gen_rtx (NOT, CCmode, operands[4]); ! 443: else ! 444: { ! 445: /* Make the condition pairs line up by rotating the compare word. */ ! 446: int cv1 = condition_value (operands[1]); ! 447: int cv2 = condition_value (operands[3]); ! 448: ! 449: operands[4] = gen_rtx (ROTATE, CCmode, operands[4], ! 450: gen_rtx (CONST_INT, VOIDmode, ! 451: ((cv2 & ~1) - (cv1 & ~1)) & 0x1f)); ! 452: /* Reverse the condition if needed. */ ! 453: if ((cv1 & 1) != (cv2 & 1)) ! 454: operands[4] = gen_rtx (NOT, CCmode, operands[4]); ! 455: }") ! 456: ! 457: (define_split ! 458: [(set (match_operand:SI 0 "register_operand" "=r") ! 459: (ior:SI (match_operator 1 "relop" ! 460: [(match_operand:CC 2 "register_operand" "%r") ! 461: (const_int 0)]) ! 462: (match_operator 3 "relop" ! 463: [(match_operand:CC 4 "register_operand" "r") ! 464: (const_int 0)]))) ! 465: (clobber (match_operand:SI 5 "register_operand" "=r"))] ! 466: "GET_CODE (operands[1]) == GET_CODE (operands[3]) ! 467: || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))" ! 468: [(set (match_dup 5) ! 469: (ior:CC (match_dup 4) ! 470: (match_dup 2))) ! 471: (set (match_dup 0) ! 472: (match_op_dup 1 [(match_dup 5) (const_int 0)]))] ! 473: "operands[5] = gen_rtx (SUBREG, CCmode, operands[5], 0); ! 474: /* Reverse the condition by complimenting the compare word. */ ! 475: if (GET_CODE (operands[1]) != GET_CODE (operands[3])) ! 476: operands[4] = gen_rtx (NOT, CCmode, operands[4]);") ! 477: ! 478: (define_split ! 479: [(set (match_operand:SI 0 "register_operand" "=r") ! 480: (and:SI (neg:SI ! 481: (match_operator 1 "relop" ! 482: [(match_operand:CC 2 "register_operand" "%r") ! 483: (const_int 0)])) ! 484: (neg:SI ! 485: (match_operator 3 "relop" ! 486: [(match_operand:CC 4 "register_operand" "r") ! 487: (const_int 0)])))) ! 488: (clobber (match_operand:SI 5 "register_operand" "=r"))] ! 489: "" ! 490: [(set (match_dup 5) ! 491: (and:CC (match_dup 4) ! 492: (match_dup 2))) ! 493: (set (match_dup 0) ! 494: (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))] ! 495: "operands[5] = gen_rtx (SUBREG, CCmode, operands[5], 0); ! 496: if (GET_CODE (operands[1]) == GET_CODE (operands[3])) ! 497: ; /* The conditions match. */ ! 498: else if (GET_CODE (operands[1]) ! 499: == reverse_condition (GET_CODE (operands[3]))) ! 500: /* Reverse the condition by complimenting the compare word. */ ! 501: operands[4] = gen_rtx (NOT, CCmode, operands[4]); ! 502: else ! 503: { ! 504: /* Make the condition pairs line up by rotating the compare word. */ ! 505: int cv1 = condition_value (operands[1]); ! 506: int cv2 = condition_value (operands[3]); ! 507: ! 508: operands[4] = gen_rtx (ROTATE, CCmode, operands[4], ! 509: gen_rtx (CONST_INT, VOIDmode, ! 510: ((cv2 & ~1) - (cv1 & ~1)) & 0x1f)); ! 511: /* Reverse the condition if needed. */ ! 512: if ((cv1 & 1) != (cv2 & 1)) ! 513: operands[4] = gen_rtx (NOT, CCmode, operands[4]); ! 514: }") ! 515: ! 516: (define_split ! 517: [(set (match_operand:SI 0 "register_operand" "=r") ! 518: (and:SI (match_operator 1 "relop" ! 519: [(match_operand:CC 2 "register_operand" "%r") ! 520: (const_int 0)]) ! 521: (match_operator 3 "relop" ! 522: [(match_operand:CC 4 "register_operand" "r") ! 523: (const_int 0)]))) ! 524: (clobber (match_operand:SI 5 "register_operand" "=r"))] ! 525: "GET_CODE (operands[1]) == GET_CODE (operands[3]) ! 526: || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))" ! 527: [(set (match_dup 5) ! 528: (and:CC (match_dup 4) ! 529: (match_dup 2))) ! 530: (set (match_dup 0) ! 531: (match_op_dup 1 [(match_dup 5) (const_int 0)]))] ! 532: "operands[5] = gen_rtx (SUBREG, CCmode, operands[5], 0); ! 533: /* Reverse the condition by complimenting the compare word. */ ! 534: if (GET_CODE (operands[1]) != GET_CODE (operands[3])) ! 535: operands[4] = gen_rtx (NOT, CCmode, operands[4]);") ! 536: ! 537: ;; Logical operations on compare words. ! 538: ! 539: (define_insn "" ! 540: [(set (match_operand:CC 0 "register_operand" "=r") ! 541: (and:CC (not:CC (match_operand:CC 1 "register_operand" "r")) ! 542: (match_operand:CC 2 "register_operand" "r")))] ! 543: "" ! 544: "and.c %0,%2,%1") ! 545: ! 546: ! 547: (define_insn "" ! 548: [(set (match_operand:CC 0 "register_operand" "=r") ! 549: (and:CC (match_operand:CC 1 "register_operand" "%r") ! 550: (match_operand:CC 2 "register_operand" "r")))] ! 551: "" ! 552: "and %0,%1,%2") ! 553: ! 554: (define_insn "" ! 555: [(set (match_operand:CC 0 "register_operand" "=r") ! 556: (ior:CC (not:CC (match_operand:CC 1 "register_operand" "r")) ! 557: (match_operand:CC 2 "register_operand" "r")))] ! 558: "" ! 559: "or.c %0,%2,%1") ! 560: ! 561: (define_insn "" ! 562: [(set (match_operand:CC 0 "register_operand" "=r") ! 563: (ior:CC (match_operand:CC 1 "register_operand" "%r") ! 564: (match_operand:CC 2 "register_operand" "r")))] ! 565: "" ! 566: "or %0,%1,%2") ! 567: ! 568: (define_insn "" ! 569: [(set (match_operand:CC 0 "register_operand" "=r") ! 570: (rotate:CC (match_operand:CC 1 "register_operand" "r") ! 571: (match_operand:CC 2 "int5_operand" "")))] ! 572: "" ! 573: "rot %0,%1,%2" ! 574: [(set_attr "type" "bit")]) ! 575: ! 576: ;; rotate/and[.c] and rotate/ior[.c] ! 577: ! 578: (define_split ! 579: [(set (match_operand:CC 0 "register_operand" "=r") ! 580: (ior:CC (rotate:CC (match_operand:CC 1 "register_operand" "r") ! 581: (match_operand:CC 2 "int5_operand" "")) ! 582: (match_operand:CC 3 "register_operand" "r"))) ! 583: (clobber (match_operand:CC 4 "register_operand" "=r"))] ! 584: "" ! 585: [(set (match_dup 4) ! 586: (rotate:CC (match_dup 1) (match_dup 2))) ! 587: (set (match_dup 0) ! 588: (ior:CC (match_dup 4) (match_dup 3)))] ! 589: "") ! 590: ! 591: (define_insn "" ! 592: [(set (match_operand:CC 0 "register_operand" "=r") ! 593: (ior:CC (rotate:CC (match_operand:CC 1 "register_operand" "r") ! 594: (match_operand:CC 2 "int5_operand" "")) ! 595: (match_operand:CC 3 "register_operand" "r"))) ! 596: (clobber (match_scratch:CC 4 "=r"))] ! 597: "" ! 598: "#") ! 599: ! 600: (define_split ! 601: [(set (match_operand:CC 0 "register_operand" "=r") ! 602: (ior:CC (not:CC (rotate:CC (match_operand:CC 1 "register_operand" "r") ! 603: (match_operand:CC 2 "int5_operand" ""))) ! 604: (match_operand:CC 3 "register_operand" "r"))) ! 605: (clobber (match_operand:CC 4 "register_operand" "=r"))] ! 606: "" ! 607: [(set (match_dup 4) ! 608: (rotate:CC (match_dup 1) (match_dup 2))) ! 609: (set (match_dup 0) ! 610: (ior:CC (not:CC (match_dup 4)) (match_dup 3)))] ! 611: "") ! 612: ! 613: (define_insn "" ! 614: [(set (match_operand:CC 0 "register_operand" "=r") ! 615: (ior:CC (not:CC (rotate:CC (match_operand:CC 1 "register_operand" "r") ! 616: (match_operand:CC 2 "int5_operand" ""))) ! 617: (match_operand:CC 3 "register_operand" "r"))) ! 618: (clobber (match_scratch:CC 4 "=r"))] ! 619: "" ! 620: "#") ! 621: ! 622: (define_split ! 623: [(set (match_operand:CC 0 "register_operand" "=r") ! 624: (and:CC (rotate:CC (match_operand:CC 1 "register_operand" "r") ! 625: (match_operand:CC 2 "int5_operand" "")) ! 626: (match_operand:CC 3 "register_operand" "r"))) ! 627: (clobber (match_operand:CC 4 "register_operand" "=r"))] ! 628: "" ! 629: [(set (match_dup 4) ! 630: (rotate:CC (match_dup 1) (match_dup 2))) ! 631: (set (match_dup 0) ! 632: (and:CC (match_dup 4) (match_dup 3)))] ! 633: "") ! 634: ! 635: (define_insn "" ! 636: [(set (match_operand:CC 0 "register_operand" "=r") ! 637: (and:CC (rotate:CC (match_operand:CC 1 "register_operand" "r") ! 638: (match_operand:CC 2 "int5_operand" "")) ! 639: (match_operand:CC 3 "register_operand" "r"))) ! 640: (clobber (match_scratch:CC 4 "=r"))] ! 641: "" ! 642: "#") ! 643: ! 644: (define_split ! 645: [(set (match_operand:CC 0 "register_operand" "=r") ! 646: (and:CC (not:CC (rotate:CC (match_operand:CC 1 "register_operand" "r") ! 647: (match_operand:CC 2 "int5_operand" ""))) ! 648: (match_operand:CC 3 "register_operand" "r"))) ! 649: (clobber (match_operand:CC 4 "register_operand" "=r"))] ! 650: "" ! 651: [(set (match_dup 4) ! 652: (rotate:CC (match_dup 1) (match_dup 2))) ! 653: (set (match_dup 0) ! 654: (and:CC (not:CC (match_dup 4)) (match_dup 3)))] ! 655: "") ! 656: ! 657: (define_insn "" ! 658: [(set (match_operand:CC 0 "register_operand" "=r") ! 659: (and:CC (not:CC (rotate:CC (match_operand:CC 1 "register_operand" "r") ! 660: (match_operand:CC 2 "int5_operand" ""))) ! 661: (match_operand:CC 3 "register_operand" "r"))) ! 662: (clobber (match_scratch:CC 4 "=r"))] ! 663: "" ! 664: "#") ! 665: ! 666: ;; Recognize bcnd instructions for integer values. This is distinguished ! 667: ;; from a conditional branch instruction (below) with SImode instead of ! 668: ;; CCmode. ! 669: ! 670: (define_insn "" ! 671: [(set (pc) ! 672: (if_then_else ! 673: (match_operator 0 "relop_no_unsigned" ! 674: [(match_operand:SI 1 "register_operand" "r") ! 675: (const_int 0)]) ! 676: (match_operand 2 "pc_or_label_ref" "") ! 677: (match_operand 3 "pc_or_label_ref" "")))] ! 678: "" ! 679: "bcnd%. %R3%B0,%1,%P2%P3" ! 680: [(set_attr "type" "branch")]) ! 681: ! 682: ;; Recognize tests for sign and zero. ! 683: ! 684: (define_insn "" ! 685: [(set (pc) ! 686: (if_then_else ! 687: (match_operator 0 "equality_op" ! 688: [(match_operand:SI 1 "register_operand" "r") ! 689: (const_int -2147483648)]) ! 690: (match_operand 2 "pc_or_label_ref" "") ! 691: (match_operand 3 "pc_or_label_ref" "")))] ! 692: "" ! 693: "bcnd%. %R3%E0,%1,%P2%P3" ! 694: [(set_attr "type" "branch")]) ! 695: ! 696: (define_insn "" ! 697: [(set (pc) ! 698: (if_then_else ! 699: (match_operator 0 "equality_op" ! 700: [(zero_extract:SI ! 701: (match_operand:SI 1 "register_operand" "r") ! 702: (const_int 31) ! 703: (const_int 1)) ! 704: (const_int 0)]) ! 705: (match_operand 2 "pc_or_label_ref" "") ! 706: (match_operand 3 "pc_or_label_ref" "")))] ! 707: "" ! 708: "bcnd%. %R3%D0,%1,%P2%P3" ! 709: [(set_attr "type" "branch")]) ! 710: ! 711: ;; Recognize bcnd instructions for double integer values ! 712: ! 713: (define_insn "" ! 714: [(set (pc) ! 715: (if_then_else ! 716: (match_operator 0 "relop_no_unsigned" ! 717: [(sign_extend:DI ! 718: (match_operand:SI 1 "register_operand" "r")) ! 719: (const_int 0)]) ! 720: (match_operand 2 "pc_or_label_ref" "") ! 721: (match_operand 3 "pc_or_label_ref" "")))] ! 722: "" ! 723: "bcnd%. %R3%B0,%1,%P2%P3" ! 724: [(set_attr "type" "branch")]) ! 725: ! 726: (define_insn "" ! 727: [(set (pc) ! 728: (if_then_else ! 729: (match_operator 0 "equality_op" ! 730: [(zero_extend:DI ! 731: (match_operand:SI 1 "register_operand" "r")) ! 732: (const_int 0)]) ! 733: (match_operand 2 "pc_or_label_ref" "") ! 734: (match_operand 3 "pc_or_label_ref" "")))] ! 735: "" ! 736: "bcnd%. %R3%B0,%1,%P2%P3" ! 737: [(set_attr "type" "branch")]) ! 738: ! 739: ; @@ I doubt this is interesting until cmpdi is provided. Anyway, it needs ! 740: ; to be reworked. ! 741: ; ! 742: ;(define_insn "" ! 743: ; [(set (pc) ! 744: ; (if_then_else ! 745: ; (match_operator 0 "relop_no_unsigned" ! 746: ; [(match_operand:DI 1 "register_operand" "r") ! 747: ; (const_int 0)]) ! 748: ; (match_operand 2 "pc_or_label_ref" "") ! 749: ; (match_operand 3 "pc_or_label_ref" "")))] ! 750: ; "" ! 751: ; "* ! 752: ;{ ! 753: ; switch (GET_CODE (operands[0])) ! 754: ; { ! 755: ; case EQ: ! 756: ; case NE: ! 757: ; /* I'm not sure if it's safe to use .n here. */ ! 758: ; return \"or %!,%1,%d1\;bcnd %R3%B0,%!,%P2%P3\"; ! 759: ; case GE: ! 760: ; case LT: ! 761: ; return \"bcnd%. %R3%B0,%1,%P2%P3\"; ! 762: ; case GT: ! 763: ; { ! 764: ; rtx op2 = operands[2]; ! 765: ; operands[2] = operands[3]; ! 766: ; operands[3] = op2; ! 767: ; } ! 768: ; case LE: ! 769: ; if (GET_CODE (operands[3]) == LABEL_REF) ! 770: ; { ! 771: ; int label_num; ! 772: ; operands[2] = gen_label_rtx (); ! 773: ; label_num = XINT (operands[2], 3); ! 774: ; output_asm_insn ! 775: ; (\"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#ne0,%!,%3\", operands); ! 776: ; output_label (label_num); ! 777: ; return \"\"; ! 778: ; } ! 779: ; else ! 780: ; return \"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#eq0,%!,%2\"; ! 781: ; } ! 782: ;}") ! 783: ! 784: ;; Recognize bcnd instructions for single precision float values ! 785: ;; Exclude relational operations as they must signal NaNs. ! 786: ! 787: ;; @@ These bcnd insns for float and double values don't seem to be recognized. ! 788: ! 789: (define_insn "" ! 790: [(set (pc) ! 791: (if_then_else ! 792: (match_operator 0 "equality_op" ! 793: [(float_extend:DF ! 794: (match_operand:SF 1 "register_operand" "r")) ! 795: (const_int 0)]) ! 796: (match_operand 2 "pc_or_label_ref" "") ! 797: (match_operand 3 "pc_or_label_ref" "")))] ! 798: "" ! 799: "bcnd%. %R3%D0,%1,%P2%P3" ! 800: [(set_attr "type" "branch")]) ! 801: ! 802: (define_insn "" ! 803: [(set (pc) ! 804: (if_then_else ! 805: (match_operator 0 "equality_op" ! 806: [(match_operand:SF 1 "register_operand" "r") ! 807: (const_int 0)]) ! 808: (match_operand 2 "pc_or_label_ref" "") ! 809: (match_operand 3 "pc_or_label_ref" "")))] ! 810: "" ! 811: "bcnd%. %R3%D0,%1,%P2%P3" ! 812: [(set_attr "type" "branch")]) ! 813: ! 814: ;; Recognize bcnd instructions for double precision float values ! 815: ;; Exclude relational operations as they must signal NaNs. ! 816: ! 817: (define_insn "" ! 818: [(set (pc) ! 819: (if_then_else ! 820: (match_operator 0 "equality_op" ! 821: [(match_operand:DF 1 "register_operand" "r") ! 822: (const_int 0)]) ! 823: (match_operand 2 "pc_or_label_ref" "") ! 824: (match_operand 3 "pc_or_label_ref" "")))] ! 825: "" ! 826: "* ! 827: { ! 828: int label_num; ! 829: ! 830: if (GET_CODE (operands[0]) == NE) ! 831: { ! 832: rtx op2 = operands[2]; ! 833: operands[2] = operands[3]; ! 834: operands[3] = op2; ! 835: } ! 836: if (GET_CODE (operands[3]) == LABEL_REF) ! 837: return \"bcnd 0x5,%1,%3\;bcnd %#ne0,%d1,%3\"; ! 838: ! 839: operands[3] = gen_label_rtx (); ! 840: label_num = XINT (operands[3], 3); ! 841: output_asm_insn (\"bcnd 0x5,%1,%3\;bcnd %#eq0,%d1,%2\", operands); ! 842: output_label (label_num); ! 843: return \"\"; ! 844: }" ! 845: [(set_attr "type" "weird") ! 846: (set_attr "length" "3")]) ! 847: ! 848: ;; Recognize bb0 and bb1 instructions. These use two unusual template ! 849: ;; patterns, %Lx and %Px. %Lx outputs a 1 if operand `x' is a LABEL_REF ! 850: ;; otherwise it outputs a 0. It then may print ".n" if the delay slot ! 851: ;; is used. %Px does noting if `x' is PC and outputs the operand if `x' ! 852: ;; is a LABEL_REF. ! 853: ! 854: (define_insn "" ! 855: [(set (pc) ! 856: (if_then_else ! 857: (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "r") ! 858: (const_int 1) ! 859: (match_operand:SI 1 "int5_operand" "")) ! 860: (const_int 0)) ! 861: (match_operand 2 "pc_or_label_ref" "") ! 862: (match_operand 3 "pc_or_label_ref" "")))] ! 863: "" ! 864: "bb%L2 (31-%1),%0,%P2%P3" ! 865: [(set_attr "type" "branch")]) ! 866: ! 867: (define_insn "" ! 868: [(set (pc) ! 869: (if_then_else ! 870: (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "r") ! 871: (const_int 1) ! 872: (match_operand:SI 1 "int5_operand" "")) ! 873: (const_int 0)) ! 874: (match_operand 2 "pc_or_label_ref" "") ! 875: (match_operand 3 "pc_or_label_ref" "")))] ! 876: "" ! 877: "bb%L3 (31-%1),%0,%P2%P3" ! 878: [(set_attr "type" "branch")]) ! 879: ! 880: (define_insn "" ! 881: [(set (pc) ! 882: (if_then_else ! 883: (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r") ! 884: (const_int 1) ! 885: (match_operand:SI 1 "int5_operand" "")) ! 886: (const_int 0)) ! 887: (match_operand 2 "pc_or_label_ref" "") ! 888: (match_operand 3 "pc_or_label_ref" "")))] ! 889: "" ! 890: "bb%L2 (31-%1),%0,%P2%P3" ! 891: [(set_attr "type" "branch")]) ! 892: ! 893: (define_insn "" ! 894: [(set (pc) ! 895: (if_then_else ! 896: (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r") ! 897: (const_int 1) ! 898: (match_operand:SI 1 "int5_operand" "")) ! 899: (const_int 0)) ! 900: (match_operand 2 "pc_or_label_ref" "") ! 901: (match_operand 3 "pc_or_label_ref" "")))] ! 902: "" ! 903: "bb%L3 (31-%1),%0,%P2%P3" ! 904: [(set_attr "type" "branch")]) ! 905: ! 906: (define_insn "" ! 907: [(set (pc) ! 908: (if_then_else ! 909: (eq (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r") ! 910: (match_operand:SI 1 "reg_or_bbx_mask_operand" "n")) ! 911: (const_int 0)) ! 912: (match_operand 2 "pc_or_label_ref" "") ! 913: (match_operand 3 "pc_or_label_ref" "")))] ! 914: "(GET_CODE (operands[0]) == CONST_INT) ! 915: != (GET_CODE (operands[1]) == CONST_INT)" ! 916: "bb%L3 %p1,%0,%P2%P3" ! 917: [(set_attr "type" "branch")]) ! 918: ! 919: (define_insn "" ! 920: [(set (pc) ! 921: (if_then_else ! 922: (ne (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r") ! 923: (match_operand:SI 1 "reg_or_bbx_mask_operand" "n")) ! 924: (const_int 0)) ! 925: (match_operand 2 "pc_or_label_ref" "") ! 926: (match_operand 3 "pc_or_label_ref" "")))] ! 927: "(GET_CODE (operands[0]) == CONST_INT) ! 928: != (GET_CODE (operands[1]) == CONST_INT)" ! 929: "bb%L2 %p1,%0,%P2%P3" ! 930: [(set_attr "type" "branch")]) ! 931: ! 932: ;; The comparison operations store the comparison into a register and ! 933: ;; record that register. The following Bxx or Sxx insn uses that ! 934: ;; register as an input. To facilitate use of bcnd instead of cmp/bb1, ! 935: ;; cmpsi records it's operands and produces no code when any operand ! 936: ;; is constant. In this case, the Bxx insns use gen_bcnd and the ! 937: ;; Sxx insns use gen_test to ensure a cmp has been emitted. ! 938: ;; ! 939: ;; This could also be done for SFmode and DFmode having only beq and bne ! 940: ;; use gen_bcnd. The others must signal NaNs. It seems though that zero ! 941: ;; has already been copied into a register. ! 942: ;; ! 943: ;; cmpsi/beq and cmpsi/bne can always be done with bcnd if any operand ! 944: ;; is a constant. (This idea is due to Torbjorn Granlund.) Others can ! 945: ;; use bcnd only if an operand is zero. ! 946: ;; ! 947: ;; It is necessary to distinguish a register holding condition codes. ! 948: ;; This is done by context. ! 949: ! 950: (define_expand "test" ! 951: [(set (match_dup 2) ! 952: (compare:CC (match_operand 0 "" "") ! 953: (match_operand 1 "" "")))] ! 954: "" ! 955: " ! 956: { ! 957: if (m88k_compare_reg) ! 958: abort (); ! 959: ! 960: if (GET_CODE (operands[0]) == CONST_INT ! 961: && ! SMALL_INT (operands[0])) ! 962: operands[0] = force_reg (SImode, operands[0]); ! 963: ! 964: if (GET_CODE (operands[1]) == CONST_INT ! 965: && ! SMALL_INT (operands[1])) ! 966: operands[1] = force_reg (SImode, operands[1]); ! 967: ! 968: operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode); ! 969: }") ! 970: ! 971: ; @@ The docs say don't do this. It's probably a nop since the insn looks ! 972: ; identical to cmpsi against zero. Is there an advantage to providing ! 973: ; this, perhaps with a different form? ! 974: ! 975: ;(define_expand "tstsi" ! 976: ; [(set (match_dup 1) ! 977: ; (compare:CC (match_operand:SI 0 "register_operand" "") ! 978: ; (const_int 0)))] ! 979: ; "" ! 980: ; " ! 981: ;{ ! 982: ; m88k_compare_reg = 0; ! 983: ; m88k_compare_op0 = operands[0]; ! 984: ; m88k_compare_op1 = const0_rtx; ! 985: ; DONE; ! 986: ;}") ! 987: ! 988: (define_expand "cmpsi" ! 989: [(set (match_dup 2) ! 990: (compare:CC (match_operand:SI 0 "register_operand" "") ! 991: (match_operand:SI 1 "arith32_operand" "")))] ! 992: "" ! 993: " ! 994: { ! 995: if (GET_CODE (operands[0]) == CONST_INT ! 996: || GET_CODE (operands[1]) == CONST_INT) ! 997: { ! 998: m88k_compare_reg = 0; ! 999: m88k_compare_op0 = operands[0]; ! 1000: m88k_compare_op1 = operands[1]; ! 1001: DONE; ! 1002: } ! 1003: operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode); ! 1004: }") ! 1005: ! 1006: (define_expand "cmpsf" ! 1007: [(set (match_dup 2) ! 1008: (compare:CC (match_operand:SF 0 "register_operand" "") ! 1009: (match_operand:SF 1 "register_operand" "")))] ! 1010: "" ! 1011: "operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);") ! 1012: ! 1013: (define_expand "cmpdf" ! 1014: [(set (match_dup 2) ! 1015: (compare:CC (match_operand:DF 0 "general_operand" "") ! 1016: (match_operand:DF 1 "general_operand" "")))] ! 1017: "" ! 1018: " ! 1019: { ! 1020: operands[0] = legitimize_operand (operands[0], DFmode); ! 1021: operands[1] = legitimize_operand (operands[1], DFmode); ! 1022: operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode); ! 1023: }") ! 1024: ! 1025: ; @@ Get back to this later on. ! 1026: ; ! 1027: ;(define_insn "cmpdi" ! 1028: ; [(set (cc0) ! 1029: ; (compare:CC (match_operand:DI 0 "register_operand" "r") ! 1030: ; (match_operand:DI 1 "register_operand" "r")))] ! 1031: ; "" ! 1032: ; "* ! 1033: ;{ ! 1034: ; if ((cc_status.mdep & MDEP_LS_CHANGE) != 0) ! 1035: ; abort (); /* output_move_double MDEP_LS_CHANGE bits were set. */ ! 1036: ; ! 1037: ; cc_status.mdep &= ~ MDEP_LS_MASK; ! 1038: ; ! 1039: ; operands[2] = gen_label_rtx (); ! 1040: ; /* Remember, %! is the condition code register and %@ is the ! 1041: ; literal synthesis register. */ ! 1042: ; ! 1043: ; output_asm_insn (\"cmp %!,%0,%1\;bb0 %#eq,%!,%l2\;cmp %!,%d0,%d1\", ! 1044: ; operands); ! 1045: ; ! 1046: ; output_asm_insn (\"extu %@,%!,4<8>\;clr %!,%!,4<4>\", operands); ! 1047: ; output_asm_insn (\"mak %@,%@,4<4>\;or %!,%!,%@\", operands); ! 1048: ; output_label (XINT (operands[2], 3)); ! 1049: ; return \"\"; ! 1050: ;}" ! 1051: ! 1052: ;; The actual compare instructions. ! 1053: ! 1054: (define_insn "" ! 1055: [(set (match_operand:CC 0 "register_operand" "=r") ! 1056: (compare:CC (match_operand:SI 1 "register_operand" "rO") ! 1057: (match_operand:SI 2 "arith_operand" "rI")))] ! 1058: "" ! 1059: "cmp %0,%r1,%2") ! 1060: ! 1061: (define_insn "" ! 1062: [(set (match_operand:CC 0 "register_operand" "=r,r,r,r") ! 1063: (compare:CC (match_operand:SF 1 "register_operand" "r,r,x,x") ! 1064: (match_operand:SF 2 "real_or_0_operand" "r,G,x,G")))] ! 1065: "" ! 1066: "@ ! 1067: fcmp.sss %0,%1,%2 ! 1068: fcmp.sss %0,%1,%#r0 ! 1069: fcmp.sss %0,%1,%2 ! 1070: fcmp.sss %0,%1,%#x0" ! 1071: [(set_attr "type" "spcmp")]) ! 1072: ! 1073: (define_insn "" ! 1074: [(set (match_operand:CC 0 "register_operand" "=r,r") ! 1075: (compare:CC (match_operand:DF 1 "register_operand" "r,x") ! 1076: (float_extend:DF ! 1077: (match_operand:SF 2 "register_operand" "r,x"))))] ! 1078: "" ! 1079: "fcmp.sds %0,%1,%2" ! 1080: [(set_attr "type" "dpcmp")]) ! 1081: ! 1082: (define_insn "" ! 1083: [(set (match_operand:CC 0 "register_operand" "=r,r") ! 1084: (compare:CC (float_extend:DF ! 1085: (match_operand:SF 1 "register_operand" "r,x")) ! 1086: (match_operand:DF 2 "register_operand" "r,x")))] ! 1087: "" ! 1088: "fcmp.ssd %0,%1,%2" ! 1089: [(set_attr "type" "dpcmp")]) ! 1090: ! 1091: (define_insn "" ! 1092: [(set (match_operand:CC 0 "register_operand" "=r,r,r,r") ! 1093: (compare:CC (match_operand:DF 1 "register_operand" "r,r,x,x") ! 1094: (match_operand:DF 2 "real_or_0_operand" "r,G,x,G")))] ! 1095: "" ! 1096: "@ ! 1097: fcmp.sdd %0,%1,%2 ! 1098: fcmp.sds %0,%1,%#r0 ! 1099: fcmp.sdd %0,%1,%2 ! 1100: fcmp.sds %0,%1,%#x0" ! 1101: [(set_attr "type" "dpcmp")]) ! 1102: ! 1103: ;; Store condition code insns. The compare insns set a register ! 1104: ;; rather than cc0 and record that register for use here. See above ! 1105: ;; for the special treatment of cmpsi with a constant operand. ! 1106: ! 1107: ;; @@ For the m88110, use fcmpu for bxx sxx inequality comparisons. ! 1108: ! 1109: (define_expand "seq" ! 1110: [(set (match_operand:SI 0 "register_operand" "") ! 1111: (match_dup 1))] ! 1112: "" ! 1113: "operands[1] = emit_test (EQ, SImode);") ! 1114: ! 1115: (define_expand "sne" ! 1116: [(set (match_operand:SI 0 "register_operand" "") ! 1117: (match_dup 1))] ! 1118: "" ! 1119: "operands[1] = emit_test (NE, SImode);") ! 1120: ! 1121: (define_expand "sgt" ! 1122: [(set (match_operand:SI 0 "register_operand" "") ! 1123: (match_dup 1))] ! 1124: "" ! 1125: "operands[1] = emit_test (GT, SImode);") ! 1126: ! 1127: (define_expand "sgtu" ! 1128: [(set (match_operand:SI 0 "register_operand" "") ! 1129: (match_dup 1))] ! 1130: "" ! 1131: "operands[1] = emit_test (GTU, SImode);") ! 1132: ! 1133: (define_expand "slt" ! 1134: [(set (match_operand:SI 0 "register_operand" "") ! 1135: (match_dup 1))] ! 1136: "" ! 1137: "operands[1] = emit_test (LT, SImode);") ! 1138: ! 1139: (define_expand "sltu" ! 1140: [(set (match_operand:SI 0 "register_operand" "") ! 1141: (match_dup 1))] ! 1142: "" ! 1143: "operands[1] = emit_test (LTU, SImode);") ! 1144: ! 1145: (define_expand "sge" ! 1146: [(set (match_operand:SI 0 "register_operand" "") ! 1147: (match_dup 1))] ! 1148: "" ! 1149: "operands[1] = emit_test (GE, SImode);") ! 1150: ! 1151: (define_expand "sgeu" ! 1152: [(set (match_operand:SI 0 "register_operand" "") ! 1153: (match_dup 1))] ! 1154: "" ! 1155: "operands[1] = emit_test (GEU, SImode);") ! 1156: ! 1157: (define_expand "sle" ! 1158: [(set (match_operand:SI 0 "register_operand" "") ! 1159: (match_dup 1))] ! 1160: "" ! 1161: "operands[1] = emit_test (LE, SImode);") ! 1162: ! 1163: (define_expand "sleu" ! 1164: [(set (match_operand:SI 0 "register_operand" "") ! 1165: (match_dup 1))] ! 1166: "" ! 1167: "operands[1] = emit_test (LEU, SImode);") ! 1168: ! 1169: ;; The actual set condition code instruction. ! 1170: ! 1171: (define_insn "" ! 1172: [(set (match_operand:SI 0 "register_operand" "=r") ! 1173: (match_operator:SI 1 "relop" ! 1174: [(match_operand:CC 2 "register_operand" "r") ! 1175: (const_int 0)]))] ! 1176: "" ! 1177: "ext %0,%2,1<%C1>" ! 1178: [(set_attr "type" "bit")]) ! 1179: ! 1180: (define_insn "" ! 1181: [(set (match_operand:SI 0 "register_operand" "=r") ! 1182: (neg:SI ! 1183: (match_operator:SI 1 "relop" ! 1184: [(match_operand:CC 2 "register_operand" "r") ! 1185: (const_int 0)])))] ! 1186: "" ! 1187: "extu %0,%2,1<%C1>" ! 1188: [(set_attr "type" "bit")]) ! 1189: ! 1190: ;; Conditional branch insns. The compare insns set a register ! 1191: ;; rather than cc0 and record that register for use here. See above ! 1192: ;; for the special case of cmpsi with a constant operand. ! 1193: ! 1194: (define_expand "bcnd" ! 1195: [(set (pc) ! 1196: (if_then_else (match_operand 0 "" "") ! 1197: (label_ref (match_operand 1 "" "")) ! 1198: (pc)))] ! 1199: "" ! 1200: "if (m88k_compare_reg) abort ();") ! 1201: ! 1202: (define_expand "bxx" ! 1203: [(set (pc) ! 1204: (if_then_else (match_operand 0 "" "") ! 1205: (label_ref (match_operand 1 "" "")) ! 1206: (pc)))] ! 1207: "" ! 1208: "if (m88k_compare_reg == 0) abort ();") ! 1209: ! 1210: (define_expand "beq" ! 1211: [(set (pc) ! 1212: (if_then_else (eq (match_dup 1) (const_int 0)) ! 1213: (label_ref (match_operand 0 "" "")) ! 1214: (pc)))] ! 1215: "" ! 1216: "if (m88k_compare_reg == 0) ! 1217: { ! 1218: emit_bcnd (EQ, operands[0]); ! 1219: DONE; ! 1220: } ! 1221: operands[1] = m88k_compare_reg;") ! 1222: ! 1223: (define_expand "bne" ! 1224: [(set (pc) ! 1225: (if_then_else (ne (match_dup 1) (const_int 0)) ! 1226: (label_ref (match_operand 0 "" "")) ! 1227: (pc)))] ! 1228: "" ! 1229: "if (m88k_compare_reg == 0) ! 1230: { ! 1231: emit_bcnd (NE, operands[0]); ! 1232: DONE; ! 1233: } ! 1234: operands[1] = m88k_compare_reg;") ! 1235: ! 1236: (define_expand "bgt" ! 1237: [(set (pc) ! 1238: (if_then_else (gt (match_dup 1) (const_int 0)) ! 1239: (label_ref (match_operand 0 "" "")) ! 1240: (pc)))] ! 1241: "" ! 1242: "if (m88k_compare_reg == 0) ! 1243: { ! 1244: emit_bcnd (GT, operands[0]); ! 1245: DONE; ! 1246: } ! 1247: operands[1] = m88k_compare_reg;") ! 1248: ! 1249: (define_expand "bgtu" ! 1250: [(set (pc) ! 1251: (if_then_else (gtu (match_dup 1) (const_int 0)) ! 1252: (label_ref (match_operand 0 "" "")) ! 1253: (pc)))] ! 1254: "" ! 1255: "if (m88k_compare_reg == 0) ! 1256: { ! 1257: emit_jump_insn (gen_bxx (emit_test (GTU, VOIDmode), operands[0])); ! 1258: DONE; ! 1259: } ! 1260: operands[1] = m88k_compare_reg;") ! 1261: ! 1262: (define_expand "blt" ! 1263: [(set (pc) ! 1264: (if_then_else (lt (match_dup 1) (const_int 0)) ! 1265: (label_ref (match_operand 0 "" "")) ! 1266: (pc)))] ! 1267: "" ! 1268: "if (m88k_compare_reg == 0) ! 1269: { ! 1270: emit_bcnd (LT, operands[0]); ! 1271: DONE; ! 1272: } ! 1273: operands[1] = m88k_compare_reg;") ! 1274: ! 1275: (define_expand "bltu" ! 1276: [(set (pc) ! 1277: (if_then_else (ltu (match_dup 1) (const_int 0)) ! 1278: (label_ref (match_operand 0 "" "")) ! 1279: (pc)))] ! 1280: "" ! 1281: "if (m88k_compare_reg == 0) ! 1282: { ! 1283: emit_jump_insn (gen_bxx (emit_test (LTU, VOIDmode), operands[0])); ! 1284: DONE; ! 1285: } ! 1286: operands[1] = m88k_compare_reg;") ! 1287: ! 1288: (define_expand "bge" ! 1289: [(set (pc) ! 1290: (if_then_else (ge (match_dup 1) (const_int 0)) ! 1291: (label_ref (match_operand 0 "" "")) ! 1292: (pc)))] ! 1293: "" ! 1294: "if (m88k_compare_reg == 0) ! 1295: { ! 1296: emit_bcnd (GE, operands[0]); ! 1297: DONE; ! 1298: } ! 1299: operands[1] = m88k_compare_reg;") ! 1300: ! 1301: (define_expand "bgeu" ! 1302: [(set (pc) ! 1303: (if_then_else (geu (match_dup 1) (const_int 0)) ! 1304: (label_ref (match_operand 0 "" "")) ! 1305: (pc)))] ! 1306: "" ! 1307: "if (m88k_compare_reg == 0) ! 1308: { ! 1309: emit_jump_insn (gen_bxx (emit_test (GEU, VOIDmode), operands[0])); ! 1310: DONE; ! 1311: } ! 1312: operands[1] = m88k_compare_reg;") ! 1313: ! 1314: (define_expand "ble" ! 1315: [(set (pc) ! 1316: (if_then_else (le (match_dup 1) (const_int 0)) ! 1317: (label_ref (match_operand 0 "" "")) ! 1318: (pc)))] ! 1319: "" ! 1320: "if (m88k_compare_reg == 0) ! 1321: { ! 1322: emit_bcnd (LE, operands[0]); ! 1323: DONE; ! 1324: } ! 1325: operands[1] = m88k_compare_reg;") ! 1326: ! 1327: (define_expand "bleu" ! 1328: [(set (pc) ! 1329: (if_then_else (leu (match_dup 1) (const_int 0)) ! 1330: (label_ref (match_operand 0 "" "")) ! 1331: (pc)))] ! 1332: "" ! 1333: "if (m88k_compare_reg == 0) ! 1334: { ! 1335: emit_jump_insn (gen_bxx (emit_test (LEU, VOIDmode), operands[0])); ! 1336: DONE; ! 1337: } ! 1338: operands[1] = m88k_compare_reg;") ! 1339: ! 1340: ;; The actual conditional branch instruction (both directions). This ! 1341: ;; uses two unusual template patterns, %Rx and %Px. %Rx is a prefix code ! 1342: ;; for the immediately following condition and reverses the condition iff ! 1343: ;; operand `x' is a LABEL_REF. %Px does nothing if `x' is PC and outputs ! 1344: ;; the operand if `x' is a LABEL_REF. ! 1345: ! 1346: (define_insn "" ! 1347: [(set (pc) (if_then_else ! 1348: (match_operator 0 "relop" ! 1349: [(match_operand:CC 1 "register_operand" "r") ! 1350: (const_int 0)]) ! 1351: (match_operand 2 "pc_or_label_ref" "") ! 1352: (match_operand 3 "pc_or_label_ref" "")))] ! 1353: "" ! 1354: "* ! 1355: { ! 1356: if (mostly_false_jump (insn, operands[0])) ! 1357: return \"bb0%. %R2%C0,%1,%P2%P3\"; ! 1358: else ! 1359: return \"bb1%. %R3%C0,%1,%P2%P3\"; ! 1360: }" ! 1361: [(set_attr "type" "branch")]) ! 1362: ! 1363: ;; Branch conditional on scc values. These arise from manipulations on ! 1364: ;; compare words above. ! 1365: ! 1366: (define_insn "" ! 1367: [(set (pc) ! 1368: (if_then_else ! 1369: (ne (match_operator 0 "relop" ! 1370: [(match_operand:CC 1 "register_operand" "r") ! 1371: (const_int 0)]) ! 1372: (const_int 0)) ! 1373: (match_operand 2 "pc_or_label_ref" "") ! 1374: (match_operand 3 "pc_or_label_ref" "")))] ! 1375: "" ! 1376: "bb%L2 %C0,%1,%P2%P3" ! 1377: [(set_attr "type" "branch")]) ! 1378: ! 1379: (define_insn "" ! 1380: [(set (pc) ! 1381: (if_then_else ! 1382: (eq (match_operator 0 "relop" ! 1383: [(match_operand:CC 1 "register_operand" "r") ! 1384: (const_int 0)]) ! 1385: (const_int 0)) ! 1386: (match_operand 2 "pc_or_label_ref" "") ! 1387: (match_operand 3 "pc_or_label_ref" "")))] ! 1388: "" ! 1389: "bb%L3 %C0,%1,%P2%P3" ! 1390: [(set_attr "type" "branch")]) ! 1391: ! 1392: (define_insn "locate1" ! 1393: [(set (match_operand:SI 0 "register_operand" "=r") ! 1394: (high:SI (unspec:SI [(label_ref (match_operand 1 "" ""))] 0)))] ! 1395: "" ! 1396: "or.u %0,%#r0,%#hi16(%1#abdiff)") ! 1397: ! 1398: (define_insn "locate2" ! 1399: [(parallel [(set (reg:SI 1) (pc)) ! 1400: (set (match_operand:SI 0 "register_operand" "=r") ! 1401: (lo_sum:SI (match_dup 0) ! 1402: (unspec:SI ! 1403: [(label_ref (match_operand 1 "" ""))] 0)))])] ! 1404: "" ! 1405: "bsr.n %1\;or %0,%0,%#lo16(%1#abdiff)\\n%1:" ! 1406: [(set_attr "length" "2")]) ! 1407: ! 1408: ;; SImode move instructions ! 1409: ! 1410: (define_expand "movsi" ! 1411: [(set (match_operand:SI 0 "general_operand" "") ! 1412: (match_operand:SI 1 "general_operand" ""))] ! 1413: "" ! 1414: " ! 1415: { ! 1416: if (emit_move_sequence (operands, SImode, 0)) ! 1417: DONE; ! 1418: }") ! 1419: ! 1420: (define_expand "reload_insi" ! 1421: [(set (match_operand:SI 0 "register_operand" "=r") ! 1422: (match_operand:SI 1 "general_operand" "")) ! 1423: (clobber (match_operand:SI 2 "register_operand" "=&r"))] ! 1424: "" ! 1425: " ! 1426: { ! 1427: if (emit_move_sequence (operands, SImode, operands[2])) ! 1428: DONE; ! 1429: ! 1430: /* We don't want the clobber emitted, so handle this ourselves. */ ! 1431: emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); ! 1432: DONE; ! 1433: }") ! 1434: ! 1435: (define_insn "" ! 1436: [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,x,x,x,m") ! 1437: (match_operand:SI 1 "move_operand" "rI,m,rO,J,M,x,r,x,m,x"))] ! 1438: "(register_operand (operands[0], SImode) ! 1439: || register_operand (operands[1], SImode) ! 1440: || operands[1] == const0_rtx)" ! 1441: "@ ! 1442: or %0,%#r0,%1 ! 1443: %V1ld\\t %0,%1 ! 1444: %v0st\\t %r1,%0 ! 1445: subu %0,%#r0,%n1 ! 1446: set %0,%#r0,%s1 ! 1447: mov.s %0,%1 ! 1448: mov.s %0,%1 ! 1449: mov %0,%1 ! 1450: %V1ld\\t %0,%1 ! 1451: %v0st\\t %1,%0" ! 1452: [(set_attr "type" "arith,load,store,arith,bit,mov,mov,mov,load,store")]) ! 1453: ! 1454: (define_insn "" ! 1455: [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r") ! 1456: (match_operand:SI 1 "arith32_operand" "rI,J,L,M,n"))] ! 1457: "" ! 1458: "@ ! 1459: or %0,%#r0,%1 ! 1460: subu %0,%#r0,%n1 ! 1461: or.u %0,%#r0,%X1 ! 1462: set %0,%#r0,%s1 ! 1463: or.u %0,%#r0,%X1\;or %0,%0,%x1" ! 1464: [(set_attr "type" "arith,arith,arith,bit,marith")]) ! 1465: ! 1466: ;; @@ Why the constraint "in"? Doesn't `i' include `n'? ! 1467: (define_insn "" ! 1468: [(set (match_operand:SI 0 "register_operand" "=r") ! 1469: (lo_sum:SI (match_operand:SI 1 "register_operand" "r") ! 1470: (match_operand:SI 2 "immediate_operand" "in")))] ! 1471: "" ! 1472: "or %0,%1,%#lo16(%g2)") ! 1473: ! 1474: (define_insn "" ! 1475: [(set (match_operand:SI 0 "register_operand" "=r") ! 1476: (high:SI (match_operand 1 "" "")))] ! 1477: "" ! 1478: "or.u %0,%#r0,%#hi16(%g1)") ! 1479: ! 1480: ;; HImode move instructions ! 1481: ! 1482: (define_expand "movhi" ! 1483: [(set (match_operand:HI 0 "general_operand" "") ! 1484: (match_operand:HI 1 "general_operand" ""))] ! 1485: "" ! 1486: " ! 1487: { ! 1488: if (emit_move_sequence (operands, HImode, 0)) ! 1489: DONE; ! 1490: }") ! 1491: ! 1492: (define_insn "" ! 1493: [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r") ! 1494: (match_operand:HI 1 "move_operand" "rP,m,rO,N"))] ! 1495: "(register_operand (operands[0], HImode) ! 1496: || register_operand (operands[1], HImode) ! 1497: || operands[1] == const0_rtx)" ! 1498: "@ ! 1499: or %0,%#r0,%h1 ! 1500: %V1ld.hu\\t %0,%1 ! 1501: %v0st.h\\t %r1,%0 ! 1502: subu %0,%#r0,%H1" ! 1503: [(set_attr "type" "arith,load,store,arith")]) ! 1504: ! 1505: (define_insn "" ! 1506: [(set (match_operand:HI 0 "register_operand" "=r") ! 1507: (subreg:HI (lo_sum:SI (match_operand:SI 1 "register_operand" "r") ! 1508: (match_operand:SI 2 "immediate_operand" "in")) 0))] ! 1509: "!flag_pic" ! 1510: "or %0,%1,%#lo16(%2)") ! 1511: ! 1512: ;; QImode move instructions ! 1513: ! 1514: (define_expand "movqi" ! 1515: [(set (match_operand:QI 0 "general_operand" "") ! 1516: (match_operand:QI 1 "general_operand" ""))] ! 1517: "" ! 1518: " ! 1519: { ! 1520: if (emit_move_sequence (operands, QImode, 0)) ! 1521: DONE; ! 1522: }") ! 1523: ! 1524: (define_insn "" ! 1525: [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r") ! 1526: (match_operand:QI 1 "move_operand" "rP,m,rO,N"))] ! 1527: "(register_operand (operands[0], QImode) ! 1528: || register_operand (operands[1], QImode) ! 1529: || operands[1] == const0_rtx)" ! 1530: "@ ! 1531: or %0,%#r0,%q1 ! 1532: %V1ld.bu\\t %0,%1 ! 1533: %v0st.b\\t %r1,%0 ! 1534: subu %r0,%#r0,%Q1" ! 1535: [(set_attr "type" "arith,load,store,arith")]) ! 1536: ! 1537: (define_insn "" ! 1538: [(set (match_operand:QI 0 "register_operand" "=r") ! 1539: (subreg:QI (lo_sum:SI (match_operand:SI 1 "register_operand" "r") ! 1540: (match_operand:SI 2 "immediate_operand" "in")) 0))] ! 1541: "!flag_pic" ! 1542: "or %0,%1,%#lo16(%2)") ! 1543: ! 1544: ;; DImode move instructions ! 1545: ! 1546: (define_expand "movdi" ! 1547: [(set (match_operand:DI 0 "general_operand" "") ! 1548: (match_operand:DI 1 "general_operand" ""))] ! 1549: "" ! 1550: " ! 1551: { ! 1552: if (emit_move_sequence (operands, DImode, 0)) ! 1553: DONE; ! 1554: }") ! 1555: ! 1556: (define_insn "" ! 1557: [(set (match_operand:DI 0 "register_operand" "=r,x") ! 1558: (const_int 0))] ! 1559: "" ! 1560: "@ ! 1561: or %0,%#r0,0\;or %d0,%#r0,0 ! 1562: mov %0,%#x0" ! 1563: [(set_attr "type" "marith,mov")]) ! 1564: ! 1565: (define_insn "" ! 1566: [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,x,x,x,m") ! 1567: (match_operand:DI 1 "nonimmediate_operand" "r,m,r,x,r,x,m,x"))] ! 1568: "" ! 1569: "@ ! 1570: or %0,%#r0,%1\;or %d0,%#r0,%d1 ! 1571: %V1ld.d\\t %0,%1 ! 1572: %v0st.d\\t %1,%0 ! 1573: mov.d %0,%1 ! 1574: mov.d %0,%1 ! 1575: mov %0,%1 ! 1576: %V1ld.d\\t %0,%1 ! 1577: %v0st.d\\t %1,%0" ! 1578: [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")]) ! 1579: ! 1580: (define_insn "" ! 1581: [(set (match_operand:DI 0 "register_operand" "=r") ! 1582: (subreg:DI (lo_sum:SI (match_operand:SI 1 "register_operand" "r") ! 1583: (match_operand:SI 2 "immediate_operand" "in")) 0))] ! 1584: "!flag_pic" ! 1585: "or %0,%1,%#lo16(%2)") ! 1586: ! 1587: (define_insn "" ! 1588: [(set (match_operand:DI 0 "register_operand" "=r") ! 1589: (match_operand:DI 1 "immediate_operand" "n"))] ! 1590: "" ! 1591: "* return output_load_const_dimode (operands);" ! 1592: [(set_attr "type" "marith") ! 1593: (set_attr "length" "4")]) ; length is 2, 3 or 4. ! 1594: ! 1595: ;; DFmode move instructions ! 1596: ! 1597: (define_expand "movdf" ! 1598: [(set (match_operand:DF 0 "general_operand" "") ! 1599: (match_operand:DF 1 "general_operand" ""))] ! 1600: "" ! 1601: " ! 1602: { ! 1603: if (emit_move_sequence (operands, DFmode, 0)) ! 1604: DONE; ! 1605: }") ! 1606: ! 1607: ;; @@ This pattern is incomplete and doesn't appear necessary. ! 1608: ;; ! 1609: ;; This pattern forces (set (reg:DF ...) (const_double ...)) ! 1610: ;; to be reloaded by putting the constant into memory. ! 1611: ;; It must come before the more general movdf pattern. ! 1612: ! 1613: ;(define_insn "" ! 1614: ; [(set (match_operand:DF 0 "general_operand" "=r,o") ! 1615: ; (match_operand:DF 1 "" "G,G"))] ! 1616: ; "GET_CODE (operands[1]) == CONST_DOUBLE" ! 1617: ; "* ! 1618: ;{ ! 1619: ; switch (which_alternative) ! 1620: ; { ! 1621: ; case 0: ! 1622: ; return \"or %0,%#r0,0\;or %d0,%#r0,0\"; ! 1623: ; case 1: ! 1624: ; operands[1] = adj_offsettable_operand (operands[0], 4); ! 1625: ; return \"%v0st\\t %#r0,%0\;st %#r0,%1\"; ! 1626: ; } ! 1627: ;}") ! 1628: ! 1629: (define_insn "" ! 1630: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 1631: (const_int 0))] ! 1632: "" ! 1633: "@ ! 1634: or %0,%#r0,0\;or %d0,%#r0,0 ! 1635: mov %0,%#x0" ! 1636: [(set_attr "type" "marith,mov")]) ! 1637: ! 1638: (define_insn "" ! 1639: [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m") ! 1640: (match_operand:DF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))] ! 1641: "" ! 1642: "@ ! 1643: or %0,%#r0,%1\;or %d0,%#r0,%d1 ! 1644: %V1ld.d\\t %0,%1 ! 1645: %v0st.d\\t %1,%0 ! 1646: mov.d %0,%1 ! 1647: mov.d %0,%1 ! 1648: mov %0,%1 ! 1649: %V1ld.d\\t %0,%1 ! 1650: %v0st.d\\t %1,%0" ! 1651: [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")]) ! 1652: ! 1653: (define_insn "" ! 1654: [(set (match_operand:DF 0 "register_operand" "=r") ! 1655: (subreg:DF (lo_sum:SI (match_operand:SI 1 "register_operand" "r") ! 1656: (match_operand:SI 2 "immediate_operand" "in")) 0))] ! 1657: "!flag_pic" ! 1658: "or %0,%1,%#lo16(%2)") ! 1659: ! 1660: (define_insn "" ! 1661: [(set (match_operand:DF 0 "register_operand" "=r") ! 1662: (match_operand:DF 1 "immediate_operand" "F"))] ! 1663: "" ! 1664: "* return output_load_const_double (operands);" ! 1665: [(set_attr "type" "marith") ! 1666: (set_attr "length" "4")]) ; length is 2, 3, or 4. ! 1667: ! 1668: ;; SFmode move instructions ! 1669: ! 1670: (define_expand "movsf" ! 1671: [(set (match_operand:SF 0 "general_operand" "") ! 1672: (match_operand:SF 1 "general_operand" ""))] ! 1673: "" ! 1674: " ! 1675: { ! 1676: if (emit_move_sequence (operands, SFmode, 0)) ! 1677: DONE; ! 1678: }") ! 1679: ! 1680: ;; @@ What happens to fconst0_rtx? ! 1681: (define_insn "" ! 1682: [(set (match_operand:SF 0 "register_operand" "=r,x") ! 1683: (const_int 0))] ! 1684: "" ! 1685: "@ ! 1686: or %0,%#r0,0 ! 1687: mov %0,%#x0" ! 1688: [(set_attr "type" "arith,mov")]) ! 1689: ! 1690: (define_insn "" ! 1691: [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m") ! 1692: (match_operand:SF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))] ! 1693: "" ! 1694: "@ ! 1695: or %0,%#r0,%1 ! 1696: %V1ld\\t %0,%1 ! 1697: %v0st\\t %r1,%0 ! 1698: mov.s %0,%1 ! 1699: mov.s %0,%1 ! 1700: mov %0,%1 ! 1701: %V1ld\\t %0,%1 ! 1702: %v0st\\t %r1,%0" ! 1703: [(set_attr "type" "arith,load,store,mov,mov,mov,load,store")]) ! 1704: ! 1705: (define_insn "" ! 1706: [(set (match_operand:SF 0 "register_operand" "=r") ! 1707: (subreg:SF (lo_sum:SI (match_operand:SI 1 "register_operand" "r") ! 1708: (match_operand:SI 2 "immediate_operand" "in")) 0))] ! 1709: "!flag_pic" ! 1710: "or %0,%1,%#lo16(%2)") ! 1711: ! 1712: (define_insn "" ! 1713: [(set (match_operand:SF 0 "register_operand" "=r") ! 1714: (match_operand:SF 1 "immediate_operand" "F"))] ! 1715: "operands[1] != const0_rtx" ! 1716: "* return output_load_const_float (operands);" ! 1717: [(set_attr "type" "marith")]) ; length is 1 or 2. ! 1718: ! 1719: ;; String/block move insn. See m88k.c for details. ! 1720: ! 1721: (define_expand "movstrsi" ! 1722: [(parallel [(set (mem:BLK (match_operand:BLK 0 "" "")) ! 1723: (mem:BLK (match_operand:BLK 1 "" ""))) ! 1724: (use (match_operand:SI 2 "arith32_operand" "")) ! 1725: (use (match_operand:SI 3 "immediate_operand" ""))])] ! 1726: "" ! 1727: " ! 1728: { ! 1729: rtx dest_mem = operands[0]; ! 1730: rtx src_mem = operands[1]; ! 1731: operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0)); ! 1732: operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); ! 1733: expand_block_move (dest_mem, src_mem, operands); ! 1734: DONE; ! 1735: }") ! 1736: ! 1737: (define_insn "" ! 1738: [(set (match_operand:QI 0 "register_operand" "=r") ! 1739: (match_operand:BLK 1 "memory_operand" "m"))] ! 1740: "" ! 1741: "%V1ld.bu\\t %0,%1" ! 1742: [(set_attr "type" "load")]) ! 1743: ! 1744: (define_insn "" ! 1745: [(set (match_operand:HI 0 "register_operand" "=r") ! 1746: (match_operand:BLK 1 "memory_operand" "m"))] ! 1747: "" ! 1748: "%V1ld.hu\\t %0,%1" ! 1749: [(set_attr "type" "load")]) ! 1750: ! 1751: (define_insn "" ! 1752: [(set (match_operand:SI 0 "register_operand" "=r") ! 1753: (match_operand:BLK 1 "memory_operand" "m"))] ! 1754: "" ! 1755: "%V1ld\\t %0,%1" ! 1756: [(set_attr "type" "load")]) ! 1757: ! 1758: (define_insn "" ! 1759: [(set (match_operand:DI 0 "register_operand" "=r") ! 1760: (match_operand:BLK 1 "memory_operand" "m"))] ! 1761: "" ! 1762: "%V1ld.d\\t %0,%1" ! 1763: [(set_attr "type" "loadd")]) ! 1764: ! 1765: (define_insn "" ! 1766: [(set (match_operand:BLK 0 "memory_operand" "=m") ! 1767: (match_operand:QI 1 "register_operand" "r"))] ! 1768: "" ! 1769: "%v0st.b\\t %1,%0" ! 1770: [(set_attr "type" "store")]) ! 1771: ! 1772: (define_insn "" ! 1773: [(set (match_operand:BLK 0 "memory_operand" "=m") ! 1774: (match_operand:HI 1 "register_operand" "r"))] ! 1775: "" ! 1776: "%v0st.h\\t %1,%0" ! 1777: [(set_attr "type" "store")]) ! 1778: ! 1779: (define_insn "" ! 1780: [(set (match_operand:BLK 0 "memory_operand" "=m") ! 1781: (match_operand:SI 1 "register_operand" "r"))] ! 1782: "" ! 1783: "%v0st\\t %1,%0" ! 1784: [(set_attr "type" "store")]) ! 1785: ! 1786: (define_insn "" ! 1787: [(set (match_operand:BLK 0 "memory_operand" "=m") ! 1788: (match_operand:DI 1 "register_operand" "r"))] ! 1789: "" ! 1790: "%v0st.d\\t %1,%0" ! 1791: [(set_attr "type" "store")]) ! 1792: ! 1793: ;; Call a non-looping block move library function (e.g. __movstrSI96x64). ! 1794: ;; operand 0 is the function name ! 1795: ;; operand 1 is the destination pointer ! 1796: ;; operand 2 is the source pointer ! 1797: ;; operand 3 is the offset for the source and destination pointers ! 1798: ;; operand 4 is the first value to be loaded ! 1799: ;; operand 5 is the register to hold the value (r4 or r5) ! 1800: ! 1801: (define_expand "call_block_move" ! 1802: [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "") ! 1803: (match_operand:SI 3 "immediate_operand" ""))) ! 1804: (set (match_operand 5 "register_operand" "") ! 1805: (match_operand 4 "memory_operand" "")) ! 1806: (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "") ! 1807: (match_dup 3))) ! 1808: (use (reg:SI 2)) ! 1809: (use (reg:SI 3)) ! 1810: (use (match_dup 5)) ! 1811: (parallel [(set (reg:DI 2) ! 1812: (call (mem:SI (match_operand 0 "" "")) ! 1813: (const_int 0))) ! 1814: (clobber (reg:SI 1))])] ! 1815: "" ! 1816: "") ! 1817: ! 1818: ;; Call an SImode looping block move library function (e.g. __movstrSI64n68). ! 1819: ;; operands 0-5 as in the non-looping interface ! 1820: ;; operand 6 is the loop count ! 1821: ! 1822: (define_expand "call_movstrsi_loop" ! 1823: [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "") ! 1824: (match_operand:SI 3 "immediate_operand" ""))) ! 1825: (set (match_operand:SI 5 "register_operand" "") ! 1826: (match_operand 4 "memory_operand" "")) ! 1827: (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "") ! 1828: (match_dup 3))) ! 1829: (set (reg:SI 6) (match_operand:SI 6 "immediate_operand" "")) ! 1830: (use (reg:SI 2)) ! 1831: (use (reg:SI 3)) ! 1832: (use (match_dup 5)) ! 1833: (use (reg:SI 6)) ! 1834: (parallel [(set (reg:DI 2) ! 1835: (call (mem:SI (match_operand 0 "" "")) ! 1836: (const_int 0))) ! 1837: (clobber (reg:SI 1))])] ! 1838: "" ! 1839: "") ! 1840: ! 1841: ;;- zero extension instructions ! 1842: ! 1843: (define_expand "zero_extendhisi2" ! 1844: [(set (match_operand:SI 0 "register_operand" "") ! 1845: (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] ! 1846: "" ! 1847: " ! 1848: { ! 1849: if (GET_CODE (operands[1]) == MEM ! 1850: && symbolic_address_p (XEXP (operands[1], 0))) ! 1851: operands[1] ! 1852: = legitimize_address (flag_pic, operands[1], 0, 0); ! 1853: }") ! 1854: ! 1855: (define_insn "" ! 1856: [(set (match_operand:SI 0 "register_operand" "=r,r,r") ! 1857: (zero_extend:SI (match_operand:HI 1 "move_operand" "!r,n,m")))] ! 1858: "GET_CODE (operands[1]) != CONST_INT" ! 1859: "@ ! 1860: mask %0,%1,0xffff ! 1861: or %0,%#r0,%h1 ! 1862: %V1ld.hu\\t %0,%1" ! 1863: [(set_attr "type" "arith,arith,load")]) ! 1864: ! 1865: (define_expand "zero_extendqihi2" ! 1866: [(set (match_operand:HI 0 "register_operand" "") ! 1867: (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] ! 1868: "" ! 1869: " ! 1870: { ! 1871: if (GET_CODE (operands[1]) == MEM ! 1872: && symbolic_address_p (XEXP (operands[1], 0))) ! 1873: operands[1] ! 1874: = legitimize_address (flag_pic, operands[1], 0, 0); ! 1875: }") ! 1876: ! 1877: (define_insn "" ! 1878: [(set (match_operand:HI 0 "register_operand" "=r,r,r") ! 1879: (zero_extend:HI (match_operand:QI 1 "move_operand" "r,n,m")))] ! 1880: "GET_CODE (operands[1]) != CONST_INT" ! 1881: "@ ! 1882: mask %0,%1,0xff ! 1883: or %0,%#r0,%q1 ! 1884: %V1ld.bu\\t %0,%1" ! 1885: [(set_attr "type" "arith,arith,load")]) ! 1886: ! 1887: (define_expand "zero_extendqisi2" ! 1888: [(set (match_operand:SI 0 "register_operand" "") ! 1889: (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] ! 1890: "" ! 1891: " ! 1892: { ! 1893: if (GET_CODE (operands[1]) == MEM ! 1894: && symbolic_address_p (XEXP (operands[1], 0))) ! 1895: { ! 1896: operands[1] ! 1897: = legitimize_address (flag_pic, operands[1], 0, 0); ! 1898: emit_insn (gen_rtx (SET, VOIDmode, operands[0], ! 1899: gen_rtx (ZERO_EXTEND, SImode, operands[1]))); ! 1900: DONE; ! 1901: } ! 1902: }") ! 1903: ! 1904: (define_insn "" ! 1905: [(set (match_operand:SI 0 "register_operand" "=r,r,r") ! 1906: (zero_extend:SI (match_operand:QI 1 "move_operand" "r,n,m")))] ! 1907: "GET_CODE (operands[1]) != CONST_INT" ! 1908: "@ ! 1909: mask %0,%1,0xff ! 1910: or %0,%#r0,%q1 ! 1911: %V1ld.bu\\t %0,%1" ! 1912: [(set_attr "type" "arith,arith,load")]) ! 1913: ! 1914: ;;- sign extension instructions ! 1915: ! 1916: (define_expand "extendsidi2" ! 1917: [(set (subreg:SI (match_operand:DI 0 "register_operand" "=r") 1) ! 1918: (match_operand:SI 1 "general_operand" "g")) ! 1919: (set (subreg:SI (match_dup 0) 0) ! 1920: (ashiftrt:SI (subreg:SI (match_dup 0) 1) ! 1921: (const_int 31)))] ! 1922: "" ! 1923: "") ! 1924: ! 1925: (define_expand "extendhisi2" ! 1926: [(set (match_operand:SI 0 "register_operand" "") ! 1927: (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] ! 1928: "" ! 1929: " ! 1930: { ! 1931: if (GET_CODE (operands[1]) == MEM ! 1932: && symbolic_address_p (XEXP (operands[1], 0))) ! 1933: operands[1] ! 1934: = legitimize_address (flag_pic, operands[1], 0, 0); ! 1935: }") ! 1936: ! 1937: (define_insn "" ! 1938: [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") ! 1939: (sign_extend:SI (match_operand:HI 1 "move_operand" "!r,P,N,m")))] ! 1940: "GET_CODE (operands[1]) != CONST_INT" ! 1941: "@ ! 1942: ext %0,%1,16<0> ! 1943: or %0,%#r0,%h1 ! 1944: subu %0,%#r0,%H1 ! 1945: %V1ld.h\\t %0,%1" ! 1946: [(set_attr "type" "bit,arith,arith,load")]) ! 1947: ! 1948: (define_expand "extendqihi2" ! 1949: [(set (match_operand:HI 0 "register_operand" "") ! 1950: (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] ! 1951: "" ! 1952: " ! 1953: { ! 1954: if (GET_CODE (operands[1]) == MEM ! 1955: && symbolic_address_p (XEXP (operands[1], 0))) ! 1956: operands[1] ! 1957: = legitimize_address (flag_pic, operands[1], 0, 0); ! 1958: }") ! 1959: ! 1960: (define_insn "" ! 1961: [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") ! 1962: (sign_extend:HI (match_operand:QI 1 "move_operand" "!r,P,N,m")))] ! 1963: "GET_CODE (operands[1]) != CONST_INT" ! 1964: "@ ! 1965: ext %0,%1,8<0> ! 1966: or %0,%#r0,%q1 ! 1967: subu %0,%#r0,%Q1 ! 1968: %V1ld.b\\t %0,%1" ! 1969: [(set_attr "type" "bit,arith,arith,load")]) ! 1970: ! 1971: (define_expand "extendqisi2" ! 1972: [(set (match_operand:SI 0 "register_operand" "") ! 1973: (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] ! 1974: "" ! 1975: " ! 1976: { ! 1977: if (GET_CODE (operands[1]) == MEM ! 1978: && symbolic_address_p (XEXP (operands[1], 0))) ! 1979: operands[1] ! 1980: = legitimize_address (flag_pic, operands[1], 0, 0); ! 1981: }") ! 1982: ! 1983: (define_insn "" ! 1984: [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") ! 1985: (sign_extend:SI (match_operand:QI 1 "move_operand" "!r,P,N,m")))] ! 1986: "GET_CODE (operands[1]) != CONST_INT" ! 1987: "@ ! 1988: ext %0,%1,8<0> ! 1989: or %0,%#r0,%q1 ! 1990: subu %0,%#r0,%Q1 ! 1991: %V1ld.b\\t %0,%1" ! 1992: [(set_attr "type" "bit,arith,arith,load")]) ! 1993: ! 1994: ;; Conversions between float and double. ! 1995: ! 1996: ;; The fadd instruction does not conform to IEEE 754 when used to ! 1997: ;; convert between float and double. In particular, the sign of -0 is ! 1998: ;; not preserved. Interestingly, fsub does conform. ! 1999: ! 2000: (define_expand "extendsfdf2" ! 2001: [(set (match_operand:DF 0 "register_operand" "=r") ! 2002: (float_extend:DF (match_operand:SF 1 "register_operand" "r")))] ! 2003: "" ! 2004: "") ! 2005: ! 2006: (define_insn "" ! 2007: [(set (match_operand:DF 0 "register_operand" "=r") ! 2008: (float_extend:DF (match_operand:SF 1 "register_operand" "r")))] ! 2009: "! TARGET_88110" ! 2010: "fsub.dss %0,%1,%#r0" ! 2011: [(set_attr "type" "spadd")]) ! 2012: ! 2013: (define_insn "" ! 2014: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2015: (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")))] ! 2016: "TARGET_88110" ! 2017: "fcvt.ds %0,%1" ! 2018: [(set_attr "type" "spadd")]) ! 2019: ! 2020: (define_expand "truncdfsf2" ! 2021: [(set (match_operand:SF 0 "register_operand" "=r") ! 2022: (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))] ! 2023: "" ! 2024: "") ! 2025: ! 2026: (define_insn "" ! 2027: [(set (match_operand:SF 0 "register_operand" "=r") ! 2028: (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))] ! 2029: "! TARGET_88110" ! 2030: "fsub.sds %0,%1,%#r0" ! 2031: [(set_attr "type" "dpadd")]) ! 2032: ! 2033: (define_insn "" ! 2034: [(set (match_operand:SF 0 "register_operand" "=r,x") ! 2035: (float_truncate:SF (match_operand:DF 1 "register_operand" "r,x")))] ! 2036: "TARGET_88110" ! 2037: "fcvt.sd %0,%1" ! 2038: [(set_attr "type" "dpadd")]) ! 2039: ! 2040: ;; Conversions between floating point and integer ! 2041: ! 2042: (define_insn "floatsidf2" ! 2043: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2044: (float:DF (match_operand:SI 1 "register_operand" "r,r")))] ! 2045: "" ! 2046: "flt.ds %0,%1" ! 2047: [(set_attr "type" "spadd,dpadd")]) ! 2048: ! 2049: (define_insn "floatsisf2" ! 2050: [(set (match_operand:SF 0 "register_operand" "=r,x") ! 2051: (float:SF (match_operand:SI 1 "register_operand" "r,r")))] ! 2052: "" ! 2053: "flt.ss %0,%1" ! 2054: [(set_attr "type" "spadd,spadd")]) ! 2055: ! 2056: (define_insn "fix_truncdfsi2" ! 2057: [(set (match_operand:SI 0 "register_operand" "=r,r") ! 2058: (fix:SI (match_operand:DF 1 "register_operand" "r,x")))] ! 2059: "" ! 2060: "trnc.sd %0,%1" ! 2061: [(set_attr "type" "dpadd,dpadd")]) ! 2062: ! 2063: (define_insn "fix_truncsfsi2" ! 2064: [(set (match_operand:SI 0 "register_operand" "=r,r") ! 2065: (fix:SI (match_operand:SF 1 "register_operand" "r,x")))] ! 2066: "" ! 2067: "trnc.ss %0,%1" ! 2068: [(set_attr "type" "spadd,dpadd")]) ! 2069: ! 2070: ! 2071: ;;- arithmetic instructions ! 2072: ;;- add instructions ! 2073: ! 2074: (define_insn "addsi3" ! 2075: [(set (match_operand:SI 0 "register_operand" "=r,r") ! 2076: (plus:SI (match_operand:SI 1 "add_operand" "%r,r") ! 2077: (match_operand:SI 2 "add_operand" "rI,J")))] ! 2078: "" ! 2079: "@ ! 2080: addu %0,%1,%2 ! 2081: subu %0,%1,%n2") ! 2082: ! 2083: ;; patterns for mixed mode floating point. ! 2084: ;; Do not define patterns that utilize mixed mode arithmetic that result ! 2085: ;; in narrowing the precision, because it loses accuracy, since the standard ! 2086: ;; requires double rounding, whereas the 88000 instruction only rounds once. ! 2087: ! 2088: (define_expand "adddf3" ! 2089: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2090: (plus:DF (match_operand:DF 1 "general_operand" "%r,x") ! 2091: (match_operand:DF 2 "general_operand" "r,x")))] ! 2092: "" ! 2093: " ! 2094: { ! 2095: operands[1] = legitimize_operand (operands[1], DFmode); ! 2096: operands[2] = legitimize_operand (operands[2], DFmode); ! 2097: }") ! 2098: ! 2099: (define_insn "" ! 2100: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2101: (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) ! 2102: (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] ! 2103: "" ! 2104: "fadd.dss %0,%1,%2" ! 2105: [(set_attr "type" "spadd")]) ! 2106: ! 2107: (define_insn "" ! 2108: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2109: (plus:DF (match_operand:DF 1 "register_operand" "r,x") ! 2110: (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] ! 2111: "" ! 2112: "fadd.dds %0,%1,%2" ! 2113: [(set_attr "type" "dpadd")]) ! 2114: ! 2115: (define_insn "" ! 2116: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2117: (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) ! 2118: (match_operand:DF 2 "register_operand" "r,x")))] ! 2119: "" ! 2120: "fadd.dsd %0,%1,%2" ! 2121: [(set_attr "type" "dpadd")]) ! 2122: ! 2123: (define_insn "" ! 2124: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2125: (plus:DF (match_operand:DF 1 "register_operand" "%r,x") ! 2126: (match_operand:DF 2 "register_operand" "r,x")))] ! 2127: "" ! 2128: "fadd.ddd %0,%1,%2" ! 2129: [(set_attr "type" "dpadd")]) ! 2130: ! 2131: (define_insn "addsf3" ! 2132: [(set (match_operand:SF 0 "register_operand" "=r,x") ! 2133: (plus:SF (match_operand:SF 1 "register_operand" "%r,x") ! 2134: (match_operand:SF 2 "register_operand" "r,x")))] ! 2135: "" ! 2136: "fadd.sss %0,%1,%2" ! 2137: [(set_attr "type" "spadd")]) ! 2138: ! 2139: (define_insn "" ! 2140: [(set (match_operand:DI 0 "register_operand" "=r") ! 2141: (plus:DI (match_operand:DI 1 "register_operand" "r") ! 2142: (zero_extend:DI ! 2143: (match_operand:SI 2 "register_operand" "r")))) ! 2144: (clobber (reg:CC 0))] ! 2145: "" ! 2146: "addu.co %d0,%d1,%2\;addu.ci %0,%1,%#r0" ! 2147: [(set_attr "type" "marith")]) ! 2148: ! 2149: (define_insn "" ! 2150: [(set (match_operand:DI 0 "register_operand" "=r") ! 2151: (plus:DI (zero_extend:DI ! 2152: (match_operand:SI 1 "register_operand" "r")) ! 2153: (match_operand:DI 2 "register_operand" "r"))) ! 2154: (clobber (reg:CC 0))] ! 2155: "" ! 2156: "addu.co %d0,%1,%d2\;addu.ci %0,%#r0,%2" ! 2157: [(set_attr "type" "marith")]) ! 2158: ! 2159: (define_insn "adddi3" ! 2160: [(set (match_operand:DI 0 "register_operand" "=r") ! 2161: (plus:DI (match_operand:DI 1 "register_operand" "%r") ! 2162: (match_operand:DI 2 "register_operand" "r"))) ! 2163: (clobber (reg:CC 0))] ! 2164: "" ! 2165: "addu.co %d0,%d1,%d2\;addu.ci %0,%1,%2" ! 2166: [(set_attr "type" "marith")]) ! 2167: ! 2168: ;; Add with carry insns. ! 2169: ! 2170: (define_insn "" ! 2171: [(parallel [(set (match_operand:SI 0 "reg_or_0_operand" "=r") ! 2172: (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO") ! 2173: (match_operand:SI 2 "reg_or_0_operand" "rO"))) ! 2174: (set (reg:CC 0) ! 2175: (unspec:CC [(match_dup 1) (match_dup 2)] 0))])] ! 2176: "" ! 2177: "addu.co %r0,%r1,%r2") ! 2178: ! 2179: (define_insn "" ! 2180: [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO") ! 2181: (match_operand:SI 1 "reg_or_0_operand" "rO")] ! 2182: 0))] ! 2183: "" ! 2184: "addu.co %#r0,%r0,%r1") ! 2185: ! 2186: (define_insn "" ! 2187: [(set (match_operand:SI 0 "reg_or_0_operand" "=r") ! 2188: (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO") ! 2189: (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO") ! 2190: (reg:CC 0)] 0)))] ! 2191: "" ! 2192: "addu.ci %r0,%r1,%r2") ! 2193: ! 2194: ;;- subtract instructions ! 2195: ! 2196: (define_insn "subsi3" ! 2197: [(set (match_operand:SI 0 "register_operand" "=r") ! 2198: (minus:SI (match_operand:SI 1 "register_operand" "r") ! 2199: (match_operand:SI 2 "arith32_operand" "rI")))] ! 2200: "" ! 2201: "subu %0,%1,%2") ! 2202: ! 2203: ;; patterns for mixed mode floating point ! 2204: ;; Do not define patterns that utilize mixed mode arithmetic that result ! 2205: ;; in narrowing the precision, because it loses accuracy, since the standard ! 2206: ;; requires double rounding, whereas the 88000 instruction only rounds once. ! 2207: ! 2208: (define_expand "subdf3" ! 2209: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2210: (minus:DF (match_operand:DF 1 "general_operand" "r,x") ! 2211: (match_operand:DF 2 "general_operand" "r,x")))] ! 2212: "" ! 2213: " ! 2214: { ! 2215: operands[1] = legitimize_operand (operands[1], DFmode); ! 2216: operands[2] = legitimize_operand (operands[2], DFmode); ! 2217: }") ! 2218: ! 2219: (define_insn "" ! 2220: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2221: (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) ! 2222: (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] ! 2223: "" ! 2224: "fsub.dss %0,%1,%2" ! 2225: [(set_attr "type" "spadd")]) ! 2226: ! 2227: (define_insn "" ! 2228: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2229: (minus:DF (match_operand:DF 1 "register_operand" "r,x") ! 2230: (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] ! 2231: "" ! 2232: "fsub.dds %0,%1,%2" ! 2233: [(set_attr "type" "dpadd")]) ! 2234: ! 2235: (define_insn "" ! 2236: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2237: (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) ! 2238: (match_operand:DF 2 "register_operand" "r,x")))] ! 2239: "" ! 2240: "fsub.dsd %0,%1,%2" ! 2241: [(set_attr "type" "dpadd")]) ! 2242: ! 2243: (define_insn "" ! 2244: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2245: (minus:DF (match_operand:DF 1 "register_operand" "r,x") ! 2246: (match_operand:DF 2 "register_operand" "r,x")))] ! 2247: "" ! 2248: "fsub.ddd %0,%1,%2" ! 2249: [(set_attr "type" "dpadd")]) ! 2250: ! 2251: (define_insn "subsf3" ! 2252: [(set (match_operand:SF 0 "register_operand" "=r,x") ! 2253: (minus:SF (match_operand:SF 1 "register_operand" "r,x") ! 2254: (match_operand:SF 2 "register_operand" "r,x")))] ! 2255: "" ! 2256: "fsub.sss %0,%1,%2" ! 2257: [(set_attr "type" "spadd")]) ! 2258: ! 2259: (define_insn "" ! 2260: [(set (match_operand:DI 0 "register_operand" "=r") ! 2261: (minus:DI (match_operand:DI 1 "register_operand" "r") ! 2262: (zero_extend:DI ! 2263: (match_operand:SI 2 "register_operand" "r")))) ! 2264: (clobber (reg:CC 0))] ! 2265: "" ! 2266: "subu.co %d0,%d1,%2\;subu.ci %0,%1,%#r0" ! 2267: [(set_attr "type" "marith")]) ! 2268: ! 2269: (define_insn "" ! 2270: [(set (match_operand:DI 0 "register_operand" "=r") ! 2271: (minus:DI (zero_extend:DI ! 2272: (match_operand:SI 1 "register_operand" "r")) ! 2273: (match_operand:DI 2 "register_operand" "r"))) ! 2274: (clobber (reg:CC 0))] ! 2275: "" ! 2276: "subu.co %d0,%1,%d2\;subu.ci %0,%#r0,%2" ! 2277: [(set_attr "type" "marith")]) ! 2278: ! 2279: (define_insn "subdi3" ! 2280: [(set (match_operand:DI 0 "register_operand" "=r") ! 2281: (minus:DI (match_operand:DI 1 "register_operand" "r") ! 2282: (match_operand:DI 2 "register_operand" "r"))) ! 2283: (clobber (reg:CC 0))] ! 2284: "" ! 2285: "subu.co %d0,%d1,%d2\;subu.ci %0,%1,%2" ! 2286: [(set_attr "type" "marith")]) ! 2287: ! 2288: ;; Subtract with carry insns. ! 2289: ! 2290: (define_insn "" ! 2291: [(parallel [(set (match_operand:SI 0 "reg_or_0_operand" "=r") ! 2292: (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO") ! 2293: (match_operand:SI 2 "reg_or_0_operand" "rO"))) ! 2294: (set (reg:CC 0) ! 2295: (unspec:CC [(match_dup 1) (match_dup 2)] 1))])] ! 2296: "" ! 2297: "subu.co %r0,%r1,%r2") ! 2298: ! 2299: (define_insn "" ! 2300: [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO") ! 2301: (match_operand:SI 1 "reg_or_0_operand" "rO")] ! 2302: 1))] ! 2303: "" ! 2304: "subu.co %#r0,%r0,%r1") ! 2305: ! 2306: (define_insn "" ! 2307: [(set (match_operand:SI 0 "reg_or_0_operand" "=r") ! 2308: (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO") ! 2309: (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO") ! 2310: (reg:CC 0)] 1)))] ! 2311: "" ! 2312: "subu.ci %r0,%r1,%r2") ! 2313: ! 2314: ;;- multiply instructions ! 2315: ;; ! 2316: ;; There is an unfounded silicon eratta for E.1 requiring that an ! 2317: ;; immediate constant value in div/divu/mul instructions be less than ! 2318: ;; 0x800. This is no longer provided for. ! 2319: ! 2320: (define_insn "mulsi3" ! 2321: [(set (match_operand:SI 0 "register_operand" "=r") ! 2322: (mult:SI (match_operand:SI 1 "arith32_operand" "%r") ! 2323: (match_operand:SI 2 "arith32_operand" "rI")))] ! 2324: "" ! 2325: "mul %0,%1,%2" ! 2326: [(set_attr "type" "imul")]) ! 2327: ! 2328: (define_insn "umulsidi3" ! 2329: [(set (match_operand:DI 0 "register_operand" "=r") ! 2330: (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r")) ! 2331: (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))] ! 2332: "TARGET_88110" ! 2333: "mulu.d %0,%1,%2" ! 2334: [(set_attr "type" "imul")]) ! 2335: ! 2336: ;; patterns for mixed mode floating point ! 2337: ;; Do not define patterns that utilize mixed mode arithmetic that result ! 2338: ;; in narrowing the precision, because it loses accuracy, since the standard ! 2339: ;; requires double rounding, whereas the 88000 instruction only rounds once. ! 2340: ! 2341: (define_expand "muldf3" ! 2342: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2343: (mult:DF (match_operand:DF 1 "general_operand" "%r,x") ! 2344: (match_operand:DF 2 "general_operand" "r,x")))] ! 2345: "" ! 2346: " ! 2347: { ! 2348: operands[1] = legitimize_operand (operands[1], DFmode); ! 2349: operands[2] = legitimize_operand (operands[2], DFmode); ! 2350: }") ! 2351: ! 2352: (define_insn "" ! 2353: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2354: (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) ! 2355: (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] ! 2356: "" ! 2357: "fmul.dss %0,%1,%2" ! 2358: [(set_attr "type" "spmul")]) ! 2359: ! 2360: (define_insn "" ! 2361: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2362: (mult:DF (match_operand:DF 1 "register_operand" "r,x") ! 2363: (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] ! 2364: "" ! 2365: "fmul.dds %0,%1,%2" ! 2366: [(set_attr "type" "spmul")]) ! 2367: ! 2368: (define_insn "" ! 2369: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2370: (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) ! 2371: (match_operand:DF 2 "register_operand" "r,x")))] ! 2372: "" ! 2373: "fmul.dsd %0,%1,%2" ! 2374: [(set_attr "type" "spmul")]) ! 2375: ! 2376: (define_insn "" ! 2377: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2378: (mult:DF (match_operand:DF 1 "register_operand" "%r,x") ! 2379: (match_operand:DF 2 "register_operand" "r,x")))] ! 2380: "" ! 2381: "fmul.ddd %0,%1,%2" ! 2382: [(set_attr "type" "dpmul")]) ! 2383: ! 2384: (define_insn "mulsf3" ! 2385: [(set (match_operand:SF 0 "register_operand" "=r,x") ! 2386: (mult:SF (match_operand:SF 1 "register_operand" "%r,x") ! 2387: (match_operand:SF 2 "register_operand" "r,x")))] ! 2388: "" ! 2389: "fmul.sss %0,%1,%2" ! 2390: [(set_attr "type" "spmul")]) ! 2391: ! 2392: ;;- divide instructions ! 2393: ;; ! 2394: ;; The 88k div and divu instructions don't reliably trap on ! 2395: ;; divide-by-zero. A trap to vector 503 asserts divide-by-zero. The ! 2396: ;; general scheme for doing divide is to do a 4-way split based on the ! 2397: ;; sign of the two operand and do the appropriate negates. ! 2398: ;; ! 2399: ;; The conditional trap instruction is not used as this serializes the ! 2400: ;; processor. Instead a conditional branch and an unconditional trap ! 2401: ;; are used, but after the divu. Since the divu takes up to 38 cycles, ! 2402: ;; the conditional branch is essentially free. ! 2403: ;; ! 2404: ;; Two target options control how divide is done. One options selects ! 2405: ;; whether to do the branch and negate scheme instead of using the div ! 2406: ;; instruction; the other option selects whether to explicitly check ! 2407: ;; for divide-by-zero or take your chances. If the div instruction is ! 2408: ;; used, the O/S must complete the operation if the operands are ! 2409: ;; negative. The O/S will signal an overflow condition if the most ! 2410: ;; negative number (-214783648) is divided by negative 1. ! 2411: ;; ! 2412: ;; There is an unfounded silicon eratta for E.1 requiring that an ! 2413: ;; immediate constant value in div/divu/mul instructions be less than ! 2414: ;; 0x800. This is no longer provided for. ! 2415: ! 2416: ;; Division by 0 trap ! 2417: (define_insn "trap_divide_by_zero" ! 2418: [(trap_if (const_int 1) 503)] ! 2419: "" ! 2420: "tb0 0,%#r0,503" ! 2421: [(set_attr "type" "weird")]) ! 2422: ! 2423: ;; Conditional division by 0 trap. ! 2424: (define_expand "tcnd_divide_by_zero" ! 2425: [(set (pc) ! 2426: (if_then_else (eq (match_operand:SI 0 "register_operand" "") ! 2427: (const_int 0)) ! 2428: (pc) ! 2429: (match_operand 1 "" ""))) ! 2430: (trap_if (const_int 1) 503)] ! 2431: "" ! 2432: " ! 2433: { ! 2434: emit_insn (gen_cmpsi (operands[0], const0_rtx)); ! 2435: emit_jump_insn (gen_bne (operands[1])); ! 2436: emit_insn (gen_trap_divide_by_zero ()); ! 2437: DONE; ! 2438: }") ! 2439: ! 2440: (define_expand "divsi3" ! 2441: [(set (match_operand:SI 0 "register_operand" "") ! 2442: (div:SI (match_operand:SI 1 "arith32_operand" "") ! 2443: (match_operand:SI 2 "arith32_operand" "")))] ! 2444: "" ! 2445: " ! 2446: { ! 2447: rtx op0 = operands[0]; ! 2448: rtx op1 = operands[1]; ! 2449: rtx op2 = operands[2]; ! 2450: rtx join_label; ! 2451: ! 2452: /* @@ This needs to be reworked. Torbjorn Granlund has suggested making ! 2453: it a runtime (perhaps quite special). */ ! 2454: ! 2455: if (GET_CODE (op1) == CONST_INT) ! 2456: op1 = force_reg (SImode, op1); ! 2457: ! 2458: else if (GET_CODE (op2) == CONST_INT ! 2459: && ! SMALL_INT (operands[2])) ! 2460: op2 = force_reg (SImode, op2); ! 2461: ! 2462: if (op2 == const0_rtx) ! 2463: { ! 2464: emit_insn (gen_trap_divide_by_zero ()); ! 2465: emit_insn (gen_dummy (op0)); ! 2466: DONE; ! 2467: } ! 2468: ! 2469: if (TARGET_USE_DIV) ! 2470: { ! 2471: emit_move_insn (op0, gen_rtx (DIV, SImode, op1, op2)); ! 2472: if (TARGET_CHECK_ZERO_DIV && GET_CODE (op2) != CONST_INT) ! 2473: { ! 2474: rtx label = gen_label_rtx (); ! 2475: emit_insn (gen_tcnd_divide_by_zero (op2, label)); ! 2476: emit_label (label); ! 2477: emit_insn (gen_dummy (op0)); ! 2478: } ! 2479: DONE; ! 2480: } ! 2481: ! 2482: join_label = gen_label_rtx (); ! 2483: if (GET_CODE (op1) == CONST_INT) ! 2484: { ! 2485: int neg = FALSE; ! 2486: rtx neg_op2 = gen_reg_rtx (SImode); ! 2487: rtx label1 = gen_label_rtx (); ! 2488: ! 2489: if (INTVAL (op1) < 0) ! 2490: { ! 2491: neg = TRUE; ! 2492: op1 = gen_rtx (CONST_INT, VOIDmode, -INTVAL (op1)); ! 2493: } ! 2494: op1 = force_reg (SImode, op1); ! 2495: ! 2496: emit_insn (gen_negsi2 (neg_op2, op2)); ! 2497: emit_insn (gen_cmpsi (op2, const0_rtx)); ! 2498: emit_jump_insn (gen_bgt (label1)); ! 2499: /* constant / 0-or-negative */ ! 2500: emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, neg_op2)); ! 2501: if (!neg) ! 2502: emit_insn (gen_negsi2 (op0, op0)); ! 2503: ! 2504: if (TARGET_CHECK_ZERO_DIV) ! 2505: emit_insn (gen_tcnd_divide_by_zero (op2, join_label)); ! 2506: emit_jump_insn (gen_jump (join_label)); ! 2507: emit_barrier (); ! 2508: ! 2509: emit_label (label1); /* constant / positive */ ! 2510: emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2)); ! 2511: if (neg) ! 2512: emit_insn (gen_negsi2 (op0, op0)); ! 2513: } ! 2514: ! 2515: else if (GET_CODE (op2) == CONST_INT) ! 2516: { ! 2517: int neg = FALSE; ! 2518: rtx neg_op1 = gen_reg_rtx (SImode); ! 2519: rtx label1 = gen_label_rtx (); ! 2520: ! 2521: if (INTVAL (op2) < 0) ! 2522: { ! 2523: neg = TRUE; ! 2524: op2 = gen_rtx (CONST_INT, VOIDmode, -INTVAL (op2)); ! 2525: } ! 2526: else if (! SMALL_INT (operands[2])) ! 2527: op2 = force_reg (SImode, op2); ! 2528: ! 2529: emit_insn (gen_negsi2 (neg_op1, op1)); ! 2530: emit_insn (gen_cmpsi (op1, const0_rtx)); ! 2531: emit_jump_insn (gen_bge (label1)); ! 2532: /* 0-or-negative / constant */ ! 2533: emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, op2)); ! 2534: if (!neg) ! 2535: emit_insn (gen_negsi2 (op0, op0)); ! 2536: ! 2537: emit_jump_insn (gen_jump (join_label)); ! 2538: emit_barrier (); ! 2539: ! 2540: emit_label (label1); /* positive / constant */ ! 2541: emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2)); ! 2542: if (neg) ! 2543: emit_insn (gen_negsi2 (op0, op0)); ! 2544: } ! 2545: ! 2546: else ! 2547: { ! 2548: rtx neg_op1 = gen_reg_rtx (SImode); ! 2549: rtx neg_op2 = gen_reg_rtx (SImode); ! 2550: rtx label1 = gen_label_rtx (); ! 2551: rtx label2 = gen_label_rtx (); ! 2552: rtx label3 = gen_label_rtx (); ! 2553: rtx label4; ! 2554: ! 2555: emit_insn (gen_negsi2 (neg_op2, op2)); ! 2556: emit_insn (gen_cmpsi (op2, const0_rtx)); ! 2557: emit_jump_insn (gen_bgt (label1)); ! 2558: ! 2559: emit_insn (gen_negsi2 (neg_op1, op1)); ! 2560: emit_insn (gen_cmpsi (op1, const0_rtx)); ! 2561: emit_jump_insn (gen_bge (label2)); ! 2562: /* negative / negative-or-0 */ ! 2563: emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, neg_op2)); ! 2564: ! 2565: if (TARGET_CHECK_ZERO_DIV) ! 2566: { ! 2567: label4 = gen_label_rtx (); ! 2568: emit_insn (gen_cmpsi (op2, const0_rtx)); ! 2569: emit_jump_insn (gen_bne (join_label)); ! 2570: emit_label (label4); ! 2571: emit_insn (gen_trap_divide_by_zero ()); ! 2572: } ! 2573: emit_jump_insn (gen_jump (join_label)); ! 2574: emit_barrier (); ! 2575: ! 2576: emit_label (label2); /* pos.-or-0 / neg.-or-0 */ ! 2577: emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, neg_op2)); ! 2578: ! 2579: if (TARGET_CHECK_ZERO_DIV) ! 2580: { ! 2581: emit_insn (gen_cmpsi (op2, const0_rtx)); ! 2582: emit_jump_insn (gen_beq (label4)); ! 2583: } ! 2584: ! 2585: emit_insn (gen_negsi2 (op0, op0)); ! 2586: emit_jump_insn (gen_jump (join_label)); ! 2587: emit_barrier (); ! 2588: ! 2589: emit_label (label1); ! 2590: emit_insn (gen_negsi2 (neg_op1, op1)); ! 2591: emit_insn (gen_cmpsi (op1, const0_rtx)); ! 2592: emit_jump_insn (gen_bge (label3)); ! 2593: /* negative / positive */ ! 2594: emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, op2)); ! 2595: emit_insn (gen_negsi2 (op0, op0)); ! 2596: emit_jump_insn (gen_jump (join_label)); ! 2597: emit_barrier (); ! 2598: ! 2599: emit_label (label3); /* positive-or-0 / positive */ ! 2600: emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2)); ! 2601: } ! 2602: ! 2603: emit_label (join_label); ! 2604: ! 2605: emit_insn (gen_dummy (op0)); ! 2606: DONE; ! 2607: }") ! 2608: ! 2609: (define_insn "" ! 2610: [(set (match_operand:SI 0 "register_operand" "=r") ! 2611: (div:SI (match_operand:SI 1 "register_operand" "r") ! 2612: (match_operand:SI 2 "arith_operand" "rI")))] ! 2613: "" ! 2614: "div %0,%1,%2" ! 2615: [(set_attr "type" "idiv")]) ! 2616: ! 2617: (define_expand "udivsi3" ! 2618: [(set (match_operand:SI 0 "register_operand" "") ! 2619: (udiv:SI (match_operand:SI 1 "register_operand" "") ! 2620: (match_operand:SI 2 "arith32_operand" "")))] ! 2621: "" ! 2622: " ! 2623: { ! 2624: rtx op2 = operands[2]; ! 2625: ! 2626: if (op2 == const0_rtx) ! 2627: { ! 2628: emit_insn (gen_trap_divide_by_zero ()); ! 2629: emit_insn (gen_dummy (operands[0])); ! 2630: DONE; ! 2631: } ! 2632: else if (GET_CODE (op2) != CONST_INT && TARGET_CHECK_ZERO_DIV) ! 2633: { ! 2634: rtx label = gen_label_rtx (); ! 2635: emit_insn (gen_rtx (SET, VOIDmode, operands[0], ! 2636: gen_rtx (UDIV, SImode, operands[1], op2))); ! 2637: emit_insn (gen_tcnd_divide_by_zero (op2, label)); ! 2638: emit_label (label); ! 2639: emit_insn (gen_dummy (operands[0])); ! 2640: DONE; ! 2641: } ! 2642: }") ! 2643: ! 2644: (define_insn "" ! 2645: [(set (match_operand:SI 0 "register_operand" "=r") ! 2646: (udiv:SI (match_operand:SI 1 "register_operand" "r") ! 2647: (match_operand:SI 2 "arith32_operand" "rI")))] ! 2648: "operands[2] != const0_rtx" ! 2649: "divu %0,%1,%2" ! 2650: [(set_attr "type" "idiv")]) ! 2651: ! 2652: (define_insn "" ! 2653: [(set (match_operand:SI 0 "register_operand" "=r") ! 2654: (udiv:SI (match_operand:SI 1 "register_operand" "r") ! 2655: (const_int 0)))] ! 2656: "" ! 2657: "tb0 0,%#r0,503" ! 2658: [(set_attr "type" "weird")]) ! 2659: ! 2660: ;; patterns for mixed mode floating point. ! 2661: ;; Do not define patterns that utilize mixed mode arithmetic that result ! 2662: ;; in narrowing the precision, because it loses accuracy, since the standard ! 2663: ;; requires double rounding, whereas the 88000 instruction only rounds once. ! 2664: ! 2665: (define_expand "divdf3" ! 2666: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2667: (div:DF (match_operand:DF 1 "general_operand" "r,x") ! 2668: (match_operand:DF 2 "general_operand" "r,x")))] ! 2669: "" ! 2670: " ! 2671: { ! 2672: operands[1] = legitimize_operand (operands[1], DFmode); ! 2673: if (real_power_of_2_operand (operands[2])) ! 2674: { ! 2675: union real_extract u; ! 2676: bcopy (&CONST_DOUBLE_LOW (operands[2]), &u, sizeof u); ! 2677: emit_insn (gen_muldf3 (operands[0], operands[1], ! 2678: CONST_DOUBLE_FROM_REAL_VALUE (1.0/u.d, DFmode))); ! 2679: DONE; ! 2680: } ! 2681: else if (! register_operand (operands[2], DFmode)) ! 2682: operands[2] = force_reg (DFmode, operands[2]); ! 2683: }") ! 2684: ! 2685: (define_insn "" ! 2686: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2687: (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) ! 2688: (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] ! 2689: "" ! 2690: "fdiv.dss %0,%1,%2" ! 2691: [(set_attr "type" "dpdiv")]) ! 2692: ! 2693: (define_insn "" ! 2694: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2695: (div:DF (match_operand:DF 1 "register_operand" "r,x") ! 2696: (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] ! 2697: "" ! 2698: "fdiv.dds %0,%1,%2" ! 2699: [(set_attr "type" "dpdiv")]) ! 2700: ! 2701: (define_insn "" ! 2702: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2703: (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) ! 2704: (match_operand:DF 2 "register_operand" "r,x")))] ! 2705: "" ! 2706: "fdiv.dsd %0,%1,%2" ! 2707: [(set_attr "type" "dpdiv")]) ! 2708: ! 2709: (define_insn "divsf3" ! 2710: [(set (match_operand:SF 0 "register_operand" "=r,x") ! 2711: (div:SF (match_operand:SF 1 "register_operand" "r,x") ! 2712: (match_operand:SF 2 "register_operand" "r,x")))] ! 2713: "" ! 2714: "fdiv.sss %0,%1,%2" ! 2715: [(set_attr "type" "spdiv")]) ! 2716: ! 2717: (define_insn "" ! 2718: [(set (match_operand:DF 0 "register_operand" "=r,x") ! 2719: (div:DF (match_operand:DF 1 "register_operand" "r,x") ! 2720: (match_operand:DF 2 "register_operand" "r,x")))] ! 2721: "" ! 2722: "fdiv.ddd %0,%1,%2" ! 2723: [(set_attr "type" "dpdiv")]) ! 2724: ! 2725: ;; - remainder instructions, don't define, since the hardware doesn't have any ! 2726: ;; direct support, and GNU can synthesis them out of div/mul just fine. ! 2727: ! 2728: ;;- load effective address, must come after add, so that we favor using ! 2729: ;; addu reg,reg,reg instead of: lda reg,reg,reg (addu doesn't require ! 2730: ;; the data unit), and also future 88k chips might not support unscaled ! 2731: ;; lda instructions. ! 2732: ! 2733: (define_insn "" ! 2734: [(set (match_operand:SI 0 "register_operand" "=r") ! 2735: (match_operand:SI 1 "address_operand" "p"))] ! 2736: "m88k_gp_threshold > 0 && symbolic_address_p (operands[1])" ! 2737: "addu %0,%a1") ! 2738: ! 2739: (define_insn "" ! 2740: [(set (match_operand:SI 0 "register_operand" "=r") ! 2741: (match_operand:HI 1 "address_operand" "p"))] ! 2742: "" ! 2743: "lda.h %0,%a1" ! 2744: [(set_attr "type" "loada")]) ! 2745: ! 2746: (define_insn "" ! 2747: [(set (match_operand:SI 0 "register_operand" "=r") ! 2748: (match_operand:SI 1 "address_operand" "p"))] ! 2749: "" ! 2750: "lda %0,%a1" ! 2751: [(set_attr "type" "loada")]) ! 2752: ! 2753: (define_insn "" ! 2754: [(set (match_operand:SI 0 "register_operand" "=r") ! 2755: (match_operand:DI 1 "address_operand" "p"))] ! 2756: "" ! 2757: "lda.d %0,%a1" ! 2758: [(set_attr "type" "loada")]) ! 2759: ! 2760: (define_insn "" ! 2761: [(set (match_operand:SI 0 "register_operand" "=r") ! 2762: (match_operand:SF 1 "address_operand" "p"))] ! 2763: "" ! 2764: "lda %0,%a1" ! 2765: [(set_attr "type" "loada")]) ! 2766: ! 2767: (define_insn "" ! 2768: [(set (match_operand:SI 0 "register_operand" "=r") ! 2769: (match_operand:DF 1 "address_operand" "p"))] ! 2770: "" ! 2771: "lda.d %0,%a1" ! 2772: [(set_attr "type" "loada")]) ! 2773: ! 2774: ;;- and instructions (with complement also) ! 2775: (define_insn "" ! 2776: [(set (match_operand:SI 0 "register_operand" "=r") ! 2777: (and:SI (not:SI (match_operand:SI 1 "register_operand" "r")) ! 2778: (match_operand:SI 2 "register_operand" "r")))] ! 2779: "" ! 2780: "and.c %0,%2,%1") ! 2781: ! 2782: ;; If the operation is being performed on a 32-bit constant such that ! 2783: ;; it cannot be done in one insn, do it in two. We may lose a bit on ! 2784: ;; CSE in pathological cases, but it seems better doing it this way. ! 2785: ! 2786: (define_expand "andsi3" ! 2787: [(set (match_operand:SI 0 "register_operand" "") ! 2788: (and:SI (match_operand:SI 1 "arith32_operand" "") ! 2789: (match_operand:SI 2 "arith32_operand" "")))] ! 2790: "" ! 2791: " ! 2792: { ! 2793: if (GET_CODE (operands[2]) == CONST_INT) ! 2794: { ! 2795: int value = INTVAL (operands[2]); ! 2796: ! 2797: if (! (SMALL_INTVAL (value) ! 2798: || (value & 0xffff0000) == 0xffff0000 ! 2799: || (value & 0xffff) == 0xffff ! 2800: || (value & 0xffff) == 0 ! 2801: || integer_ok_for_set (~value))) ! 2802: { ! 2803: emit_insn (gen_andsi3 (operands[0], operands[1], ! 2804: gen_rtx (CONST_INT, VOIDmode, ! 2805: value | 0xffff))); ! 2806: operands[1] = operands[0]; ! 2807: operands[2] = gen_rtx (CONST_INT, VOIDmode, value | 0xffff0000); ! 2808: } ! 2809: } ! 2810: }") ! 2811: ! 2812: (define_insn "" ! 2813: [(set (match_operand:SI 0 "register_operand" "=r,r") ! 2814: (and:SI (match_operand:SI 1 "arith32_operand" "%r,r") ! 2815: (match_operand:SI 2 "arith32_operand" "rIJL,rn")))] ! 2816: "" ! 2817: "* return output_and (operands);" ! 2818: [(set_attr "type" "arith,marith")]) ! 2819: ! 2820: (define_insn "" ! 2821: [(set (match_operand:DI 0 "register_operand" "=r") ! 2822: (and:DI (not:DI (match_operand:DI 1 "register_operand" "r")) ! 2823: (match_operand:DI 2 "register_operand" "r")))] ! 2824: "" ! 2825: "and.c %d0,%d2,%d1\;and.c %0,%2,%1" ! 2826: [(set_attr "type" "marith")]) ! 2827: ! 2828: (define_insn "anddi3" ! 2829: [(set (match_operand:DI 0 "register_operand" "=r") ! 2830: (and:DI (match_operand:DI 1 "arith64_operand" "%r") ! 2831: (match_operand:DI 2 "arith64_operand" "rn")))] ! 2832: "" ! 2833: "* ! 2834: { ! 2835: rtx xoperands[10]; ! 2836: ! 2837: xoperands[0] = operand_subword (operands[0], 1, 0, DImode); ! 2838: xoperands[1] = operand_subword (operands[1], 1, 0, DImode); ! 2839: xoperands[2] = operand_subword (operands[2], 1, 0, DImode); ! 2840: ! 2841: output_asm_insn (output_and (xoperands), xoperands); ! 2842: ! 2843: operands[0] = operand_subword (operands[0], 0, 0, DImode); ! 2844: operands[1] = operand_subword (operands[1], 0, 0, DImode); ! 2845: operands[2] = operand_subword (operands[2], 0, 0, DImode); ! 2846: ! 2847: return output_and (operands); ! 2848: }" ! 2849: [(set_attr "type" "marith") ! 2850: (set_attr "length" "4")]) ; length is 2, 3, or 4. ! 2851: ! 2852: ;;- Bit set (inclusive or) instructions (with complement also) ! 2853: (define_insn "" ! 2854: [(set (match_operand:SI 0 "register_operand" "=r") ! 2855: (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r")) ! 2856: (match_operand:SI 2 "register_operand" "r")))] ! 2857: "" ! 2858: "or.c %0,%2,%1") ! 2859: ! 2860: (define_expand "iorsi3" ! 2861: [(set (match_operand:SI 0 "register_operand" "") ! 2862: (ior:SI (match_operand:SI 1 "arith32_operand" "") ! 2863: (match_operand:SI 2 "arith32_operand" "")))] ! 2864: "" ! 2865: " ! 2866: { ! 2867: if (GET_CODE (operands[2]) == CONST_INT) ! 2868: { ! 2869: int value = INTVAL (operands[2]); ! 2870: ! 2871: if (! (SMALL_INTVAL (value) ! 2872: || (value & 0xffff) == 0 ! 2873: || integer_ok_for_set (value))) ! 2874: { ! 2875: emit_insn (gen_iorsi3 (operands[0], operands[1], ! 2876: gen_rtx (CONST_INT, VOIDmode, ! 2877: value & 0xffff0000))); ! 2878: operands[1] = operands[0]; ! 2879: operands[2] = gen_rtx (CONST_INT, VOIDmode, value & 0xffff); ! 2880: } ! 2881: } ! 2882: }") ! 2883: ! 2884: (define_insn "" ! 2885: [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") ! 2886: (ior:SI (match_operand:SI 1 "arith32_operand" "%r,r,r,r") ! 2887: (match_operand:SI 2 "arith32_operand" "rI,L,M,n")))] ! 2888: "" ! 2889: "@ ! 2890: or %0,%1,%2 ! 2891: or.u %0,%1,%X2 ! 2892: set %0,%1,%s2 ! 2893: or.u %0,%1,%X2\;or %0,%0,%x2" ! 2894: [(set_attr "type" "arith,arith,bit,marith")]) ! 2895: ! 2896: (define_insn "" ! 2897: [(set (match_operand:DI 0 "register_operand" "=r") ! 2898: (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r")) ! 2899: (match_operand:DI 2 "register_operand" "r")))] ! 2900: "" ! 2901: "or.c %d0,%d2,%d1\;or.c %0,%2,%1" ! 2902: [(set_attr "type" "marith")]) ! 2903: ! 2904: (define_insn "iordi3" ! 2905: [(set (match_operand:DI 0 "register_operand" "=r") ! 2906: (ior:DI (match_operand:DI 1 "arith64_operand" "%r") ! 2907: (match_operand:DI 2 "arith64_operand" "rn")))] ! 2908: "" ! 2909: "* ! 2910: { ! 2911: rtx xoperands[10]; ! 2912: ! 2913: xoperands[0] = operand_subword (operands[0], 1, 0, DImode); ! 2914: xoperands[1] = operand_subword (operands[1], 1, 0, DImode); ! 2915: xoperands[2] = operand_subword (operands[2], 1, 0, DImode); ! 2916: ! 2917: output_asm_insn (output_ior (xoperands), xoperands); ! 2918: ! 2919: operands[0] = operand_subword (operands[0], 0, 0, DImode); ! 2920: operands[1] = operand_subword (operands[1], 0, 0, DImode); ! 2921: operands[2] = operand_subword (operands[2], 0, 0, DImode); ! 2922: ! 2923: return output_ior (operands); ! 2924: }" ! 2925: [(set_attr "type" "marith") ! 2926: (set_attr "length" "4")]) ; length is 2, 3, or 4. ! 2927: ! 2928: ;;- xor instructions (with complement also) ! 2929: (define_insn "" ! 2930: [(set (match_operand:SI 0 "register_operand" "=r") ! 2931: (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%r") ! 2932: (match_operand:SI 2 "register_operand" "r"))))] ! 2933: "" ! 2934: "xor.c %0,%1,%2") ! 2935: ! 2936: (define_expand "xorsi3" ! 2937: [(set (match_operand:SI 0 "register_operand" "") ! 2938: (xor:SI (match_operand:SI 1 "arith32_operand" "") ! 2939: (match_operand:SI 2 "arith32_operand" "")))] ! 2940: "" ! 2941: " ! 2942: { ! 2943: if (GET_CODE (operands[2]) == CONST_INT) ! 2944: { ! 2945: int value = INTVAL (operands[2]); ! 2946: ! 2947: if (! (SMALL_INTVAL (value) ! 2948: || (value & 0xffff) == 0)) ! 2949: { ! 2950: emit_insn (gen_xorsi3 (operands[0], operands[1], ! 2951: gen_rtx (CONST_INT, VOIDmode, ! 2952: value & 0xffff0000))); ! 2953: operands[1] = operands[0]; ! 2954: operands[2] = gen_rtx (CONST_INT, VOIDmode, value & 0xffff); ! 2955: } ! 2956: } ! 2957: }") ! 2958: ! 2959: (define_insn "" ! 2960: [(set (match_operand:SI 0 "register_operand" "=r,r,r") ! 2961: (xor:SI (match_operand:SI 1 "arith32_operand" "%r,r,r") ! 2962: (match_operand:SI 2 "arith32_operand" "rI,L,n")))] ! 2963: "" ! 2964: "@ ! 2965: xor %0,%1,%2 ! 2966: xor.u %0,%1,%X2 ! 2967: xor.u %0,%1,%X2\;xor %0,%0,%x2" ! 2968: [(set_attr "type" "arith,arith,marith")]) ! 2969: ! 2970: (define_insn "" ! 2971: [(set (match_operand:DI 0 "register_operand" "=r") ! 2972: (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r") ! 2973: (match_operand:DI 2 "register_operand" "r"))))] ! 2974: "" ! 2975: "xor.c %d0,%d1,%d2\;xor.c %0,%1,%2" ! 2976: [(set_attr "type" "marith")]) ! 2977: ! 2978: (define_insn "xordi3" ! 2979: [(set (match_operand:DI 0 "register_operand" "=r") ! 2980: (xor:DI (match_operand:DI 1 "arith64_operand" "%r") ! 2981: (match_operand:DI 2 "arith64_operand" "rn")))] ! 2982: "" ! 2983: "* ! 2984: { ! 2985: rtx xoperands[10]; ! 2986: ! 2987: xoperands[0] = operand_subword (operands[0], 1, 0, DImode); ! 2988: xoperands[1] = operand_subword (operands[1], 1, 0, DImode); ! 2989: xoperands[2] = operand_subword (operands[2], 1, 0, DImode); ! 2990: ! 2991: output_asm_insn (output_xor (xoperands), xoperands); ! 2992: ! 2993: operands[0] = operand_subword (operands[0], 0, 0, DImode); ! 2994: operands[1] = operand_subword (operands[1], 0, 0, DImode); ! 2995: operands[2] = operand_subword (operands[2], 0, 0, DImode); ! 2996: ! 2997: return output_xor (operands); ! 2998: }" ! 2999: [(set_attr "type" "marith") ! 3000: (set_attr "length" "4")]) ; length is 2, 3, or 4. ! 3001: ! 3002: ;;- ones complement instructions ! 3003: (define_insn "one_cmplsi2" ! 3004: [(set (match_operand:SI 0 "register_operand" "=r") ! 3005: (not:SI (match_operand:SI 1 "register_operand" "r")))] ! 3006: "" ! 3007: "xor.c %0,%1,%#r0") ! 3008: ! 3009: (define_insn "one_cmpldi2" ! 3010: [(set (match_operand:DI 0 "register_operand" "=r") ! 3011: (not:DI (match_operand:DI 1 "register_operand" "r")))] ! 3012: "" ! 3013: "xor.c %d0,%d1,%#r0\;xor.c %0,%1,%#r0" ! 3014: [(set_attr "type" "marith")]) ! 3015: ! 3016: ;; Optimized special cases of shifting. ! 3017: ;; Must precede the general case. ! 3018: ! 3019: ;; @@ What about HImode shifted by 8? ! 3020: ! 3021: (define_insn "" ! 3022: [(set (match_operand:SI 0 "register_operand" "=r") ! 3023: (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m") ! 3024: (const_int 24)))] ! 3025: "! SCALED_ADDRESS_P (XEXP (operands[1], 0))" ! 3026: "%V1ld.b\\t %0,%1" ! 3027: [(set_attr "type" "load")]) ! 3028: ! 3029: (define_insn "" ! 3030: [(set (match_operand:SI 0 "register_operand" "=r") ! 3031: (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") ! 3032: (const_int 24)))] ! 3033: "! SCALED_ADDRESS_P (XEXP (operands[1], 0))" ! 3034: "%V1ld.bu\\t %0,%1" ! 3035: [(set_attr "type" "load")]) ! 3036: ! 3037: (define_insn "" ! 3038: [(set (match_operand:SI 0 "register_operand" "=r") ! 3039: (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m") ! 3040: (const_int 16)))] ! 3041: "! SCALED_ADDRESS_P (XEXP (operands[1], 0))" ! 3042: "%V1ld.h\\t %0,%1" ! 3043: [(set_attr "type" "load")]) ! 3044: ! 3045: (define_insn "" ! 3046: [(set (match_operand:SI 0 "register_operand" "=r") ! 3047: (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") ! 3048: (const_int 16)))] ! 3049: "! SCALED_ADDRESS_P (XEXP (operands[1], 0))" ! 3050: "%V1ld.hu\\t %0,%1" ! 3051: [(set_attr "type" "load")]) ! 3052: ! 3053: ;;- arithmetic shift instructions. ! 3054: ! 3055: ;; @@ Do the optimized patterns with -1 get used? Perhaps operand 1 should ! 3056: ;; be arith32_operand? ! 3057: ! 3058: ;; Use tbnd to support TARGET_TRAP_LARGE_SHIFT. ! 3059: (define_insn "tbnd" ! 3060: [(trap_if (gtu (match_operand:SI 0 "register_operand" "r") ! 3061: (match_operand:SI 1 "arith_operand" "rI")) ! 3062: 7)] ! 3063: "" ! 3064: "tbnd %r0,%1" ! 3065: [(set_attr "type" "weird")]) ! 3066: ! 3067: ;; Just in case the optimizer decides to fold away the test. ! 3068: (define_insn "" ! 3069: [(trap_if (const_int 1) 7)] ! 3070: "" ! 3071: "tbnd %#r31,0" ! 3072: [(set_attr "type" "weird")]) ! 3073: ! 3074: (define_expand "ashlsi3" ! 3075: [(set (match_operand:SI 0 "register_operand" "") ! 3076: (ashift:SI (match_operand:SI 1 "register_operand" "") ! 3077: (match_operand:SI 2 "arith32_operand" "")))] ! 3078: "" ! 3079: " ! 3080: { ! 3081: if (GET_CODE (operands[2]) == CONST_INT) ! 3082: { ! 3083: if ((unsigned) INTVAL (operands[2]) > 31) ! 3084: { ! 3085: if (TARGET_TRAP_LARGE_SHIFT) ! 3086: emit_insn (gen_tbnd (force_reg (SImode, operands[2]), ! 3087: gen_rtx (CONST_INT, VOIDmode, 31))); ! 3088: else ! 3089: emit_move_insn (operands[0], const0_rtx); ! 3090: DONE; ! 3091: } ! 3092: } ! 3093: ! 3094: else if (TARGET_TRAP_LARGE_SHIFT) ! 3095: emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31))); ! 3096: ! 3097: else if (TARGET_HANDLE_LARGE_SHIFT) ! 3098: { ! 3099: rtx reg = gen_reg_rtx (SImode); ! 3100: emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31))); ! 3101: emit_insn (gen_sleu (reg)); ! 3102: emit_insn (gen_andsi3 (reg, operands[1], reg)); ! 3103: operands[1] = reg; ! 3104: } ! 3105: }") ! 3106: ! 3107: (define_insn "" ! 3108: [(set (match_operand:SI 0 "register_operand" "=r,r") ! 3109: (ashift:SI (match_operand:SI 1 "register_operand" "r,r") ! 3110: (match_operand:SI 2 "arith5_operand" "r,K")))] ! 3111: "" ! 3112: "@ ! 3113: mak %0,%1,%2 ! 3114: mak %0,%1,0<%2>" ! 3115: [(set_attr "type" "bit")]) ! 3116: ! 3117: (define_expand "ashrsi3" ! 3118: [(set (match_operand:SI 0 "register_operand" "") ! 3119: (ashiftrt:SI (match_operand:SI 1 "register_operand" "") ! 3120: (match_operand:SI 2 "arith32_operand" "")))] ! 3121: "" ! 3122: " ! 3123: { ! 3124: if (GET_CODE (operands[2]) == CONST_INT) ! 3125: { ! 3126: if ((unsigned) INTVAL (operands[2]) > 31) ! 3127: { ! 3128: if (TARGET_TRAP_LARGE_SHIFT) ! 3129: { ! 3130: emit_insn (gen_tbnd (force_reg (SImode, operands[2]), ! 3131: gen_rtx (CONST_INT, VOIDmode, 31))); ! 3132: DONE; ! 3133: } ! 3134: else ! 3135: operands[2] = gen_rtx (CONST_INT, VOIDmode, 31); ! 3136: } ! 3137: } ! 3138: ! 3139: else if (TARGET_TRAP_LARGE_SHIFT) ! 3140: emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31))); ! 3141: ! 3142: else if (TARGET_HANDLE_LARGE_SHIFT) ! 3143: { ! 3144: rtx reg = gen_reg_rtx (SImode); ! 3145: emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31))); ! 3146: emit_insn (gen_sgtu (reg)); ! 3147: emit_insn (gen_iorsi3 (reg, operands[2], reg)); ! 3148: operands[2] = reg; ! 3149: } ! 3150: }") ! 3151: ! 3152: (define_insn "" ! 3153: [(set (match_operand:SI 0 "register_operand" "=r,r") ! 3154: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r") ! 3155: (match_operand:SI 2 "arith5_operand" "r,K")))] ! 3156: "" ! 3157: "@ ! 3158: ext %0,%1,%2 ! 3159: ext %0,%1,0<%2>" ! 3160: [(set_attr "type" "bit")]) ! 3161: ! 3162: ;;- logical shift instructions. Logical shift left becomes arithmetic ! 3163: ;; shift left. LSHIFT is not normally produced, but is supported. ! 3164: ! 3165: (define_expand "lshlsi3" ! 3166: [(set (match_operand:SI 0 "register_operand" "") ! 3167: (lshift:SI (match_operand:SI 1 "register_operand" "") ! 3168: (match_operand:SI 2 "arith32_operand" "")))] ! 3169: "" ! 3170: " ! 3171: { ! 3172: emit_insn (gen_ashlsi3 (operands[0], operands[1], operands[2])); ! 3173: DONE; ! 3174: }") ! 3175: ! 3176: (define_insn "" ! 3177: [(set (match_operand:SI 0 "register_operand" "=r,r") ! 3178: (lshift:SI (match_operand:SI 1 "register_operand" "r,r") ! 3179: (match_operand:SI 2 "arith5_operand" "r,K")))] ! 3180: "" ! 3181: "@ ! 3182: mak %0,%1,%2 ! 3183: mak %0,%1,0<%2>" ! 3184: [(set_attr "type" "bit")]) ! 3185: ! 3186: (define_expand "lshrsi3" ! 3187: [(set (match_operand:SI 0 "register_operand" "") ! 3188: (lshiftrt:SI (match_operand:SI 1 "register_operand" "") ! 3189: (match_operand:SI 2 "arith32_operand" "")))] ! 3190: "" ! 3191: " ! 3192: { ! 3193: if (GET_CODE (operands[2]) == CONST_INT) ! 3194: { ! 3195: if ((unsigned) INTVAL (operands[2]) > 31) ! 3196: { ! 3197: if (TARGET_TRAP_LARGE_SHIFT) ! 3198: emit_insn (gen_tbnd (force_reg (SImode, operands[2]), ! 3199: gen_rtx (CONST_INT, VOIDmode, 31))); ! 3200: else ! 3201: emit_move_insn (operands[0], const0_rtx); ! 3202: DONE; ! 3203: } ! 3204: } ! 3205: ! 3206: else if (TARGET_TRAP_LARGE_SHIFT) ! 3207: emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31))); ! 3208: ! 3209: else if (TARGET_HANDLE_LARGE_SHIFT) ! 3210: { ! 3211: rtx reg = gen_reg_rtx (SImode); ! 3212: emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31))); ! 3213: emit_insn (gen_sleu (reg)); ! 3214: emit_insn (gen_andsi3 (reg, operands[1], reg)); ! 3215: operands[1] = reg; ! 3216: } ! 3217: }") ! 3218: ! 3219: (define_insn "" ! 3220: [(set (match_operand:SI 0 "register_operand" "=r,r") ! 3221: (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r") ! 3222: (match_operand:SI 2 "arith5_operand" "r,K")))] ! 3223: "" ! 3224: "@ ! 3225: extu %0,%1,%2 ! 3226: extu %0,%1,0<%2>" ! 3227: [(set_attr "type" "bit")]) ! 3228: ! 3229: ;;- rotate instructions ! 3230: ! 3231: (define_expand "rotlsi3" ! 3232: [(set (match_operand:SI 0 "register_operand" "") ! 3233: (rotatert:SI (match_operand:SI 1 "register_operand" "") ! 3234: (match_operand:SI 2 "arith32_operand" "")))] ! 3235: "" ! 3236: " ! 3237: { ! 3238: if (GET_CODE (operands[2]) == CONST_INT ! 3239: && (unsigned) INTVAL (operands[2]) >= 32) ! 3240: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 3241: (32 - INTVAL (operands[2])) % 32); ! 3242: else ! 3243: { ! 3244: rtx op = gen_reg_rtx (SImode); ! 3245: emit_insn (gen_negsi2 (op, operands[2])); ! 3246: operands[2] = op; ! 3247: } ! 3248: }") ! 3249: ! 3250: (define_insn "rotrsi3" ! 3251: [(set (match_operand:SI 0 "register_operand" "=r") ! 3252: (rotatert:SI (match_operand:SI 1 "register_operand" "r") ! 3253: (match_operand:SI 2 "arith_operand" "rI")))] ! 3254: "" ! 3255: "rot %0,%1,%2" ! 3256: [(set_attr "type" "bit")]) ! 3257: ! 3258: ;; find first set. ! 3259: ! 3260: ;; The ff1 instruction searches from the most significant bit while ffs ! 3261: ;; searches from the least significant bit. The bit index and treatment of ! 3262: ;; zero also differ. This amazing sequence was discovered using the GNU ! 3263: ;; Superoptimizer. ! 3264: ! 3265: (define_insn "ffssi2" ! 3266: [(set (match_operand:SI 0 "register_operand" "=r,&r") ! 3267: (ffs:SI (match_operand:SI 1 "register_operand" "0,r"))) ! 3268: (clobber (reg:CC 0)) ! 3269: (clobber (match_scratch:SI 2 "=r,X"))] ! 3270: "" ! 3271: "@ ! 3272: subu.co %2,%#r0,%1\;and %2,%2,%1\;addu.ci %2,%2,%2\;ff1 %0,%2 ! 3273: subu.co %0,%#r0,%1\;and %0,%0,%1\;addu.ci %0,%0,%0\;ff1 %0,%0" ! 3274: [(set_attr "type" "marith") ! 3275: (set_attr "length" "4")]) ! 3276: ! 3277: ;; Bit field instructions. ! 3278: ! 3279: (define_insn "" ! 3280: [(set (match_operand:SI 0 "register_operand" "=r") ! 3281: (sign_extract:SI (match_operand:SI 1 "register_operand" "r") ! 3282: (const_int 32) ! 3283: (const_int 0)))] ! 3284: "" ! 3285: "or %0,%#r0,%1") ! 3286: ! 3287: (define_insn "extv" ! 3288: [(set (match_operand:SI 0 "register_operand" "=r") ! 3289: (sign_extract:SI (match_operand:SI 1 "register_operand" "r") ! 3290: (match_operand:SI 2 "int5_operand" "") ! 3291: (match_operand:SI 3 "int5_operand" "")))] ! 3292: "" ! 3293: "* ! 3294: { ! 3295: operands[4] = gen_rtx (CONST_INT, SImode, ! 3296: (32 - INTVAL (operands[2])) - INTVAL (operands[3])); ! 3297: return \"ext %0,%1,%2<%4>\"; /* <(32-%2-%3)> */ ! 3298: }" ! 3299: [(set_attr "type" "bit")]) ! 3300: ! 3301: (define_insn "" ! 3302: [(set (match_operand:SI 0 "register_operand" "=r") ! 3303: (zero_extract:SI (match_operand:SI 1 "register_operand" "r") ! 3304: (const_int 32) ! 3305: (const_int 0)))] ! 3306: "" ! 3307: "or %0,%#r0,%1") ! 3308: ! 3309: (define_insn "extzv" ! 3310: [(set (match_operand:SI 0 "register_operand" "=r") ! 3311: (zero_extract:SI (match_operand:SI 1 "register_operand" "r") ! 3312: (match_operand:SI 2 "int5_operand" "") ! 3313: (match_operand:SI 3 "int5_operand" "")))] ! 3314: "" ! 3315: "* ! 3316: { ! 3317: operands[4] = gen_rtx (CONST_INT, SImode, ! 3318: (32 - INTVAL (operands[2])) - INTVAL (operands[3])); ! 3319: return \"extu %0,%1,%2<%4>\"; /* <(32-%2-%3)> */ ! 3320: }" ! 3321: [(set_attr "type" "bit")]) ! 3322: ! 3323: (define_insn "" ! 3324: [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") ! 3325: (match_operand:SI 1 "int5_operand" "") ! 3326: (match_operand:SI 2 "int5_operand" "")) ! 3327: (const_int 0))] ! 3328: "" ! 3329: "* ! 3330: { ! 3331: operands[3] = gen_rtx (CONST_INT, SImode, ! 3332: (32 - INTVAL (operands[1])) - INTVAL (operands[2])); ! 3333: return \"clr %0,%0,%1<%3>\"; /* <(32-%1-%2)> */ ! 3334: }" ! 3335: [(set_attr "type" "bit")]) ! 3336: ! 3337: (define_insn "" ! 3338: [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") ! 3339: (match_operand:SI 1 "int5_operand" "") ! 3340: (match_operand:SI 2 "int5_operand" "")) ! 3341: (const_int -1))] ! 3342: "" ! 3343: "* ! 3344: { ! 3345: operands[3] = gen_rtx (CONST_INT, SImode, ! 3346: (32 - INTVAL (operands[1])) - INTVAL (operands[2])); ! 3347: return \"set %0,%0,%1<%3>\"; /* <(32-%1-%2)> */ ! 3348: }" ! 3349: [(set_attr "type" "bit")]) ! 3350: ! 3351: (define_insn "" ! 3352: [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") ! 3353: (match_operand:SI 1 "int5_operand" "") ! 3354: (match_operand:SI 2 "int5_operand" "")) ! 3355: (match_operand:SI 3 "int32_operand" "n"))] ! 3356: "" ! 3357: "* ! 3358: { ! 3359: int value = INTVAL (operands[3]); ! 3360: ! 3361: if (INTVAL (operands[1]) < 32) ! 3362: value &= (1 << INTVAL (operands[1])) - 1; ! 3363: ! 3364: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 3365: 32 - (INTVAL(operands[1]) + INTVAL(operands[2]))); ! 3366: ! 3367: value <<= INTVAL (operands[2]); ! 3368: operands[3] = gen_rtx (CONST_INT, VOIDmode, value); ! 3369: ! 3370: if (SMALL_INTVAL (value)) ! 3371: return \"clr %0,%0,%1<%2>\;or %0,%0,%3\"; ! 3372: else if ((value & 0x0000ffff) == 0) ! 3373: return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\"; ! 3374: else ! 3375: return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\;or %0,%0,%x3\"; ! 3376: }" ! 3377: [(set_attr "type" "marith") ! 3378: (set_attr "length" "3")]) ; may be 2 or 3. ! 3379: ! 3380: ;; negate insns ! 3381: (define_insn "negsi2" ! 3382: [(set (match_operand:SI 0 "register_operand" "=r") ! 3383: (neg:SI (match_operand:SI 1 "arith_operand" "rI")))] ! 3384: "" ! 3385: "subu %0,%#r0,%1") ! 3386: ! 3387: (define_insn "" ! 3388: [(set (match_operand:SF 0 "register_operand" "=r,x") ! 3389: (float_truncate:SF (neg:DF (match_operand:DF 1 "register_operand" "r,x"))))] ! 3390: "" ! 3391: "@ ! 3392: fsub.ssd %0,%#r0,%1 ! 3393: fsub.ssd %0,%#x0,%1" ! 3394: [(set_attr "type" "dpadd")]) ! 3395: ! 3396: (define_insn "negdf2" ! 3397: [(set (match_operand:DF 0 "register_operand" "=&r,r") ! 3398: (neg:DF (match_operand:DF 1 "register_operand" "r,0")))] ! 3399: "" ! 3400: "@ ! 3401: xor.u %0,%1,0x8000\;or %d0,%#r0,%d1 ! 3402: xor.u %0,%0,0x8000" ! 3403: [(set_attr "type" "marith,arith")]) ! 3404: ! 3405: (define_insn "negsf2" ! 3406: [(set (match_operand:SF 0 "register_operand" "=r") ! 3407: (neg:SF (match_operand:SF 1 "register_operand" "r")))] ! 3408: "" ! 3409: "xor.u %0,%1,0x8000") ! 3410: ! 3411: ;; absolute value insns for floating-point (integer abs can be done using the ! 3412: ;; machine-independent sequence). ! 3413: ! 3414: (define_insn "absdf2" ! 3415: [(set (match_operand:DF 0 "register_operand" "=&r,r") ! 3416: (abs:DF (match_operand:DF 1 "register_operand" "r,0")))] ! 3417: "" ! 3418: "@ ! 3419: and.u %0,%1,0x7fff\;or %d0,%#r0,%d1 ! 3420: and.u %0,%0,0x7fff" ! 3421: [(set_attr "type" "marith,arith")]) ! 3422: ! 3423: (define_insn "abssf2" ! 3424: [(set (match_operand:SF 0 "register_operand" "=r") ! 3425: (abs:SF (match_operand:SF 1 "register_operand" "r")))] ! 3426: "" ! 3427: "and.u %0,%1,0x7fff") ! 3428: ! 3429: ;; Subroutines of "casesi". ! 3430: ! 3431: ;; Operand 0 is index ! 3432: ;; operand 1 is the minimum bound ! 3433: ;; operand 2 is the maximum bound - minimum bound + 1 ! 3434: ;; operand 3 is CODE_LABEL for the table; ! 3435: ;; operand 4 is the CODE_LABEL to go to if index out of range. ! 3436: ! 3437: (define_expand "casesi" ! 3438: ;; We don't use these for generating the RTL, but we must describe ! 3439: ;; the operands here. ! 3440: [(match_operand:SI 0 "general_operand" "") ! 3441: (match_operand:SI 1 "immediate_operand" "") ! 3442: (match_operand:SI 2 "immediate_operand" "") ! 3443: (match_operand 3 "" "") ! 3444: (match_operand 4 "" "")] ! 3445: "" ! 3446: " ! 3447: { ! 3448: register rtx index_diff = gen_reg_rtx (SImode); ! 3449: register rtx low = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[1])); ! 3450: register rtx label = gen_rtx (LABEL_REF, VOIDmode, operands[3]); ! 3451: register rtx base; ! 3452: ! 3453: if (! CASE_VECTOR_INSNS) ! 3454: /* These instructions are likely to be scheduled and made loop invariant. ! 3455: This decreases the cost of the dispatch at the expense of the default ! 3456: case. */ ! 3457: base = force_reg (SImode, memory_address_noforce (SImode, label)); ! 3458: ! 3459: /* Compute the index difference and handle the default case. */ ! 3460: emit_insn (gen_addsi3 (index_diff, ! 3461: force_reg (SImode, operands[0]), ! 3462: ADD_INT (low) ? low : force_reg (SImode, low))); ! 3463: emit_insn (gen_cmpsi (index_diff, operands[2])); ! 3464: /* It's possible to replace this branch with sgtu/iorsi3 and adding a -1 ! 3465: entry to the table. However, that doesn't seem to win on the m88110. */ ! 3466: emit_jump_insn (gen_bgtu (operands[4])); ! 3467: ! 3468: if (CASE_VECTOR_INSNS) ! 3469: /* Call the jump that will branch to the appropriate case. */ ! 3470: emit_jump_insn (gen_casesi_enter (label, index_diff, operands[3])); ! 3471: else ! 3472: /* Load the table entry and jump to it. */ ! 3473: emit_jump_insn (gen_casesi_jump (gen_reg_rtx (SImode), base, index_diff)); ! 3474: ! 3475: /* Claim that flow drops into the table so it will be adjacent by not ! 3476: emitting a barrier. */ ! 3477: DONE; ! 3478: }") ! 3479: ! 3480: (define_expand "casesi_jump" ! 3481: [(set (match_operand:SI 0 "" "") ! 3482: (mem:SI (plus:SI (match_operand:SI 1 "" "") ! 3483: (mult:SI (match_operand:SI 2 "" "") ! 3484: (const_int 4))))) ! 3485: (set (pc) (match_dup 0))] ! 3486: "" ! 3487: "") ! 3488: ! 3489: ;; The bsr.n instruction is directed to the END of the table. See ! 3490: ;; ASM_OUTPUT_CASE_END. ! 3491: ! 3492: (define_insn "casesi_enter" ! 3493: [(set (pc) (match_operand 0 "" "")) ! 3494: (use (match_operand:SI 1 "register_operand" "r")) ! 3495: ;; The USE here is so that at least one jump-insn will refer to the label, ! 3496: ;; to keep it alive in jump_optimize. ! 3497: (use (label_ref (match_operand 2 "" ""))) ! 3498: (clobber (reg:SI 1))] ! 3499: "" ! 3500: "* ! 3501: { ! 3502: if (flag_delayed_branch) ! 3503: return \"bsr.n %0e\;lda %#r1,%#r1[%1]\"; ! 3504: m88k_case_index = REGNO (operands[1]); ! 3505: return \"bsr %0e\"; ! 3506: }" ! 3507: [(set_attr "type" "weird") ! 3508: (set_attr "length" "3")]) ; Including the "jmp r1". ! 3509: ! 3510: ;;- jump to subroutine ! 3511: (define_expand "call" ! 3512: [(parallel [(call (match_operand:SI 0 "" "") ! 3513: (match_operand 1 "" "")) ! 3514: (clobber (reg:SI 1))])] ! 3515: "" ! 3516: " ! 3517: { ! 3518: if (GET_CODE (operands[0]) == MEM ! 3519: && ! call_address_operand (XEXP (operands[0], 0), SImode)) ! 3520: operands[0] = gen_rtx (MEM, GET_MODE (operands[0]), ! 3521: force_reg (Pmode, XEXP (operands[0], 0))); ! 3522: }") ! 3523: ! 3524: (define_insn "" ! 3525: [(parallel [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rQ")) ! 3526: (match_operand 1 "" "")) ! 3527: (clobber (reg:SI 1))])] ! 3528: "" ! 3529: "* return output_call (operands, operands[0]);" ! 3530: [(set_attr "type" "call")]) ! 3531: ! 3532: (define_expand "call_value" ! 3533: [(parallel [(set (match_operand 0 "register_operand" "") ! 3534: (call (match_operand:SI 1 "" "") ! 3535: (match_operand 2 "" ""))) ! 3536: (clobber (reg:SI 1))])] ! 3537: "" ! 3538: " ! 3539: { ! 3540: if (GET_CODE (operands[1]) == MEM ! 3541: && ! call_address_operand (XEXP (operands[1], 0), SImode)) ! 3542: operands[1] = gen_rtx (MEM, GET_MODE (operands[1]), ! 3543: force_reg (Pmode, XEXP (operands[1], 0))); ! 3544: }") ! 3545: ! 3546: (define_insn "" ! 3547: [(parallel [(set (match_operand 0 "register_operand" "=r") ! 3548: (call (mem:SI ! 3549: (match_operand:SI 1 "call_address_operand" "rQ")) ! 3550: (match_operand 2 "" ""))) ! 3551: (clobber (reg:SI 1))])] ! 3552: "" ! 3553: "* return output_call (operands, operands[1]);" ! 3554: [(set_attr "type" "call")]) ! 3555: ! 3556: ;; Nop instruction and others ! 3557: ! 3558: (define_insn "nop" ! 3559: [(const_int 0)] ! 3560: "" ! 3561: "ff0 %#r0,%#r0" ! 3562: [(set_attr "type" "bit")]) ! 3563: ! 3564: (define_insn "return" ! 3565: [(return)] ! 3566: "reload_completed" ! 3567: "jmp%. %#r1" ! 3568: [(set_attr "type" "jump")]) ! 3569: ! 3570: (define_expand "prologue" ! 3571: [(const_int 0)] ! 3572: "" ! 3573: "m88k_expand_prologue (); DONE;") ! 3574: ! 3575: (define_expand "epilogue" ! 3576: [(return)] ! 3577: "! null_prologue ()" ! 3578: "m88k_expand_epilogue ();") ! 3579: ! 3580: (define_insn "blockage" ! 3581: [(unspec_volatile [(const_int 0)] 0)] ! 3582: "" ! 3583: "" ! 3584: [(set_attr "length" "0")]) ! 3585: ! 3586: (define_insn "indirect_jump" ! 3587: [(set (pc) (match_operand:SI 0 "register_operand" "r"))] ! 3588: "" ! 3589: "jmp%. %0" ! 3590: [(set_attr "type" "jump")]) ! 3591: ! 3592: (define_insn "jump" ! 3593: [(set (pc) ! 3594: (label_ref (match_operand 0 "" "")))] ! 3595: "" ! 3596: "br%. %l0" ! 3597: [(set_attr "type" "jump")]) ! 3598: ! 3599: ;; This insn is used for some loop tests, typically loops reversed when ! 3600: ;; strength reduction is used. It is actually created when the instruction ! 3601: ;; combination phase combines the special loop test. Since this insn ! 3602: ;; is both a jump insn and has an output, it must deal with it's own ! 3603: ;; reloads, hence the `m' constraints. The `!' constraints direct reload ! 3604: ;; to not choose the register alternatives in the event a reload is needed. ! 3605: ! 3606: (define_insn "decrement_and_branch_until_zero" ! 3607: [(set (pc) ! 3608: (if_then_else ! 3609: (match_operator 0 "relop_no_unsigned" ! 3610: [(match_operand:SI 1 "register_operand" "+!r,!r,m,m") ! 3611: (const_int 0)]) ! 3612: (label_ref (match_operand 2 "" "")) ! 3613: (pc))) ! 3614: (set (match_dup 1) ! 3615: (plus:SI (match_dup 1) ! 3616: (match_operand:SI 3 "add_operand" "rI,J,rI,J"))) ! 3617: (clobber (match_scratch:SI 4 "=X,X,&r,&r")) ! 3618: (clobber (match_scratch:SI 5 "=X,X,&r,&r"))] ! 3619: "find_reg_note (insn, REG_NONNEG, 0)" ! 3620: "@ ! 3621: bcnd.n %B0,%1,%2\;addu %1,%1,%3 ! 3622: bcnd.n %B0,%1,%2\;subu %1,%1,%n3 ! 3623: ld %4,%1\;addu %5,%4,%3\;bcnd.n %B0,%4,%2\;st %5,%1 ! 3624: ld %4,%1\;subu %5,%4,%n3\;bcnd.n %B0,%4,%2\;st %5,%1" ! 3625: [(set_attr "type" "weird") ! 3626: (set_attr "length" "2,2,4,4")]) ! 3627: ! 3628: ;; Special insn to serve as the last insn of a define_expand. This insn ! 3629: ;; will generate no code. ! 3630: ! 3631: (define_expand "dummy" ! 3632: [(set (match_operand 0 "" "") (match_dup 0))] ! 3633: "" ! 3634: "")
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.