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