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