|
|
1.1 root 1: ;;- Machine description for the Motorola 88000 for GNU C compiler 1.1.1.3 ! root 2: ;; Copyright (C) 1988, 89, 90, 91, 93, 1994 Free Software Foundation, Inc. 1.1 root 3: ;; Contributed by Michael Tiemann ([email protected]) 4: ;; Additional changes by Michael Meissner ([email protected]) 1.1.1.3 ! root 5: ;; Version 2 port by Tom Wood ([email protected]) 1.1 root 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: 1.1.1.3 ! root 26: ;; RCS rev field. This is a NOP, just to get the RCS id into the 1.1 root 27: ;; program image. 1.1.1.3 ! root 28: (define_expand "m88k_rcs_id" 1.1 root 29: [(match_operand:SI 0 "" "")] 30: "" 1.1.1.3 ! root 31: "{ static char rcs_id[] = \"$What: <@(#) m88k.md,v 1.5> $\"; 1.1 root 32: FAIL; }") 33: 1.1.1.3 ! root 34: ;; Attribute describing the processor. This attribute must match exactly ! 35: ;; with the processor_type enumeration in m88k.h. 1.1 root 36: 37: ; Target CPU. 38: (define_attr "cpu" "m88100,m88110,m88000" 39: (const (symbol_ref "m88k_cpu"))) 40: 41: ; Type of each instruction. Default is arithmetic. 42: ; I'd like to write the list as this, but genattrtab won't accept it. 43: ; 44: ; "branch,jump,call, ; flow-control instructions 45: ; load,store,loadd,loada, ; data unit instructions 46: ; spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv, ; FPU add instructions 47: ; spmul,dpmul,imul, ; FPU multiply instructions 48: ; arith,bit,mov ; integer unit instructions 49: ; marith,weird" ; multi-word instructions 50: 51: ; Classification of each insn. Some insns of TYPE_BRANCH are multi-word. 52: (define_attr "type" 53: "branch,jump,call,load,store,loadd,loada,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv,spmul,dpmul,imul,arith,bit,mov,marith,weird" 54: (const_string "arith")) 55: 56: (define_attr "fpu" "yes,no" 57: (if_then_else 58: (eq_attr "type" "spmul,dpmul,imul,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv") 59: (const_string "yes") (const_string "no"))) 60: 61: ; Length in # of instructions of each insn. The values are not exact, but 62: ; are safe. 63: (define_attr "length" "" 64: (cond [(eq_attr "type" "marith,weird,branch") 65: (const_int 2)] 66: (const_int 1))) 67: 68: ; Describe a user's asm statement. 69: (define_asm_attributes 70: [(set_attr "type" "weird")]) 71: 72: ; Define the delay slot requirements for branches and calls. 73: ; The m88100 annuls instructions if a conditional branch is taken. 74: ; For insns of TYPE_BRANCH that are multi-word instructions, the 75: ; delay slot applies to the first instruction. 76: 77: ; @@ For the moment, reorg.c requires that the delay slot of a branch not 78: ; be a call or branch. 79: 80: (define_delay (eq_attr "type" "branch,jump") 81: [(and 82: (and 83: (eq_attr "type" "!branch,jump,call,marith,weird") ; required. 84: (eq_attr "type" "!load,loadd")) ; issue as-soon-as-possible. 85: (eq_attr "fpu" "no")) ; issue as-soon-as-possible. 86: (eq_attr "type" "!call,branch,jump") (nil)]) ; @@ was (const_int 1) 87: 88: ; output_call supports an unconditional branch in the delay slot of 89: ; a call. (@@ Support for this case is expected in reorg.c soon.) 90: 91: (define_delay (eq_attr "type" "call") 92: [(eq_attr "type" "!branch,call,marith,weird") ; required. 93: (nil) (nil)]) 94: 95: ; An abstract block diagram of the function units for the m88100. 96: ; 97: ; * 98: ; | 99: ; +---v----+ 100: ; | decode | 101: ; +-vv-v-v-+ fpu 102: ; ,----------'| | `----------------------. 103: ; | | | | ,-----. 104: ; load | store | | arith | | | 105: ; | | | +-v-v-+ | dp source 106: ; | | | | fp1 |---' 107: ; store | | | div +-v-v-+ 108: ; ,------. | | | ,-----. ,-----------' `-----------. 109: ; | | | | | | | | | 110: ; | +--v---v--+ ,---' | | +-v-v---+ +---v---+ 111: ; | | stage 2 | | | `---| add 2 | | mul 2 | 112: ; | +---------+ | +--v--+ +-------+ imul +-------+ 113: ; | | stage 1 | | | alu | | add 3 | ,--------| mul 3 | 114: ; | +---------+ | +--v--+ +-------+ | +-------+ 115: ; | | stage 0 | | | | add 4 | | | mul 4 | 116: ; | +--v---v--+ | | +---v---+ | +-------+ 117: ; | | | | | | | | mul 5 | 118: ; | * | | | | | +---v---+ 119: ; | | | | | +----v----+ | 120: ; | load | | | fp add `------>| fp last |<------' fp mul 121: ; | | | | +---v-v--^+ 122: ; | | | | | | | 123: ; | | | | | `--' dp dest 124: ; | | +--v-----v--+ | 125: ; | `--->| writeback |<--------------------' 126: ; | +--v-----v--+ 127: ; | | | 128: ; `------------------' * 129: ; 130: ; The decode unit need not be specified. 131: ; Consideration of writeback contention is critical to superb scheduling. 132: ; 133: ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY 134: ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST]) 135: 136: ; Describing the '100 alu is currently not useful. 137: ;(define_function_unit "alu" 1 0 (eq_attr "type" 138: ; "!store,marith,weird") 1 0) 139: ;(define_function_unit "alu" 1 0 (eq_attr "type" "marith,weird") 2 0) 140: 141: (define_function_unit "alu" 1 0 142: (and (eq_attr "type" "loada,arith,mov") (eq_attr "cpu" "!m88100")) 2 0) 143: (define_function_unit "alu" 1 0 144: (and (eq_attr "type" "marith,weird") (eq_attr "cpu" "!m88100")) 4 0) 145: 146: (define_function_unit "bit" 1 0 147: (and (eq_attr "type" "bit") (eq_attr "cpu" "!m88100")) 2 2) 148: 149: (define_function_unit "mem100" 1 0 150: (and (eq_attr "type" "store,loada") (eq_attr "cpu" "m88100")) 1 0) 151: (define_function_unit "mem100" 1 0 152: (and (eq_attr "type" "load") (eq_attr "cpu" "m88100")) 3 0) 153: (define_function_unit "mem100" 1 0 154: (and (eq_attr "type" "loadd") (eq_attr "cpu" "m88100")) 3 2) 155: 156: (define_function_unit "mem110" 1 0 157: (and (eq_attr "type" "load,loadd") (eq_attr "cpu" "!m88100")) 3 2) 158: (define_function_unit "mem110" 1 0 159: (and (eq_attr "type" "store") (eq_attr "cpu" "!m88100")) 1 2) 160: 161: ; The times are adjusted to include fp1 and fplast, but then are further 162: ; adjusted based on the actual generated code. The notation to the right 163: ; is the total latency. A range denotes a group of instructions and/or 164: ; conditions (the extra clock of fplast time with some sequences). 165: 166: (define_function_unit "fpmul100" 1 0 167: (and (eq_attr "type" "spmul") (eq_attr "cpu" "m88100")) 4 0) ; 6-8 168: (define_function_unit "fpmul100" 1 0 169: (and (eq_attr "type" "dpmul") (eq_attr "cpu" "m88100")) 7 0) ; 9-10 170: (define_function_unit "fpmul100" 1 0 171: (and (eq_attr "type" "imul") (eq_attr "cpu" "m88100")) 3 0) ; 4 172: 173: (define_function_unit "fpmul110" 1 0 174: (and (eq_attr "type" "imul,spmul,dpmul") 175: (eq_attr "cpu" "!m88100")) 5 2) ; 3 176: 177: (define_function_unit "fpadd100" 1 5 178: (and (eq_attr "type" "spadd,spcmp") (eq_attr "cpu" "m88100")) 3 0) ; 5-6 179: (define_function_unit "fpadd100" 1 5 180: (and (eq_attr "type" "dpadd,dpcmp") (eq_attr "cpu" "m88100")) 4 0) ; 6-7 181: 182: (define_function_unit "fpadd110" 1 0 183: (and (eq_attr "type" "spadd,dpadd") (eq_attr "cpu" "!m88100")) 5 2) ; 3 184: (define_function_unit "fpadd110" 1 0 185: (and (eq_attr "type" "spcmp,dpcmp") (eq_attr "cpu" "!m88100")) 2 2) ; 1 186: 187: (define_function_unit "fpadd100" 1 5 188: (and (eq_attr "type" "spdiv") (eq_attr "cpu" "m88100")) 30 0) ; 30-31 189: (define_function_unit "fpadd100" 1 5 190: (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "m88100")) 60 0) ; 60-61 191: (define_function_unit "fpadd100" 1 5 192: (and (eq_attr "type" "idiv") (eq_attr "cpu" "m88100")) 38 0) ; 38 193: 194: (define_function_unit "div" 1 1 195: (and (eq_attr "type" "spdiv") (eq_attr "cpu" "!m88100")) 25 2) ; 13 196: (define_function_unit "div" 1 1 197: (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "!m88100")) 45 2) ; 23 198: (define_function_unit "div" 1 1 199: (and (eq_attr "type" "idiv") (eq_attr "cpu" "!m88100")) 35 2) ; 18 200: 201: ;; Superoptimizer sequences 202: 203: ;; geu+: { r = ((unsigned_word) v0 >= (unsigned_word) v1) + v2; } 204: ;; subu.co r5,r2,r3 205: ;; addu.cio r6,r4,r0 206: 207: (define_split 208: [(set (match_operand:SI 0 "register_operand" "=r") 209: (minus:SI (match_operand:SI 1 "register_operand" "r") 210: (geu:SI (match_operand:SI 2 "register_operand" "r") 211: (match_operand:SI 3 "register_operand" "r"))))] 212: "" 213: [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1)) 214: (set (match_dup 0) 215: (plus:SI (match_dup 1) 216: (unspec:SI [(const_int 0) 217: (reg:CC 0)] 0)))] 218: "") 219: 220: ;; leu+: { r = ((unsigned_word) v0 <= (unsigned_word) v1) + v2; } 221: ;; subu.co r5,r3,r2 222: ;; addu.cio r6,r4,r0 223: 224: (define_split 225: [(set (match_operand:SI 0 "register_operand" "=r") 226: (minus:SI (match_operand:SI 1 "register_operand" "r") 227: (leu:SI (match_operand:SI 3 "register_operand" "r") 228: (match_operand:SI 2 "register_operand" "r"))))] 229: "" 230: [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1)) 231: (set (match_dup 0) 232: (plus:SI (match_dup 1) 233: (unspec:SI [(const_int 0) 234: (reg:CC 0)] 0)))] 235: "") 236: 237: ;; eq0+: { r = (v0 == 0) + v1; } 238: ;; subu.co r4,r0,r2 239: ;; addu.cio r5,r3,r0 240: 241: (define_split 242: [(set (match_operand:SI 0 "register_operand" "=r") 243: (minus:SI (match_operand:SI 1 "register_operand" "r") 244: (eq:SI (match_operand:SI 2 "register_operand" "r") 245: (const_int 0))))] 246: "" 247: [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1)) 248: (set (match_dup 0) 249: (plus:SI (match_dup 1) 250: (unspec:SI [(const_int 0) 251: (reg:CC 0)] 0)))] 252: "") 253: 254: ;; ltu-: { r = v2 - ((unsigned_word) v0 < (unsigned_word) v1); } 255: ;; subu.co r5,r2,r3 256: ;; subu.cio r6,r4,r0 257: 258: (define_split 259: [(set (match_operand:SI 0 "register_operand" "=r") 260: (plus:SI (ltu:SI (match_operand:SI 2 "register_operand" "r") 261: (match_operand:SI 3 "register_operand" "r")) 262: (match_operand:SI 1 "register_operand" "r")))] 263: "" 264: [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1)) 265: (set (match_dup 0) 266: (minus:SI (match_dup 1) 267: (unspec:SI [(const_int 0) 268: (reg:CC 0)] 1)))] 269: "") 270: 271: ;; gtu-: { r = v2 - ((unsigned_word) v0 > (unsigned_word) v1); } 272: ;; subu.co r5,r3,r2 273: ;; subu.cio r6,r4,r0 274: 275: (define_split 276: [(set (match_operand:SI 0 "register_operand" "=r") 277: (plus:SI (gtu:SI (match_operand:SI 3 "register_operand" "r") 278: (match_operand:SI 2 "register_operand" "r")) 279: (match_operand:SI 1 "register_operand" "r")))] 280: "" 281: [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1)) 282: (set (match_dup 0) 283: (minus:SI (match_dup 1) 284: (unspec:SI [(const_int 0) 285: (reg:CC 0)] 1)))] 286: "") 287: 288: ;; ne0-: { r = v1 - (v0 != 0); } 289: ;; subu.co r4,r0,r2 290: ;; subu.cio r5,r3,r0 291: 292: (define_split 293: [(set (match_operand:SI 0 "register_operand" "=r") 294: (plus:SI (ne:SI (match_operand:SI 2 "register_operand" "r") 295: (const_int 0)) 296: (match_operand:SI 1 "register_operand" "r")))] 297: "" 298: [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1)) 299: (set (match_dup 0) 300: (minus:SI (match_dup 1) 301: (unspec:SI [(const_int 0) 302: (reg:CC 0)] 1)))] 303: "") 304: 305: ;; ges0-: { r = v1 - ((signed_word) v0 >= 0); } 306: ;; addu.co r4,r2,r2 307: ;; subu.cio r5,r3,r0 308: 309: (define_split 310: [(set (match_operand:SI 0 "register_operand" "=r") 311: (minus:SI (match_operand:SI 1 "register_operand" "r") 312: (xor:SI (lshiftrt:SI 313: (match_operand:SI 2 "register_operand" "r") 314: (const_int 31)) 315: (const_int 1))))] 316: "" 317: [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 2)] 0)) 318: (set (match_dup 0) 319: (minus:SI (match_dup 1) 320: (unspec:SI [(const_int 0) 321: (reg:CC 0)] 1)))] 322: "") 323: 324: ;; This rich set of complex patterns are mostly due to Torbjorn Granlund 325: ;; ([email protected]). They've changed since then, so don't complain to him 326: ;; if they don't work right. 327: 1.1.1.3 ! root 328: ;; Regarding shifts, gen_lshlsi3 generates ASHIFT. The gen functions 1.1 root 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: 1.1.1.3 ! root 1840: ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't ! 1841: ;; confuse them with real addresses. ! 1842: (define_insn "" ! 1843: [(set (match_operand:SI 0 "register_operand" "=r") ! 1844: (lo_sum:SI (match_operand:SI 1 "register_operand" "r") ! 1845: (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))] ! 1846: "" ! 1847: "or %0,%1,%#lo16(%g2)" ! 1848: ;; Need to set length for this arith insn because operand2 ! 1849: ;; is not an "arith_operand". ! 1850: [(set_attr "length" "1")]) ! 1851: 1.1 root 1852: (define_insn "" 1853: [(set (match_operand:SI 0 "register_operand" "=r") 1854: (high:SI (match_operand 1 "" "")))] 1855: "" 1856: "or.u %0,%#r0,%#hi16(%g1)") 1857: 1.1.1.3 ! root 1858: ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't ! 1859: ;; confuse them with real addresses. ! 1860: (define_insn "" ! 1861: [(set (match_operand:SI 0 "register_operand" "=r") ! 1862: (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))] ! 1863: "" ! 1864: "or.u %0,%#r0,%#hi16(%g1)" ! 1865: ;; Need to set length for this arith insn because operand2 ! 1866: ;; is not an arith_operand. ! 1867: [(set_attr "length" "1")]) ! 1868: 1.1 root 1869: ;; HImode move instructions 1870: 1871: (define_expand "movhi" 1872: [(set (match_operand:HI 0 "general_operand" "") 1873: (match_operand:HI 1 "general_operand" ""))] 1874: "" 1875: " 1876: { 1877: if (emit_move_sequence (operands, HImode, 0)) 1878: DONE; 1879: }") 1880: 1881: (define_insn "" 1882: [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r") 1883: (match_operand:HI 1 "move_operand" "rP,m,rO,N"))] 1884: "(register_operand (operands[0], HImode) 1885: || register_operand (operands[1], HImode) 1886: || operands[1] == const0_rtx)" 1887: "@ 1888: or %0,%#r0,%h1 1889: %V1ld.hu\\t %0,%1 1890: %v0st.h\\t %r1,%0 1891: subu %0,%#r0,%H1" 1892: [(set_attr "type" "arith,load,store,arith")]) 1893: 1894: (define_insn "" 1895: [(set (match_operand:HI 0 "register_operand" "=r") 1896: (subreg:HI (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 1897: (match_operand:SI 2 "immediate_operand" "in")) 0))] 1898: "!flag_pic" 1899: "or %0,%1,%#lo16(%2)") 1900: 1901: ;; QImode move instructions 1902: 1903: (define_expand "movqi" 1904: [(set (match_operand:QI 0 "general_operand" "") 1905: (match_operand:QI 1 "general_operand" ""))] 1906: "" 1907: " 1908: { 1909: if (emit_move_sequence (operands, QImode, 0)) 1910: DONE; 1911: }") 1912: 1913: (define_insn "" 1914: [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r") 1915: (match_operand:QI 1 "move_operand" "rP,m,rO,N"))] 1916: "(register_operand (operands[0], QImode) 1917: || register_operand (operands[1], QImode) 1918: || operands[1] == const0_rtx)" 1919: "@ 1920: or %0,%#r0,%q1 1921: %V1ld.bu\\t %0,%1 1922: %v0st.b\\t %r1,%0 1923: subu %r0,%#r0,%Q1" 1924: [(set_attr "type" "arith,load,store,arith")]) 1925: 1926: (define_insn "" 1927: [(set (match_operand:QI 0 "register_operand" "=r") 1928: (subreg:QI (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 1929: (match_operand:SI 2 "immediate_operand" "in")) 0))] 1930: "!flag_pic" 1931: "or %0,%1,%#lo16(%2)") 1932: 1933: ;; DImode move instructions 1934: 1935: (define_expand "movdi" 1936: [(set (match_operand:DI 0 "general_operand" "") 1937: (match_operand:DI 1 "general_operand" ""))] 1938: "" 1939: " 1940: { 1941: if (emit_move_sequence (operands, DImode, 0)) 1942: DONE; 1943: }") 1944: 1945: (define_insn "" 1946: [(set (match_operand:DI 0 "register_operand" "=r,x") 1947: (const_int 0))] 1948: "" 1949: "@ 1950: or %0,%#r0,0\;or %d0,%#r0,0 1951: mov %0,%#x0" 1952: [(set_attr "type" "marith,mov")]) 1953: 1954: (define_insn "" 1955: [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,x,x,x,m") 1956: (match_operand:DI 1 "nonimmediate_operand" "r,m,r,x,r,x,m,x"))] 1957: "" 1958: "@ 1959: or %0,%#r0,%1\;or %d0,%#r0,%d1 1960: %V1ld.d\\t %0,%1 1961: %v0st.d\\t %1,%0 1962: mov.d %0,%1 1963: mov.d %0,%1 1964: mov %0,%1 1965: %V1ld.d\\t %0,%1 1966: %v0st.d\\t %1,%0" 1967: [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")]) 1968: 1969: (define_insn "" 1970: [(set (match_operand:DI 0 "register_operand" "=r") 1971: (subreg:DI (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 1972: (match_operand:SI 2 "immediate_operand" "in")) 0))] 1973: "!flag_pic" 1974: "or %0,%1,%#lo16(%2)") 1975: 1976: (define_insn "" 1977: [(set (match_operand:DI 0 "register_operand" "=r") 1978: (match_operand:DI 1 "immediate_operand" "n"))] 1979: "" 1980: "* return output_load_const_dimode (operands);" 1981: [(set_attr "type" "marith") 1982: (set_attr "length" "4")]) ; length is 2, 3 or 4. 1983: 1984: ;; DFmode move instructions 1985: 1986: (define_expand "movdf" 1987: [(set (match_operand:DF 0 "general_operand" "") 1988: (match_operand:DF 1 "general_operand" ""))] 1989: "" 1990: " 1991: { 1992: if (emit_move_sequence (operands, DFmode, 0)) 1993: DONE; 1994: }") 1995: 1.1.1.3 ! root 1996: (define_split ! 1997: [(set (match_operand:DF 0 "register_operand" "=r") ! 1998: (match_operand:DF 1 "register_operand" "r"))] ! 1999: "reload_completed ! 2000: && GET_CODE (operands[0]) == REG && !XRF_REGNO_P (REGNO (operands[0])) ! 2001: && GET_CODE (operands[1]) == REG && !XRF_REGNO_P (REGNO (operands[1]))" ! 2002: [(set (match_dup 2) (match_dup 3)) ! 2003: (set (match_dup 4) (match_dup 5))] ! 2004: " ! 2005: { operands[2] = operand_subword (operands[0], 0, 0, DFmode); ! 2006: operands[3] = operand_subword (operands[1], 0, 0, DFmode); ! 2007: operands[4] = operand_subword (operands[0], 1, 0, DFmode); ! 2008: operands[5] = operand_subword (operands[1], 1, 0, DFmode); }") ! 2009: 1.1 root 2010: ;; @@ This pattern is incomplete and doesn't appear necessary. 2011: ;; 2012: ;; This pattern forces (set (reg:DF ...) (const_double ...)) 2013: ;; to be reloaded by putting the constant into memory. 2014: ;; It must come before the more general movdf pattern. 2015: 2016: ;(define_insn "" 2017: ; [(set (match_operand:DF 0 "general_operand" "=r,o") 2018: ; (match_operand:DF 1 "" "G,G"))] 2019: ; "GET_CODE (operands[1]) == CONST_DOUBLE" 2020: ; "* 2021: ;{ 2022: ; switch (which_alternative) 2023: ; { 2024: ; case 0: 2025: ; return \"or %0,%#r0,0\;or %d0,%#r0,0\"; 2026: ; case 1: 2027: ; operands[1] = adj_offsettable_operand (operands[0], 4); 2028: ; return \"%v0st\\t %#r0,%0\;st %#r0,%1\"; 2029: ; } 2030: ;}") 2031: 2032: (define_insn "" 2033: [(set (match_operand:DF 0 "register_operand" "=r,x") 2034: (const_int 0))] 2035: "" 2036: "@ 2037: or %0,%#r0,0\;or %d0,%#r0,0 2038: mov %0,%#x0" 2039: [(set_attr "type" "marith,mov")]) 2040: 2041: (define_insn "" 2042: [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m") 2043: (match_operand:DF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))] 2044: "" 2045: "@ 2046: or %0,%#r0,%1\;or %d0,%#r0,%d1 2047: %V1ld.d\\t %0,%1 2048: %v0st.d\\t %1,%0 2049: mov.d %0,%1 2050: mov.d %0,%1 2051: mov %0,%1 2052: %V1ld.d\\t %0,%1 2053: %v0st.d\\t %1,%0" 2054: [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")]) 2055: 2056: (define_insn "" 2057: [(set (match_operand:DF 0 "register_operand" "=r") 2058: (subreg:DF (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 2059: (match_operand:SI 2 "immediate_operand" "in")) 0))] 2060: "!flag_pic" 2061: "or %0,%1,%#lo16(%2)") 2062: 2063: (define_insn "" 2064: [(set (match_operand:DF 0 "register_operand" "=r") 2065: (match_operand:DF 1 "immediate_operand" "F"))] 2066: "" 2067: "* return output_load_const_double (operands);" 2068: [(set_attr "type" "marith") 2069: (set_attr "length" "4")]) ; length is 2, 3, or 4. 2070: 2071: ;; SFmode move instructions 2072: 2073: (define_expand "movsf" 2074: [(set (match_operand:SF 0 "general_operand" "") 2075: (match_operand:SF 1 "general_operand" ""))] 2076: "" 2077: " 2078: { 2079: if (emit_move_sequence (operands, SFmode, 0)) 2080: DONE; 2081: }") 2082: 2083: ;; @@ What happens to fconst0_rtx? 2084: (define_insn "" 2085: [(set (match_operand:SF 0 "register_operand" "=r,x") 2086: (const_int 0))] 2087: "" 2088: "@ 2089: or %0,%#r0,0 2090: mov %0,%#x0" 2091: [(set_attr "type" "arith,mov")]) 2092: 2093: (define_insn "" 2094: [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m") 2095: (match_operand:SF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))] 2096: "" 2097: "@ 2098: or %0,%#r0,%1 2099: %V1ld\\t %0,%1 2100: %v0st\\t %r1,%0 2101: mov.s %0,%1 2102: mov.s %0,%1 2103: mov %0,%1 2104: %V1ld\\t %0,%1 2105: %v0st\\t %r1,%0" 2106: [(set_attr "type" "arith,load,store,mov,mov,mov,load,store")]) 2107: 2108: (define_insn "" 2109: [(set (match_operand:SF 0 "register_operand" "=r") 2110: (subreg:SF (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 2111: (match_operand:SI 2 "immediate_operand" "in")) 0))] 2112: "!flag_pic" 2113: "or %0,%1,%#lo16(%2)") 2114: 2115: (define_insn "" 2116: [(set (match_operand:SF 0 "register_operand" "=r") 2117: (match_operand:SF 1 "immediate_operand" "F"))] 2118: "operands[1] != const0_rtx" 2119: "* return output_load_const_float (operands);" 2120: [(set_attr "type" "marith")]) ; length is 1 or 2. 2121: 2122: ;; String/block move insn. See m88k.c for details. 2123: 2124: (define_expand "movstrsi" 2125: [(parallel [(set (mem:BLK (match_operand:BLK 0 "" "")) 2126: (mem:BLK (match_operand:BLK 1 "" ""))) 2127: (use (match_operand:SI 2 "arith32_operand" "")) 2128: (use (match_operand:SI 3 "immediate_operand" ""))])] 2129: "" 2130: " 2131: { 2132: rtx dest_mem = operands[0]; 2133: rtx src_mem = operands[1]; 2134: operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0)); 2135: operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); 2136: expand_block_move (dest_mem, src_mem, operands); 2137: DONE; 2138: }") 2139: 2140: (define_insn "" 2141: [(set (match_operand:QI 0 "register_operand" "=r") 2142: (match_operand:BLK 1 "memory_operand" "m"))] 2143: "" 2144: "%V1ld.bu\\t %0,%1" 2145: [(set_attr "type" "load")]) 2146: 2147: (define_insn "" 2148: [(set (match_operand:HI 0 "register_operand" "=r") 2149: (match_operand:BLK 1 "memory_operand" "m"))] 2150: "" 2151: "%V1ld.hu\\t %0,%1" 2152: [(set_attr "type" "load")]) 2153: 2154: (define_insn "" 2155: [(set (match_operand:SI 0 "register_operand" "=r") 2156: (match_operand:BLK 1 "memory_operand" "m"))] 2157: "" 2158: "%V1ld\\t %0,%1" 2159: [(set_attr "type" "load")]) 2160: 2161: (define_insn "" 2162: [(set (match_operand:DI 0 "register_operand" "=r") 2163: (match_operand:BLK 1 "memory_operand" "m"))] 2164: "" 2165: "%V1ld.d\\t %0,%1" 2166: [(set_attr "type" "loadd")]) 2167: 2168: (define_insn "" 2169: [(set (match_operand:BLK 0 "memory_operand" "=m") 2170: (match_operand:QI 1 "register_operand" "r"))] 2171: "" 2172: "%v0st.b\\t %1,%0" 2173: [(set_attr "type" "store")]) 2174: 2175: (define_insn "" 2176: [(set (match_operand:BLK 0 "memory_operand" "=m") 2177: (match_operand:HI 1 "register_operand" "r"))] 2178: "" 2179: "%v0st.h\\t %1,%0" 2180: [(set_attr "type" "store")]) 2181: 2182: (define_insn "" 2183: [(set (match_operand:BLK 0 "memory_operand" "=m") 2184: (match_operand:SI 1 "register_operand" "r"))] 2185: "" 2186: "%v0st\\t %1,%0" 2187: [(set_attr "type" "store")]) 2188: 2189: (define_insn "" 2190: [(set (match_operand:BLK 0 "memory_operand" "=m") 2191: (match_operand:DI 1 "register_operand" "r"))] 2192: "" 2193: "%v0st.d\\t %1,%0" 2194: [(set_attr "type" "store")]) 2195: 2196: ;; Call a non-looping block move library function (e.g. __movstrSI96x64). 2197: ;; operand 0 is the function name 2198: ;; operand 1 is the destination pointer 2199: ;; operand 2 is the source pointer 2200: ;; operand 3 is the offset for the source and destination pointers 2201: ;; operand 4 is the first value to be loaded 2202: ;; operand 5 is the register to hold the value (r4 or r5) 2203: 2204: (define_expand "call_block_move" 2205: [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "") 2206: (match_operand:SI 3 "immediate_operand" ""))) 2207: (set (match_operand 5 "register_operand" "") 2208: (match_operand 4 "memory_operand" "")) 2209: (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "") 2210: (match_dup 3))) 2211: (use (reg:SI 2)) 2212: (use (reg:SI 3)) 2213: (use (match_dup 5)) 2214: (parallel [(set (reg:DI 2) 2215: (call (mem:SI (match_operand 0 "" "")) 2216: (const_int 0))) 2217: (clobber (reg:SI 1))])] 2218: "" 2219: "") 2220: 2221: ;; Call an SImode looping block move library function (e.g. __movstrSI64n68). 2222: ;; operands 0-5 as in the non-looping interface 2223: ;; operand 6 is the loop count 2224: 2225: (define_expand "call_movstrsi_loop" 2226: [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "") 2227: (match_operand:SI 3 "immediate_operand" ""))) 2228: (set (match_operand:SI 5 "register_operand" "") 2229: (match_operand 4 "memory_operand" "")) 2230: (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "") 2231: (match_dup 3))) 2232: (set (reg:SI 6) (match_operand:SI 6 "immediate_operand" "")) 2233: (use (reg:SI 2)) 2234: (use (reg:SI 3)) 2235: (use (match_dup 5)) 2236: (use (reg:SI 6)) 2237: (parallel [(set (reg:DI 2) 2238: (call (mem:SI (match_operand 0 "" "")) 2239: (const_int 0))) 2240: (clobber (reg:SI 1))])] 2241: "" 2242: "") 2243: 2244: ;;- zero extension instructions 2245: 2246: (define_expand "zero_extendhisi2" 2247: [(set (match_operand:SI 0 "register_operand" "") 2248: (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 2249: "" 2250: " 2251: { 2252: if (GET_CODE (operands[1]) == MEM 2253: && symbolic_address_p (XEXP (operands[1], 0))) 2254: operands[1] 2255: = legitimize_address (flag_pic, operands[1], 0, 0); 2256: }") 2257: 2258: (define_insn "" 2259: [(set (match_operand:SI 0 "register_operand" "=r,r,r") 2260: (zero_extend:SI (match_operand:HI 1 "move_operand" "!r,n,m")))] 2261: "GET_CODE (operands[1]) != CONST_INT" 2262: "@ 2263: mask %0,%1,0xffff 2264: or %0,%#r0,%h1 2265: %V1ld.hu\\t %0,%1" 2266: [(set_attr "type" "arith,arith,load")]) 2267: 2268: (define_expand "zero_extendqihi2" 2269: [(set (match_operand:HI 0 "register_operand" "") 2270: (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] 2271: "" 2272: " 2273: { 2274: if (GET_CODE (operands[1]) == MEM 2275: && symbolic_address_p (XEXP (operands[1], 0))) 2276: operands[1] 2277: = legitimize_address (flag_pic, operands[1], 0, 0); 2278: }") 2279: 2280: (define_insn "" 2281: [(set (match_operand:HI 0 "register_operand" "=r,r,r") 2282: (zero_extend:HI (match_operand:QI 1 "move_operand" "r,n,m")))] 2283: "GET_CODE (operands[1]) != CONST_INT" 2284: "@ 2285: mask %0,%1,0xff 2286: or %0,%#r0,%q1 2287: %V1ld.bu\\t %0,%1" 2288: [(set_attr "type" "arith,arith,load")]) 2289: 2290: (define_expand "zero_extendqisi2" 2291: [(set (match_operand:SI 0 "register_operand" "") 2292: (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] 2293: "" 2294: " 2295: { 2296: if (GET_CODE (operands[1]) == MEM 2297: && symbolic_address_p (XEXP (operands[1], 0))) 2298: { 2299: operands[1] 2300: = legitimize_address (flag_pic, operands[1], 0, 0); 2301: emit_insn (gen_rtx (SET, VOIDmode, operands[0], 2302: gen_rtx (ZERO_EXTEND, SImode, operands[1]))); 2303: DONE; 2304: } 2305: }") 2306: 2307: (define_insn "" 2308: [(set (match_operand:SI 0 "register_operand" "=r,r,r") 2309: (zero_extend:SI (match_operand:QI 1 "move_operand" "r,n,m")))] 2310: "GET_CODE (operands[1]) != CONST_INT" 2311: "@ 2312: mask %0,%1,0xff 2313: or %0,%#r0,%q1 2314: %V1ld.bu\\t %0,%1" 2315: [(set_attr "type" "arith,arith,load")]) 2316: 2317: ;;- sign extension instructions 2318: 2319: (define_expand "extendsidi2" 2320: [(set (subreg:SI (match_operand:DI 0 "register_operand" "=r") 1) 2321: (match_operand:SI 1 "general_operand" "g")) 2322: (set (subreg:SI (match_dup 0) 0) 2323: (ashiftrt:SI (subreg:SI (match_dup 0) 1) 2324: (const_int 31)))] 2325: "" 2326: "") 2327: 2328: (define_expand "extendhisi2" 2329: [(set (match_operand:SI 0 "register_operand" "") 2330: (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 2331: "" 2332: " 2333: { 2334: if (GET_CODE (operands[1]) == MEM 2335: && symbolic_address_p (XEXP (operands[1], 0))) 2336: operands[1] 2337: = legitimize_address (flag_pic, operands[1], 0, 0); 2338: }") 2339: 2340: (define_insn "" 2341: [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 2342: (sign_extend:SI (match_operand:HI 1 "move_operand" "!r,P,N,m")))] 2343: "GET_CODE (operands[1]) != CONST_INT" 2344: "@ 2345: ext %0,%1,16<0> 2346: or %0,%#r0,%h1 2347: subu %0,%#r0,%H1 2348: %V1ld.h\\t %0,%1" 2349: [(set_attr "type" "bit,arith,arith,load")]) 2350: 2351: (define_expand "extendqihi2" 2352: [(set (match_operand:HI 0 "register_operand" "") 2353: (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] 2354: "" 2355: " 2356: { 2357: if (GET_CODE (operands[1]) == MEM 2358: && symbolic_address_p (XEXP (operands[1], 0))) 2359: operands[1] 2360: = legitimize_address (flag_pic, operands[1], 0, 0); 2361: }") 2362: 2363: (define_insn "" 2364: [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") 2365: (sign_extend:HI (match_operand:QI 1 "move_operand" "!r,P,N,m")))] 2366: "GET_CODE (operands[1]) != CONST_INT" 2367: "@ 2368: ext %0,%1,8<0> 2369: or %0,%#r0,%q1 2370: subu %0,%#r0,%Q1 2371: %V1ld.b\\t %0,%1" 2372: [(set_attr "type" "bit,arith,arith,load")]) 2373: 2374: (define_expand "extendqisi2" 2375: [(set (match_operand:SI 0 "register_operand" "") 2376: (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] 2377: "" 2378: " 2379: { 2380: if (GET_CODE (operands[1]) == MEM 2381: && symbolic_address_p (XEXP (operands[1], 0))) 2382: operands[1] 2383: = legitimize_address (flag_pic, operands[1], 0, 0); 2384: }") 2385: 2386: (define_insn "" 2387: [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 2388: (sign_extend:SI (match_operand:QI 1 "move_operand" "!r,P,N,m")))] 2389: "GET_CODE (operands[1]) != CONST_INT" 2390: "@ 2391: ext %0,%1,8<0> 2392: or %0,%#r0,%q1 2393: subu %0,%#r0,%Q1 2394: %V1ld.b\\t %0,%1" 2395: [(set_attr "type" "bit,arith,arith,load")]) 2396: 2397: ;; Conversions between float and double. 2398: 2399: ;; The fadd instruction does not conform to IEEE 754 when used to 2400: ;; convert between float and double. In particular, the sign of -0 is 2401: ;; not preserved. Interestingly, fsub does conform. 2402: 2403: (define_expand "extendsfdf2" 2404: [(set (match_operand:DF 0 "register_operand" "=r") 2405: (float_extend:DF (match_operand:SF 1 "register_operand" "r")))] 2406: "" 2407: "") 2408: 2409: (define_insn "" 2410: [(set (match_operand:DF 0 "register_operand" "=r") 2411: (float_extend:DF (match_operand:SF 1 "register_operand" "r")))] 2412: "! TARGET_88110" 2413: "fsub.dss %0,%1,%#r0" 2414: [(set_attr "type" "spadd")]) 2415: 2416: (define_insn "" 2417: [(set (match_operand:DF 0 "register_operand" "=r,x") 2418: (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")))] 2419: "TARGET_88110" 2420: "fcvt.ds %0,%1" 2421: [(set_attr "type" "spadd")]) 2422: 2423: (define_expand "truncdfsf2" 2424: [(set (match_operand:SF 0 "register_operand" "=r") 2425: (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))] 2426: "" 2427: "") 2428: 2429: (define_insn "" 2430: [(set (match_operand:SF 0 "register_operand" "=r") 2431: (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))] 2432: "! TARGET_88110" 2433: "fsub.sds %0,%1,%#r0" 2434: [(set_attr "type" "dpadd")]) 2435: 2436: (define_insn "" 2437: [(set (match_operand:SF 0 "register_operand" "=r,x") 2438: (float_truncate:SF (match_operand:DF 1 "register_operand" "r,x")))] 2439: "TARGET_88110" 2440: "fcvt.sd %0,%1" 2441: [(set_attr "type" "dpadd")]) 2442: 2443: ;; Conversions between floating point and integer 2444: 2445: (define_insn "floatsidf2" 2446: [(set (match_operand:DF 0 "register_operand" "=r,x") 2447: (float:DF (match_operand:SI 1 "register_operand" "r,r")))] 2448: "" 2449: "flt.ds %0,%1" 2450: [(set_attr "type" "spadd,dpadd")]) 2451: 2452: (define_insn "floatsisf2" 2453: [(set (match_operand:SF 0 "register_operand" "=r,x") 2454: (float:SF (match_operand:SI 1 "register_operand" "r,r")))] 2455: "" 2456: "flt.ss %0,%1" 2457: [(set_attr "type" "spadd,spadd")]) 2458: 2459: (define_insn "fix_truncdfsi2" 2460: [(set (match_operand:SI 0 "register_operand" "=r,r") 2461: (fix:SI (match_operand:DF 1 "register_operand" "r,x")))] 2462: "" 2463: "trnc.sd %0,%1" 2464: [(set_attr "type" "dpadd,dpadd")]) 2465: 2466: (define_insn "fix_truncsfsi2" 2467: [(set (match_operand:SI 0 "register_operand" "=r,r") 2468: (fix:SI (match_operand:SF 1 "register_operand" "r,x")))] 2469: "" 2470: "trnc.ss %0,%1" 2471: [(set_attr "type" "spadd,dpadd")]) 2472: 2473: 2474: ;;- arithmetic instructions 2475: ;;- add instructions 2476: 2477: (define_insn "addsi3" 2478: [(set (match_operand:SI 0 "register_operand" "=r,r") 2479: (plus:SI (match_operand:SI 1 "add_operand" "%r,r") 2480: (match_operand:SI 2 "add_operand" "rI,J")))] 2481: "" 2482: "@ 2483: addu %0,%1,%2 2484: subu %0,%1,%n2") 2485: 2486: ;; patterns for mixed mode floating point. 2487: ;; Do not define patterns that utilize mixed mode arithmetic that result 2488: ;; in narrowing the precision, because it loses accuracy, since the standard 2489: ;; requires double rounding, whereas the 88000 instruction only rounds once. 2490: 2491: (define_expand "adddf3" 2492: [(set (match_operand:DF 0 "register_operand" "=r,x") 2493: (plus:DF (match_operand:DF 1 "general_operand" "%r,x") 2494: (match_operand:DF 2 "general_operand" "r,x")))] 2495: "" 2496: " 2497: { 2498: operands[1] = legitimize_operand (operands[1], DFmode); 2499: operands[2] = legitimize_operand (operands[2], DFmode); 2500: }") 2501: 2502: (define_insn "" 2503: [(set (match_operand:DF 0 "register_operand" "=r,x") 2504: (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) 2505: (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] 2506: "" 2507: "fadd.dss %0,%1,%2" 2508: [(set_attr "type" "spadd")]) 2509: 2510: (define_insn "" 2511: [(set (match_operand:DF 0 "register_operand" "=r,x") 2512: (plus:DF (match_operand:DF 1 "register_operand" "r,x") 2513: (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] 2514: "" 2515: "fadd.dds %0,%1,%2" 2516: [(set_attr "type" "dpadd")]) 2517: 2518: (define_insn "" 2519: [(set (match_operand:DF 0 "register_operand" "=r,x") 2520: (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) 2521: (match_operand:DF 2 "register_operand" "r,x")))] 2522: "" 2523: "fadd.dsd %0,%1,%2" 2524: [(set_attr "type" "dpadd")]) 2525: 2526: (define_insn "" 2527: [(set (match_operand:DF 0 "register_operand" "=r,x") 2528: (plus:DF (match_operand:DF 1 "register_operand" "%r,x") 2529: (match_operand:DF 2 "register_operand" "r,x")))] 2530: "" 2531: "fadd.ddd %0,%1,%2" 2532: [(set_attr "type" "dpadd")]) 2533: 2534: (define_insn "addsf3" 2535: [(set (match_operand:SF 0 "register_operand" "=r,x") 2536: (plus:SF (match_operand:SF 1 "register_operand" "%r,x") 2537: (match_operand:SF 2 "register_operand" "r,x")))] 2538: "" 2539: "fadd.sss %0,%1,%2" 2540: [(set_attr "type" "spadd")]) 2541: 2542: (define_insn "" 2543: [(set (match_operand:DI 0 "register_operand" "=r") 2544: (plus:DI (match_operand:DI 1 "register_operand" "r") 2545: (zero_extend:DI 2546: (match_operand:SI 2 "register_operand" "r")))) 2547: (clobber (reg:CC 0))] 2548: "" 2549: "addu.co %d0,%d1,%2\;addu.ci %0,%1,%#r0" 2550: [(set_attr "type" "marith")]) 2551: 2552: (define_insn "" 2553: [(set (match_operand:DI 0 "register_operand" "=r") 2554: (plus:DI (zero_extend:DI 2555: (match_operand:SI 1 "register_operand" "r")) 2556: (match_operand:DI 2 "register_operand" "r"))) 2557: (clobber (reg:CC 0))] 2558: "" 2559: "addu.co %d0,%1,%d2\;addu.ci %0,%#r0,%2" 2560: [(set_attr "type" "marith")]) 2561: 2562: (define_insn "adddi3" 2563: [(set (match_operand:DI 0 "register_operand" "=r") 2564: (plus:DI (match_operand:DI 1 "register_operand" "%r") 2565: (match_operand:DI 2 "register_operand" "r"))) 2566: (clobber (reg:CC 0))] 2567: "" 2568: "addu.co %d0,%d1,%d2\;addu.ci %0,%1,%2" 2569: [(set_attr "type" "marith")]) 2570: 2571: ;; Add with carry insns. 2572: 2573: (define_insn "" 2574: [(parallel [(set (match_operand:SI 0 "reg_or_0_operand" "=r") 2575: (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO") 2576: (match_operand:SI 2 "reg_or_0_operand" "rO"))) 2577: (set (reg:CC 0) 2578: (unspec:CC [(match_dup 1) (match_dup 2)] 0))])] 2579: "" 2580: "addu.co %r0,%r1,%r2") 2581: 2582: (define_insn "" 2583: [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO") 2584: (match_operand:SI 1 "reg_or_0_operand" "rO")] 2585: 0))] 2586: "" 2587: "addu.co %#r0,%r0,%r1") 2588: 2589: (define_insn "" 2590: [(set (match_operand:SI 0 "reg_or_0_operand" "=r") 2591: (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO") 2592: (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO") 2593: (reg:CC 0)] 0)))] 2594: "" 2595: "addu.ci %r0,%r1,%r2") 2596: 2597: ;;- subtract instructions 2598: 2599: (define_insn "subsi3" 2600: [(set (match_operand:SI 0 "register_operand" "=r") 2601: (minus:SI (match_operand:SI 1 "register_operand" "r") 2602: (match_operand:SI 2 "arith32_operand" "rI")))] 2603: "" 2604: "subu %0,%1,%2") 2605: 2606: ;; patterns for mixed mode floating point 2607: ;; Do not define patterns that utilize mixed mode arithmetic that result 2608: ;; in narrowing the precision, because it loses accuracy, since the standard 2609: ;; requires double rounding, whereas the 88000 instruction only rounds once. 2610: 2611: (define_expand "subdf3" 2612: [(set (match_operand:DF 0 "register_operand" "=r,x") 2613: (minus:DF (match_operand:DF 1 "general_operand" "r,x") 2614: (match_operand:DF 2 "general_operand" "r,x")))] 2615: "" 2616: " 2617: { 2618: operands[1] = legitimize_operand (operands[1], DFmode); 2619: operands[2] = legitimize_operand (operands[2], DFmode); 2620: }") 2621: 2622: (define_insn "" 2623: [(set (match_operand:DF 0 "register_operand" "=r,x") 2624: (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) 2625: (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] 2626: "" 2627: "fsub.dss %0,%1,%2" 2628: [(set_attr "type" "spadd")]) 2629: 2630: (define_insn "" 2631: [(set (match_operand:DF 0 "register_operand" "=r,x") 2632: (minus:DF (match_operand:DF 1 "register_operand" "r,x") 2633: (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] 2634: "" 2635: "fsub.dds %0,%1,%2" 2636: [(set_attr "type" "dpadd")]) 2637: 2638: (define_insn "" 2639: [(set (match_operand:DF 0 "register_operand" "=r,x") 2640: (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) 2641: (match_operand:DF 2 "register_operand" "r,x")))] 2642: "" 2643: "fsub.dsd %0,%1,%2" 2644: [(set_attr "type" "dpadd")]) 2645: 2646: (define_insn "" 2647: [(set (match_operand:DF 0 "register_operand" "=r,x") 2648: (minus:DF (match_operand:DF 1 "register_operand" "r,x") 2649: (match_operand:DF 2 "register_operand" "r,x")))] 2650: "" 2651: "fsub.ddd %0,%1,%2" 2652: [(set_attr "type" "dpadd")]) 2653: 2654: (define_insn "subsf3" 2655: [(set (match_operand:SF 0 "register_operand" "=r,x") 2656: (minus:SF (match_operand:SF 1 "register_operand" "r,x") 2657: (match_operand:SF 2 "register_operand" "r,x")))] 2658: "" 2659: "fsub.sss %0,%1,%2" 2660: [(set_attr "type" "spadd")]) 2661: 2662: (define_insn "" 2663: [(set (match_operand:DI 0 "register_operand" "=r") 2664: (minus:DI (match_operand:DI 1 "register_operand" "r") 2665: (zero_extend:DI 2666: (match_operand:SI 2 "register_operand" "r")))) 2667: (clobber (reg:CC 0))] 2668: "" 2669: "subu.co %d0,%d1,%2\;subu.ci %0,%1,%#r0" 2670: [(set_attr "type" "marith")]) 2671: 2672: (define_insn "" 2673: [(set (match_operand:DI 0 "register_operand" "=r") 2674: (minus:DI (zero_extend:DI 2675: (match_operand:SI 1 "register_operand" "r")) 2676: (match_operand:DI 2 "register_operand" "r"))) 2677: (clobber (reg:CC 0))] 2678: "" 2679: "subu.co %d0,%1,%d2\;subu.ci %0,%#r0,%2" 2680: [(set_attr "type" "marith")]) 2681: 2682: (define_insn "subdi3" 2683: [(set (match_operand:DI 0 "register_operand" "=r") 2684: (minus:DI (match_operand:DI 1 "register_operand" "r") 2685: (match_operand:DI 2 "register_operand" "r"))) 2686: (clobber (reg:CC 0))] 2687: "" 2688: "subu.co %d0,%d1,%d2\;subu.ci %0,%1,%2" 2689: [(set_attr "type" "marith")]) 2690: 2691: ;; Subtract with carry insns. 2692: 2693: (define_insn "" 2694: [(parallel [(set (match_operand:SI 0 "reg_or_0_operand" "=r") 2695: (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO") 2696: (match_operand:SI 2 "reg_or_0_operand" "rO"))) 2697: (set (reg:CC 0) 2698: (unspec:CC [(match_dup 1) (match_dup 2)] 1))])] 2699: "" 2700: "subu.co %r0,%r1,%r2") 2701: 2702: (define_insn "" 2703: [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO") 2704: (match_operand:SI 1 "reg_or_0_operand" "rO")] 2705: 1))] 2706: "" 2707: "subu.co %#r0,%r0,%r1") 2708: 2709: (define_insn "" 2710: [(set (match_operand:SI 0 "reg_or_0_operand" "=r") 2711: (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO") 2712: (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO") 2713: (reg:CC 0)] 1)))] 2714: "" 2715: "subu.ci %r0,%r1,%r2") 2716: 2717: ;;- multiply instructions 2718: ;; 2719: ;; There is an unfounded silicon eratta for E.1 requiring that an 2720: ;; immediate constant value in div/divu/mul instructions be less than 2721: ;; 0x800. This is no longer provided for. 2722: 2723: (define_insn "mulsi3" 2724: [(set (match_operand:SI 0 "register_operand" "=r") 2725: (mult:SI (match_operand:SI 1 "arith32_operand" "%r") 2726: (match_operand:SI 2 "arith32_operand" "rI")))] 2727: "" 2728: "mul %0,%1,%2" 2729: [(set_attr "type" "imul")]) 2730: 2731: (define_insn "umulsidi3" 2732: [(set (match_operand:DI 0 "register_operand" "=r") 2733: (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r")) 2734: (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))] 2735: "TARGET_88110" 2736: "mulu.d %0,%1,%2" 2737: [(set_attr "type" "imul")]) 2738: 2739: ;; patterns for mixed mode floating point 2740: ;; Do not define patterns that utilize mixed mode arithmetic that result 2741: ;; in narrowing the precision, because it loses accuracy, since the standard 2742: ;; requires double rounding, whereas the 88000 instruction only rounds once. 2743: 2744: (define_expand "muldf3" 2745: [(set (match_operand:DF 0 "register_operand" "=r,x") 2746: (mult:DF (match_operand:DF 1 "general_operand" "%r,x") 2747: (match_operand:DF 2 "general_operand" "r,x")))] 2748: "" 2749: " 2750: { 2751: operands[1] = legitimize_operand (operands[1], DFmode); 2752: operands[2] = legitimize_operand (operands[2], DFmode); 2753: }") 2754: 2755: (define_insn "" 2756: [(set (match_operand:DF 0 "register_operand" "=r,x") 2757: (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) 2758: (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] 2759: "" 2760: "fmul.dss %0,%1,%2" 2761: [(set_attr "type" "spmul")]) 2762: 2763: (define_insn "" 2764: [(set (match_operand:DF 0 "register_operand" "=r,x") 2765: (mult:DF (match_operand:DF 1 "register_operand" "r,x") 2766: (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] 2767: "" 2768: "fmul.dds %0,%1,%2" 2769: [(set_attr "type" "spmul")]) 2770: 2771: (define_insn "" 2772: [(set (match_operand:DF 0 "register_operand" "=r,x") 2773: (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) 2774: (match_operand:DF 2 "register_operand" "r,x")))] 2775: "" 2776: "fmul.dsd %0,%1,%2" 2777: [(set_attr "type" "spmul")]) 2778: 2779: (define_insn "" 2780: [(set (match_operand:DF 0 "register_operand" "=r,x") 2781: (mult:DF (match_operand:DF 1 "register_operand" "%r,x") 2782: (match_operand:DF 2 "register_operand" "r,x")))] 2783: "" 2784: "fmul.ddd %0,%1,%2" 2785: [(set_attr "type" "dpmul")]) 2786: 2787: (define_insn "mulsf3" 2788: [(set (match_operand:SF 0 "register_operand" "=r,x") 2789: (mult:SF (match_operand:SF 1 "register_operand" "%r,x") 2790: (match_operand:SF 2 "register_operand" "r,x")))] 2791: "" 2792: "fmul.sss %0,%1,%2" 2793: [(set_attr "type" "spmul")]) 2794: 2795: ;;- divide instructions 2796: ;; 2797: ;; The 88k div and divu instructions don't reliably trap on 2798: ;; divide-by-zero. A trap to vector 503 asserts divide-by-zero. The 2799: ;; general scheme for doing divide is to do a 4-way split based on the 2800: ;; sign of the two operand and do the appropriate negates. 2801: ;; 2802: ;; The conditional trap instruction is not used as this serializes the 2803: ;; processor. Instead a conditional branch and an unconditional trap 2804: ;; are used, but after the divu. Since the divu takes up to 38 cycles, 2805: ;; the conditional branch is essentially free. 2806: ;; 2807: ;; Two target options control how divide is done. One options selects 2808: ;; whether to do the branch and negate scheme instead of using the div 2809: ;; instruction; the other option selects whether to explicitly check 2810: ;; for divide-by-zero or take your chances. If the div instruction is 2811: ;; used, the O/S must complete the operation if the operands are 2812: ;; negative. The O/S will signal an overflow condition if the most 2813: ;; negative number (-214783648) is divided by negative 1. 2814: ;; 2815: ;; There is an unfounded silicon eratta for E.1 requiring that an 2816: ;; immediate constant value in div/divu/mul instructions be less than 2817: ;; 0x800. This is no longer provided for. 2818: 2819: ;; Division by 0 trap 2820: (define_insn "trap_divide_by_zero" 2821: [(trap_if (const_int 1) 503)] 2822: "" 2823: "tb0 0,%#r0,503" 2824: [(set_attr "type" "weird")]) 2825: 2826: ;; Conditional division by 0 trap. 2827: (define_expand "tcnd_divide_by_zero" 2828: [(set (pc) 2829: (if_then_else (eq (match_operand:SI 0 "register_operand" "") 2830: (const_int 0)) 2831: (pc) 2832: (match_operand 1 "" ""))) 2833: (trap_if (const_int 1) 503)] 2834: "" 2835: " 2836: { 2837: emit_insn (gen_cmpsi (operands[0], const0_rtx)); 2838: emit_jump_insn (gen_bne (operands[1])); 2839: emit_insn (gen_trap_divide_by_zero ()); 2840: DONE; 2841: }") 2842: 2843: (define_expand "divsi3" 2844: [(set (match_operand:SI 0 "register_operand" "") 2845: (div:SI (match_operand:SI 1 "arith32_operand" "") 2846: (match_operand:SI 2 "arith32_operand" "")))] 2847: "" 2848: " 2849: { 2850: rtx op0 = operands[0]; 2851: rtx op1 = operands[1]; 2852: rtx op2 = operands[2]; 2853: rtx join_label; 2854: 2855: /* @@ This needs to be reworked. Torbjorn Granlund has suggested making 2856: it a runtime (perhaps quite special). */ 2857: 2858: if (GET_CODE (op1) == CONST_INT) 2859: op1 = force_reg (SImode, op1); 2860: 2861: else if (GET_CODE (op2) == CONST_INT 2862: && ! SMALL_INT (operands[2])) 2863: op2 = force_reg (SImode, op2); 2864: 2865: if (op2 == const0_rtx) 2866: { 2867: emit_insn (gen_trap_divide_by_zero ()); 2868: emit_insn (gen_dummy (op0)); 2869: DONE; 2870: } 2871: 2872: if (TARGET_USE_DIV) 2873: { 2874: emit_move_insn (op0, gen_rtx (DIV, SImode, op1, op2)); 2875: if (TARGET_CHECK_ZERO_DIV && GET_CODE (op2) != CONST_INT) 2876: { 2877: rtx label = gen_label_rtx (); 2878: emit_insn (gen_tcnd_divide_by_zero (op2, label)); 2879: emit_label (label); 2880: emit_insn (gen_dummy (op0)); 2881: } 2882: DONE; 2883: } 2884: 2885: join_label = gen_label_rtx (); 2886: if (GET_CODE (op1) == CONST_INT) 2887: { 2888: int neg = FALSE; 2889: rtx neg_op2 = gen_reg_rtx (SImode); 2890: rtx label1 = gen_label_rtx (); 2891: 2892: if (INTVAL (op1) < 0) 2893: { 2894: neg = TRUE; 2895: op1 = gen_rtx (CONST_INT, VOIDmode, -INTVAL (op1)); 2896: } 2897: op1 = force_reg (SImode, op1); 2898: 2899: emit_insn (gen_negsi2 (neg_op2, op2)); 2900: emit_insn (gen_cmpsi (op2, const0_rtx)); 2901: emit_jump_insn (gen_bgt (label1)); 2902: /* constant / 0-or-negative */ 2903: emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, neg_op2)); 2904: if (!neg) 2905: emit_insn (gen_negsi2 (op0, op0)); 2906: 2907: if (TARGET_CHECK_ZERO_DIV) 2908: emit_insn (gen_tcnd_divide_by_zero (op2, join_label)); 2909: emit_jump_insn (gen_jump (join_label)); 2910: emit_barrier (); 2911: 2912: emit_label (label1); /* constant / positive */ 2913: emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2)); 2914: if (neg) 2915: emit_insn (gen_negsi2 (op0, op0)); 2916: } 2917: 2918: else if (GET_CODE (op2) == CONST_INT) 2919: { 2920: int neg = FALSE; 2921: rtx neg_op1 = gen_reg_rtx (SImode); 2922: rtx label1 = gen_label_rtx (); 2923: 2924: if (INTVAL (op2) < 0) 2925: { 2926: neg = TRUE; 2927: op2 = gen_rtx (CONST_INT, VOIDmode, -INTVAL (op2)); 2928: } 2929: else if (! SMALL_INT (operands[2])) 2930: op2 = force_reg (SImode, op2); 2931: 2932: emit_insn (gen_negsi2 (neg_op1, op1)); 2933: emit_insn (gen_cmpsi (op1, const0_rtx)); 2934: emit_jump_insn (gen_bge (label1)); 2935: /* 0-or-negative / constant */ 2936: emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, op2)); 2937: if (!neg) 2938: emit_insn (gen_negsi2 (op0, op0)); 2939: 2940: emit_jump_insn (gen_jump (join_label)); 2941: emit_barrier (); 2942: 2943: emit_label (label1); /* positive / constant */ 2944: emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2)); 2945: if (neg) 2946: emit_insn (gen_negsi2 (op0, op0)); 2947: } 2948: 2949: else 2950: { 2951: rtx neg_op1 = gen_reg_rtx (SImode); 2952: rtx neg_op2 = gen_reg_rtx (SImode); 2953: rtx label1 = gen_label_rtx (); 2954: rtx label2 = gen_label_rtx (); 2955: rtx label3 = gen_label_rtx (); 2956: rtx label4; 2957: 2958: emit_insn (gen_negsi2 (neg_op2, op2)); 2959: emit_insn (gen_cmpsi (op2, const0_rtx)); 2960: emit_jump_insn (gen_bgt (label1)); 2961: 2962: emit_insn (gen_negsi2 (neg_op1, op1)); 2963: emit_insn (gen_cmpsi (op1, const0_rtx)); 2964: emit_jump_insn (gen_bge (label2)); 2965: /* negative / negative-or-0 */ 2966: emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, neg_op2)); 2967: 2968: if (TARGET_CHECK_ZERO_DIV) 2969: { 2970: label4 = gen_label_rtx (); 2971: emit_insn (gen_cmpsi (op2, const0_rtx)); 2972: emit_jump_insn (gen_bne (join_label)); 2973: emit_label (label4); 2974: emit_insn (gen_trap_divide_by_zero ()); 2975: } 2976: emit_jump_insn (gen_jump (join_label)); 2977: emit_barrier (); 2978: 2979: emit_label (label2); /* pos.-or-0 / neg.-or-0 */ 2980: emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, neg_op2)); 2981: 2982: if (TARGET_CHECK_ZERO_DIV) 2983: { 2984: emit_insn (gen_cmpsi (op2, const0_rtx)); 2985: emit_jump_insn (gen_beq (label4)); 2986: } 2987: 2988: emit_insn (gen_negsi2 (op0, op0)); 2989: emit_jump_insn (gen_jump (join_label)); 2990: emit_barrier (); 2991: 2992: emit_label (label1); 2993: emit_insn (gen_negsi2 (neg_op1, op1)); 2994: emit_insn (gen_cmpsi (op1, const0_rtx)); 2995: emit_jump_insn (gen_bge (label3)); 2996: /* negative / positive */ 2997: emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, op2)); 2998: emit_insn (gen_negsi2 (op0, op0)); 2999: emit_jump_insn (gen_jump (join_label)); 3000: emit_barrier (); 3001: 3002: emit_label (label3); /* positive-or-0 / positive */ 3003: emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2)); 3004: } 3005: 3006: emit_label (join_label); 3007: 3008: emit_insn (gen_dummy (op0)); 3009: DONE; 3010: }") 3011: 3012: (define_insn "" 3013: [(set (match_operand:SI 0 "register_operand" "=r") 3014: (div:SI (match_operand:SI 1 "register_operand" "r") 3015: (match_operand:SI 2 "arith_operand" "rI")))] 3016: "" 3017: "div %0,%1,%2" 3018: [(set_attr "type" "idiv")]) 3019: 3020: (define_expand "udivsi3" 3021: [(set (match_operand:SI 0 "register_operand" "") 3022: (udiv:SI (match_operand:SI 1 "register_operand" "") 3023: (match_operand:SI 2 "arith32_operand" "")))] 3024: "" 3025: " 3026: { 3027: rtx op2 = operands[2]; 3028: 3029: if (op2 == const0_rtx) 3030: { 3031: emit_insn (gen_trap_divide_by_zero ()); 3032: emit_insn (gen_dummy (operands[0])); 3033: DONE; 3034: } 3035: else if (GET_CODE (op2) != CONST_INT && TARGET_CHECK_ZERO_DIV) 3036: { 3037: rtx label = gen_label_rtx (); 3038: emit_insn (gen_rtx (SET, VOIDmode, operands[0], 3039: gen_rtx (UDIV, SImode, operands[1], op2))); 3040: emit_insn (gen_tcnd_divide_by_zero (op2, label)); 3041: emit_label (label); 3042: emit_insn (gen_dummy (operands[0])); 3043: DONE; 3044: } 3045: }") 3046: 3047: (define_insn "" 3048: [(set (match_operand:SI 0 "register_operand" "=r") 3049: (udiv:SI (match_operand:SI 1 "register_operand" "r") 3050: (match_operand:SI 2 "arith32_operand" "rI")))] 3051: "operands[2] != const0_rtx" 3052: "divu %0,%1,%2" 3053: [(set_attr "type" "idiv")]) 3054: 3055: (define_insn "" 3056: [(set (match_operand:SI 0 "register_operand" "=r") 3057: (udiv:SI (match_operand:SI 1 "register_operand" "r") 3058: (const_int 0)))] 3059: "" 3060: "tb0 0,%#r0,503" 3061: [(set_attr "type" "weird")]) 3062: 3063: ;; patterns for mixed mode floating point. 3064: ;; Do not define patterns that utilize mixed mode arithmetic that result 3065: ;; in narrowing the precision, because it loses accuracy, since the standard 3066: ;; requires double rounding, whereas the 88000 instruction only rounds once. 3067: 3068: (define_expand "divdf3" 3069: [(set (match_operand:DF 0 "register_operand" "=r,x") 3070: (div:DF (match_operand:DF 1 "general_operand" "r,x") 3071: (match_operand:DF 2 "general_operand" "r,x")))] 3072: "" 3073: " 3074: { 3075: operands[1] = legitimize_operand (operands[1], DFmode); 3076: if (real_power_of_2_operand (operands[2])) 3077: { 3078: union real_extract u; 3079: bcopy (&CONST_DOUBLE_LOW (operands[2]), &u, sizeof u); 3080: emit_insn (gen_muldf3 (operands[0], operands[1], 3081: CONST_DOUBLE_FROM_REAL_VALUE (1.0/u.d, DFmode))); 3082: DONE; 3083: } 3084: else if (! register_operand (operands[2], DFmode)) 3085: operands[2] = force_reg (DFmode, operands[2]); 3086: }") 3087: 3088: (define_insn "" 3089: [(set (match_operand:DF 0 "register_operand" "=r,x") 3090: (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) 3091: (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] 3092: "" 3093: "fdiv.dss %0,%1,%2" 3094: [(set_attr "type" "dpdiv")]) 3095: 3096: (define_insn "" 3097: [(set (match_operand:DF 0 "register_operand" "=r,x") 3098: (div:DF (match_operand:DF 1 "register_operand" "r,x") 3099: (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))] 3100: "" 3101: "fdiv.dds %0,%1,%2" 3102: [(set_attr "type" "dpdiv")]) 3103: 3104: (define_insn "" 3105: [(set (match_operand:DF 0 "register_operand" "=r,x") 3106: (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")) 3107: (match_operand:DF 2 "register_operand" "r,x")))] 3108: "" 3109: "fdiv.dsd %0,%1,%2" 3110: [(set_attr "type" "dpdiv")]) 3111: 3112: (define_insn "divsf3" 3113: [(set (match_operand:SF 0 "register_operand" "=r,x") 3114: (div:SF (match_operand:SF 1 "register_operand" "r,x") 3115: (match_operand:SF 2 "register_operand" "r,x")))] 3116: "" 3117: "fdiv.sss %0,%1,%2" 3118: [(set_attr "type" "spdiv")]) 3119: 3120: (define_insn "" 3121: [(set (match_operand:DF 0 "register_operand" "=r,x") 3122: (div:DF (match_operand:DF 1 "register_operand" "r,x") 3123: (match_operand:DF 2 "register_operand" "r,x")))] 3124: "" 3125: "fdiv.ddd %0,%1,%2" 3126: [(set_attr "type" "dpdiv")]) 3127: 3128: ;; - remainder instructions, don't define, since the hardware doesn't have any 3129: ;; direct support, and GNU can synthesis them out of div/mul just fine. 3130: 3131: ;;- load effective address, must come after add, so that we favor using 3132: ;; addu reg,reg,reg instead of: lda reg,reg,reg (addu doesn't require 3133: ;; the data unit), and also future 88k chips might not support unscaled 3134: ;; lda instructions. 3135: 3136: (define_insn "" 3137: [(set (match_operand:SI 0 "register_operand" "=r") 3138: (match_operand:SI 1 "address_operand" "p"))] 3139: "m88k_gp_threshold > 0 && symbolic_address_p (operands[1])" 3140: "addu %0,%a1") 3141: 3142: (define_insn "" 3143: [(set (match_operand:SI 0 "register_operand" "=r") 3144: (match_operand:HI 1 "address_operand" "p"))] 3145: "" 3146: "lda.h %0,%a1" 3147: [(set_attr "type" "loada")]) 3148: 3149: (define_insn "" 3150: [(set (match_operand:SI 0 "register_operand" "=r") 3151: (match_operand:SI 1 "address_operand" "p"))] 3152: "" 3153: "lda %0,%a1" 3154: [(set_attr "type" "loada")]) 3155: 3156: (define_insn "" 3157: [(set (match_operand:SI 0 "register_operand" "=r") 3158: (match_operand:DI 1 "address_operand" "p"))] 3159: "" 3160: "lda.d %0,%a1" 3161: [(set_attr "type" "loada")]) 3162: 3163: (define_insn "" 3164: [(set (match_operand:SI 0 "register_operand" "=r") 3165: (match_operand:SF 1 "address_operand" "p"))] 3166: "" 3167: "lda %0,%a1" 3168: [(set_attr "type" "loada")]) 3169: 3170: (define_insn "" 3171: [(set (match_operand:SI 0 "register_operand" "=r") 3172: (match_operand:DF 1 "address_operand" "p"))] 3173: "" 3174: "lda.d %0,%a1" 3175: [(set_attr "type" "loada")]) 3176: 3177: ;;- and instructions (with complement also) 3178: (define_insn "" 3179: [(set (match_operand:SI 0 "register_operand" "=r") 3180: (and:SI (not:SI (match_operand:SI 1 "register_operand" "r")) 3181: (match_operand:SI 2 "register_operand" "r")))] 3182: "" 3183: "and.c %0,%2,%1") 3184: 3185: ;; If the operation is being performed on a 32-bit constant such that 3186: ;; it cannot be done in one insn, do it in two. We may lose a bit on 3187: ;; CSE in pathological cases, but it seems better doing it this way. 3188: 3189: (define_expand "andsi3" 3190: [(set (match_operand:SI 0 "register_operand" "") 3191: (and:SI (match_operand:SI 1 "arith32_operand" "") 3192: (match_operand:SI 2 "arith32_operand" "")))] 3193: "" 3194: " 3195: { 3196: if (GET_CODE (operands[2]) == CONST_INT) 3197: { 3198: int value = INTVAL (operands[2]); 3199: 3200: if (! (SMALL_INTVAL (value) 3201: || (value & 0xffff0000) == 0xffff0000 3202: || (value & 0xffff) == 0xffff 3203: || (value & 0xffff) == 0 3204: || integer_ok_for_set (~value))) 3205: { 3206: emit_insn (gen_andsi3 (operands[0], operands[1], 3207: gen_rtx (CONST_INT, VOIDmode, 3208: value | 0xffff))); 3209: operands[1] = operands[0]; 3210: operands[2] = gen_rtx (CONST_INT, VOIDmode, value | 0xffff0000); 3211: } 3212: } 3213: }") 3214: 3215: (define_insn "" 3216: [(set (match_operand:SI 0 "register_operand" "=r,r") 3217: (and:SI (match_operand:SI 1 "arith32_operand" "%r,r") 3218: (match_operand:SI 2 "arith32_operand" "rIJL,rn")))] 3219: "" 3220: "* return output_and (operands);" 3221: [(set_attr "type" "arith,marith")]) 3222: 3223: (define_insn "" 3224: [(set (match_operand:DI 0 "register_operand" "=r") 3225: (and:DI (not:DI (match_operand:DI 1 "register_operand" "r")) 3226: (match_operand:DI 2 "register_operand" "r")))] 3227: "" 3228: "and.c %d0,%d2,%d1\;and.c %0,%2,%1" 3229: [(set_attr "type" "marith")]) 3230: 3231: (define_insn "anddi3" 3232: [(set (match_operand:DI 0 "register_operand" "=r") 3233: (and:DI (match_operand:DI 1 "arith64_operand" "%r") 3234: (match_operand:DI 2 "arith64_operand" "rn")))] 3235: "" 3236: "* 3237: { 3238: rtx xoperands[10]; 3239: 3240: xoperands[0] = operand_subword (operands[0], 1, 0, DImode); 3241: xoperands[1] = operand_subword (operands[1], 1, 0, DImode); 3242: xoperands[2] = operand_subword (operands[2], 1, 0, DImode); 3243: 3244: output_asm_insn (output_and (xoperands), xoperands); 3245: 3246: operands[0] = operand_subword (operands[0], 0, 0, DImode); 3247: operands[1] = operand_subword (operands[1], 0, 0, DImode); 3248: operands[2] = operand_subword (operands[2], 0, 0, DImode); 3249: 3250: return output_and (operands); 3251: }" 3252: [(set_attr "type" "marith") 3253: (set_attr "length" "4")]) ; length is 2, 3, or 4. 3254: 3255: ;;- Bit set (inclusive or) instructions (with complement also) 3256: (define_insn "" 3257: [(set (match_operand:SI 0 "register_operand" "=r") 3258: (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r")) 3259: (match_operand:SI 2 "register_operand" "r")))] 3260: "" 3261: "or.c %0,%2,%1") 3262: 3263: (define_expand "iorsi3" 3264: [(set (match_operand:SI 0 "register_operand" "") 3265: (ior:SI (match_operand:SI 1 "arith32_operand" "") 3266: (match_operand:SI 2 "arith32_operand" "")))] 3267: "" 3268: " 3269: { 3270: if (GET_CODE (operands[2]) == CONST_INT) 3271: { 3272: int value = INTVAL (operands[2]); 3273: 3274: if (! (SMALL_INTVAL (value) 3275: || (value & 0xffff) == 0 3276: || integer_ok_for_set (value))) 3277: { 3278: emit_insn (gen_iorsi3 (operands[0], operands[1], 3279: gen_rtx (CONST_INT, VOIDmode, 3280: value & 0xffff0000))); 3281: operands[1] = operands[0]; 3282: operands[2] = gen_rtx (CONST_INT, VOIDmode, value & 0xffff); 3283: } 3284: } 3285: }") 3286: 3287: (define_insn "" 3288: [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 3289: (ior:SI (match_operand:SI 1 "arith32_operand" "%r,r,r,r") 3290: (match_operand:SI 2 "arith32_operand" "rI,L,M,n")))] 3291: "" 3292: "@ 3293: or %0,%1,%2 3294: or.u %0,%1,%X2 3295: set %0,%1,%s2 3296: or.u %0,%1,%X2\;or %0,%0,%x2" 3297: [(set_attr "type" "arith,arith,bit,marith")]) 3298: 3299: (define_insn "" 3300: [(set (match_operand:DI 0 "register_operand" "=r") 3301: (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r")) 3302: (match_operand:DI 2 "register_operand" "r")))] 3303: "" 3304: "or.c %d0,%d2,%d1\;or.c %0,%2,%1" 3305: [(set_attr "type" "marith")]) 3306: 3307: (define_insn "iordi3" 3308: [(set (match_operand:DI 0 "register_operand" "=r") 3309: (ior:DI (match_operand:DI 1 "arith64_operand" "%r") 3310: (match_operand:DI 2 "arith64_operand" "rn")))] 3311: "" 3312: "* 3313: { 3314: rtx xoperands[10]; 3315: 3316: xoperands[0] = operand_subword (operands[0], 1, 0, DImode); 3317: xoperands[1] = operand_subword (operands[1], 1, 0, DImode); 3318: xoperands[2] = operand_subword (operands[2], 1, 0, DImode); 3319: 3320: output_asm_insn (output_ior (xoperands), xoperands); 3321: 3322: operands[0] = operand_subword (operands[0], 0, 0, DImode); 3323: operands[1] = operand_subword (operands[1], 0, 0, DImode); 3324: operands[2] = operand_subword (operands[2], 0, 0, DImode); 3325: 3326: return output_ior (operands); 3327: }" 3328: [(set_attr "type" "marith") 3329: (set_attr "length" "4")]) ; length is 2, 3, or 4. 3330: 3331: ;;- xor instructions (with complement also) 3332: (define_insn "" 3333: [(set (match_operand:SI 0 "register_operand" "=r") 3334: (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%r") 3335: (match_operand:SI 2 "register_operand" "r"))))] 3336: "" 3337: "xor.c %0,%1,%2") 3338: 3339: (define_expand "xorsi3" 3340: [(set (match_operand:SI 0 "register_operand" "") 3341: (xor:SI (match_operand:SI 1 "arith32_operand" "") 3342: (match_operand:SI 2 "arith32_operand" "")))] 3343: "" 3344: " 3345: { 3346: if (GET_CODE (operands[2]) == CONST_INT) 3347: { 3348: int value = INTVAL (operands[2]); 3349: 3350: if (! (SMALL_INTVAL (value) 3351: || (value & 0xffff) == 0)) 3352: { 3353: emit_insn (gen_xorsi3 (operands[0], operands[1], 3354: gen_rtx (CONST_INT, VOIDmode, 3355: value & 0xffff0000))); 3356: operands[1] = operands[0]; 3357: operands[2] = gen_rtx (CONST_INT, VOIDmode, value & 0xffff); 3358: } 3359: } 3360: }") 3361: 3362: (define_insn "" 3363: [(set (match_operand:SI 0 "register_operand" "=r,r,r") 3364: (xor:SI (match_operand:SI 1 "arith32_operand" "%r,r,r") 3365: (match_operand:SI 2 "arith32_operand" "rI,L,n")))] 3366: "" 3367: "@ 3368: xor %0,%1,%2 3369: xor.u %0,%1,%X2 3370: xor.u %0,%1,%X2\;xor %0,%0,%x2" 3371: [(set_attr "type" "arith,arith,marith")]) 3372: 3373: (define_insn "" 3374: [(set (match_operand:DI 0 "register_operand" "=r") 3375: (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r") 3376: (match_operand:DI 2 "register_operand" "r"))))] 3377: "" 3378: "xor.c %d0,%d1,%d2\;xor.c %0,%1,%2" 3379: [(set_attr "type" "marith")]) 3380: 3381: (define_insn "xordi3" 3382: [(set (match_operand:DI 0 "register_operand" "=r") 3383: (xor:DI (match_operand:DI 1 "arith64_operand" "%r") 3384: (match_operand:DI 2 "arith64_operand" "rn")))] 3385: "" 3386: "* 3387: { 3388: rtx xoperands[10]; 3389: 3390: xoperands[0] = operand_subword (operands[0], 1, 0, DImode); 3391: xoperands[1] = operand_subword (operands[1], 1, 0, DImode); 3392: xoperands[2] = operand_subword (operands[2], 1, 0, DImode); 3393: 3394: output_asm_insn (output_xor (xoperands), xoperands); 3395: 3396: operands[0] = operand_subword (operands[0], 0, 0, DImode); 3397: operands[1] = operand_subword (operands[1], 0, 0, DImode); 3398: operands[2] = operand_subword (operands[2], 0, 0, DImode); 3399: 3400: return output_xor (operands); 3401: }" 3402: [(set_attr "type" "marith") 3403: (set_attr "length" "4")]) ; length is 2, 3, or 4. 3404: 3405: ;;- ones complement instructions 3406: (define_insn "one_cmplsi2" 3407: [(set (match_operand:SI 0 "register_operand" "=r") 3408: (not:SI (match_operand:SI 1 "register_operand" "r")))] 3409: "" 3410: "xor.c %0,%1,%#r0") 3411: 3412: (define_insn "one_cmpldi2" 3413: [(set (match_operand:DI 0 "register_operand" "=r") 3414: (not:DI (match_operand:DI 1 "register_operand" "r")))] 3415: "" 3416: "xor.c %d0,%d1,%#r0\;xor.c %0,%1,%#r0" 3417: [(set_attr "type" "marith")]) 3418: 3419: ;; Optimized special cases of shifting. 3420: ;; Must precede the general case. 3421: 3422: ;; @@ What about HImode shifted by 8? 3423: 3424: (define_insn "" 3425: [(set (match_operand:SI 0 "register_operand" "=r") 3426: (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m") 3427: (const_int 24)))] 3428: "! SCALED_ADDRESS_P (XEXP (operands[1], 0))" 3429: "%V1ld.b\\t %0,%1" 3430: [(set_attr "type" "load")]) 3431: 3432: (define_insn "" 3433: [(set (match_operand:SI 0 "register_operand" "=r") 3434: (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") 3435: (const_int 24)))] 3436: "! SCALED_ADDRESS_P (XEXP (operands[1], 0))" 3437: "%V1ld.bu\\t %0,%1" 3438: [(set_attr "type" "load")]) 3439: 3440: (define_insn "" 3441: [(set (match_operand:SI 0 "register_operand" "=r") 3442: (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m") 3443: (const_int 16)))] 3444: "! SCALED_ADDRESS_P (XEXP (operands[1], 0))" 3445: "%V1ld.h\\t %0,%1" 3446: [(set_attr "type" "load")]) 3447: 3448: (define_insn "" 3449: [(set (match_operand:SI 0 "register_operand" "=r") 3450: (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") 3451: (const_int 16)))] 3452: "! SCALED_ADDRESS_P (XEXP (operands[1], 0))" 3453: "%V1ld.hu\\t %0,%1" 3454: [(set_attr "type" "load")]) 3455: 3456: ;;- arithmetic shift instructions. 3457: 3458: ;; @@ Do the optimized patterns with -1 get used? Perhaps operand 1 should 3459: ;; be arith32_operand? 3460: 3461: ;; Use tbnd to support TARGET_TRAP_LARGE_SHIFT. 3462: (define_insn "tbnd" 3463: [(trap_if (gtu (match_operand:SI 0 "register_operand" "r") 3464: (match_operand:SI 1 "arith_operand" "rI")) 3465: 7)] 3466: "" 3467: "tbnd %r0,%1" 3468: [(set_attr "type" "weird")]) 3469: 3470: ;; Just in case the optimizer decides to fold away the test. 3471: (define_insn "" 3472: [(trap_if (const_int 1) 7)] 3473: "" 3474: "tbnd %#r31,0" 3475: [(set_attr "type" "weird")]) 3476: 3477: (define_expand "ashlsi3" 3478: [(set (match_operand:SI 0 "register_operand" "") 3479: (ashift:SI (match_operand:SI 1 "register_operand" "") 3480: (match_operand:SI 2 "arith32_operand" "")))] 3481: "" 3482: " 3483: { 3484: if (GET_CODE (operands[2]) == CONST_INT) 3485: { 3486: if ((unsigned) INTVAL (operands[2]) > 31) 3487: { 3488: if (TARGET_TRAP_LARGE_SHIFT) 3489: emit_insn (gen_tbnd (force_reg (SImode, operands[2]), 3490: gen_rtx (CONST_INT, VOIDmode, 31))); 3491: else 3492: emit_move_insn (operands[0], const0_rtx); 3493: DONE; 3494: } 3495: } 3496: 3497: else if (TARGET_TRAP_LARGE_SHIFT) 3498: emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31))); 3499: 3500: else if (TARGET_HANDLE_LARGE_SHIFT) 3501: { 3502: rtx reg = gen_reg_rtx (SImode); 3503: emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31))); 3504: emit_insn (gen_sleu (reg)); 3505: emit_insn (gen_andsi3 (reg, operands[1], reg)); 3506: operands[1] = reg; 3507: } 3508: }") 3509: 3510: (define_insn "" 3511: [(set (match_operand:SI 0 "register_operand" "=r,r") 3512: (ashift:SI (match_operand:SI 1 "register_operand" "r,r") 3513: (match_operand:SI 2 "arith5_operand" "r,K")))] 3514: "" 3515: "@ 3516: mak %0,%1,%2 3517: mak %0,%1,0<%2>" 3518: [(set_attr "type" "bit")]) 3519: 3520: (define_expand "ashrsi3" 3521: [(set (match_operand:SI 0 "register_operand" "") 3522: (ashiftrt:SI (match_operand:SI 1 "register_operand" "") 3523: (match_operand:SI 2 "arith32_operand" "")))] 3524: "" 3525: " 3526: { 3527: if (GET_CODE (operands[2]) == CONST_INT) 3528: { 3529: if ((unsigned) INTVAL (operands[2]) > 31) 3530: { 3531: if (TARGET_TRAP_LARGE_SHIFT) 3532: { 3533: emit_insn (gen_tbnd (force_reg (SImode, operands[2]), 3534: gen_rtx (CONST_INT, VOIDmode, 31))); 3535: DONE; 3536: } 3537: else 3538: operands[2] = gen_rtx (CONST_INT, VOIDmode, 31); 3539: } 3540: } 3541: 3542: else if (TARGET_TRAP_LARGE_SHIFT) 3543: emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31))); 3544: 3545: else if (TARGET_HANDLE_LARGE_SHIFT) 3546: { 3547: rtx reg = gen_reg_rtx (SImode); 3548: emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31))); 3549: emit_insn (gen_sgtu (reg)); 3550: emit_insn (gen_iorsi3 (reg, operands[2], reg)); 3551: operands[2] = reg; 3552: } 3553: }") 3554: 3555: (define_insn "" 3556: [(set (match_operand:SI 0 "register_operand" "=r,r") 3557: (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r") 3558: (match_operand:SI 2 "arith5_operand" "r,K")))] 3559: "" 3560: "@ 3561: ext %0,%1,%2 3562: ext %0,%1,0<%2>" 3563: [(set_attr "type" "bit")]) 3564: 3565: ;;- logical shift instructions. Logical shift left becomes arithmetic 1.1.1.3 ! root 3566: ;; shift left. 1.1 root 3567: 3568: (define_expand "lshrsi3" 3569: [(set (match_operand:SI 0 "register_operand" "") 3570: (lshiftrt:SI (match_operand:SI 1 "register_operand" "") 3571: (match_operand:SI 2 "arith32_operand" "")))] 3572: "" 3573: " 3574: { 3575: if (GET_CODE (operands[2]) == CONST_INT) 3576: { 3577: if ((unsigned) INTVAL (operands[2]) > 31) 3578: { 3579: if (TARGET_TRAP_LARGE_SHIFT) 3580: emit_insn (gen_tbnd (force_reg (SImode, operands[2]), 3581: gen_rtx (CONST_INT, VOIDmode, 31))); 3582: else 3583: emit_move_insn (operands[0], const0_rtx); 3584: DONE; 3585: } 3586: } 3587: 3588: else if (TARGET_TRAP_LARGE_SHIFT) 3589: emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31))); 3590: 3591: else if (TARGET_HANDLE_LARGE_SHIFT) 3592: { 3593: rtx reg = gen_reg_rtx (SImode); 3594: emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31))); 3595: emit_insn (gen_sleu (reg)); 3596: emit_insn (gen_andsi3 (reg, operands[1], reg)); 3597: operands[1] = reg; 3598: } 3599: }") 3600: 3601: (define_insn "" 3602: [(set (match_operand:SI 0 "register_operand" "=r,r") 3603: (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r") 3604: (match_operand:SI 2 "arith5_operand" "r,K")))] 3605: "" 3606: "@ 3607: extu %0,%1,%2 3608: extu %0,%1,0<%2>" 3609: [(set_attr "type" "bit")]) 3610: 3611: ;;- rotate instructions 3612: 3613: (define_expand "rotlsi3" 3614: [(set (match_operand:SI 0 "register_operand" "") 3615: (rotatert:SI (match_operand:SI 1 "register_operand" "") 3616: (match_operand:SI 2 "arith32_operand" "")))] 3617: "" 3618: " 3619: { 3620: if (GET_CODE (operands[2]) == CONST_INT 3621: && (unsigned) INTVAL (operands[2]) >= 32) 3622: operands[2] = gen_rtx (CONST_INT, VOIDmode, 3623: (32 - INTVAL (operands[2])) % 32); 3624: else 3625: { 3626: rtx op = gen_reg_rtx (SImode); 3627: emit_insn (gen_negsi2 (op, operands[2])); 3628: operands[2] = op; 3629: } 3630: }") 3631: 3632: (define_insn "rotrsi3" 3633: [(set (match_operand:SI 0 "register_operand" "=r") 3634: (rotatert:SI (match_operand:SI 1 "register_operand" "r") 3635: (match_operand:SI 2 "arith_operand" "rI")))] 3636: "" 3637: "rot %0,%1,%2" 3638: [(set_attr "type" "bit")]) 3639: 3640: ;; find first set. 3641: 3642: ;; The ff1 instruction searches from the most significant bit while ffs 3643: ;; searches from the least significant bit. The bit index and treatment of 3644: ;; zero also differ. This amazing sequence was discovered using the GNU 3645: ;; Superoptimizer. 3646: 3647: (define_insn "ffssi2" 3648: [(set (match_operand:SI 0 "register_operand" "=r,&r") 3649: (ffs:SI (match_operand:SI 1 "register_operand" "0,r"))) 3650: (clobber (reg:CC 0)) 3651: (clobber (match_scratch:SI 2 "=r,X"))] 3652: "" 3653: "@ 3654: subu.co %2,%#r0,%1\;and %2,%2,%1\;addu.ci %2,%2,%2\;ff1 %0,%2 3655: subu.co %0,%#r0,%1\;and %0,%0,%1\;addu.ci %0,%0,%0\;ff1 %0,%0" 3656: [(set_attr "type" "marith") 3657: (set_attr "length" "4")]) 3658: 3659: ;; Bit field instructions. 3660: 3661: (define_insn "" 3662: [(set (match_operand:SI 0 "register_operand" "=r") 3663: (sign_extract:SI (match_operand:SI 1 "register_operand" "r") 3664: (const_int 32) 3665: (const_int 0)))] 3666: "" 3667: "or %0,%#r0,%1") 3668: 3669: (define_insn "extv" 3670: [(set (match_operand:SI 0 "register_operand" "=r") 3671: (sign_extract:SI (match_operand:SI 1 "register_operand" "r") 3672: (match_operand:SI 2 "int5_operand" "") 3673: (match_operand:SI 3 "int5_operand" "")))] 3674: "" 3675: "* 3676: { 3677: operands[4] = gen_rtx (CONST_INT, SImode, 3678: (32 - INTVAL (operands[2])) - INTVAL (operands[3])); 3679: return \"ext %0,%1,%2<%4>\"; /* <(32-%2-%3)> */ 3680: }" 3681: [(set_attr "type" "bit")]) 3682: 3683: (define_insn "" 3684: [(set (match_operand:SI 0 "register_operand" "=r") 3685: (zero_extract:SI (match_operand:SI 1 "register_operand" "r") 3686: (const_int 32) 3687: (const_int 0)))] 3688: "" 3689: "or %0,%#r0,%1") 3690: 3691: (define_insn "extzv" 3692: [(set (match_operand:SI 0 "register_operand" "=r") 3693: (zero_extract:SI (match_operand:SI 1 "register_operand" "r") 3694: (match_operand:SI 2 "int5_operand" "") 3695: (match_operand:SI 3 "int5_operand" "")))] 3696: "" 3697: "* 3698: { 3699: operands[4] = gen_rtx (CONST_INT, SImode, 3700: (32 - INTVAL (operands[2])) - INTVAL (operands[3])); 3701: return \"extu %0,%1,%2<%4>\"; /* <(32-%2-%3)> */ 3702: }" 3703: [(set_attr "type" "bit")]) 3704: 3705: (define_insn "" 3706: [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") 3707: (match_operand:SI 1 "int5_operand" "") 3708: (match_operand:SI 2 "int5_operand" "")) 3709: (const_int 0))] 3710: "" 3711: "* 3712: { 3713: operands[3] = gen_rtx (CONST_INT, SImode, 3714: (32 - INTVAL (operands[1])) - INTVAL (operands[2])); 3715: return \"clr %0,%0,%1<%3>\"; /* <(32-%1-%2)> */ 3716: }" 3717: [(set_attr "type" "bit")]) 3718: 3719: (define_insn "" 3720: [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") 3721: (match_operand:SI 1 "int5_operand" "") 3722: (match_operand:SI 2 "int5_operand" "")) 3723: (const_int -1))] 3724: "" 3725: "* 3726: { 3727: operands[3] = gen_rtx (CONST_INT, SImode, 3728: (32 - INTVAL (operands[1])) - INTVAL (operands[2])); 3729: return \"set %0,%0,%1<%3>\"; /* <(32-%1-%2)> */ 3730: }" 3731: [(set_attr "type" "bit")]) 3732: 3733: (define_insn "" 3734: [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") 3735: (match_operand:SI 1 "int5_operand" "") 3736: (match_operand:SI 2 "int5_operand" "")) 3737: (match_operand:SI 3 "int32_operand" "n"))] 3738: "" 3739: "* 3740: { 3741: int value = INTVAL (operands[3]); 3742: 3743: if (INTVAL (operands[1]) < 32) 3744: value &= (1 << INTVAL (operands[1])) - 1; 3745: 3746: operands[2] = gen_rtx (CONST_INT, VOIDmode, 3747: 32 - (INTVAL(operands[1]) + INTVAL(operands[2]))); 3748: 3749: value <<= INTVAL (operands[2]); 3750: operands[3] = gen_rtx (CONST_INT, VOIDmode, value); 3751: 3752: if (SMALL_INTVAL (value)) 3753: return \"clr %0,%0,%1<%2>\;or %0,%0,%3\"; 3754: else if ((value & 0x0000ffff) == 0) 3755: return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\"; 3756: else 3757: return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\;or %0,%0,%x3\"; 3758: }" 3759: [(set_attr "type" "marith") 3760: (set_attr "length" "3")]) ; may be 2 or 3. 3761: 3762: ;; negate insns 3763: (define_insn "negsi2" 3764: [(set (match_operand:SI 0 "register_operand" "=r") 3765: (neg:SI (match_operand:SI 1 "arith_operand" "rI")))] 3766: "" 3767: "subu %0,%#r0,%1") 3768: 3769: (define_insn "" 3770: [(set (match_operand:SF 0 "register_operand" "=r,x") 3771: (float_truncate:SF (neg:DF (match_operand:DF 1 "register_operand" "r,x"))))] 3772: "" 3773: "@ 3774: fsub.ssd %0,%#r0,%1 3775: fsub.ssd %0,%#x0,%1" 3776: [(set_attr "type" "dpadd")]) 3777: 3778: (define_insn "negdf2" 3779: [(set (match_operand:DF 0 "register_operand" "=&r,r") 3780: (neg:DF (match_operand:DF 1 "register_operand" "r,0")))] 3781: "" 3782: "@ 3783: xor.u %0,%1,0x8000\;or %d0,%#r0,%d1 3784: xor.u %0,%0,0x8000" 3785: [(set_attr "type" "marith,arith")]) 3786: 3787: (define_insn "negsf2" 3788: [(set (match_operand:SF 0 "register_operand" "=r") 3789: (neg:SF (match_operand:SF 1 "register_operand" "r")))] 3790: "" 3791: "xor.u %0,%1,0x8000") 3792: 3793: ;; absolute value insns for floating-point (integer abs can be done using the 3794: ;; machine-independent sequence). 3795: 3796: (define_insn "absdf2" 3797: [(set (match_operand:DF 0 "register_operand" "=&r,r") 3798: (abs:DF (match_operand:DF 1 "register_operand" "r,0")))] 3799: "" 3800: "@ 3801: and.u %0,%1,0x7fff\;or %d0,%#r0,%d1 3802: and.u %0,%0,0x7fff" 3803: [(set_attr "type" "marith,arith")]) 3804: 3805: (define_insn "abssf2" 3806: [(set (match_operand:SF 0 "register_operand" "=r") 3807: (abs:SF (match_operand:SF 1 "register_operand" "r")))] 3808: "" 3809: "and.u %0,%1,0x7fff") 3810: 3811: ;; Subroutines of "casesi". 3812: 3813: ;; Operand 0 is index 3814: ;; operand 1 is the minimum bound 3815: ;; operand 2 is the maximum bound - minimum bound + 1 3816: ;; operand 3 is CODE_LABEL for the table; 3817: ;; operand 4 is the CODE_LABEL to go to if index out of range. 3818: 3819: (define_expand "casesi" 3820: ;; We don't use these for generating the RTL, but we must describe 3821: ;; the operands here. 3822: [(match_operand:SI 0 "general_operand" "") 3823: (match_operand:SI 1 "immediate_operand" "") 3824: (match_operand:SI 2 "immediate_operand" "") 3825: (match_operand 3 "" "") 3826: (match_operand 4 "" "")] 3827: "" 3828: " 3829: { 3830: register rtx index_diff = gen_reg_rtx (SImode); 3831: register rtx low = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[1])); 3832: register rtx label = gen_rtx (LABEL_REF, VOIDmode, operands[3]); 3833: register rtx base; 3834: 3835: if (! CASE_VECTOR_INSNS) 3836: /* These instructions are likely to be scheduled and made loop invariant. 3837: This decreases the cost of the dispatch at the expense of the default 3838: case. */ 3839: base = force_reg (SImode, memory_address_noforce (SImode, label)); 3840: 3841: /* Compute the index difference and handle the default case. */ 3842: emit_insn (gen_addsi3 (index_diff, 3843: force_reg (SImode, operands[0]), 3844: ADD_INT (low) ? low : force_reg (SImode, low))); 3845: emit_insn (gen_cmpsi (index_diff, operands[2])); 3846: /* It's possible to replace this branch with sgtu/iorsi3 and adding a -1 3847: entry to the table. However, that doesn't seem to win on the m88110. */ 3848: emit_jump_insn (gen_bgtu (operands[4])); 3849: 3850: if (CASE_VECTOR_INSNS) 3851: /* Call the jump that will branch to the appropriate case. */ 3852: emit_jump_insn (gen_casesi_enter (label, index_diff, operands[3])); 3853: else 3854: /* Load the table entry and jump to it. */ 3855: emit_jump_insn (gen_casesi_jump (gen_reg_rtx (SImode), base, index_diff)); 3856: 3857: /* Claim that flow drops into the table so it will be adjacent by not 3858: emitting a barrier. */ 3859: DONE; 3860: }") 3861: 3862: (define_expand "casesi_jump" 3863: [(set (match_operand:SI 0 "" "") 3864: (mem:SI (plus:SI (match_operand:SI 1 "" "") 3865: (mult:SI (match_operand:SI 2 "" "") 3866: (const_int 4))))) 3867: (set (pc) (match_dup 0))] 3868: "" 3869: "") 3870: 3871: ;; The bsr.n instruction is directed to the END of the table. See 3872: ;; ASM_OUTPUT_CASE_END. 3873: 3874: (define_insn "casesi_enter" 3875: [(set (pc) (match_operand 0 "" "")) 3876: (use (match_operand:SI 1 "register_operand" "r")) 3877: ;; The USE here is so that at least one jump-insn will refer to the label, 3878: ;; to keep it alive in jump_optimize. 3879: (use (label_ref (match_operand 2 "" ""))) 3880: (clobber (reg:SI 1))] 3881: "" 3882: "* 3883: { 3884: if (flag_delayed_branch) 3885: return \"bsr.n %0e\;lda %#r1,%#r1[%1]\"; 3886: m88k_case_index = REGNO (operands[1]); 3887: return \"bsr %0e\"; 3888: }" 3889: [(set_attr "type" "weird") 3890: (set_attr "length" "3")]) ; Including the "jmp r1". 3891: 3892: ;;- jump to subroutine 3893: (define_expand "call" 3894: [(parallel [(call (match_operand:SI 0 "" "") 3895: (match_operand 1 "" "")) 3896: (clobber (reg:SI 1))])] 3897: "" 3898: " 3899: { 3900: if (GET_CODE (operands[0]) == MEM 3901: && ! call_address_operand (XEXP (operands[0], 0), SImode)) 3902: operands[0] = gen_rtx (MEM, GET_MODE (operands[0]), 3903: force_reg (Pmode, XEXP (operands[0], 0))); 3904: }") 3905: 3906: (define_insn "" 3907: [(parallel [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rQ")) 3908: (match_operand 1 "" "")) 3909: (clobber (reg:SI 1))])] 3910: "" 3911: "* return output_call (operands, operands[0]);" 3912: [(set_attr "type" "call")]) 3913: 3914: (define_expand "call_value" 3915: [(parallel [(set (match_operand 0 "register_operand" "") 3916: (call (match_operand:SI 1 "" "") 3917: (match_operand 2 "" ""))) 3918: (clobber (reg:SI 1))])] 3919: "" 3920: " 3921: { 3922: if (GET_CODE (operands[1]) == MEM 3923: && ! call_address_operand (XEXP (operands[1], 0), SImode)) 3924: operands[1] = gen_rtx (MEM, GET_MODE (operands[1]), 3925: force_reg (Pmode, XEXP (operands[1], 0))); 3926: }") 3927: 3928: (define_insn "" 3929: [(parallel [(set (match_operand 0 "register_operand" "=r") 3930: (call (mem:SI 3931: (match_operand:SI 1 "call_address_operand" "rQ")) 3932: (match_operand 2 "" ""))) 3933: (clobber (reg:SI 1))])] 3934: "" 3935: "* return output_call (operands, operands[1]);" 3936: [(set_attr "type" "call")]) 3937: 3938: ;; Nop instruction and others 3939: 3940: (define_insn "nop" 3941: [(const_int 0)] 3942: "" 3943: "ff0 %#r0,%#r0" 3944: [(set_attr "type" "bit")]) 3945: 3946: (define_insn "return" 3947: [(return)] 3948: "reload_completed" 3949: "jmp%. %#r1" 3950: [(set_attr "type" "jump")]) 3951: 3952: (define_expand "prologue" 3953: [(const_int 0)] 3954: "" 3955: "m88k_expand_prologue (); DONE;") 3956: 3957: (define_expand "epilogue" 3958: [(return)] 3959: "! null_prologue ()" 3960: "m88k_expand_epilogue ();") 3961: 3962: (define_insn "blockage" 3963: [(unspec_volatile [(const_int 0)] 0)] 3964: "" 3965: "" 3966: [(set_attr "length" "0")]) 3967: 3968: (define_insn "indirect_jump" 3969: [(set (pc) (match_operand:SI 0 "register_operand" "r"))] 3970: "" 3971: "jmp%. %0" 3972: [(set_attr "type" "jump")]) 3973: 3974: (define_insn "jump" 3975: [(set (pc) 3976: (label_ref (match_operand 0 "" "")))] 3977: "" 3978: "br%. %l0" 3979: [(set_attr "type" "jump")]) 3980: 3981: ;; This insn is used for some loop tests, typically loops reversed when 3982: ;; strength reduction is used. It is actually created when the instruction 3983: ;; combination phase combines the special loop test. Since this insn 3984: ;; is both a jump insn and has an output, it must deal with it's own 3985: ;; reloads, hence the `m' constraints. The `!' constraints direct reload 3986: ;; to not choose the register alternatives in the event a reload is needed. 3987: 3988: (define_insn "decrement_and_branch_until_zero" 3989: [(set (pc) 3990: (if_then_else 3991: (match_operator 0 "relop_no_unsigned" 3992: [(match_operand:SI 1 "register_operand" "+!r,!r,m,m") 3993: (const_int 0)]) 3994: (label_ref (match_operand 2 "" "")) 3995: (pc))) 3996: (set (match_dup 1) 3997: (plus:SI (match_dup 1) 3998: (match_operand:SI 3 "add_operand" "rI,J,rI,J"))) 3999: (clobber (match_scratch:SI 4 "=X,X,&r,&r")) 4000: (clobber (match_scratch:SI 5 "=X,X,&r,&r"))] 4001: "find_reg_note (insn, REG_NONNEG, 0)" 4002: "@ 4003: bcnd.n %B0,%1,%2\;addu %1,%1,%3 4004: bcnd.n %B0,%1,%2\;subu %1,%1,%n3 4005: ld %4,%1\;addu %5,%4,%3\;bcnd.n %B0,%4,%2\;st %5,%1 4006: ld %4,%1\;subu %5,%4,%n3\;bcnd.n %B0,%4,%2\;st %5,%1" 4007: [(set_attr "type" "weird") 4008: (set_attr "length" "2,2,4,4")]) 4009: 4010: ;; Special insn to serve as the last insn of a define_expand. This insn 4011: ;; will generate no code. 4012: 4013: (define_expand "dummy" 4014: [(set (match_operand 0 "" "") (match_dup 0))] 4015: "" 4016: "")
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.