|
|
1.1 ! root 1: ;; Mips.md Machine Description for MIPS based processors ! 2: ;; Contributed by A. Lichnewsky, [email protected] ! 3: ;; Changes by Michael Meissner, [email protected] ! 4: ;; Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. ! 5: ! 6: ;; This file is part of GNU CC. ! 7: ! 8: ;; GNU CC is free software; you can redistribute it and/or modify ! 9: ;; it under the terms of the GNU General Public License as published by ! 10: ;; the Free Software Foundation; either version 2, or (at your option) ! 11: ;; any later version. ! 12: ! 13: ;; GNU CC is distributed in the hope that it will be useful, ! 14: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ! 15: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 16: ;; GNU General Public License for more details. ! 17: ! 18: ;; You should have received a copy of the GNU General Public License ! 19: ;; along with GNU CC; see the file COPYING. If not, write to ! 20: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ! 21: ! 22: ! 23: ! 24: ;; .................... ! 25: ;; ! 26: ;; Attributes ! 27: ;; ! 28: ;; .................... ! 29: ! 30: ;; Classification of each insn. ! 31: ;; branch conditional branch ! 32: ;; jump unconditional jump ! 33: ;; call unconditional call ! 34: ;; load load instruction(s) ! 35: ;; store store instruction(s) ! 36: ;; move data movement within same register set ! 37: ;; xfer transfer to/from coprocessor ! 38: ;; hilo transfer of hi/lo registers ! 39: ;; arith integer arithmetic instruction ! 40: ;; darith double precision integer arithmetic instructions ! 41: ;; imul integer multiply ! 42: ;; idiv integer divide ! 43: ;; icmp integer compare ! 44: ;; fadd floating point add/subtract ! 45: ;; fmul floating point multiply ! 46: ;; fdiv floating point divide ! 47: ;; fabs floating point absolute value ! 48: ;; fneg floating point negation ! 49: ;; fcmp floating point compare ! 50: ;; fcvt floating point convert ! 51: ;; fsqrt floating point square root ! 52: ;; multi multiword sequence (or user asm statements) ! 53: ;; nop no operation ! 54: ! 55: (define_attr "type" ! 56: "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,idiv,icmp,fadd,fmul,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,multi,nop" ! 57: (const_string "unknown")) ! 58: ! 59: ;; Main data type used by the insn ! 60: (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown")) ! 61: ! 62: ;; # instructions (4 bytes each) ! 63: (define_attr "length" "" (const_int 1)) ! 64: ! 65: ;; whether or not an instruction has a mandatory delay slot ! 66: (define_attr "dslot" "no,yes" ! 67: (if_then_else (eq_attr "type" "branch,jump,call,load,xfer,hilo,fcmp") ! 68: (const_string "yes") ! 69: (const_string "no"))) ! 70: ! 71: ;; Attribute describing the processor. This attribute must match exactly ! 72: ;; with the processor_type enumeration in mips.h. ! 73: ! 74: ;; Attribute describing the processor ! 75: ;; (define_attr "cpu" "default,r3000,r6000,r4000" ! 76: ;; (const ! 77: ;; (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000")) (const_string "r3000") ! 78: ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000")) (const_string "r4000") ! 79: ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000")) (const_string "r6000")] ! 80: ;; (const_string "default")))) ! 81: ! 82: (define_attr "cpu" "default,r3000,r6000,r4000" ! 83: (const (symbol_ref "mips_cpu_attr"))) ! 84: ! 85: ;; Attribute defining whether or not we can use the branch-likely instructions ! 86: ;; (MIPS ISA level 2) ! 87: ! 88: (define_attr "branch_likely" "no,yes" ! 89: (const ! 90: (if_then_else (ge (symbol_ref "mips_isa") (const_int 2)) ! 91: (const_string "yes") ! 92: (const_string "no")))) ! 93: ! 94: ! 95: ;; Describe a user's asm statement. ! 96: (define_asm_attributes ! 97: [(set_attr "type" "multi")]) ! 98: ! 99: ;; whether or not generating calls to position independent functions ! 100: (define_attr "abicalls" "no,yes" ! 101: (const (symbol_ref "mips_abicalls_attr"))) ! 102: ! 103: ! 104: ! 105: ;; ......................... ! 106: ;; ! 107: ;; Delay slots, can't describe load/fcmp/xfer delay slots here ! 108: ;; ! 109: ;; ......................... ! 110: ! 111: (define_delay (eq_attr "type" "branch") ! 112: [(and (eq_attr "dslot" "no") (eq_attr "length" "1")) ! 113: (nil) ! 114: (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "no") (eq_attr "length" "1")))]) ! 115: ! 116: (define_delay (eq_attr "type" "jump") ! 117: [(and (eq_attr "dslot" "no") (eq_attr "length" "1")) ! 118: (nil) ! 119: (nil)]) ! 120: ! 121: (define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no")) ! 122: [(and (eq_attr "dslot" "no") (eq_attr "length" "1")) ! 123: (nil) ! 124: (nil)]) ! 125: ! 126: ! 127: ! 128: ;; ......................... ! 129: ;; ! 130: ;; Functional units ! 131: ;; ! 132: ;; ......................... ! 133: ! 134: ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY ! 135: ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST]) ! 136: ! 137: ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case ! 138: ! 139: (define_function_unit "memory" 1 0 ! 140: (and (eq_attr "type" "load") (eq_attr "cpu" "!r3000")) ! 141: 3 0) ! 142: ! 143: (define_function_unit "memory" 1 0 ! 144: (and (eq_attr "type" "load") (eq_attr "cpu" "r3000")) ! 145: 2 0) ! 146: ! 147: (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0) ! 148: ! 149: (define_function_unit "addr" 1 0 (eq_attr "type" "fcmp") 2 0) ! 150: ! 151: (define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0) ! 152: (define_function_unit "memory" 1 0 (eq_attr "type" "hilo") 3 0) ! 153: ! 154: (define_function_unit "imuldiv" 1 1 ! 155: (and (eq_attr "type" "imul") (eq_attr "cpu" "!r3000,r4000")) ! 156: 17 0) ! 157: ! 158: (define_function_unit "imuldiv" 1 1 ! 159: (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000")) ! 160: 12 0) ! 161: ! 162: (define_function_unit "imuldiv" 1 1 ! 163: (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000")) ! 164: 10 0) ! 165: ! 166: (define_function_unit "imuldiv" 1 1 ! 167: (and (eq_attr "type" "idiv") (eq_attr "cpu" "!r3000,r4000")) ! 168: 38 0) ! 169: ! 170: (define_function_unit "imuldiv" 1 1 ! 171: (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000")) ! 172: 35 0) ! 173: ! 174: (define_function_unit "imuldiv" 1 1 ! 175: (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000")) ! 176: 69 0) ! 177: ! 178: (define_function_unit "adder" 1 1 ! 179: (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r6000")) ! 180: 4 0) ! 181: ! 182: (define_function_unit "adder" 1 1 ! 183: (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000")) ! 184: 2 0) ! 185: ! 186: (define_function_unit "adder" 1 1 ! 187: (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000")) ! 188: 3 0) ! 189: ! 190: (define_function_unit "adder" 1 1 ! 191: (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "!r3000")) ! 192: 2 0) ! 193: ! 194: (define_function_unit "adder" 1 1 ! 195: (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000")) ! 196: 1 0) ! 197: ! 198: (define_function_unit "mult" 1 1 ! 199: (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r3000,r6000"))) ! 200: 7 0) ! 201: ! 202: (define_function_unit "mult" 1 1 ! 203: (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000"))) ! 204: 4 0) ! 205: ! 206: (define_function_unit "mult" 1 1 ! 207: (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000"))) ! 208: 5 0) ! 209: ! 210: (define_function_unit "mult" 1 1 ! 211: (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r6000"))) ! 212: 8 0) ! 213: ! 214: (define_function_unit "mult" 1 1 ! 215: (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000"))) ! 216: 5 0) ! 217: ! 218: (define_function_unit "mult" 1 1 ! 219: (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000"))) ! 220: 6 0) ! 221: ! 222: (define_function_unit "divide" 1 1 ! 223: (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r3000,r6000"))) ! 224: 23 0) ! 225: ! 226: (define_function_unit "divide" 1 1 ! 227: (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000"))) ! 228: 12 0) ! 229: ! 230: (define_function_unit "divide" 1 1 ! 231: (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000"))) ! 232: 15 0) ! 233: ! 234: (define_function_unit "divide" 1 1 ! 235: (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r6000"))) ! 236: 36 0) ! 237: ! 238: (define_function_unit "divide" 1 1 ! 239: (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000"))) ! 240: 19 0) ! 241: ! 242: (define_function_unit "divide" 1 1 ! 243: (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000"))) ! 244: 16 0) ! 245: ! 246: (define_function_unit "divide" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 0) ! 247: (define_function_unit "divide" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0) ! 248: ! 249: ! 250: ;; The following functional units do not use the cpu type, and use ! 251: ;; much less memory in genattrtab.c. ! 252: ! 253: ;; (define_function_unit "memory" 1 0 (eq_attr "type" "load") 3 0) ! 254: ;; (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0) ! 255: ;; ! 256: ;; (define_function_unit "fp_comp" 1 0 (eq_attr "type" "fcmp") 2 0) ! 257: ;; ! 258: ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer") 2 0) ! 259: ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo") 3 0) ! 260: ;; ! 261: ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "imul") 17 0) ! 262: ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "idiv") 38 0) ! 263: ;; ! 264: ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fadd") 4 0) ! 265: ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fabs,fneg") 2 0) ! 266: ;; ! 267: ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF")) 7 0) ! 268: ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF")) 8 0) ! 269: ;; ! 270: ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF")) 23 0) ! 271: ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF")) 36 0) ! 272: ;; ! 273: ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 0) ! 274: ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0) ! 275: ! 276: ! 277: ;; ! 278: ;; .................... ! 279: ;; ! 280: ;; ADDITION ! 281: ;; ! 282: ;; .................... ! 283: ;; ! 284: ! 285: (define_insn "adddf3" ! 286: [(set (match_operand:DF 0 "register_operand" "=f") ! 287: (plus:DF (match_operand:DF 1 "register_operand" "f") ! 288: (match_operand:DF 2 "register_operand" "f")))] ! 289: "TARGET_HARD_FLOAT" ! 290: "add.d\\t%0,%1,%2" ! 291: [(set_attr "type" "fadd") ! 292: (set_attr "mode" "DF") ! 293: (set_attr "length" "1")]) ! 294: ! 295: (define_insn "addsf3" ! 296: [(set (match_operand:SF 0 "register_operand" "=f") ! 297: (plus:SF (match_operand:SF 1 "register_operand" "f") ! 298: (match_operand:SF 2 "register_operand" "f")))] ! 299: "TARGET_HARD_FLOAT" ! 300: "add.s\\t%0,%1,%2" ! 301: [(set_attr "type" "fadd") ! 302: (set_attr "mode" "SF") ! 303: (set_attr "length" "1")]) ! 304: ! 305: (define_expand "addsi3" ! 306: [(set (match_operand:SI 0 "register_operand" "=d") ! 307: (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ") ! 308: (match_operand:SI 2 "arith_operand" "dI")))] ! 309: "" ! 310: " ! 311: { ! 312: if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768) ! 313: operands[2] = force_reg (SImode, operands[2]); ! 314: }") ! 315: ! 316: (define_insn "addsi3_internal" ! 317: [(set (match_operand:SI 0 "register_operand" "=d") ! 318: (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ") ! 319: (match_operand:SI 2 "arith_operand" "dI")))] ! 320: "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768" ! 321: "* ! 322: { ! 323: return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) ! 324: ? \"subu\\t%0,%z1,%n2\" ! 325: : \"addu\\t%0,%z1,%2\"; ! 326: }" ! 327: [(set_attr "type" "arith") ! 328: (set_attr "mode" "SI") ! 329: (set_attr "length" "1")]) ! 330: ! 331: (define_expand "adddi3" ! 332: [(parallel [(set (match_operand:DI 0 "register_operand" "") ! 333: (plus:DI (match_operand:DI 1 "register_operand" "") ! 334: (match_operand:DI 2 "arith_operand" ""))) ! 335: (clobber (match_dup 3))])] ! 336: "!TARGET_DEBUG_G_MODE" ! 337: " ! 338: { ! 339: if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768) ! 340: operands[2] = force_reg (DImode, operands[2]); ! 341: ! 342: operands[3] = gen_reg_rtx (SImode); ! 343: }") ! 344: ! 345: (define_insn "adddi3_internal_1" ! 346: [(set (match_operand:DI 0 "register_operand" "=d,&d") ! 347: (plus:DI (match_operand:DI 1 "register_operand" "0,d") ! 348: (match_operand:DI 2 "register_operand" "d,d"))) ! 349: (clobber (match_operand:SI 3 "register_operand" "=d,d"))] ! 350: "!TARGET_DEBUG_G_MODE" ! 351: "* ! 352: { ! 353: return (REGNO (operands[0]) == REGNO (operands[1]) ! 354: && REGNO (operands[0]) == REGNO (operands[2])) ! 355: ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\" ! 356: : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\"; ! 357: }" ! 358: [(set_attr "type" "darith") ! 359: (set_attr "mode" "DI") ! 360: (set_attr "length" "4")]) ! 361: ! 362: (define_split ! 363: [(set (match_operand:DI 0 "register_operand" "") ! 364: (plus:DI (match_operand:DI 1 "register_operand" "") ! 365: (match_operand:DI 2 "register_operand" ""))) ! 366: (clobber (match_operand:SI 3 "register_operand" ""))] ! 367: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 368: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) ! 369: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) ! 370: && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2])) ! 371: && (REGNO (operands[0]) != REGNO (operands[1]) ! 372: || REGNO (operands[0]) != REGNO (operands[2]))" ! 373: ! 374: [(set (subreg:SI (match_dup 0) 0) ! 375: (plus:SI (subreg:SI (match_dup 1) 0) ! 376: (subreg:SI (match_dup 2) 0))) ! 377: ! 378: (set (match_dup 3) ! 379: (ltu:SI (subreg:SI (match_dup 0) 0) ! 380: (subreg:SI (match_dup 2) 0))) ! 381: ! 382: (set (subreg:SI (match_dup 0) 1) ! 383: (plus:SI (subreg:SI (match_dup 1) 1) ! 384: (subreg:SI (match_dup 2) 1))) ! 385: ! 386: (set (subreg:SI (match_dup 0) 1) ! 387: (plus:SI (subreg:SI (match_dup 0) 1) ! 388: (match_dup 3)))] ! 389: "") ! 390: ! 391: (define_split ! 392: [(set (match_operand:DI 0 "register_operand" "") ! 393: (plus:DI (match_operand:DI 1 "register_operand" "") ! 394: (match_operand:DI 2 "register_operand" ""))) ! 395: (clobber (match_operand:SI 3 "register_operand" ""))] ! 396: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 397: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) ! 398: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) ! 399: && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2])) ! 400: && (REGNO (operands[0]) != REGNO (operands[1]) ! 401: || REGNO (operands[0]) != REGNO (operands[2]))" ! 402: ! 403: [(set (subreg:SI (match_dup 0) 1) ! 404: (plus:SI (subreg:SI (match_dup 1) 1) ! 405: (subreg:SI (match_dup 2) 1))) ! 406: ! 407: (set (match_dup 3) ! 408: (ltu:SI (subreg:SI (match_dup 0) 1) ! 409: (subreg:SI (match_dup 2) 1))) ! 410: ! 411: (set (subreg:SI (match_dup 0) 0) ! 412: (plus:SI (subreg:SI (match_dup 1) 0) ! 413: (subreg:SI (match_dup 2) 0))) ! 414: ! 415: (set (subreg:SI (match_dup 0) 0) ! 416: (plus:SI (subreg:SI (match_dup 0) 0) ! 417: (match_dup 3)))] ! 418: "") ! 419: ! 420: (define_insn "adddi3_internal_2" ! 421: [(set (match_operand:DI 0 "register_operand" "=d,d,d") ! 422: (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d") ! 423: (match_operand:DI 2 "small_int" "P,J,N"))) ! 424: (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))] ! 425: "!TARGET_DEBUG_G_MODE && INTVAL (operands[2]) != -32768" ! 426: "@ ! 427: addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3 ! 428: move\\t%L0,%L1\;move\\t%M0,%M1 ! 429: subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3" ! 430: [(set_attr "type" "darith") ! 431: (set_attr "mode" "DI") ! 432: (set_attr "length" "3,2,4")]) ! 433: ! 434: (define_split ! 435: [(set (match_operand:DI 0 "register_operand" "") ! 436: (plus:DI (match_operand:DI 1 "register_operand" "") ! 437: (match_operand:DI 2 "small_int" ""))) ! 438: (clobber (match_operand:SI 3 "register_operand" "=d"))] ! 439: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 440: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) ! 441: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) ! 442: && INTVAL (operands[2]) > 0" ! 443: ! 444: [(set (subreg:SI (match_dup 0) 0) ! 445: (plus:SI (subreg:SI (match_dup 1) 0) ! 446: (match_dup 2))) ! 447: ! 448: (set (match_dup 3) ! 449: (ltu:SI (subreg:SI (match_dup 0) 0) ! 450: (match_dup 2))) ! 451: ! 452: (set (subreg:SI (match_dup 0) 1) ! 453: (plus:SI (subreg:SI (match_dup 1) 1) ! 454: (match_dup 3)))] ! 455: "") ! 456: ! 457: (define_split ! 458: [(set (match_operand:DI 0 "register_operand" "") ! 459: (plus:DI (match_operand:DI 1 "register_operand" "") ! 460: (match_operand:DI 2 "small_int" ""))) ! 461: (clobber (match_operand:SI 3 "register_operand" "=d"))] ! 462: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 463: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) ! 464: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) ! 465: && INTVAL (operands[2]) > 0" ! 466: ! 467: [(set (subreg:SI (match_dup 0) 1) ! 468: (plus:SI (subreg:SI (match_dup 1) 1) ! 469: (match_dup 2))) ! 470: ! 471: (set (match_dup 3) ! 472: (ltu:SI (subreg:SI (match_dup 0) 1) ! 473: (match_dup 2))) ! 474: ! 475: (set (subreg:SI (match_dup 0) 0) ! 476: (plus:SI (subreg:SI (match_dup 1) 0) ! 477: (match_dup 3)))] ! 478: "") ! 479: ! 480: ;; ! 481: ;; .................... ! 482: ;; ! 483: ;; SUBTRACTION ! 484: ;; ! 485: ;; .................... ! 486: ;; ! 487: ! 488: (define_insn "subdf3" ! 489: [(set (match_operand:DF 0 "register_operand" "=f") ! 490: (minus:DF (match_operand:DF 1 "register_operand" "f") ! 491: (match_operand:DF 2 "register_operand" "f")))] ! 492: "TARGET_HARD_FLOAT" ! 493: "sub.d\\t%0,%1,%2" ! 494: [(set_attr "type" "fadd") ! 495: (set_attr "mode" "DF") ! 496: (set_attr "length" "1")]) ! 497: ! 498: (define_insn "subsf3" ! 499: [(set (match_operand:SF 0 "register_operand" "=f") ! 500: (minus:SF (match_operand:SF 1 "register_operand" "f") ! 501: (match_operand:SF 2 "register_operand" "f")))] ! 502: "TARGET_HARD_FLOAT" ! 503: "sub.s\\t%0,%1,%2" ! 504: [(set_attr "type" "fadd") ! 505: (set_attr "mode" "SF") ! 506: (set_attr "length" "1")]) ! 507: ! 508: (define_expand "subsi3" ! 509: [(set (match_operand:SI 0 "register_operand" "=d") ! 510: (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ") ! 511: (match_operand:SI 2 "arith_operand" "dI")))] ! 512: "" ! 513: " ! 514: { ! 515: if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768) ! 516: operands[2] = force_reg (SImode, operands[2]); ! 517: }") ! 518: ! 519: (define_insn "subsi3_internal" ! 520: [(set (match_operand:SI 0 "register_operand" "=d") ! 521: (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ") ! 522: (match_operand:SI 2 "arith_operand" "dI")))] ! 523: "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768" ! 524: "* ! 525: { ! 526: return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) ! 527: ? \"addu\\t%0,%z1,%n2\" ! 528: : \"subu\\t%0,%z1,%2\"; ! 529: }" ! 530: [(set_attr "type" "arith") ! 531: (set_attr "mode" "SI") ! 532: (set_attr "length" "1")]) ! 533: ! 534: (define_expand "subdi3" ! 535: [(parallel [(set (match_operand:DI 0 "register_operand" "=d") ! 536: (minus:DI (match_operand:DI 1 "register_operand" "d") ! 537: (match_operand:DI 2 "register_operand" "d"))) ! 538: (clobber (match_dup 3))])] ! 539: "!TARGET_DEBUG_G_MODE" ! 540: "operands[3] = gen_reg_rtx (SImode);") ! 541: ! 542: (define_insn "subdi3_internal" ! 543: [(set (match_operand:DI 0 "register_operand" "=d") ! 544: (minus:DI (match_operand:DI 1 "register_operand" "d") ! 545: (match_operand:DI 2 "register_operand" "d"))) ! 546: (clobber (match_operand:SI 3 "register_operand" "=d"))] ! 547: "!TARGET_DEBUG_G_MODE" ! 548: "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3" ! 549: [(set_attr "type" "darith") ! 550: (set_attr "mode" "DI") ! 551: (set_attr "length" "4")]) ! 552: ! 553: (define_split ! 554: [(set (match_operand:DI 0 "register_operand" "") ! 555: (minus:DI (match_operand:DI 1 "register_operand" "") ! 556: (match_operand:DI 2 "register_operand" ""))) ! 557: (clobber (match_operand:SI 3 "register_operand" ""))] ! 558: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 559: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) ! 560: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) ! 561: && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))" ! 562: ! 563: [(set (match_dup 3) ! 564: (ltu:SI (subreg:SI (match_dup 1) 0) ! 565: (subreg:SI (match_dup 2) 0))) ! 566: ! 567: (set (subreg:SI (match_dup 0) 0) ! 568: (minus:SI (subreg:SI (match_dup 1) 0) ! 569: (subreg:SI (match_dup 2) 0))) ! 570: ! 571: (set (subreg:SI (match_dup 0) 1) ! 572: (minus:SI (subreg:SI (match_dup 1) 1) ! 573: (subreg:SI (match_dup 2) 1))) ! 574: ! 575: (set (subreg:SI (match_dup 0) 1) ! 576: (minus:SI (subreg:SI (match_dup 0) 1) ! 577: (match_dup 3)))] ! 578: "") ! 579: ! 580: (define_split ! 581: [(set (match_operand:DI 0 "register_operand" "") ! 582: (minus:DI (match_operand:DI 1 "register_operand" "") ! 583: (match_operand:DI 2 "register_operand" ""))) ! 584: (clobber (match_operand:SI 3 "register_operand" ""))] ! 585: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 586: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) ! 587: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) ! 588: && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))" ! 589: ! 590: [(set (match_dup 3) ! 591: (ltu:SI (subreg:SI (match_dup 1) 1) ! 592: (subreg:SI (match_dup 2) 1))) ! 593: ! 594: (set (subreg:SI (match_dup 0) 1) ! 595: (minus:SI (subreg:SI (match_dup 1) 1) ! 596: (subreg:SI (match_dup 2) 1))) ! 597: ! 598: (set (subreg:SI (match_dup 0) 0) ! 599: (minus:SI (subreg:SI (match_dup 1) 0) ! 600: (subreg:SI (match_dup 2) 0))) ! 601: ! 602: (set (subreg:SI (match_dup 0) 0) ! 603: (minus:SI (subreg:SI (match_dup 0) 0) ! 604: (match_dup 3)))] ! 605: "") ! 606: ! 607: (define_insn "subdi3_internal_2" ! 608: [(set (match_operand:DI 0 "register_operand" "=d,d,d") ! 609: (minus:DI (match_operand:DI 1 "register_operand" "d,d,d") ! 610: (match_operand:DI 2 "small_int" "P,J,N"))) ! 611: (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))] ! 612: "!TARGET_DEBUG_G_MODE && INTVAL (operands[2]) != -32768" ! 613: "@ ! 614: sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3 ! 615: move\\t%L0,%L1\;move\\t%M0,%M1 ! 616: sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3" ! 617: [(set_attr "type" "darith") ! 618: (set_attr "mode" "DI") ! 619: (set_attr "length" "3,2,4")]) ! 620: ! 621: (define_split ! 622: [(set (match_operand:DI 0 "register_operand" "") ! 623: (minus:DI (match_operand:DI 1 "register_operand" "") ! 624: (match_operand:DI 2 "small_int" ""))) ! 625: (clobber (match_operand:SI 3 "register_operand" ""))] ! 626: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 627: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) ! 628: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) ! 629: && INTVAL (operands[2]) > 0" ! 630: ! 631: [(set (match_dup 3) ! 632: (ltu:SI (subreg:SI (match_dup 1) 0) ! 633: (match_dup 2))) ! 634: ! 635: (set (subreg:SI (match_dup 0) 0) ! 636: (minus:SI (subreg:SI (match_dup 1) 0) ! 637: (match_dup 2))) ! 638: ! 639: (set (subreg:SI (match_dup 0) 1) ! 640: (minus:SI (subreg:SI (match_dup 1) 1) ! 641: (match_dup 3)))] ! 642: "") ! 643: ! 644: (define_split ! 645: [(set (match_operand:DI 0 "register_operand" "") ! 646: (minus:DI (match_operand:DI 1 "register_operand" "") ! 647: (match_operand:DI 2 "small_int" ""))) ! 648: (clobber (match_operand:SI 3 "register_operand" ""))] ! 649: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 650: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) ! 651: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) ! 652: && INTVAL (operands[2]) > 0" ! 653: ! 654: [(set (match_dup 3) ! 655: (ltu:SI (subreg:SI (match_dup 1) 1) ! 656: (match_dup 2))) ! 657: ! 658: (set (subreg:SI (match_dup 0) 1) ! 659: (minus:SI (subreg:SI (match_dup 1) 1) ! 660: (match_dup 2))) ! 661: ! 662: (set (subreg:SI (match_dup 0) 0) ! 663: (minus:SI (subreg:SI (match_dup 1) 0) ! 664: (match_dup 3)))] ! 665: "") ! 666: ! 667: ! 668: ;; ! 669: ;; .................... ! 670: ;; ! 671: ;; MULTIPLICATION ! 672: ;; ! 673: ;; .................... ! 674: ;; ! 675: ! 676: (define_insn "muldf3" ! 677: [(set (match_operand:DF 0 "register_operand" "=f") ! 678: (mult:DF (match_operand:DF 1 "register_operand" "f") ! 679: (match_operand:DF 2 "register_operand" "f")))] ! 680: "TARGET_HARD_FLOAT" ! 681: "mul.d\\t%0,%1,%2" ! 682: [(set_attr "type" "fmul") ! 683: (set_attr "mode" "DF") ! 684: (set_attr "length" "1")]) ! 685: ! 686: (define_insn "mulsf3" ! 687: [(set (match_operand:SF 0 "register_operand" "=f") ! 688: (mult:SF (match_operand:SF 1 "register_operand" "f") ! 689: (match_operand:SF 2 "register_operand" "f")))] ! 690: "TARGET_HARD_FLOAT" ! 691: "mul.s\\t%0,%1,%2" ! 692: [(set_attr "type" "fmul") ! 693: (set_attr "mode" "SF") ! 694: (set_attr "length" "1")]) ! 695: ! 696: (define_insn "mulsi3" ! 697: [(set (match_operand:SI 0 "register_operand" "=d") ! 698: (mult:SI (match_operand:SI 1 "register_operand" "d") ! 699: (match_operand:SI 2 "register_operand" "d"))) ! 700: (clobber (reg:SI 64)) ! 701: (clobber (reg:SI 65))] ! 702: "" ! 703: "* ! 704: { ! 705: rtx xoperands[10]; ! 706: ! 707: xoperands[0] = operands[0]; ! 708: xoperands[1] = gen_rtx (REG, SImode, LO_REGNUM); ! 709: ! 710: output_asm_insn (\"mult\\t%1,%2\", operands); ! 711: output_asm_insn (mips_move_1word (xoperands, insn), xoperands); ! 712: return \"\"; ! 713: }" ! 714: [(set_attr "type" "imul") ! 715: (set_attr "mode" "SI") ! 716: (set_attr "length" "3")]) ;; mult + mflo + delay ! 717: ! 718: (define_split ! 719: [(set (match_operand:SI 0 "register_operand" "") ! 720: (mult:SI (match_operand:SI 1 "register_operand" "") ! 721: (match_operand:SI 2 "register_operand" ""))) ! 722: (clobber (reg:SI 64)) ! 723: (clobber (reg:SI 65))] ! 724: "!TARGET_DEBUG_D_MODE" ! 725: [(parallel [(set (reg:SI 65) ;; low register ! 726: (mult:SI (match_dup 1) ! 727: (match_dup 2))) ! 728: (clobber (reg:SI 64))]) ! 729: (set (match_dup 0) ! 730: (reg:SI 65))] ! 731: "") ! 732: ! 733: (define_insn "mulsi3_internal" ! 734: [(set (reg:SI 65) ;; low register ! 735: (mult:SI (match_operand:SI 0 "register_operand" "d") ! 736: (match_operand:SI 1 "register_operand" "d"))) ! 737: (clobber (reg:SI 64))] ! 738: "" ! 739: "mult\\t%0,%1" ! 740: [(set_attr "type" "imul") ! 741: (set_attr "mode" "SI") ! 742: (set_attr "length" "1")]) ! 743: ! 744: (define_insn "mulsidi3" ! 745: [(set (match_operand:DI 0 "register_operand" "=d") ! 746: (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) ! 747: (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))) ! 748: (clobber (reg:DI 64))] ! 749: "" ! 750: "* ! 751: { ! 752: rtx xoperands[10]; ! 753: ! 754: xoperands[0] = operands[0]; ! 755: xoperands[1] = gen_rtx (REG, DImode, MD_REG_FIRST); ! 756: ! 757: output_asm_insn (\"mult\\t%1,%2\", operands); ! 758: output_asm_insn (mips_move_2words (xoperands, insn), xoperands); ! 759: return \"\"; ! 760: }" ! 761: [(set_attr "type" "imul") ! 762: (set_attr "mode" "SI") ! 763: (set_attr "length" "4")]) ;; mult + mflo + mfhi + delay ! 764: ! 765: (define_insn "umulsidi3" ! 766: [(set (match_operand:DI 0 "register_operand" "=d") ! 767: (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) ! 768: (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))) ! 769: (clobber (reg:DI 64))] ! 770: "" ! 771: "* ! 772: { ! 773: rtx xoperands[10]; ! 774: ! 775: xoperands[0] = operands[0]; ! 776: xoperands[1] = gen_rtx (REG, DImode, MD_REG_FIRST); ! 777: ! 778: output_asm_insn (\"multu\\t%1,%2\", operands); ! 779: output_asm_insn (mips_move_2words (xoperands, insn), xoperands); ! 780: return \"\"; ! 781: }" ! 782: [(set_attr "type" "imul") ! 783: (set_attr "mode" "SI") ! 784: (set_attr "length" "4")]) ;; mult + mflo + mfhi + delay ! 785: ! 786: ! 787: ;; ! 788: ;; .................... ! 789: ;; ! 790: ;; DIVISION and REMAINDER ! 791: ;; ! 792: ;; .................... ! 793: ;; ! 794: ! 795: (define_insn "divdf3" ! 796: [(set (match_operand:DF 0 "register_operand" "=f") ! 797: (div:DF (match_operand:DF 1 "register_operand" "f") ! 798: (match_operand:DF 2 "register_operand" "f")))] ! 799: "TARGET_HARD_FLOAT" ! 800: "div.d\\t%0,%1,%2" ! 801: [(set_attr "type" "fdiv") ! 802: (set_attr "mode" "DF") ! 803: (set_attr "length" "1")]) ! 804: ! 805: (define_insn "divsf3" ! 806: [(set (match_operand:SF 0 "register_operand" "=f") ! 807: (div:SF (match_operand:SF 1 "register_operand" "f") ! 808: (match_operand:SF 2 "register_operand" "f")))] ! 809: "TARGET_HARD_FLOAT" ! 810: "div.s\\t%0,%1,%2" ! 811: [(set_attr "type" "fdiv") ! 812: (set_attr "mode" "SF") ! 813: (set_attr "length" "1")]) ! 814: ! 815: ;; If optimizing, prefer the divmod functions over separate div and ! 816: ;; mod functions, since this will allow using one instruction for both ! 817: ;; the quotient and remainder. At present, the divmod is not moved out ! 818: ;; of loops if it is constant within the loop, so allow -mdebugc to ! 819: ;; use the old method of doing things. ! 820: ! 821: ;; 64 is the multiply/divide hi register ! 822: ;; 65 is the multiply/divide lo register ! 823: ! 824: (define_insn "divmodsi4" ! 825: [(set (match_operand:SI 0 "register_operand" "=d") ! 826: (div:SI (match_operand:SI 1 "register_operand" "d") ! 827: (match_operand:SI 2 "register_operand" "d"))) ! 828: (set (match_operand:SI 3 "register_operand" "=d") ! 829: (mod:SI (match_dup 1) ! 830: (match_dup 2))) ! 831: (clobber (reg:SI 64)) ! 832: (clobber (reg:SI 65))] ! 833: "optimize" ! 834: "* ! 835: { ! 836: if (find_reg_note (insn, REG_UNUSED, operands[3])) ! 837: return \"div\\t%0,%1,%2\"; ! 838: ! 839: if (find_reg_note (insn, REG_UNUSED, operands[0])) ! 840: return \"rem\\t%3,%1,%2\"; ! 841: ! 842: return \"div\\t%0,%1,%2\;mfhi\\t%3\"; ! 843: }" ! 844: [(set_attr "type" "idiv") ! 845: (set_attr "mode" "SI") ! 846: (set_attr "length" "13")]) ;; various tests for dividing by 0 and such ! 847: ! 848: (define_insn "udivmodsi4" ! 849: [(set (match_operand:SI 0 "register_operand" "=d") ! 850: (udiv:SI (match_operand:SI 1 "register_operand" "d") ! 851: (match_operand:SI 2 "register_operand" "d"))) ! 852: (set (match_operand:SI 3 "register_operand" "=d") ! 853: (umod:SI (match_dup 1) ! 854: (match_dup 2))) ! 855: (clobber (reg:SI 64)) ! 856: (clobber (reg:SI 65))] ! 857: "optimize" ! 858: "* ! 859: { ! 860: if (find_reg_note (insn, REG_UNUSED, operands[3])) ! 861: return \"divu\\t%0,%1,%2\"; ! 862: ! 863: if (find_reg_note (insn, REG_UNUSED, operands[0])) ! 864: return \"remu\\t%3,%1,%2\"; ! 865: ! 866: return \"divu\\t%0,%1,%2\;mfhi\\t%3\"; ! 867: }" ! 868: [(set_attr "type" "idiv") ! 869: (set_attr "mode" "SI") ! 870: (set_attr "length" "13")]) ;; various tests for dividing by 0 and such ! 871: ! 872: (define_insn "divsi3" ! 873: [(set (match_operand:SI 0 "register_operand" "=d") ! 874: (div:SI (match_operand:SI 1 "register_operand" "d") ! 875: (match_operand:SI 2 "register_operand" "d"))) ! 876: (clobber (reg:SI 64)) ! 877: (clobber (reg:SI 65))] ! 878: "!optimize" ! 879: "div\\t%0,%1,%2" ! 880: [(set_attr "type" "idiv") ! 881: (set_attr "mode" "SI") ! 882: (set_attr "length" "13")]) ;; various tests for dividing by 0 and such ! 883: ! 884: (define_insn "modsi3" ! 885: [(set (match_operand:SI 0 "register_operand" "=d") ! 886: (mod:SI (match_operand:SI 1 "register_operand" "d") ! 887: (match_operand:SI 2 "register_operand" "d"))) ! 888: (clobber (reg:SI 64)) ! 889: (clobber (reg:SI 65))] ! 890: "!optimize" ! 891: "rem\\t%0,%1,%2" ! 892: [(set_attr "type" "idiv") ! 893: (set_attr "mode" "SI") ! 894: (set_attr "length" "14")]) ;; various tests for dividing by 0 and such ! 895: ! 896: (define_insn "udivsi3" ! 897: [(set (match_operand:SI 0 "register_operand" "=d") ! 898: (udiv:SI (match_operand:SI 1 "register_operand" "d") ! 899: (match_operand:SI 2 "register_operand" "d"))) ! 900: (clobber (reg:SI 64)) ! 901: (clobber (reg:SI 65))] ! 902: "!optimize" ! 903: "divu\\t%0,%1,%2" ! 904: [(set_attr "type" "idiv") ! 905: (set_attr "mode" "SI") ! 906: (set_attr "length" "14")]) ;; various tests for dividing by 0 and such ! 907: ! 908: (define_insn "umodsi3" ! 909: [(set (match_operand:SI 0 "register_operand" "=d") ! 910: (umod:SI (match_operand:SI 1 "register_operand" "d") ! 911: (match_operand:SI 2 "register_operand" "d"))) ! 912: (clobber (reg:SI 64)) ! 913: (clobber (reg:SI 65))] ! 914: "!optimize" ! 915: "remu\\t%0,%1,%2" ! 916: [(set_attr "type" "idiv") ! 917: (set_attr "mode" "SI") ! 918: (set_attr "length" "14")]) ;; various tests for dividing by 0 and such ! 919: ! 920: ! 921: ;; ! 922: ;; .................... ! 923: ;; ! 924: ;; SQUARE ROOT ! 925: ;; ! 926: ;; .................... ! 927: ! 928: (define_insn "sqrtdf2" ! 929: [(set (match_operand:DF 0 "register_operand" "=f") ! 930: (sqrt:DF (match_operand:DF 1 "register_operand" "f")))] ! 931: "TARGET_HARD_FLOAT && HAVE_SQRT_P()" ! 932: "sqrt.d\\t%0,%1" ! 933: [(set_attr "type" "fabs") ! 934: (set_attr "mode" "DF") ! 935: (set_attr "length" "1")]) ! 936: ! 937: (define_insn "sqrtsf2" ! 938: [(set (match_operand:SF 0 "register_operand" "=f") ! 939: (sqrt:SF (match_operand:SF 1 "register_operand" "f")))] ! 940: "TARGET_HARD_FLOAT && HAVE_SQRT_P()" ! 941: "sqrt.s\\t%0,%1" ! 942: [(set_attr "type" "fabs") ! 943: (set_attr "mode" "SF") ! 944: (set_attr "length" "1")]) ! 945: ! 946: ! 947: ;; ! 948: ;; .................... ! 949: ;; ! 950: ;; ABSOLUTE VALUE ! 951: ;; ! 952: ;; .................... ! 953: ! 954: ;; Do not use the integer abs macro instruction, since that signals an ! 955: ;; exception on -2147483648 (sigh). ! 956: ! 957: (define_insn "abssi2" ! 958: [(set (match_operand:SI 0 "register_operand" "=d") ! 959: (abs:SI (match_operand:SI 1 "register_operand" "d")))] ! 960: "" ! 961: "* ! 962: { ! 963: dslots_jump_total++; ! 964: dslots_jump_filled++; ! 965: operands[2] = const0_rtx; ! 966: ! 967: return (REGNO (operands[0]) == REGNO (operands[1])) ! 968: ? \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n1:\" ! 969: : \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n1:%)\"; ! 970: }" ! 971: [(set_attr "type" "multi") ! 972: (set_attr "mode" "SI") ! 973: (set_attr "length" "3")]) ! 974: ! 975: (define_insn "absdf2" ! 976: [(set (match_operand:DF 0 "register_operand" "=f") ! 977: (abs:DF (match_operand:DF 1 "register_operand" "f")))] ! 978: "TARGET_HARD_FLOAT" ! 979: "abs.d\\t%0,%1" ! 980: [(set_attr "type" "fabs") ! 981: (set_attr "mode" "DF") ! 982: (set_attr "length" "1")]) ! 983: ! 984: (define_insn "abssf2" ! 985: [(set (match_operand:SF 0 "register_operand" "=f") ! 986: (abs:SF (match_operand:SF 1 "register_operand" "f")))] ! 987: "TARGET_HARD_FLOAT" ! 988: "abs.s\\t%0,%1" ! 989: [(set_attr "type" "fabs") ! 990: (set_attr "mode" "SF") ! 991: (set_attr "length" "1")]) ! 992: ! 993: ! 994: ;; ! 995: ;; .................... ! 996: ;; ! 997: ;; FIND FIRST BIT INSTRUCTION ! 998: ;; ! 999: ;; .................... ! 1000: ;; ! 1001: ! 1002: (define_insn "ffssi2" ! 1003: [(set (match_operand:SI 0 "register_operand" "=&d") ! 1004: (ffs:SI (match_operand:SI 1 "register_operand" "d"))) ! 1005: (clobber (match_scratch:SI 2 "=&d")) ! 1006: (clobber (match_scratch:SI 3 "=&d"))] ! 1007: "" ! 1008: "* ! 1009: { ! 1010: dslots_jump_total += 2; ! 1011: dslots_jump_filled += 2; ! 1012: operands[4] = const0_rtx; ! 1013: ! 1014: if (optimize && find_reg_note (insn, REG_DEAD, operands[1])) ! 1015: return \"%(\\ ! 1016: move\\t%0,%z4\\n\\ ! 1017: \\tbeq\\t%1,%z4,2f\\n\\ ! 1018: 1:\\tand\\t%2,%1,0x0001\\n\\ ! 1019: \\taddu\\t%0,%0,1\\n\\ ! 1020: \\tbeq\\t%2,%z4,1b\\n\\ ! 1021: \\tsrl\\t%1,%1,1\\n\\ ! 1022: 2:%)\"; ! 1023: ! 1024: return \"%(\\ ! 1025: move\\t%0,%z4\\n\\ ! 1026: \\tmove\\t%3,%1\\n\\ ! 1027: \\tbeq\\t%3,%z4,2f\\n\\ ! 1028: 1:\\tand\\t%2,%3,0x0001\\n\\ ! 1029: \\taddu\\t%0,%0,1\\n\\ ! 1030: \\tbeq\\t%2,%z4,1b\\n\\ ! 1031: \\tsrl\\t%3,%3,1\\n\\ ! 1032: 2:%)\"; ! 1033: }" ! 1034: [(set_attr "type" "multi") ! 1035: (set_attr "mode" "SI") ! 1036: (set_attr "length" "6")]) ! 1037: ! 1038: ! 1039: ;; ! 1040: ;; .................... ! 1041: ;; ! 1042: ;; NEGATION and ONE'S COMPLEMENT ! 1043: ;; ! 1044: ;; .................... ! 1045: ! 1046: (define_insn "negsi2" ! 1047: [(set (match_operand:SI 0 "register_operand" "=d") ! 1048: (neg:SI (match_operand:SI 1 "register_operand" "d")))] ! 1049: "" ! 1050: "* ! 1051: { ! 1052: operands[2] = const0_rtx; ! 1053: return \"subu\\t%0,%z2,%1\"; ! 1054: }" ! 1055: [(set_attr "type" "arith") ! 1056: (set_attr "mode" "SI") ! 1057: (set_attr "length" "1")]) ! 1058: ! 1059: (define_expand "negdi2" ! 1060: [(parallel [(set (match_operand:DI 0 "register_operand" "=d") ! 1061: (neg:DI (match_operand:DI 1 "register_operand" "d"))) ! 1062: (clobber (match_dup 2))])] ! 1063: "!TARGET_DEBUG_G_MODE" ! 1064: "operands[2] = gen_reg_rtx (SImode);") ! 1065: ! 1066: (define_insn "negdi2_internal" ! 1067: [(set (match_operand:DI 0 "register_operand" "=d") ! 1068: (neg:DI (match_operand:DI 1 "register_operand" "d"))) ! 1069: (clobber (match_operand:SI 2 "register_operand" "=d"))] ! 1070: "!TARGET_DEBUG_G_MODE" ! 1071: "* ! 1072: { ! 1073: operands[3] = const0_rtx; ! 1074: return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\"; ! 1075: }" ! 1076: [(set_attr "type" "darith") ! 1077: (set_attr "mode" "DI") ! 1078: (set_attr "length" "4")]) ! 1079: ! 1080: (define_insn "negdf2" ! 1081: [(set (match_operand:DF 0 "register_operand" "=f") ! 1082: (neg:DF (match_operand:DF 1 "register_operand" "f")))] ! 1083: "TARGET_HARD_FLOAT" ! 1084: "neg.d\\t%0,%1" ! 1085: [(set_attr "type" "fneg") ! 1086: (set_attr "mode" "DF") ! 1087: (set_attr "length" "1")]) ! 1088: ! 1089: (define_insn "negsf2" ! 1090: [(set (match_operand:SF 0 "register_operand" "=f") ! 1091: (neg:SF (match_operand:SF 1 "register_operand" "f")))] ! 1092: "TARGET_HARD_FLOAT" ! 1093: "neg.s\\t%0,%1" ! 1094: [(set_attr "type" "fneg") ! 1095: (set_attr "mode" "SF") ! 1096: (set_attr "length" "1")]) ! 1097: ! 1098: (define_insn "one_cmplsi2" ! 1099: [(set (match_operand:SI 0 "register_operand" "=d") ! 1100: (not:SI (match_operand:SI 1 "register_operand" "d")))] ! 1101: "" ! 1102: "* ! 1103: { ! 1104: operands[2] = const0_rtx; ! 1105: return \"nor\\t%0,%z2,%1\"; ! 1106: }" ! 1107: [(set_attr "type" "arith") ! 1108: (set_attr "mode" "SI") ! 1109: (set_attr "length" "1")]) ! 1110: ! 1111: (define_insn "one_cmpldi2" ! 1112: [(set (match_operand:DI 0 "register_operand" "=d") ! 1113: (not:SI (match_operand:DI 1 "register_operand" "d")))] ! 1114: "" ! 1115: "* ! 1116: { ! 1117: operands[2] = const0_rtx; ! 1118: return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\"; ! 1119: }" ! 1120: [(set_attr "type" "darith") ! 1121: (set_attr "mode" "DI") ! 1122: (set_attr "length" "2")]) ! 1123: ! 1124: (define_split ! 1125: [(set (match_operand:DI 0 "register_operand" "") ! 1126: (not:DI (match_operand:DI 1 "register_operand" "")))] ! 1127: "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 1128: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) ! 1129: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))" ! 1130: ! 1131: [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0))) ! 1132: (set (subreg:SI (match_dup 0) 1) (not:SI (subreg:SI (match_dup 1) 1)))] ! 1133: "") ! 1134: ! 1135: ;; Simple hack to recognize the "nor" instruction on the MIPS ! 1136: ;; This must appear before the normal or patterns, so that the ! 1137: ;; combiner will correctly fold things. ! 1138: ! 1139: (define_insn "norsi3" ! 1140: [(set (match_operand:SI 0 "register_operand" "=d") ! 1141: (not:SI (ior:SI (match_operand:SI 1 "reg_or_0_operand" "dJ") ! 1142: (match_operand:SI 2 "reg_or_0_operand" "dJ"))))] ! 1143: "" ! 1144: "nor\\t%0,%z1,%z2" ! 1145: [(set_attr "type" "arith") ! 1146: (set_attr "mode" "SI") ! 1147: (set_attr "length" "1")]) ! 1148: ! 1149: (define_insn "nordi3" ! 1150: [(set (match_operand:DI 0 "register_operand" "=d") ! 1151: (not:DI (ior:DI (match_operand:DI 1 "register_operand" "d") ! 1152: (match_operand:DI 2 "register_operand" "d"))))] ! 1153: "" ! 1154: "nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2" ! 1155: [(set_attr "type" "darith") ! 1156: (set_attr "mode" "DI") ! 1157: (set_attr "length" "2")]) ! 1158: ! 1159: (define_split ! 1160: [(set (match_operand:DI 0 "register_operand" "") ! 1161: (not:DI (ior:DI (match_operand:DI 1 "register_operand" "") ! 1162: (match_operand:DI 2 "register_operand" ""))))] ! 1163: "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 1164: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) ! 1165: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) ! 1166: && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))" ! 1167: ! 1168: [(set (subreg:SI (match_dup 0) 0) (not:SI (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))) ! 1169: (set (subreg:SI (match_dup 0) 1) (not:SI (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1))))] ! 1170: "") ! 1171: ! 1172: ! 1173: ;; ! 1174: ;; .................... ! 1175: ;; ! 1176: ;; LOGICAL ! 1177: ;; ! 1178: ;; .................... ! 1179: ;; ! 1180: ! 1181: (define_insn "andsi3" ! 1182: [(set (match_operand:SI 0 "register_operand" "=d,d") ! 1183: (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d") ! 1184: (match_operand:SI 2 "uns_arith_operand" "d,K")))] ! 1185: "" ! 1186: "@ ! 1187: and\\t%0,%1,%2 ! 1188: andi\\t%0,%1,%x2" ! 1189: [(set_attr "type" "arith") ! 1190: (set_attr "mode" "SI") ! 1191: (set_attr "length" "1")]) ! 1192: ! 1193: (define_insn "anddi3" ! 1194: [(set (match_operand:DI 0 "register_operand" "=d") ! 1195: (and:DI (match_operand:DI 1 "register_operand" "d") ! 1196: (match_operand:DI 2 "register_operand" "d")))] ! 1197: "!TARGET_DEBUG_G_MODE" ! 1198: "and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2" ! 1199: [(set_attr "type" "darith") ! 1200: (set_attr "mode" "DI") ! 1201: (set_attr "length" "2")]) ! 1202: ! 1203: (define_split ! 1204: [(set (match_operand:DI 0 "register_operand" "") ! 1205: (and:DI (match_operand:DI 1 "register_operand" "") ! 1206: (match_operand:DI 2 "register_operand" "")))] ! 1207: "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 1208: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) ! 1209: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) ! 1210: && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))" ! 1211: ! 1212: [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0))) ! 1213: (set (subreg:SI (match_dup 0) 1) (and:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))] ! 1214: "") ! 1215: ! 1216: (define_insn "iorsi3" ! 1217: [(set (match_operand:SI 0 "register_operand" "=d,d") ! 1218: (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d") ! 1219: (match_operand:SI 2 "uns_arith_operand" "d,K")))] ! 1220: "" ! 1221: "@ ! 1222: or\\t%0,%1,%2 ! 1223: ori\\t%0,%1,%x2" ! 1224: [(set_attr "type" "arith") ! 1225: (set_attr "mode" "SI") ! 1226: (set_attr "length" "1")]) ! 1227: ! 1228: (define_insn "iordi3" ! 1229: [(set (match_operand:DI 0 "register_operand" "=d") ! 1230: (ior:DI (match_operand:DI 1 "register_operand" "d") ! 1231: (match_operand:DI 2 "register_operand" "d")))] ! 1232: "!TARGET_DEBUG_G_MODE" ! 1233: "or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2" ! 1234: [(set_attr "type" "darith") ! 1235: (set_attr "mode" "DI") ! 1236: (set_attr "length" "2")]) ! 1237: ! 1238: (define_split ! 1239: [(set (match_operand:DI 0 "register_operand" "") ! 1240: (ior:DI (match_operand:DI 1 "register_operand" "") ! 1241: (match_operand:DI 2 "register_operand" "")))] ! 1242: "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 1243: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) ! 1244: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) ! 1245: && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))" ! 1246: ! 1247: [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0))) ! 1248: (set (subreg:SI (match_dup 0) 1) (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))] ! 1249: "") ! 1250: ! 1251: (define_insn "xorsi3" ! 1252: [(set (match_operand:SI 0 "register_operand" "=d,d") ! 1253: (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d") ! 1254: (match_operand:SI 2 "uns_arith_operand" "d,K")))] ! 1255: "" ! 1256: "@ ! 1257: xor\\t%0,%1,%2 ! 1258: xori\\t%0,%1,%x2" ! 1259: [(set_attr "type" "arith") ! 1260: (set_attr "mode" "SI") ! 1261: (set_attr "length" "1")]) ! 1262: ! 1263: (define_insn "xordi3" ! 1264: [(set (match_operand:DI 0 "register_operand" "=d") ! 1265: (xor:DI (match_operand:DI 1 "register_operand" "d") ! 1266: (match_operand:DI 2 "register_operand" "d")))] ! 1267: "!TARGET_DEBUG_G_MODE" ! 1268: "xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2" ! 1269: [(set_attr "type" "darith") ! 1270: (set_attr "mode" "DI") ! 1271: (set_attr "length" "2")]) ! 1272: ! 1273: (define_split ! 1274: [(set (match_operand:DI 0 "register_operand" "") ! 1275: (xor:DI (match_operand:DI 1 "register_operand" "") ! 1276: (match_operand:DI 2 "register_operand" "")))] ! 1277: "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 1278: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) ! 1279: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) ! 1280: && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))" ! 1281: ! 1282: [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0))) ! 1283: (set (subreg:SI (match_dup 0) 1) (xor:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))] ! 1284: "") ! 1285: ! 1286: ! 1287: ;; ! 1288: ;; .................... ! 1289: ;; ! 1290: ;; TRUNCATION ! 1291: ;; ! 1292: ;; .................... ! 1293: ! 1294: (define_insn "truncdfsf2" ! 1295: [(set (match_operand:SF 0 "register_operand" "=f") ! 1296: (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))] ! 1297: "TARGET_HARD_FLOAT" ! 1298: "cvt.s.d\\t%0,%1" ! 1299: [(set_attr "type" "fcvt") ! 1300: (set_attr "mode" "SF") ! 1301: (set_attr "length" "1")]) ! 1302: ! 1303: ! 1304: ;; ! 1305: ;; .................... ! 1306: ;; ! 1307: ;; ZERO EXTENSION ! 1308: ;; ! 1309: ;; .................... ! 1310: ! 1311: ;; Extension insns. ! 1312: ;; Those for integer source operand ! 1313: ;; are ordered widest source type first. ! 1314: ! 1315: (define_insn "zero_extendhisi2" ! 1316: [(set (match_operand:SI 0 "register_operand" "=d,d,d") ! 1317: (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))] ! 1318: "" ! 1319: "* ! 1320: { ! 1321: if (which_alternative == 0) ! 1322: return \"andi\\t%0,%1,0xffff\"; ! 1323: else ! 1324: return mips_move_1word (operands, insn, TRUE); ! 1325: }" ! 1326: [(set_attr "type" "arith,load,load") ! 1327: (set_attr "mode" "SI") ! 1328: (set_attr "length" "1,1,2")]) ! 1329: ! 1330: (define_insn "zero_extendqihi2" ! 1331: [(set (match_operand:HI 0 "register_operand" "=d,d,d") ! 1332: (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))] ! 1333: "" ! 1334: "* ! 1335: { ! 1336: if (which_alternative == 0) ! 1337: return \"andi\\t%0,%1,0x00ff\"; ! 1338: else ! 1339: return mips_move_1word (operands, insn, TRUE); ! 1340: }" ! 1341: [(set_attr "type" "arith,load,load") ! 1342: (set_attr "mode" "HI") ! 1343: (set_attr "length" "1,1,2")]) ! 1344: ! 1345: (define_insn "zero_extendqisi2" ! 1346: [(set (match_operand:SI 0 "register_operand" "=d,d,d") ! 1347: (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))] ! 1348: "" ! 1349: "* ! 1350: { ! 1351: if (which_alternative == 0) ! 1352: return \"andi\\t%0,%1,0x00ff\"; ! 1353: else ! 1354: return mips_move_1word (operands, insn, TRUE); ! 1355: }" ! 1356: [(set_attr "type" "arith,load,load") ! 1357: (set_attr "mode" "SI") ! 1358: (set_attr "length" "1,1,2")]) ! 1359: ! 1360: ! 1361: ;; ! 1362: ;; .................... ! 1363: ;; ! 1364: ;; SIGN EXTENSION ! 1365: ;; ! 1366: ;; .................... ! 1367: ! 1368: ;; Extension insns. ! 1369: ;; Those for integer source operand ! 1370: ;; are ordered widest source type first. ! 1371: ! 1372: ;; These patterns originally accepted general_operands, however, slightly ! 1373: ;; better code is generated by only accepting register_operands, and then ! 1374: ;; letting combine generate the lh and lb insns. ! 1375: ! 1376: (define_expand "extendhisi2" ! 1377: [(set (match_operand:SI 0 "register_operand" "") ! 1378: (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] ! 1379: "" ! 1380: " ! 1381: { ! 1382: if (optimize && GET_CODE (operands[1]) == MEM) ! 1383: operands[1] = force_not_mem (operands[1]); ! 1384: ! 1385: if (GET_CODE (operands[1]) != MEM) ! 1386: { ! 1387: rtx op1 = gen_lowpart (SImode, operands[1]); ! 1388: rtx temp = gen_reg_rtx (SImode); ! 1389: rtx shift = gen_rtx (CONST_INT, VOIDmode, 16); ! 1390: ! 1391: emit_insn (gen_ashlsi3 (temp, op1, shift)); ! 1392: emit_insn (gen_ashrsi3 (operands[0], temp, shift)); ! 1393: DONE; ! 1394: } ! 1395: }") ! 1396: ! 1397: (define_insn "extendhisi2_internal" ! 1398: [(set (match_operand:SI 0 "register_operand" "=d,d") ! 1399: (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))] ! 1400: "" ! 1401: "* return mips_move_1word (operands, insn, FALSE);" ! 1402: [(set_attr "type" "load") ! 1403: (set_attr "mode" "SI") ! 1404: (set_attr "length" "1,2")]) ! 1405: ! 1406: (define_expand "extendqihi2" ! 1407: [(set (match_operand:HI 0 "register_operand" "") ! 1408: (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] ! 1409: "" ! 1410: " ! 1411: { ! 1412: if (optimize && GET_CODE (operands[1]) == MEM) ! 1413: operands[1] = force_not_mem (operands[1]); ! 1414: ! 1415: if (GET_CODE (operands[1]) != MEM) ! 1416: { ! 1417: rtx op0 = gen_lowpart (SImode, operands[0]); ! 1418: rtx op1 = gen_lowpart (SImode, operands[1]); ! 1419: rtx temp = gen_reg_rtx (SImode); ! 1420: rtx shift = gen_rtx (CONST_INT, VOIDmode, 24); ! 1421: ! 1422: emit_insn (gen_ashlsi3 (temp, op1, shift)); ! 1423: emit_insn (gen_ashrsi3 (op0, temp, shift)); ! 1424: DONE; ! 1425: } ! 1426: }") ! 1427: ! 1428: (define_insn "extendqihi2_internal" ! 1429: [(set (match_operand:HI 0 "register_operand" "=d,d") ! 1430: (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))] ! 1431: "" ! 1432: "* return mips_move_1word (operands, insn, FALSE);" ! 1433: [(set_attr "type" "load") ! 1434: (set_attr "mode" "SI") ! 1435: (set_attr "length" "1,2")]) ! 1436: ! 1437: ! 1438: (define_expand "extendqisi2" ! 1439: [(set (match_operand:SI 0 "register_operand" "") ! 1440: (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] ! 1441: "" ! 1442: " ! 1443: { ! 1444: if (optimize && GET_CODE (operands[1]) == MEM) ! 1445: operands[1] = force_not_mem (operands[1]); ! 1446: ! 1447: if (GET_CODE (operands[1]) != MEM) ! 1448: { ! 1449: rtx op1 = gen_lowpart (SImode, operands[1]); ! 1450: rtx temp = gen_reg_rtx (SImode); ! 1451: rtx shift = gen_rtx (CONST_INT, VOIDmode, 24); ! 1452: ! 1453: emit_insn (gen_ashlsi3 (temp, op1, shift)); ! 1454: emit_insn (gen_ashrsi3 (operands[0], temp, shift)); ! 1455: DONE; ! 1456: } ! 1457: }") ! 1458: ! 1459: (define_insn "extendqisi2_insn" ! 1460: [(set (match_operand:SI 0 "register_operand" "=d,d") ! 1461: (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))] ! 1462: "" ! 1463: "* return mips_move_1word (operands, insn, FALSE);" ! 1464: [(set_attr "type" "load") ! 1465: (set_attr "mode" "SI") ! 1466: (set_attr "length" "1,2")]) ! 1467: ! 1468: ! 1469: (define_insn "extendsfdf2" ! 1470: [(set (match_operand:DF 0 "register_operand" "=f") ! 1471: (float_extend:DF (match_operand:SF 1 "register_operand" "f")))] ! 1472: "TARGET_HARD_FLOAT" ! 1473: "cvt.d.s\\t%0,%1" ! 1474: [(set_attr "type" "fcvt") ! 1475: (set_attr "mode" "DF") ! 1476: (set_attr "length" "1")]) ! 1477: ! 1478: ! 1479: ! 1480: ;; ! 1481: ;; .................... ! 1482: ;; ! 1483: ;; CONVERSIONS ! 1484: ;; ! 1485: ;; .................... ! 1486: ! 1487: ;; The SImode scratch register can not be shared with address regs used for ! 1488: ;; operand zero, because then the address in the move instruction will be ! 1489: ;; clobbered. We mark the scratch register as early clobbered to prevent this. ! 1490: ! 1491: (define_insn "fix_truncdfsi2" ! 1492: [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o") ! 1493: (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f"))) ! 1494: (clobber (match_scratch:SI 2 "=d,*d,&d,&d")) ! 1495: (clobber (match_scratch:DF 3 "=f,*X,f,f"))] ! 1496: "TARGET_HARD_FLOAT" ! 1497: "* ! 1498: { ! 1499: rtx xoperands[10]; ! 1500: ! 1501: if (which_alternative == 1) ! 1502: return \"trunc.w.d %0,%1,%2\"; ! 1503: ! 1504: output_asm_insn (\"trunc.w.d %3,%1,%2\", operands); ! 1505: ! 1506: xoperands[0] = operands[0]; ! 1507: xoperands[1] = operands[3]; ! 1508: output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands); ! 1509: return \"\"; ! 1510: }" ! 1511: [(set_attr "type" "fcvt") ! 1512: (set_attr "mode" "DF") ! 1513: (set_attr "length" "11,9,10,11")]) ! 1514: ! 1515: ! 1516: (define_insn "fix_truncsfsi2" ! 1517: [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o") ! 1518: (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f"))) ! 1519: (clobber (match_scratch:SI 2 "=d,*d,&d,&d")) ! 1520: (clobber (match_scratch:SF 3 "=f,*X,f,f"))] ! 1521: "TARGET_HARD_FLOAT" ! 1522: "* ! 1523: { ! 1524: rtx xoperands[10]; ! 1525: ! 1526: if (which_alternative == 1) ! 1527: return \"trunc.w.s %0,%1,%2\"; ! 1528: ! 1529: output_asm_insn (\"trunc.w.s %3,%1,%2\", operands); ! 1530: ! 1531: xoperands[0] = operands[0]; ! 1532: xoperands[1] = operands[3]; ! 1533: output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands); ! 1534: return \"\"; ! 1535: }" ! 1536: [(set_attr "type" "fcvt") ! 1537: (set_attr "mode" "SF") ! 1538: (set_attr "length" "11,9,10,11")]) ! 1539: ! 1540: ! 1541: (define_insn "floatsidf2" ! 1542: [(set (match_operand:DF 0 "register_operand" "=f,f,f") ! 1543: (float:DF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))] ! 1544: "TARGET_HARD_FLOAT" ! 1545: "* ! 1546: { ! 1547: dslots_load_total++; ! 1548: if (GET_CODE (operands[1]) == MEM) ! 1549: return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\"; ! 1550: ! 1551: return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\"; ! 1552: }" ! 1553: [(set_attr "type" "fcvt") ! 1554: (set_attr "mode" "DF") ! 1555: (set_attr "length" "3,4,3")]) ! 1556: ! 1557: ! 1558: (define_insn "floatsisf2" ! 1559: [(set (match_operand:SF 0 "register_operand" "=f,f,f") ! 1560: (float:SF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))] ! 1561: "TARGET_HARD_FLOAT" ! 1562: "* ! 1563: { ! 1564: dslots_load_total++; ! 1565: if (GET_CODE (operands[1]) == MEM) ! 1566: return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\"; ! 1567: ! 1568: return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\"; ! 1569: }" ! 1570: [(set_attr "type" "fcvt") ! 1571: (set_attr "mode" "SF") ! 1572: (set_attr "length" "3,4,3")]) ! 1573: ! 1574: ! 1575: (define_expand "fixuns_truncdfsi2" ! 1576: [(set (match_operand:SI 0 "register_operand" "") ! 1577: (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))] ! 1578: "TARGET_HARD_FLOAT" ! 1579: " ! 1580: { ! 1581: rtx reg1 = gen_reg_rtx (DFmode); ! 1582: rtx reg2 = gen_reg_rtx (DFmode); ! 1583: rtx reg3 = gen_reg_rtx (SImode); ! 1584: rtx label1 = gen_label_rtx (); ! 1585: rtx label2 = gen_label_rtx (); ! 1586: REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31); ! 1587: ! 1588: if (reg1) /* turn off complaints about unreached code */ ! 1589: { ! 1590: emit_move_insn (reg1, immed_real_const_1 (offset, DFmode)); ! 1591: do_pending_stack_adjust (); ! 1592: ! 1593: emit_insn (gen_cmpdf (operands[1], reg1)); ! 1594: emit_jump_insn (gen_bge (label1)); ! 1595: ! 1596: emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1])); ! 1597: emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx, ! 1598: gen_rtx (LABEL_REF, VOIDmode, label2))); ! 1599: emit_barrier (); ! 1600: ! 1601: emit_label (label1); ! 1602: emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1)); ! 1603: emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000)); ! 1604: ! 1605: emit_insn (gen_fix_truncdfsi2 (operands[0], reg2)); ! 1606: emit_insn (gen_iorsi3 (operands[0], operands[0], reg3)); ! 1607: ! 1608: emit_label (label2); ! 1609: ! 1610: /* allow REG_NOTES to be set on last insn (labels don't have enough ! 1611: fields, and can't be used for REG_NOTES anyway). */ ! 1612: emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx)); ! 1613: DONE; ! 1614: } ! 1615: }") ! 1616: ! 1617: ! 1618: (define_expand "fixuns_truncsfsi2" ! 1619: [(set (match_operand:SI 0 "register_operand" "") ! 1620: (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))] ! 1621: "TARGET_HARD_FLOAT" ! 1622: " ! 1623: { ! 1624: rtx reg1 = gen_reg_rtx (SFmode); ! 1625: rtx reg2 = gen_reg_rtx (SFmode); ! 1626: rtx reg3 = gen_reg_rtx (SImode); ! 1627: rtx label1 = gen_label_rtx (); ! 1628: rtx label2 = gen_label_rtx (); ! 1629: REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31); ! 1630: ! 1631: if (reg1) /* turn off complaints about unreached code */ ! 1632: { ! 1633: emit_move_insn (reg1, immed_real_const_1 (offset, SFmode)); ! 1634: do_pending_stack_adjust (); ! 1635: ! 1636: emit_insn (gen_cmpsf (operands[1], reg1)); ! 1637: emit_jump_insn (gen_bge (label1)); ! 1638: ! 1639: emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1])); ! 1640: emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx, ! 1641: gen_rtx (LABEL_REF, VOIDmode, label2))); ! 1642: emit_barrier (); ! 1643: ! 1644: emit_label (label1); ! 1645: emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1)); ! 1646: emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000)); ! 1647: ! 1648: emit_insn (gen_fix_truncsfsi2 (operands[0], reg2)); ! 1649: emit_insn (gen_iorsi3 (operands[0], operands[0], reg3)); ! 1650: ! 1651: emit_label (label2); ! 1652: ! 1653: /* allow REG_NOTES to be set on last insn (labels don't have enough ! 1654: fields, and can't be used for REG_NOTES anyway). */ ! 1655: emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx)); ! 1656: DONE; ! 1657: } ! 1658: }") ! 1659: ! 1660: ! 1661: ;; ! 1662: ;; .................... ! 1663: ;; ! 1664: ;; DATA MOVEMENT ! 1665: ;; ! 1666: ;; .................... ! 1667: ! 1668: ;; unaligned word moves generated by the block moves. ! 1669: ! 1670: (define_expand "movsi_unaligned" ! 1671: [(set (match_operand:SI 0 "general_operand" "") ! 1672: (unspec [(match_operand:SI 1 "general_operand" "")] 0))] ! 1673: "" ! 1674: " ! 1675: { ! 1676: /* Handle stores. */ ! 1677: if (GET_CODE (operands[0]) == MEM) ! 1678: { ! 1679: rtx reg = gen_reg_rtx (SImode); ! 1680: rtx insn = emit_insn (gen_movsi_ulw (reg, operands[1])); ! 1681: rtx addr = XEXP (operands[0], 0); ! 1682: if (CONSTANT_P (addr)) ! 1683: REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUIV, addr, REG_NOTES (insn)); ! 1684: ! 1685: if (reg_or_0_operand (operands[1], SImode)) ! 1686: DONE; ! 1687: ! 1688: operands[1] = reg; ! 1689: } ! 1690: ! 1691: /* Generate appropriate load, store. If not a load or store, ! 1692: do a normal movsi. */ ! 1693: if (GET_CODE (operands[0]) != MEM && GET_CODE (operands[1]) != MEM) ! 1694: { ! 1695: emit_insn (gen_movsi (operands[0], operands[1])); ! 1696: DONE; ! 1697: } ! 1698: ! 1699: /* Fall through and generate normal code. */ ! 1700: }") ! 1701: ! 1702: (define_insn "movsi_ulw" ! 1703: [(set (match_operand:SI 0 "register_operand" "=&d,&d,d,d") ! 1704: (unspec [(match_operand:SI 1 "general_operand" "R,o,dIKL,M")] 0))] ! 1705: "" ! 1706: "* ! 1707: { ! 1708: enum rtx_code code; ! 1709: char *ret; ! 1710: rtx offset; ! 1711: rtx addr; ! 1712: rtx mem_addr; ! 1713: ! 1714: if (which_alternative != 0) ! 1715: return mips_move_1word (operands, insn, FALSE); ! 1716: ! 1717: if (TARGET_STATS) ! 1718: mips_count_memory_refs (operands[1], 2); ! 1719: ! 1720: /* The stack/frame pointers are always aligned, so we can convert ! 1721: to the faster lw if we are referencing an aligned stack location. */ ! 1722: ! 1723: offset = const0_rtx; ! 1724: addr = XEXP (operands[1], 0); ! 1725: mem_addr = eliminate_constant_term (addr, &offset); ! 1726: ! 1727: if ((INTVAL (offset) & (UNITS_PER_WORD-1)) == 0 ! 1728: && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx)) ! 1729: ret = \"lw\\t%0,%1\"; ! 1730: ! 1731: else ! 1732: { ! 1733: ret = \"ulw\\t%0,%1\"; ! 1734: if (TARGET_GAS) ! 1735: { ! 1736: enum rtx_code code = GET_CODE (addr); ! 1737: ! 1738: if (code == CONST || code == SYMBOL_REF || code == LABEL_REF) ! 1739: { ! 1740: operands[2] = gen_rtx (REG, SImode, GP_REG_FIRST + 1); ! 1741: ret = \"%[la\\t%2,%1\;ulw\\t%0,0(%2)%]\"; ! 1742: } ! 1743: } ! 1744: } ! 1745: ! 1746: return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn); ! 1747: }" ! 1748: [(set_attr "type" "load,load,move,arith") ! 1749: (set_attr "mode" "SI") ! 1750: (set_attr "length" "2,4,1,2")]) ! 1751: ! 1752: (define_insn "movsi_usw" ! 1753: [(set (match_operand:SI 0 "memory_operand" "=R,o") ! 1754: (unspec [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")] 0))] ! 1755: "" ! 1756: "* ! 1757: { ! 1758: rtx offset = const0_rtx; ! 1759: rtx addr = XEXP (operands[0], 0); ! 1760: rtx mem_addr = eliminate_constant_term (addr, &offset); ! 1761: ! 1762: if (TARGET_STATS) ! 1763: mips_count_memory_refs (operands[0], 2); ! 1764: ! 1765: /* The stack/frame pointers are always aligned, so we can convert ! 1766: to the faster sw if we are referencing an aligned stack location. */ ! 1767: ! 1768: if ((INTVAL (offset) & (UNITS_PER_WORD-1)) == 0 ! 1769: && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx)) ! 1770: return \"sw\\t%1,%0\"; ! 1771: ! 1772: ! 1773: if (TARGET_GAS) ! 1774: { ! 1775: enum rtx_code code = GET_CODE (XEXP (operands[0], 0)); ! 1776: ! 1777: if (code == CONST || code == SYMBOL_REF || code == LABEL_REF) ! 1778: { ! 1779: operands[2] = gen_rtx (REG, SImode, GP_REG_FIRST + 1); ! 1780: return \"%[la\\t%2,%0\;usw\\t%z1,0(%2)%]\"; ! 1781: } ! 1782: } ! 1783: ! 1784: return \"usw\\t%z1,%0\"; ! 1785: }" ! 1786: [(set_attr "type" "store") ! 1787: (set_attr "mode" "SI") ! 1788: (set_attr "length" "2,4")]) ! 1789: ! 1790: ! 1791: ;; 64-bit integer moves ! 1792: ! 1793: ;; Unlike most other insns, the move insns can't be split with ! 1794: ;; different predicates, because register spilling and other parts of ! 1795: ;; the compiler, have memoized the insn number already. ! 1796: ! 1797: (define_expand "movdi" ! 1798: [(set (match_operand:DI 0 "nonimmediate_operand" "") ! 1799: (match_operand:DI 1 "general_operand" ""))] ! 1800: "" ! 1801: " ! 1802: { ! 1803: if ((reload_in_progress | reload_completed) == 0 ! 1804: && !register_operand (operands[0], DImode) ! 1805: && !register_operand (operands[1], DImode) ! 1806: && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0) ! 1807: && operands[1] != CONST0_RTX (DImode)) ! 1808: { ! 1809: rtx temp = force_reg (DImode, operands[1]); ! 1810: emit_move_insn (operands[0], temp); ! 1811: DONE; ! 1812: } ! 1813: }") ! 1814: ! 1815: (define_insn "movdi_internal" ! 1816: [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*d,*x") ! 1817: (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,*x,*d"))] ! 1818: "register_operand (operands[0], DImode) ! 1819: || register_operand (operands[1], DImode) ! 1820: || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0) ! 1821: || operands[1] == CONST0_RTX (DImode)" ! 1822: "* return mips_move_2words (operands, insn); " ! 1823: [(set_attr "type" "move,arith,load,load,store,store,hilo,hilo") ! 1824: (set_attr "mode" "DI") ! 1825: (set_attr "length" "2,4,2,4,2,4,2,2")]) ! 1826: ! 1827: (define_split ! 1828: [(set (match_operand:DI 0 "register_operand" "") ! 1829: (match_operand:DI 1 "register_operand" ""))] ! 1830: "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 1831: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) ! 1832: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))" ! 1833: ! 1834: [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0)) ! 1835: (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))] ! 1836: "") ! 1837: ! 1838: ! 1839: ;; 32-bit Integer moves ! 1840: ! 1841: (define_split ! 1842: [(set (match_operand:SI 0 "register_operand" "") ! 1843: (match_operand:SI 1 "large_int" ""))] ! 1844: "!TARGET_DEBUG_D_MODE" ! 1845: [(set (match_dup 0) ! 1846: (match_dup 2)) ! 1847: (set (match_dup 0) ! 1848: (ior:SI (match_dup 0) ! 1849: (match_dup 3)))] ! 1850: " ! 1851: { ! 1852: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff0000); ! 1853: operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0x0000ffff); ! 1854: }") ! 1855: ! 1856: ;; Unlike most other insns, the move insns can't be split with ! 1857: ;; different predicates, because register spilling and other parts of ! 1858: ;; the compiler, have memoized the insn number already. ! 1859: ! 1860: (define_expand "movsi" ! 1861: [(set (match_operand:SI 0 "nonimmediate_operand" "") ! 1862: (match_operand:SI 1 "general_operand" ""))] ! 1863: "" ! 1864: " ! 1865: { ! 1866: if ((reload_in_progress | reload_completed) == 0 ! 1867: && !register_operand (operands[0], SImode) ! 1868: && !register_operand (operands[1], SImode) ! 1869: && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)) ! 1870: { ! 1871: rtx temp = force_reg (SImode, operands[1]); ! 1872: emit_move_insn (operands[0], temp); ! 1873: DONE; ! 1874: } ! 1875: }") ! 1876: ! 1877: ;; The difference between these two is whether or not ints are allowed ! 1878: ;; in FP registers (off by default, use -mdebugh to enable). ! 1879: ! 1880: (define_insn "movsi_internal1" ! 1881: [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*f*z,*f,*f,*f,*R,*m,*x,*d") ! 1882: (match_operand:SI 1 "general_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*f*z,*d,*f,*R,*m,*f,*f,*d,*x"))] ! 1883: "TARGET_DEBUG_H_MODE ! 1884: && (register_operand (operands[0], SImode) ! 1885: || register_operand (operands[1], SImode) ! 1886: || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))" ! 1887: "* return mips_move_1word (operands, insn, TRUE);" ! 1888: [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo") ! 1889: (set_attr "mode" "SI") ! 1890: (set_attr "length" "1,2,1,2,1,2,1,2,1,1,1,1,2,1,2,1,1")]) ! 1891: ! 1892: (define_insn "movsi_internal2" ! 1893: [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*d,*x") ! 1894: (match_operand:SI 1 "general_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,*x,*d"))] ! 1895: "!TARGET_DEBUG_H_MODE ! 1896: && (register_operand (operands[0], SImode) ! 1897: || register_operand (operands[1], SImode) ! 1898: || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))" ! 1899: "* return mips_move_1word (operands, insn, TRUE);" ! 1900: [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo") ! 1901: (set_attr "mode" "SI") ! 1902: (set_attr "length" "1,2,1,2,1,2,1,2,1,1,1,1")]) ! 1903: ! 1904: ! 1905: ;; 16-bit Integer moves ! 1906: ! 1907: ;; Unlike most other insns, the move insns can't be split with ! 1908: ;; different predicates, because register spilling and other parts of ! 1909: ;; the compiler, have memoized the insn number already. ! 1910: ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined ! 1911: ! 1912: (define_expand "movhi" ! 1913: [(set (match_operand:HI 0 "nonimmediate_operand" "") ! 1914: (match_operand:HI 1 "general_operand" ""))] ! 1915: "" ! 1916: " ! 1917: { ! 1918: if ((reload_in_progress | reload_completed) == 0 ! 1919: && !register_operand (operands[0], HImode) ! 1920: && !register_operand (operands[1], HImode) ! 1921: && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)) ! 1922: { ! 1923: rtx temp = force_reg (HImode, operands[1]); ! 1924: emit_move_insn (operands[0], temp); ! 1925: DONE; ! 1926: } ! 1927: }") ! 1928: ! 1929: ;; The difference between these two is whether or not ints are allowed ! 1930: ;; in FP registers (off by default, use -mdebugh to enable). ! 1931: ! 1932: (define_insn "movhi_internal1" ! 1933: [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d") ! 1934: (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))] ! 1935: "TARGET_DEBUG_H_MODE ! 1936: && (register_operand (operands[0], HImode) ! 1937: || register_operand (operands[1], HImode) ! 1938: || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))" ! 1939: "* return mips_move_1word (operands, insn, TRUE);" ! 1940: [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo") ! 1941: (set_attr "mode" "HI") ! 1942: (set_attr "length" "1,1,1,2,1,2,1,1,1,1,1")]) ! 1943: ! 1944: (define_insn "movhi_internal2" ! 1945: [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d") ! 1946: (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))] ! 1947: "!TARGET_DEBUG_H_MODE ! 1948: && (register_operand (operands[0], HImode) ! 1949: || register_operand (operands[1], HImode) ! 1950: || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))" ! 1951: "* return mips_move_1word (operands, insn, TRUE);" ! 1952: [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo") ! 1953: (set_attr "mode" "HI") ! 1954: (set_attr "length" "1,1,1,2,1,2,1,1,1,1")]) ! 1955: ! 1956: ! 1957: ;; 8-bit Integer moves ! 1958: ! 1959: ;; Unlike most other insns, the move insns can't be split with ! 1960: ;; different predicates, because register spilling and other parts of ! 1961: ;; the compiler, have memoized the insn number already. ! 1962: ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined ! 1963: ! 1964: (define_expand "movqi" ! 1965: [(set (match_operand:QI 0 "nonimmediate_operand" "") ! 1966: (match_operand:QI 1 "general_operand" ""))] ! 1967: "" ! 1968: " ! 1969: { ! 1970: if ((reload_in_progress | reload_completed) == 0 ! 1971: && !register_operand (operands[0], QImode) ! 1972: && !register_operand (operands[1], QImode) ! 1973: && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)) ! 1974: { ! 1975: rtx temp = force_reg (QImode, operands[1]); ! 1976: emit_move_insn (operands[0], temp); ! 1977: DONE; ! 1978: } ! 1979: }") ! 1980: ! 1981: ;; The difference between these two is whether or not ints are allowed ! 1982: ;; in FP registers (off by default, use -mdebugh to enable). ! 1983: ! 1984: (define_insn "movqi_internal1" ! 1985: [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d") ! 1986: (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))] ! 1987: "TARGET_DEBUG_H_MODE ! 1988: && (register_operand (operands[0], QImode) ! 1989: || register_operand (operands[1], QImode) ! 1990: || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))" ! 1991: "* return mips_move_1word (operands, insn, TRUE);" ! 1992: [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo") ! 1993: (set_attr "mode" "QI") ! 1994: (set_attr "length" "1,1,1,2,1,2,1,1,1,1,1")]) ! 1995: ! 1996: (define_insn "movqi_internal2" ! 1997: [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d") ! 1998: (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))] ! 1999: "!TARGET_DEBUG_H_MODE ! 2000: && (register_operand (operands[0], QImode) ! 2001: || register_operand (operands[1], QImode) ! 2002: || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))" ! 2003: "* return mips_move_1word (operands, insn, TRUE);" ! 2004: [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo") ! 2005: (set_attr "mode" "QI") ! 2006: (set_attr "length" "1,1,1,2,1,2,1,1,1,1")]) ! 2007: ! 2008: ! 2009: ;; 32-bit floating point moves ! 2010: ! 2011: (define_expand "movsf" ! 2012: [(set (match_operand:SF 0 "nonimmediate_operand" "") ! 2013: (match_operand:SF 1 "general_operand" ""))] ! 2014: "" ! 2015: " ! 2016: { ! 2017: if ((reload_in_progress | reload_completed) == 0 ! 2018: && !register_operand (operands[0], SFmode) ! 2019: && !register_operand (operands[1], SFmode) ! 2020: && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0) ! 2021: && operands[1] != CONST0_RTX (SFmode)) ! 2022: { ! 2023: rtx temp = force_reg (SFmode, operands[1]); ! 2024: emit_move_insn (operands[0], temp); ! 2025: DONE; ! 2026: } ! 2027: }") ! 2028: ! 2029: (define_insn "movsf_internal1" ! 2030: [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m") ! 2031: (match_operand:SF 1 "general_operand" "f,G,R,Em,fG,fG,*d,*f,*G*d,*R,*E*m,*d,*d"))] ! 2032: "TARGET_HARD_FLOAT ! 2033: && (register_operand (operands[0], SFmode) ! 2034: || register_operand (operands[1], SFmode) ! 2035: || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0) ! 2036: || operands[1] == CONST0_RTX (SFmode))" ! 2037: "* return mips_move_1word (operands, insn, FALSE);" ! 2038: [(set_attr "type" "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store") ! 2039: (set_attr "mode" "SF") ! 2040: (set_attr "length" "1,1,1,2,1,2,1,1,1,1,2,1,2")]) ! 2041: ! 2042: ! 2043: (define_insn "movsf_internal2" ! 2044: [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m") ! 2045: (match_operand:SF 1 "general_operand" " Gd,R,Em,d,d"))] ! 2046: "TARGET_SOFT_FLOAT ! 2047: && (register_operand (operands[0], SFmode) ! 2048: || register_operand (operands[1], SFmode) ! 2049: || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0) ! 2050: || operands[1] == CONST0_RTX (SFmode))" ! 2051: "* return mips_move_1word (operands, insn, FALSE);" ! 2052: [(set_attr "type" "move,load,load,store,store") ! 2053: (set_attr "mode" "SF") ! 2054: (set_attr "length" "1,1,2,1,2")]) ! 2055: ! 2056: ! 2057: ;; 64-bit floating point moves ! 2058: ! 2059: (define_expand "movdf" ! 2060: [(set (match_operand:DF 0 "nonimmediate_operand" "") ! 2061: (match_operand:DF 1 "general_operand" ""))] ! 2062: "" ! 2063: " ! 2064: { ! 2065: if ((reload_in_progress | reload_completed) == 0 ! 2066: && !register_operand (operands[0], DFmode) ! 2067: && !register_operand (operands[1], DFmode) ! 2068: && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0) ! 2069: && operands[1] != CONST0_RTX (DFmode)) ! 2070: { ! 2071: rtx temp = force_reg (DFmode, operands[1]); ! 2072: emit_move_insn (operands[0], temp); ! 2073: DONE; ! 2074: } ! 2075: }") ! 2076: ! 2077: (define_insn "movdf_internal1" ! 2078: [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,o,f,*f,*d,*d,*d,*d,*R,*o") ! 2079: (match_operand:DF 1 "general_operand" "f,R,o,fG,fG,E,*d,*f,*d*G,*R,*o*E,*d,*d"))] ! 2080: "TARGET_HARD_FLOAT ! 2081: && (register_operand (operands[0], DFmode) ! 2082: || register_operand (operands[1], DFmode) ! 2083: || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0) ! 2084: || operands[1] == CONST0_RTX (DFmode))" ! 2085: "* return mips_move_2words (operands, insn); " ! 2086: [(set_attr "type" "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store") ! 2087: (set_attr "mode" "DF") ! 2088: (set_attr "length" "1,2,4,2,4,4,2,2,2,2,4,2,4")]) ! 2089: ! 2090: (define_insn "movdf_internal2" ! 2091: [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,o") ! 2092: (match_operand:DF 1 "general_operand" "dG,R,oE,d,d"))] ! 2093: "TARGET_SOFT_FLOAT ! 2094: && (register_operand (operands[0], DFmode) ! 2095: || register_operand (operands[1], DFmode) ! 2096: || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0) ! 2097: || operands[1] == CONST0_RTX (DFmode))" ! 2098: "* return mips_move_2words (operands, insn); " ! 2099: [(set_attr "type" "move,load,load,store,store") ! 2100: (set_attr "mode" "DF") ! 2101: (set_attr "length" "2,2,4,2,4")]) ! 2102: ! 2103: (define_split ! 2104: [(set (match_operand:DF 0 "register_operand" "") ! 2105: (match_operand:DF 1 "register_operand" ""))] ! 2106: "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 2107: && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) ! 2108: && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))" ! 2109: ! 2110: [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0)) ! 2111: (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))] ! 2112: "") ! 2113: ! 2114: ! 2115: ;; Block moves, see mips.c for more details. ! 2116: ;; Argument 0 is the destination ! 2117: ;; Argument 1 is the source ! 2118: ;; Argument 2 is the length ! 2119: ;; Argument 3 is the alignment ! 2120: ! 2121: (define_expand "movstrsi" ! 2122: [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" "")) ! 2123: (mem:BLK (match_operand:BLK 1 "general_operand" ""))) ! 2124: (use (match_operand:SI 2 "arith32_operand" "")) ! 2125: (use (match_operand:SI 3 "immediate_operand" ""))])] ! 2126: "" ! 2127: " ! 2128: { ! 2129: if (operands[0]) /* avoid unused code messages */ ! 2130: { ! 2131: expand_block_move (operands); ! 2132: DONE; ! 2133: } ! 2134: }") ! 2135: ! 2136: ;; Insn generated by block moves ! 2137: ! 2138: (define_insn "movstrsi_internal" ! 2139: [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination ! 2140: (match_operand:BLK 1 "memory_operand" "Ro")) ;; source ! 2141: (clobber (match_scratch:SI 4 "=&d")) ;; temp 1 ! 2142: (clobber (match_scratch:SI 5 "=&d")) ;; temp 2 ! 2143: (clobber (match_scratch:SI 6 "=&d")) ;; temp 3 ! 2144: (clobber (match_scratch:SI 7 "=&d")) ;; temp 4 ! 2145: (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move ! 2146: (use (match_operand:SI 3 "small_int" "I")) ;; alignment ! 2147: (use (const_int 0))] ;; normal block move ! 2148: "" ! 2149: "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);" ! 2150: [(set_attr "type" "multi") ! 2151: (set_attr "mode" "none") ! 2152: (set_attr "length" "20")]) ! 2153: ! 2154: ;; Split a block move into 2 parts, the first part is everything ! 2155: ;; except for the last move, and the second part is just the last ! 2156: ;; store, which is exactly 1 instruction (ie, not a usw), so it can ! 2157: ;; fill a delay slot. This also prevents a bug in delayed branches ! 2158: ;; from showing up, which reuses one of the registers in our clobbers. ! 2159: ! 2160: (define_split ! 2161: [(set (mem:BLK (match_operand:SI 0 "register_operand" "")) ! 2162: (mem:BLK (match_operand:SI 1 "register_operand" ""))) ! 2163: (clobber (match_operand:SI 4 "register_operand" "")) ! 2164: (clobber (match_operand:SI 5 "register_operand" "")) ! 2165: (clobber (match_operand:SI 6 "register_operand" "")) ! 2166: (clobber (match_operand:SI 7 "register_operand" "")) ! 2167: (use (match_operand:SI 2 "small_int" "")) ! 2168: (use (match_operand:SI 3 "small_int" "")) ! 2169: (use (const_int 0))] ! 2170: ! 2171: "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0" ! 2172: ! 2173: ;; All but the last move ! 2174: [(parallel [(set (mem:BLK (match_dup 0)) ! 2175: (mem:BLK (match_dup 1))) ! 2176: (clobber (match_dup 4)) ! 2177: (clobber (match_dup 5)) ! 2178: (clobber (match_dup 6)) ! 2179: (clobber (match_dup 7)) ! 2180: (use (match_dup 2)) ! 2181: (use (match_dup 3)) ! 2182: (use (const_int 1))]) ! 2183: ! 2184: ;; The last store, so it can fill a delay slot ! 2185: (parallel [(set (mem:BLK (match_dup 0)) ! 2186: (mem:BLK (match_dup 1))) ! 2187: (clobber (match_dup 4)) ! 2188: (clobber (match_dup 5)) ! 2189: (clobber (match_dup 6)) ! 2190: (clobber (match_dup 7)) ! 2191: (use (match_dup 2)) ! 2192: (use (match_dup 3)) ! 2193: (use (const_int 2))])] ! 2194: ! 2195: "") ! 2196: ! 2197: (define_insn "movstrsi_internal2" ! 2198: [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination ! 2199: (match_operand:BLK 1 "memory_operand" "Ro")) ;; source ! 2200: (clobber (match_scratch:SI 4 "=&d")) ;; temp 1 ! 2201: (clobber (match_scratch:SI 5 "=&d")) ;; temp 2 ! 2202: (clobber (match_scratch:SI 6 "=&d")) ;; temp 3 ! 2203: (clobber (match_scratch:SI 7 "=&d")) ;; temp 4 ! 2204: (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move ! 2205: (use (match_operand:SI 3 "small_int" "I")) ;; alignment ! 2206: (use (const_int 1))] ;; all but last store ! 2207: "" ! 2208: "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);" ! 2209: [(set_attr "type" "multi") ! 2210: (set_attr "mode" "none") ! 2211: (set_attr "length" "20")]) ! 2212: ! 2213: (define_insn "movstrsi_internal3" ! 2214: [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination ! 2215: (match_operand:BLK 1 "memory_operand" "Ro")) ;; source ! 2216: (clobber (match_scratch:SI 4 "=&d")) ;; temp 1 ! 2217: (clobber (match_scratch:SI 5 "=&d")) ;; temp 2 ! 2218: (clobber (match_scratch:SI 6 "=&d")) ;; temp 3 ! 2219: (clobber (match_scratch:SI 7 "=&d")) ;; temp 4 ! 2220: (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move ! 2221: (use (match_operand:SI 3 "small_int" "I")) ;; alignment ! 2222: (use (const_int 2))] ;; just last store of block mvoe ! 2223: "" ! 2224: "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);" ! 2225: [(set_attr "type" "store") ! 2226: (set_attr "mode" "none") ! 2227: (set_attr "length" "1")]) ! 2228: ! 2229: ! 2230: ;; ! 2231: ;; .................... ! 2232: ;; ! 2233: ;; SHIFTS ! 2234: ;; ! 2235: ;; .................... ! 2236: ! 2237: (define_insn "ashlsi3" ! 2238: [(set (match_operand:SI 0 "register_operand" "=d") ! 2239: (ashift:SI (match_operand:SI 1 "register_operand" "d") ! 2240: (match_operand:SI 2 "arith_operand" "dI")))] ! 2241: "" ! 2242: "* ! 2243: { ! 2244: if (GET_CODE (operands[2]) == CONST_INT) ! 2245: operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f); ! 2246: ! 2247: return \"sll\\t%0,%1,%2\"; ! 2248: }" ! 2249: [(set_attr "type" "arith") ! 2250: (set_attr "mode" "SI") ! 2251: (set_attr "length" "1")]) ! 2252: ! 2253: ! 2254: (define_expand "ashldi3" ! 2255: [(parallel [(set (match_operand:DI 0 "register_operand" "") ! 2256: (ashift:DI (match_operand:DI 1 "register_operand" "") ! 2257: (match_operand:SI 2 "arith_operand" ""))) ! 2258: (clobber (match_dup 3))])] ! 2259: "!TARGET_DEBUG_G_MODE" ! 2260: "operands[3] = gen_reg_rtx (SImode);") ! 2261: ! 2262: ! 2263: (define_insn "ashldi3_internal" ! 2264: [(set (match_operand:DI 0 "register_operand" "=&d") ! 2265: (ashift:DI (match_operand:DI 1 "register_operand" "d") ! 2266: (match_operand:SI 2 "register_operand" "d"))) ! 2267: (clobber (match_operand:SI 3 "register_operand" "=d"))] ! 2268: "!TARGET_DEBUG_G_MODE" ! 2269: "* ! 2270: { ! 2271: operands[4] = const0_rtx; ! 2272: dslots_jump_total += 3; ! 2273: dslots_jump_filled += 2; ! 2274: ! 2275: return \"sll\\t%3,%2,26\\n\\ ! 2276: \\tbgez\\t%3,1f\\n\\ ! 2277: \\tsll\\t%M0,%L1,%2\\n\\ ! 2278: \\t%(b\\t3f\\n\\ ! 2279: \\tmove\\t%L0,%z4%)\\n\\ ! 2280: \\n\\ ! 2281: 1:\\n\\ ! 2282: \\t%(beq\\t%3,%z4,2f\\n\\ ! 2283: \\tsll\\t%M0,%M1,%2%)\\n\\ ! 2284: \\n\\ ! 2285: \\tsubu\\t%3,%z4,%2\\n\\ ! 2286: \\tsrl\\t%3,%L1,%3\\n\\ ! 2287: \\tor\\t%M0,%M0,%3\\n\\ ! 2288: 2:\\n\\ ! 2289: \\tsll\\t%L0,%L1,%2\\n\\ ! 2290: 3:\"; ! 2291: }" ! 2292: [(set_attr "type" "darith") ! 2293: (set_attr "mode" "SI") ! 2294: (set_attr "length" "12")]) ! 2295: ! 2296: ! 2297: (define_insn "ashldi3_internal2" ! 2298: [(set (match_operand:DI 0 "register_operand" "=d") ! 2299: (ashift:DI (match_operand:DI 1 "register_operand" "d") ! 2300: (match_operand:SI 2 "small_int" "IJK"))) ! 2301: (clobber (match_operand:SI 3 "register_operand" "=d"))] ! 2302: "!TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0" ! 2303: "* ! 2304: { ! 2305: operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f); ! 2306: operands[4] = const0_rtx; ! 2307: return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\"; ! 2308: }" ! 2309: [(set_attr "type" "darith") ! 2310: (set_attr "mode" "DI") ! 2311: (set_attr "length" "2")]) ! 2312: ! 2313: ! 2314: (define_split ! 2315: [(set (match_operand:DI 0 "register_operand" "") ! 2316: (ashift:DI (match_operand:DI 1 "register_operand" "") ! 2317: (match_operand:SI 2 "small_int" ""))) ! 2318: (clobber (match_operand:SI 3 "register_operand" ""))] ! 2319: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 2320: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER ! 2321: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER ! 2322: && (INTVAL (operands[2]) & 32) != 0" ! 2323: ! 2324: [(set (subreg:SI (match_dup 0) 1) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2))) ! 2325: (set (subreg:SI (match_dup 0) 0) (const_int 0))] ! 2326: ! 2327: "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);") ! 2328: ! 2329: ! 2330: (define_split ! 2331: [(set (match_operand:DI 0 "register_operand" "") ! 2332: (ashift:DI (match_operand:DI 1 "register_operand" "") ! 2333: (match_operand:SI 2 "small_int" ""))) ! 2334: (clobber (match_operand:SI 3 "register_operand" ""))] ! 2335: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 2336: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER ! 2337: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER ! 2338: && (INTVAL (operands[2]) & 32) != 0" ! 2339: ! 2340: [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 1) (match_dup 2))) ! 2341: (set (subreg:SI (match_dup 0) 1) (const_int 0))] ! 2342: ! 2343: "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);") ! 2344: ! 2345: ! 2346: (define_insn "ashldi3_internal3" ! 2347: [(set (match_operand:DI 0 "register_operand" "=d") ! 2348: (ashift:DI (match_operand:DI 1 "register_operand" "d") ! 2349: (match_operand:SI 2 "small_int" "IJK"))) ! 2350: (clobber (match_operand:SI 3 "register_operand" "=d"))] ! 2351: "!TARGET_DEBUG_G_MODE ! 2352: && (INTVAL (operands[2]) & 63) < 32 ! 2353: && (INTVAL (operands[2]) & 63) != 0" ! 2354: "* ! 2355: { ! 2356: int amount = INTVAL (operands[2]); ! 2357: ! 2358: operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31)); ! 2359: operands[4] = const0_rtx; ! 2360: operands[5] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31)); ! 2361: ! 2362: return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\"; ! 2363: }" ! 2364: [(set_attr "type" "darith") ! 2365: (set_attr "mode" "DI") ! 2366: (set_attr "length" "4")]) ! 2367: ! 2368: ! 2369: (define_split ! 2370: [(set (match_operand:DI 0 "register_operand" "") ! 2371: (ashift:DI (match_operand:DI 1 "register_operand" "") ! 2372: (match_operand:SI 2 "small_int" ""))) ! 2373: (clobber (match_operand:SI 3 "register_operand" ""))] ! 2374: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 2375: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER ! 2376: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER ! 2377: && (INTVAL (operands[2]) & 63) < 32 ! 2378: && (INTVAL (operands[2]) & 63) != 0" ! 2379: ! 2380: [(set (subreg:SI (match_dup 0) 1) ! 2381: (ashift:SI (subreg:SI (match_dup 1) 1) ! 2382: (match_dup 2))) ! 2383: ! 2384: (set (match_dup 3) ! 2385: (lshiftrt:SI (subreg:SI (match_dup 1) 0) ! 2386: (match_dup 4))) ! 2387: ! 2388: (set (subreg:SI (match_dup 0) 1) ! 2389: (ior:SI (subreg:SI (match_dup 0) 1) ! 2390: (match_dup 3))) ! 2391: ! 2392: (set (subreg:SI (match_dup 0) 0) ! 2393: (ashift:SI (subreg:SI (match_dup 1) 0) ! 2394: (match_dup 2)))] ! 2395: " ! 2396: { ! 2397: int amount = INTVAL (operands[2]); ! 2398: operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31)); ! 2399: operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31)); ! 2400: }") ! 2401: ! 2402: ! 2403: (define_split ! 2404: [(set (match_operand:DI 0 "register_operand" "") ! 2405: (ashift:DI (match_operand:DI 1 "register_operand" "") ! 2406: (match_operand:SI 2 "small_int" ""))) ! 2407: (clobber (match_operand:SI 3 "register_operand" ""))] ! 2408: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 2409: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER ! 2410: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER ! 2411: && (INTVAL (operands[2]) & 63) < 32 ! 2412: && (INTVAL (operands[2]) & 63) != 0" ! 2413: ! 2414: [(set (subreg:SI (match_dup 0) 0) ! 2415: (ashift:SI (subreg:SI (match_dup 1) 0) ! 2416: (match_dup 2))) ! 2417: ! 2418: (set (match_dup 3) ! 2419: (lshiftrt:SI (subreg:SI (match_dup 1) 1) ! 2420: (match_dup 4))) ! 2421: ! 2422: (set (subreg:SI (match_dup 0) 0) ! 2423: (ior:SI (subreg:SI (match_dup 0) 0) ! 2424: (match_dup 3))) ! 2425: ! 2426: (set (subreg:SI (match_dup 0) 1) ! 2427: (ashift:SI (subreg:SI (match_dup 1) 1) ! 2428: (match_dup 2)))] ! 2429: " ! 2430: { ! 2431: int amount = INTVAL (operands[2]); ! 2432: operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31)); ! 2433: operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31)); ! 2434: }") ! 2435: ! 2436: ! 2437: (define_insn "ashrsi3" ! 2438: [(set (match_operand:SI 0 "register_operand" "=d") ! 2439: (ashiftrt:SI (match_operand:SI 1 "register_operand" "d") ! 2440: (match_operand:SI 2 "arith_operand" "dI")))] ! 2441: "" ! 2442: "* ! 2443: { ! 2444: if (GET_CODE (operands[2]) == CONST_INT) ! 2445: operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f); ! 2446: ! 2447: return \"sra\\t%0,%1,%2\"; ! 2448: }" ! 2449: [(set_attr "type" "arith") ! 2450: (set_attr "mode" "SI") ! 2451: (set_attr "length" "1")]) ! 2452: ! 2453: ! 2454: (define_expand "ashrdi3" ! 2455: [(parallel [(set (match_operand:DI 0 "register_operand" "") ! 2456: (ashiftrt:DI (match_operand:DI 1 "register_operand" "") ! 2457: (match_operand:SI 2 "arith_operand" ""))) ! 2458: (clobber (match_dup 3))])] ! 2459: "!TARGET_DEBUG_G_MODE" ! 2460: "operands[3] = gen_reg_rtx (SImode);") ! 2461: ! 2462: ! 2463: (define_insn "ashrdi3_internal" ! 2464: [(set (match_operand:DI 0 "register_operand" "=&d") ! 2465: (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") ! 2466: (match_operand:SI 2 "register_operand" "d"))) ! 2467: (clobber (match_operand:SI 3 "register_operand" "=d"))] ! 2468: "!TARGET_DEBUG_G_MODE" ! 2469: "* ! 2470: { ! 2471: operands[4] = const0_rtx; ! 2472: dslots_jump_total += 3; ! 2473: dslots_jump_filled += 2; ! 2474: ! 2475: return \"sll\\t%3,%2,26\\n\\ ! 2476: \\tbgez\\t%3,1f\\n\\ ! 2477: \\tsra\\t%L0,%M1,%2\\n\\ ! 2478: \\t%(b\\t3f\\n\\ ! 2479: \\tsra\\t%M0,%M1,31%)\\n\\ ! 2480: \\n\\ ! 2481: 1:\\n\\ ! 2482: \\t%(beq\\t%3,%z4,2f\\n\\ ! 2483: \\tsrl\\t%L0,%L1,%2%)\\n\\ ! 2484: \\n\\ ! 2485: \\tsubu\\t%3,%z4,%2\\n\\ ! 2486: \\tsll\\t%3,%M1,%3\\n\\ ! 2487: \\tor\\t%L0,%L0,%3\\n\\ ! 2488: 2:\\n\\ ! 2489: \\tsra\\t%M0,%M1,%2\\n\\ ! 2490: 3:\"; ! 2491: }" ! 2492: [(set_attr "type" "darith") ! 2493: (set_attr "mode" "DI") ! 2494: (set_attr "length" "12")]) ! 2495: ! 2496: ! 2497: (define_insn "ashrdi3_internal2" ! 2498: [(set (match_operand:DI 0 "register_operand" "=d") ! 2499: (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") ! 2500: (match_operand:SI 2 "small_int" "IJK"))) ! 2501: (clobber (match_operand:SI 3 "register_operand" "=d"))] ! 2502: "!TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0" ! 2503: "* ! 2504: { ! 2505: operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f); ! 2506: return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\"; ! 2507: }" ! 2508: [(set_attr "type" "darith") ! 2509: (set_attr "mode" "DI") ! 2510: (set_attr "length" "2")]) ! 2511: ! 2512: ! 2513: (define_split ! 2514: [(set (match_operand:DI 0 "register_operand" "") ! 2515: (ashiftrt:DI (match_operand:DI 1 "register_operand" "") ! 2516: (match_operand:SI 2 "small_int" ""))) ! 2517: (clobber (match_operand:SI 3 "register_operand" ""))] ! 2518: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 2519: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER ! 2520: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER ! 2521: && (INTVAL (operands[2]) & 32) != 0" ! 2522: ! 2523: [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2))) ! 2524: (set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (const_int 31)))] ! 2525: ! 2526: "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);") ! 2527: ! 2528: ! 2529: (define_split ! 2530: [(set (match_operand:DI 0 "register_operand" "") ! 2531: (ashiftrt:DI (match_operand:DI 1 "register_operand" "") ! 2532: (match_operand:SI 2 "small_int" ""))) ! 2533: (clobber (match_operand:SI 3 "register_operand" ""))] ! 2534: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 2535: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER ! 2536: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER ! 2537: && (INTVAL (operands[2]) & 32) != 0" ! 2538: ! 2539: [(set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2))) ! 2540: (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))] ! 2541: ! 2542: "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);") ! 2543: ! 2544: ! 2545: (define_insn "ashrdi3_internal3" ! 2546: [(set (match_operand:DI 0 "register_operand" "=d") ! 2547: (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") ! 2548: (match_operand:SI 2 "small_int" "IJK"))) ! 2549: (clobber (match_operand:SI 3 "register_operand" "=d"))] ! 2550: "!TARGET_DEBUG_G_MODE ! 2551: && (INTVAL (operands[2]) & 63) < 32 ! 2552: && (INTVAL (operands[2]) & 63) != 0" ! 2553: "* ! 2554: { ! 2555: int amount = INTVAL (operands[2]); ! 2556: ! 2557: operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31)); ! 2558: operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31)); ! 2559: ! 2560: return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\"; ! 2561: }" ! 2562: [(set_attr "type" "darith") ! 2563: (set_attr "mode" "DI") ! 2564: (set_attr "length" "4")]) ! 2565: ! 2566: ! 2567: (define_split ! 2568: [(set (match_operand:DI 0 "register_operand" "") ! 2569: (ashiftrt:DI (match_operand:DI 1 "register_operand" "") ! 2570: (match_operand:SI 2 "small_int" ""))) ! 2571: (clobber (match_operand:SI 3 "register_operand" ""))] ! 2572: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 2573: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER ! 2574: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER ! 2575: && (INTVAL (operands[2]) & 63) < 32 ! 2576: && (INTVAL (operands[2]) & 63) != 0" ! 2577: ! 2578: [(set (subreg:SI (match_dup 0) 0) ! 2579: (lshiftrt:SI (subreg:SI (match_dup 1) 0) ! 2580: (match_dup 2))) ! 2581: ! 2582: (set (match_dup 3) ! 2583: (ashift:SI (subreg:SI (match_dup 1) 1) ! 2584: (match_dup 4))) ! 2585: ! 2586: (set (subreg:SI (match_dup 0) 0) ! 2587: (ior:SI (subreg:SI (match_dup 0) 0) ! 2588: (match_dup 3))) ! 2589: ! 2590: (set (subreg:SI (match_dup 0) 1) ! 2591: (ashiftrt:SI (subreg:SI (match_dup 1) 1) ! 2592: (match_dup 2)))] ! 2593: " ! 2594: { ! 2595: int amount = INTVAL (operands[2]); ! 2596: operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31)); ! 2597: operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31)); ! 2598: }") ! 2599: ! 2600: ! 2601: (define_split ! 2602: [(set (match_operand:DI 0 "register_operand" "") ! 2603: (ashiftrt:DI (match_operand:DI 1 "register_operand" "") ! 2604: (match_operand:SI 2 "small_int" ""))) ! 2605: (clobber (match_operand:SI 3 "register_operand" ""))] ! 2606: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 2607: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER ! 2608: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER ! 2609: && (INTVAL (operands[2]) & 63) < 32 ! 2610: && (INTVAL (operands[2]) & 63) != 0" ! 2611: ! 2612: [(set (subreg:SI (match_dup 0) 1) ! 2613: (lshiftrt:SI (subreg:SI (match_dup 1) 1) ! 2614: (match_dup 2))) ! 2615: ! 2616: (set (match_dup 3) ! 2617: (ashift:SI (subreg:SI (match_dup 1) 0) ! 2618: (match_dup 4))) ! 2619: ! 2620: (set (subreg:SI (match_dup 0) 1) ! 2621: (ior:SI (subreg:SI (match_dup 0) 1) ! 2622: (match_dup 3))) ! 2623: ! 2624: (set (subreg:SI (match_dup 0) 0) ! 2625: (ashiftrt:SI (subreg:SI (match_dup 1) 0) ! 2626: (match_dup 2)))] ! 2627: " ! 2628: { ! 2629: int amount = INTVAL (operands[2]); ! 2630: operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31)); ! 2631: operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31)); ! 2632: }") ! 2633: ! 2634: ! 2635: (define_insn "lshrsi3" ! 2636: [(set (match_operand:SI 0 "register_operand" "=d") ! 2637: (lshiftrt:SI (match_operand:SI 1 "register_operand" "d") ! 2638: (match_operand:SI 2 "arith_operand" "dI")))] ! 2639: "" ! 2640: "* ! 2641: { ! 2642: if (GET_CODE (operands[2]) == CONST_INT) ! 2643: operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f); ! 2644: ! 2645: return \"srl\\t%0,%1,%2\"; ! 2646: }" ! 2647: [(set_attr "type" "arith") ! 2648: (set_attr "mode" "SI") ! 2649: (set_attr "length" "1")]) ! 2650: ! 2651: ! 2652: (define_expand "lshrdi3" ! 2653: [(parallel [(set (match_operand:DI 0 "register_operand" "") ! 2654: (lshiftrt:DI (match_operand:DI 1 "register_operand" "") ! 2655: (match_operand:SI 2 "arith_operand" ""))) ! 2656: (clobber (match_dup 3))])] ! 2657: "!TARGET_DEBUG_G_MODE" ! 2658: "operands[3] = gen_reg_rtx (SImode);") ! 2659: ! 2660: ! 2661: (define_insn "lshrdi3_internal" ! 2662: [(set (match_operand:DI 0 "register_operand" "=&d") ! 2663: (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") ! 2664: (match_operand:SI 2 "register_operand" "d"))) ! 2665: (clobber (match_operand:SI 3 "register_operand" "=d"))] ! 2666: "!TARGET_DEBUG_G_MODE" ! 2667: "* ! 2668: { ! 2669: operands[4] = const0_rtx; ! 2670: dslots_jump_total += 3; ! 2671: dslots_jump_filled += 2; ! 2672: ! 2673: return \"sll\\t%3,%2,26\\n\\ ! 2674: \\tbgez\\t%3,1f\\n\\ ! 2675: \\tsrl\\t%L0,%M1,%2\\n\\ ! 2676: \\t%(b\\t3f\\n\\ ! 2677: \\tmove\\t%M0,%z4%)\\n\\ ! 2678: \\n\\ ! 2679: 1:\\n\\ ! 2680: \\t%(beq\\t%3,%z4,2f\\n\\ ! 2681: \\tsrl\\t%L0,%L1,%2%)\\n\\ ! 2682: \\n\\ ! 2683: \\tsubu\\t%3,%z4,%2\\n\\ ! 2684: \\tsll\\t%3,%M1,%3\\n\\ ! 2685: \\tor\\t%L0,%L0,%3\\n\\ ! 2686: 2:\\n\\ ! 2687: \\tsrl\\t%M0,%M1,%2\\n\\ ! 2688: 3:\"; ! 2689: }" ! 2690: [(set_attr "type" "darith") ! 2691: (set_attr "mode" "DI") ! 2692: (set_attr "length" "12")]) ! 2693: ! 2694: ! 2695: (define_insn "lshrdi3_internal2" ! 2696: [(set (match_operand:DI 0 "register_operand" "=d") ! 2697: (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") ! 2698: (match_operand:SI 2 "small_int" "IJK"))) ! 2699: (clobber (match_operand:SI 3 "register_operand" "=d"))] ! 2700: "!TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0" ! 2701: "* ! 2702: { ! 2703: operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f); ! 2704: operands[4] = const0_rtx; ! 2705: return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\"; ! 2706: }" ! 2707: [(set_attr "type" "darith") ! 2708: (set_attr "mode" "DI") ! 2709: (set_attr "length" "2")]) ! 2710: ! 2711: ! 2712: (define_split ! 2713: [(set (match_operand:DI 0 "register_operand" "") ! 2714: (lshiftrt:DI (match_operand:DI 1 "register_operand" "") ! 2715: (match_operand:SI 2 "small_int" ""))) ! 2716: (clobber (match_operand:SI 3 "register_operand" ""))] ! 2717: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 2718: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER ! 2719: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER ! 2720: && (INTVAL (operands[2]) & 32) != 0" ! 2721: ! 2722: [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2))) ! 2723: (set (subreg:SI (match_dup 0) 1) (const_int 0))] ! 2724: ! 2725: "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);") ! 2726: ! 2727: ! 2728: (define_split ! 2729: [(set (match_operand:DI 0 "register_operand" "") ! 2730: (lshiftrt:DI (match_operand:DI 1 "register_operand" "") ! 2731: (match_operand:SI 2 "small_int" ""))) ! 2732: (clobber (match_operand:SI 3 "register_operand" ""))] ! 2733: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 2734: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER ! 2735: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER ! 2736: && (INTVAL (operands[2]) & 32) != 0" ! 2737: ! 2738: [(set (subreg:SI (match_dup 0) 1) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2))) ! 2739: (set (subreg:SI (match_dup 0) 0) (const_int 0))] ! 2740: ! 2741: "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);") ! 2742: ! 2743: ! 2744: (define_insn "lshrdi3_internal3" ! 2745: [(set (match_operand:DI 0 "register_operand" "=d") ! 2746: (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") ! 2747: (match_operand:SI 2 "small_int" "IJK"))) ! 2748: (clobber (match_operand:SI 3 "register_operand" "=d"))] ! 2749: "!TARGET_DEBUG_G_MODE ! 2750: && (INTVAL (operands[2]) & 63) < 32 ! 2751: && (INTVAL (operands[2]) & 63) != 0" ! 2752: "* ! 2753: { ! 2754: int amount = INTVAL (operands[2]); ! 2755: ! 2756: operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31)); ! 2757: operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31)); ! 2758: ! 2759: return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\"; ! 2760: }" ! 2761: [(set_attr "type" "darith") ! 2762: (set_attr "mode" "DI") ! 2763: (set_attr "length" "4")]) ! 2764: ! 2765: ! 2766: (define_split ! 2767: [(set (match_operand:DI 0 "register_operand" "") ! 2768: (lshiftrt:DI (match_operand:DI 1 "register_operand" "") ! 2769: (match_operand:SI 2 "small_int" ""))) ! 2770: (clobber (match_operand:SI 3 "register_operand" ""))] ! 2771: "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 2772: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER ! 2773: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER ! 2774: && (INTVAL (operands[2]) & 63) < 32 ! 2775: && (INTVAL (operands[2]) & 63) != 0" ! 2776: ! 2777: [(set (subreg:SI (match_dup 0) 0) ! 2778: (lshiftrt:SI (subreg:SI (match_dup 1) 0) ! 2779: (match_dup 2))) ! 2780: ! 2781: (set (match_dup 3) ! 2782: (ashift:SI (subreg:SI (match_dup 1) 1) ! 2783: (match_dup 4))) ! 2784: ! 2785: (set (subreg:SI (match_dup 0) 0) ! 2786: (ior:SI (subreg:SI (match_dup 0) 0) ! 2787: (match_dup 3))) ! 2788: ! 2789: (set (subreg:SI (match_dup 0) 1) ! 2790: (lshiftrt:SI (subreg:SI (match_dup 1) 1) ! 2791: (match_dup 2)))] ! 2792: " ! 2793: { ! 2794: int amount = INTVAL (operands[2]); ! 2795: operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31)); ! 2796: operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31)); ! 2797: }") ! 2798: ! 2799: ! 2800: (define_split ! 2801: [(set (match_operand:DI 0 "register_operand" "") ! 2802: (lshiftrt:DI (match_operand:DI 1 "register_operand" "") ! 2803: (match_operand:SI 2 "small_int" ""))) ! 2804: (clobber (match_operand:SI 3 "register_operand" ""))] ! 2805: "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE ! 2806: && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER ! 2807: && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER ! 2808: && (INTVAL (operands[2]) & 63) < 32 ! 2809: && (INTVAL (operands[2]) & 63) != 0" ! 2810: ! 2811: [(set (subreg:SI (match_dup 0) 1) ! 2812: (lshiftrt:SI (subreg:SI (match_dup 1) 1) ! 2813: (match_dup 2))) ! 2814: ! 2815: (set (match_dup 3) ! 2816: (ashift:SI (subreg:SI (match_dup 1) 0) ! 2817: (match_dup 4))) ! 2818: ! 2819: (set (subreg:SI (match_dup 0) 1) ! 2820: (ior:SI (subreg:SI (match_dup 0) 1) ! 2821: (match_dup 3))) ! 2822: ! 2823: (set (subreg:SI (match_dup 0) 0) ! 2824: (lshiftrt:SI (subreg:SI (match_dup 1) 0) ! 2825: (match_dup 2)))] ! 2826: " ! 2827: { ! 2828: int amount = INTVAL (operands[2]); ! 2829: operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31)); ! 2830: operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31)); ! 2831: }") ! 2832: ! 2833: ! 2834: ;; ! 2835: ;; .................... ! 2836: ;; ! 2837: ;; COMPARISONS ! 2838: ;; ! 2839: ;; .................... ! 2840: ! 2841: ;; Flow here is rather complex: ! 2842: ;; ! 2843: ;; 1) The cmp{si,sf,df} routine is called. It deposits the ! 2844: ;; arguments into the branch_cmp array, and the type into ! 2845: ;; branch_type. No RTL is generated. ! 2846: ;; ! 2847: ;; 2) The appropriate branch define_expand is called, which then ! 2848: ;; creates the appropriate RTL for the comparison and branch. ! 2849: ;; Different CC modes are used, based on what type of branch is ! 2850: ;; done, so that we can constrain things appropriately. There ! 2851: ;; are assumptions in the rest of GCC that break if we fold the ! 2852: ;; operands into the branchs for integer operations, and use cc0 ! 2853: ;; for floating point, so we use the fp status register instead. ! 2854: ;; If needed, an appropriate temporary is created to hold the ! 2855: ;; of the integer compare. ! 2856: ! 2857: (define_expand "cmpsi" ! 2858: [(set (cc0) ! 2859: (compare:CC (match_operand:SI 0 "register_operand" "") ! 2860: (match_operand:SI 1 "arith_operand" "")))] ! 2861: "" ! 2862: " ! 2863: { ! 2864: if (operands[0]) /* avoid unused code message */ ! 2865: { ! 2866: branch_cmp[0] = operands[0]; ! 2867: branch_cmp[1] = operands[1]; ! 2868: branch_type = CMP_SI; ! 2869: DONE; ! 2870: } ! 2871: }") ! 2872: ! 2873: (define_expand "tstsi" ! 2874: [(set (cc0) ! 2875: (match_operand:SI 0 "register_operand" ""))] ! 2876: "" ! 2877: " ! 2878: { ! 2879: if (operands[0]) /* avoid unused code message */ ! 2880: { ! 2881: branch_cmp[0] = operands[0]; ! 2882: branch_cmp[1] = const0_rtx; ! 2883: branch_type = CMP_SI; ! 2884: DONE; ! 2885: } ! 2886: }") ! 2887: ! 2888: (define_expand "cmpdf" ! 2889: [(set (cc0) ! 2890: (compare:CC_FP (match_operand:DF 0 "register_operand" "") ! 2891: (match_operand:DF 1 "register_operand" "")))] ! 2892: "TARGET_HARD_FLOAT" ! 2893: " ! 2894: { ! 2895: if (operands[0]) /* avoid unused code message */ ! 2896: { ! 2897: branch_cmp[0] = operands[0]; ! 2898: branch_cmp[1] = operands[1]; ! 2899: branch_type = CMP_DF; ! 2900: DONE; ! 2901: } ! 2902: }") ! 2903: ! 2904: (define_expand "cmpsf" ! 2905: [(set (cc0) ! 2906: (compare:CC_FP (match_operand:SF 0 "register_operand" "") ! 2907: (match_operand:SF 1 "register_operand" "")))] ! 2908: "TARGET_HARD_FLOAT" ! 2909: " ! 2910: { ! 2911: if (operands[0]) /* avoid unused code message */ ! 2912: { ! 2913: branch_cmp[0] = operands[0]; ! 2914: branch_cmp[1] = operands[1]; ! 2915: branch_type = CMP_SF; ! 2916: DONE; ! 2917: } ! 2918: }") ! 2919: ! 2920: ! 2921: ;; ! 2922: ;; .................... ! 2923: ;; ! 2924: ;; CONDITIONAL BRANCHES ! 2925: ;; ! 2926: ;; .................... ! 2927: ! 2928: (define_insn "branch_fp_ne" ! 2929: [(set (pc) ! 2930: (if_then_else (ne:CC_FP (reg:CC_FP 66) ! 2931: (const_int 0)) ! 2932: (match_operand 0 "pc_or_label_operand" "") ! 2933: (match_operand 1 "pc_or_label_operand" "")))] ! 2934: "" ! 2935: "* ! 2936: { ! 2937: mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn)); ! 2938: return (operands[0] != pc_rtx) ? \"%*bc1t%?\\t%0\" : \"%*bc1f%?\\t%1\"; ! 2939: }" ! 2940: [(set_attr "type" "branch") ! 2941: (set_attr "mode" "none") ! 2942: (set_attr "length" "1")]) ! 2943: ! 2944: (define_insn "branch_fp_ne_rev" ! 2945: [(set (pc) ! 2946: (if_then_else (ne:CC_REV_FP (reg:CC_REV_FP 66) ! 2947: (const_int 0)) ! 2948: (match_operand 0 "pc_or_label_operand" "") ! 2949: (match_operand 1 "pc_or_label_operand" "")))] ! 2950: "" ! 2951: "* ! 2952: { ! 2953: mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn)); ! 2954: return (operands[0] != pc_rtx) ? \"%*bc1f%?\\t%0\" : \"%*bc1t%?\\t%1\"; ! 2955: }" ! 2956: [(set_attr "type" "branch") ! 2957: (set_attr "mode" "none") ! 2958: (set_attr "length" "1")]) ! 2959: ! 2960: (define_insn "branch_fp_eq" ! 2961: [(set (pc) ! 2962: (if_then_else (eq:CC_FP (reg:CC_FP 66) ! 2963: (const_int 0)) ! 2964: (match_operand 0 "pc_or_label_operand" "") ! 2965: (match_operand 1 "pc_or_label_operand" "")))] ! 2966: "" ! 2967: "* ! 2968: { ! 2969: mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn)); ! 2970: return (operands[0] != pc_rtx) ? \"%*bc1f%?\\t%0\" : \"%*bc1t%?\\t%1\"; ! 2971: }" ! 2972: [(set_attr "type" "branch") ! 2973: (set_attr "mode" "none") ! 2974: (set_attr "length" "1")]) ! 2975: ! 2976: (define_insn "branch_fp_eq_rev" ! 2977: [(set (pc) ! 2978: (if_then_else (eq:CC_REV_FP (reg:CC_REV_FP 66) ! 2979: (const_int 0)) ! 2980: (match_operand 0 "pc_or_label_operand" "") ! 2981: (match_operand 1 "pc_or_label_operand" "")))] ! 2982: "" ! 2983: "* ! 2984: { ! 2985: mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn)); ! 2986: return (operands[0] != pc_rtx) ? \"%*bc1t%?\\t%0\" : \"%*bc1f%?\\t%1\"; ! 2987: }" ! 2988: [(set_attr "type" "branch") ! 2989: (set_attr "mode" "none") ! 2990: (set_attr "length" "1")]) ! 2991: ! 2992: ! 2993: (define_insn "branch_zero" ! 2994: [(set (pc) ! 2995: (if_then_else (match_operator:SI 0 "cmp_op" ! 2996: [(match_operand:SI 1 "register_operand" "d") ! 2997: (const_int 0)]) ! 2998: (match_operand 2 "pc_or_label_operand" "") ! 2999: (match_operand 3 "pc_or_label_operand" "")))] ! 3000: "" ! 3001: "* ! 3002: { ! 3003: mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn)); ! 3004: if (operands[2] != pc_rtx) ! 3005: { /* normal jump */ ! 3006: switch (GET_CODE (operands[0])) ! 3007: { ! 3008: case EQ: return \"%*beq%?\\t%z1,%.,%2\"; ! 3009: case NE: return \"%*bne%?\\t%z1,%.,%2\"; ! 3010: case GTU: return \"%*bne%?\\t%z1,%.,%2\"; ! 3011: case LEU: return \"%*beq%?\\t%z1,%.,%2\"; ! 3012: case GEU: return \"%*j\\t%2\"; ! 3013: case LTU: return \"%*bne%?\\t%.,%.,%2\"; ! 3014: } ! 3015: ! 3016: return \"%*b%C0z%?\\t%z1,%2\"; ! 3017: } ! 3018: else ! 3019: { /* inverted jump */ ! 3020: switch (GET_CODE (operands[0])) ! 3021: { ! 3022: case EQ: return \"%*bne%?\\t%z1,%.,%3\"; ! 3023: case NE: return \"%*beq%?\\t%z1,%.,%3\"; ! 3024: case GTU: return \"%*beq%?\\t%z1,%.,%3\"; ! 3025: case LEU: return \"%*bne%?\\t%z1,%.,%3\"; ! 3026: case GEU: return \"%*beq%?\\t%.,%.,%3\"; ! 3027: case LTU: return \"%*j\\t%3\"; ! 3028: } ! 3029: ! 3030: return \"%*b%N0z%?\\t%z1,%3\"; ! 3031: } ! 3032: }" ! 3033: [(set_attr "type" "branch") ! 3034: (set_attr "mode" "none") ! 3035: (set_attr "length" "1")]) ! 3036: ! 3037: ! 3038: (define_insn "branch_equality" ! 3039: [(set (pc) ! 3040: (if_then_else (match_operator:SI 0 "equality_op" ! 3041: [(match_operand:SI 1 "register_operand" "d") ! 3042: (match_operand:SI 2 "register_operand" "d")]) ! 3043: (match_operand 3 "pc_or_label_operand" "") ! 3044: (match_operand 4 "pc_or_label_operand" "")))] ! 3045: "" ! 3046: "* ! 3047: { ! 3048: mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn)); ! 3049: return (operands[3] != pc_rtx) ! 3050: ? \"%*b%C0%?\\t%z1,%z2,%3\" ! 3051: : \"%*b%N0%?\\t%z1,%z2,%4\"; ! 3052: }" ! 3053: [(set_attr "type" "branch") ! 3054: (set_attr "mode" "none") ! 3055: (set_attr "length" "1")]) ! 3056: ! 3057: ! 3058: (define_expand "beq" ! 3059: [(set (pc) ! 3060: (if_then_else (eq:CC_EQ (cc0) ! 3061: (const_int 0)) ! 3062: (label_ref (match_operand 0 "" "")) ! 3063: (pc)))] ! 3064: "" ! 3065: " ! 3066: { ! 3067: if (operands[0]) /* avoid unused code warning */ ! 3068: { ! 3069: gen_conditional_branch (operands, EQ); ! 3070: DONE; ! 3071: } ! 3072: }") ! 3073: ! 3074: (define_expand "bne" ! 3075: [(set (pc) ! 3076: (if_then_else (ne:CC_EQ (cc0) ! 3077: (const_int 0)) ! 3078: (label_ref (match_operand 0 "" "")) ! 3079: (pc)))] ! 3080: "" ! 3081: " ! 3082: { ! 3083: if (operands[0]) /* avoid unused code warning */ ! 3084: { ! 3085: gen_conditional_branch (operands, NE); ! 3086: DONE; ! 3087: } ! 3088: }") ! 3089: ! 3090: (define_expand "bgt" ! 3091: [(set (pc) ! 3092: (if_then_else (gt:CC (cc0) ! 3093: (const_int 0)) ! 3094: (label_ref (match_operand 0 "" "")) ! 3095: (pc)))] ! 3096: "" ! 3097: " ! 3098: { ! 3099: if (operands[0]) /* avoid unused code warning */ ! 3100: { ! 3101: gen_conditional_branch (operands, GT); ! 3102: DONE; ! 3103: } ! 3104: }") ! 3105: ! 3106: (define_expand "bge" ! 3107: [(set (pc) ! 3108: (if_then_else (ge:CC (cc0) ! 3109: (const_int 0)) ! 3110: (label_ref (match_operand 0 "" "")) ! 3111: (pc)))] ! 3112: "" ! 3113: " ! 3114: { ! 3115: if (operands[0]) /* avoid unused code warning */ ! 3116: { ! 3117: gen_conditional_branch (operands, GE); ! 3118: DONE; ! 3119: } ! 3120: }") ! 3121: ! 3122: (define_expand "blt" ! 3123: [(set (pc) ! 3124: (if_then_else (lt:CC (cc0) ! 3125: (const_int 0)) ! 3126: (label_ref (match_operand 0 "" "")) ! 3127: (pc)))] ! 3128: "" ! 3129: " ! 3130: { ! 3131: if (operands[0]) /* avoid unused code warning */ ! 3132: { ! 3133: gen_conditional_branch (operands, LT); ! 3134: DONE; ! 3135: } ! 3136: }") ! 3137: ! 3138: (define_expand "ble" ! 3139: [(set (pc) ! 3140: (if_then_else (le:CC (cc0) ! 3141: (const_int 0)) ! 3142: (label_ref (match_operand 0 "" "")) ! 3143: (pc)))] ! 3144: "" ! 3145: " ! 3146: { ! 3147: if (operands[0]) /* avoid unused code warning */ ! 3148: { ! 3149: gen_conditional_branch (operands, LE); ! 3150: DONE; ! 3151: } ! 3152: }") ! 3153: ! 3154: (define_expand "bgtu" ! 3155: [(set (pc) ! 3156: (if_then_else (gtu:CC (cc0) ! 3157: (const_int 0)) ! 3158: (label_ref (match_operand 0 "" "")) ! 3159: (pc)))] ! 3160: "" ! 3161: " ! 3162: { ! 3163: if (operands[0]) /* avoid unused code warning */ ! 3164: { ! 3165: gen_conditional_branch (operands, GTU); ! 3166: DONE; ! 3167: } ! 3168: }") ! 3169: ! 3170: (define_expand "bgeu" ! 3171: [(set (pc) ! 3172: (if_then_else (geu:CC (cc0) ! 3173: (const_int 0)) ! 3174: (label_ref (match_operand 0 "" "")) ! 3175: (pc)))] ! 3176: "" ! 3177: " ! 3178: { ! 3179: if (operands[0]) /* avoid unused code warning */ ! 3180: { ! 3181: gen_conditional_branch (operands, GEU); ! 3182: DONE; ! 3183: } ! 3184: }") ! 3185: ! 3186: ! 3187: (define_expand "bltu" ! 3188: [(set (pc) ! 3189: (if_then_else (ltu:CC (cc0) ! 3190: (const_int 0)) ! 3191: (label_ref (match_operand 0 "" "")) ! 3192: (pc)))] ! 3193: "" ! 3194: " ! 3195: { ! 3196: if (operands[0]) /* avoid unused code warning */ ! 3197: { ! 3198: gen_conditional_branch (operands, LTU); ! 3199: DONE; ! 3200: } ! 3201: }") ! 3202: ! 3203: (define_expand "bleu" ! 3204: [(set (pc) ! 3205: (if_then_else (leu:CC (cc0) ! 3206: (const_int 0)) ! 3207: (label_ref (match_operand 0 "" "")) ! 3208: (pc)))] ! 3209: "" ! 3210: " ! 3211: { ! 3212: if (operands[0]) /* avoid unused code warning */ ! 3213: { ! 3214: gen_conditional_branch (operands, LEU); ! 3215: DONE; ! 3216: } ! 3217: }") ! 3218: ! 3219: ! 3220: ;; ! 3221: ;; .................... ! 3222: ;; ! 3223: ;; SETTING A REGISTER FROM A COMPARISON ! 3224: ;; ! 3225: ;; .................... ! 3226: ! 3227: (define_expand "seq" ! 3228: [(set (match_operand:SI 0 "register_operand" "=d") ! 3229: (eq:SI (match_dup 1) ! 3230: (match_dup 2)))] ! 3231: "" ! 3232: " ! 3233: { ! 3234: if (branch_type != CMP_SI) ! 3235: FAIL; ! 3236: ! 3237: /* set up operands from compare. */ ! 3238: operands[1] = branch_cmp[0]; ! 3239: operands[2] = branch_cmp[1]; ! 3240: ! 3241: if (!TARGET_DEBUG_C_MODE) ! 3242: { ! 3243: gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0); ! 3244: DONE; ! 3245: } ! 3246: ! 3247: if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) ! 3248: operands[2] = force_reg (SImode, operands[2]); ! 3249: ! 3250: /* fall through and generate default code */ ! 3251: }") ! 3252: ! 3253: ! 3254: (define_insn "seq_si_zero" ! 3255: [(set (match_operand:SI 0 "register_operand" "=d") ! 3256: (eq:SI (match_operand:SI 1 "register_operand" "d") ! 3257: (const_int 0)))] ! 3258: "" ! 3259: "sltu\\t%0,%1,1" ! 3260: [(set_attr "type" "arith") ! 3261: (set_attr "mode" "SI") ! 3262: (set_attr "length" "1")]) ! 3263: ! 3264: (define_insn "seq_si" ! 3265: [(set (match_operand:SI 0 "register_operand" "=d,d") ! 3266: (eq:SI (match_operand:SI 1 "register_operand" "%d,d") ! 3267: (match_operand:SI 2 "uns_arith_operand" "d,K")))] ! 3268: "TARGET_DEBUG_C_MODE" ! 3269: "@ ! 3270: xor\\t%0,%1,%2\;sltu\\t%0,%0,1 ! 3271: xori\\t%0,%1,%2\;sltu\\t%0,%0,1" ! 3272: [(set_attr "type" "arith") ! 3273: (set_attr "mode" "SI") ! 3274: (set_attr "length" "2")]) ! 3275: ! 3276: (define_split ! 3277: [(set (match_operand:SI 0 "register_operand" "") ! 3278: (eq:SI (match_operand:SI 1 "register_operand" "") ! 3279: (match_operand:SI 2 "uns_arith_operand" "")))] ! 3280: "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE ! 3281: && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)" ! 3282: [(set (match_dup 0) ! 3283: (xor:SI (match_dup 1) ! 3284: (match_dup 2))) ! 3285: (set (match_dup 0) ! 3286: (ltu:SI (match_dup 0) ! 3287: (const_int 1)))] ! 3288: "") ! 3289: ! 3290: (define_expand "sne" ! 3291: [(set (match_operand:SI 0 "register_operand" "=d") ! 3292: (ne:SI (match_dup 1) ! 3293: (match_dup 2)))] ! 3294: "" ! 3295: " ! 3296: { ! 3297: if (branch_type != CMP_SI) ! 3298: FAIL; ! 3299: ! 3300: /* set up operands from compare. */ ! 3301: operands[1] = branch_cmp[0]; ! 3302: operands[2] = branch_cmp[1]; ! 3303: ! 3304: if (!TARGET_DEBUG_C_MODE) ! 3305: { ! 3306: gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0); ! 3307: DONE; ! 3308: } ! 3309: ! 3310: if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) ! 3311: operands[2] = force_reg (SImode, operands[2]); ! 3312: ! 3313: /* fall through and generate default code */ ! 3314: }") ! 3315: ! 3316: (define_insn "sne_si_zero" ! 3317: [(set (match_operand:SI 0 "register_operand" "=d") ! 3318: (ne:SI (match_operand:SI 1 "register_operand" "d") ! 3319: (const_int 0)))] ! 3320: "" ! 3321: "sltu\\t%0,%.,%1" ! 3322: [(set_attr "type" "arith") ! 3323: (set_attr "mode" "SI") ! 3324: (set_attr "length" "1")]) ! 3325: ! 3326: (define_insn "sne_si" ! 3327: [(set (match_operand:SI 0 "register_operand" "=d,d") ! 3328: (ne:SI (match_operand:SI 1 "register_operand" "%d,d") ! 3329: (match_operand:SI 2 "uns_arith_operand" "d,K")))] ! 3330: "TARGET_DEBUG_C_MODE" ! 3331: "@ ! 3332: xor\\t%0,%1,%2\;sltu\\t%0,%.,%0 ! 3333: xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0" ! 3334: [(set_attr "type" "arith") ! 3335: (set_attr "mode" "SI") ! 3336: (set_attr "length" "2")]) ! 3337: ! 3338: (define_split ! 3339: [(set (match_operand:SI 0 "register_operand" "") ! 3340: (ne:SI (match_operand:SI 1 "register_operand" "") ! 3341: (match_operand:SI 2 "uns_arith_operand" "")))] ! 3342: "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE ! 3343: && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)" ! 3344: [(set (match_dup 0) ! 3345: (xor:SI (match_dup 1) ! 3346: (match_dup 2))) ! 3347: (set (match_dup 0) ! 3348: (gtu:SI (match_dup 0) ! 3349: (const_int 0)))] ! 3350: "") ! 3351: ! 3352: (define_expand "sgt" ! 3353: [(set (match_operand:SI 0 "register_operand" "=d") ! 3354: (gt:SI (match_dup 1) ! 3355: (match_dup 2)))] ! 3356: "" ! 3357: " ! 3358: { ! 3359: if (branch_type != CMP_SI) ! 3360: FAIL; ! 3361: ! 3362: /* set up operands from compare. */ ! 3363: operands[1] = branch_cmp[0]; ! 3364: operands[2] = branch_cmp[1]; ! 3365: ! 3366: if (!TARGET_DEBUG_C_MODE) ! 3367: { ! 3368: gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0); ! 3369: DONE; ! 3370: } ! 3371: ! 3372: if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0) ! 3373: operands[2] = force_reg (SImode, operands[2]); ! 3374: ! 3375: /* fall through and generate default code */ ! 3376: }") ! 3377: ! 3378: (define_insn "sgt_si" ! 3379: [(set (match_operand:SI 0 "register_operand" "=d") ! 3380: (gt:SI (match_operand:SI 1 "register_operand" "d") ! 3381: (match_operand:SI 2 "reg_or_0_operand" "dJ")))] ! 3382: "" ! 3383: "slt\\t%0,%z2,%1" ! 3384: [(set_attr "type" "arith") ! 3385: (set_attr "mode" "SI") ! 3386: (set_attr "length" "1")]) ! 3387: ! 3388: (define_expand "sge" ! 3389: [(set (match_operand:SI 0 "register_operand" "=d") ! 3390: (ge:SI (match_dup 1) ! 3391: (match_dup 2)))] ! 3392: "" ! 3393: " ! 3394: { ! 3395: if (branch_type != CMP_SI) ! 3396: FAIL; ! 3397: ! 3398: /* set up operands from compare. */ ! 3399: operands[1] = branch_cmp[0]; ! 3400: operands[2] = branch_cmp[1]; ! 3401: ! 3402: if (!TARGET_DEBUG_C_MODE) ! 3403: { ! 3404: gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0); ! 3405: DONE; ! 3406: } ! 3407: ! 3408: /* fall through and generate default code */ ! 3409: }") ! 3410: ! 3411: (define_insn "sge_si" ! 3412: [(set (match_operand:SI 0 "register_operand" "=d") ! 3413: (ge:SI (match_operand:SI 1 "register_operand" "d") ! 3414: (match_operand:SI 2 "arith_operand" "dI")))] ! 3415: "TARGET_DEBUG_C_MODE" ! 3416: "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001" ! 3417: [(set_attr "type" "arith") ! 3418: (set_attr "mode" "SI") ! 3419: (set_attr "length" "2")]) ! 3420: ! 3421: (define_split ! 3422: [(set (match_operand:SI 0 "register_operand" "") ! 3423: (ge:SI (match_operand:SI 1 "register_operand" "") ! 3424: (match_operand:SI 2 "arith_operand" "")))] ! 3425: "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE" ! 3426: [(set (match_dup 0) ! 3427: (lt:SI (match_dup 1) ! 3428: (match_dup 2))) ! 3429: (set (match_dup 0) ! 3430: (xor:SI (match_dup 0) ! 3431: (const_int 1)))] ! 3432: "") ! 3433: ! 3434: (define_expand "slt" ! 3435: [(set (match_operand:SI 0 "register_operand" "=d") ! 3436: (lt:SI (match_dup 1) ! 3437: (match_dup 2)))] ! 3438: "" ! 3439: " ! 3440: { ! 3441: if (branch_type != CMP_SI) ! 3442: FAIL; ! 3443: ! 3444: /* set up operands from compare. */ ! 3445: operands[1] = branch_cmp[0]; ! 3446: operands[2] = branch_cmp[1]; ! 3447: ! 3448: if (!TARGET_DEBUG_C_MODE) ! 3449: { ! 3450: gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0); ! 3451: DONE; ! 3452: } ! 3453: ! 3454: /* fall through and generate default code */ ! 3455: }") ! 3456: ! 3457: (define_insn "slt_si" ! 3458: [(set (match_operand:SI 0 "register_operand" "=d") ! 3459: (lt:SI (match_operand:SI 1 "register_operand" "d") ! 3460: (match_operand:SI 2 "arith_operand" "dI")))] ! 3461: "" ! 3462: "slt\\t%0,%1,%2" ! 3463: [(set_attr "type" "arith") ! 3464: (set_attr "mode" "SI") ! 3465: (set_attr "length" "1")]) ! 3466: ! 3467: (define_expand "sle" ! 3468: [(set (match_operand:SI 0 "register_operand" "=d") ! 3469: (le:SI (match_dup 1) ! 3470: (match_dup 2)))] ! 3471: "" ! 3472: " ! 3473: { ! 3474: if (branch_type != CMP_SI) ! 3475: FAIL; ! 3476: ! 3477: /* set up operands from compare. */ ! 3478: operands[1] = branch_cmp[0]; ! 3479: operands[2] = branch_cmp[1]; ! 3480: ! 3481: if (!TARGET_DEBUG_C_MODE) ! 3482: { ! 3483: gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0); ! 3484: DONE; ! 3485: } ! 3486: ! 3487: if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767) ! 3488: operands[2] = force_reg (SImode, operands[2]); ! 3489: ! 3490: /* fall through and generate default code */ ! 3491: }") ! 3492: ! 3493: (define_insn "sle_si_const" ! 3494: [(set (match_operand:SI 0 "register_operand" "=d") ! 3495: (le:SI (match_operand:SI 1 "register_operand" "d") ! 3496: (match_operand:SI 2 "small_int" "I")))] ! 3497: "INTVAL (operands[2]) < 32767" ! 3498: "* ! 3499: { ! 3500: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1); ! 3501: return \"slt\\t%0,%1,%2\"; ! 3502: }" ! 3503: [(set_attr "type" "arith") ! 3504: (set_attr "mode" "SI") ! 3505: (set_attr "length" "1")]) ! 3506: ! 3507: (define_insn "sle_si_reg" ! 3508: [(set (match_operand:SI 0 "register_operand" "=d") ! 3509: (le:SI (match_operand:SI 1 "register_operand" "d") ! 3510: (match_operand:SI 2 "register_operand" "d")))] ! 3511: "TARGET_DEBUG_C_MODE" ! 3512: "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001" ! 3513: [(set_attr "type" "arith") ! 3514: (set_attr "mode" "SI") ! 3515: (set_attr "length" "2")]) ! 3516: ! 3517: (define_split ! 3518: [(set (match_operand:SI 0 "register_operand" "") ! 3519: (le:SI (match_operand:SI 1 "register_operand" "") ! 3520: (match_operand:SI 2 "register_operand" "")))] ! 3521: "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE" ! 3522: [(set (match_dup 0) ! 3523: (lt:SI (match_dup 2) ! 3524: (match_dup 1))) ! 3525: (set (match_dup 0) ! 3526: (xor:SI (match_dup 0) ! 3527: (const_int 1)))] ! 3528: "") ! 3529: ! 3530: (define_expand "sgtu" ! 3531: [(set (match_operand:SI 0 "register_operand" "=d") ! 3532: (gtu:SI (match_dup 1) ! 3533: (match_dup 2)))] ! 3534: "" ! 3535: " ! 3536: { ! 3537: if (branch_type != CMP_SI) ! 3538: FAIL; ! 3539: ! 3540: /* set up operands from compare. */ ! 3541: operands[1] = branch_cmp[0]; ! 3542: operands[2] = branch_cmp[1]; ! 3543: ! 3544: if (!TARGET_DEBUG_C_MODE) ! 3545: { ! 3546: gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0); ! 3547: DONE; ! 3548: } ! 3549: ! 3550: if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0) ! 3551: operands[2] = force_reg (SImode, operands[2]); ! 3552: ! 3553: /* fall through and generate default code */ ! 3554: }") ! 3555: ! 3556: (define_insn "sgtu_si" ! 3557: [(set (match_operand:SI 0 "register_operand" "=d") ! 3558: (gtu:SI (match_operand:SI 1 "register_operand" "d") ! 3559: (match_operand:SI 2 "reg_or_0_operand" "dJ")))] ! 3560: "" ! 3561: "sltu\\t%0,%z2,%1" ! 3562: [(set_attr "type" "arith") ! 3563: (set_attr "mode" "SI") ! 3564: (set_attr "length" "1")]) ! 3565: ! 3566: (define_expand "sgeu" ! 3567: [(set (match_operand:SI 0 "register_operand" "=d") ! 3568: (geu:SI (match_dup 1) ! 3569: (match_dup 2)))] ! 3570: "" ! 3571: " ! 3572: { ! 3573: if (branch_type != CMP_SI) ! 3574: FAIL; ! 3575: ! 3576: /* set up operands from compare. */ ! 3577: operands[1] = branch_cmp[0]; ! 3578: operands[2] = branch_cmp[1]; ! 3579: ! 3580: if (!TARGET_DEBUG_C_MODE) ! 3581: { ! 3582: gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0); ! 3583: DONE; ! 3584: } ! 3585: ! 3586: /* fall through and generate default code */ ! 3587: }") ! 3588: ! 3589: (define_insn "sgeu_si" ! 3590: [(set (match_operand:SI 0 "register_operand" "=d") ! 3591: (geu:SI (match_operand:SI 1 "register_operand" "d") ! 3592: (match_operand:SI 2 "arith_operand" "dI")))] ! 3593: "TARGET_DEBUG_C_MODE" ! 3594: "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001" ! 3595: [(set_attr "type" "arith") ! 3596: (set_attr "mode" "SI") ! 3597: (set_attr "length" "2")]) ! 3598: ! 3599: (define_split ! 3600: [(set (match_operand:SI 0 "register_operand" "") ! 3601: (geu:SI (match_operand:SI 1 "register_operand" "") ! 3602: (match_operand:SI 2 "arith_operand" "")))] ! 3603: "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE" ! 3604: [(set (match_dup 0) ! 3605: (ltu:SI (match_dup 1) ! 3606: (match_dup 2))) ! 3607: (set (match_dup 0) ! 3608: (xor:SI (match_dup 0) ! 3609: (const_int 1)))] ! 3610: "") ! 3611: ! 3612: (define_expand "sltu" ! 3613: [(set (match_operand:SI 0 "register_operand" "=d") ! 3614: (ltu:SI (match_dup 1) ! 3615: (match_dup 2)))] ! 3616: "" ! 3617: " ! 3618: { ! 3619: if (branch_type != CMP_SI) ! 3620: FAIL; ! 3621: ! 3622: /* set up operands from compare. */ ! 3623: operands[1] = branch_cmp[0]; ! 3624: operands[2] = branch_cmp[1]; ! 3625: ! 3626: if (!TARGET_DEBUG_C_MODE) ! 3627: { ! 3628: gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0); ! 3629: DONE; ! 3630: } ! 3631: ! 3632: /* fall through and generate default code */ ! 3633: }") ! 3634: ! 3635: (define_insn "sltu_si" ! 3636: [(set (match_operand:SI 0 "register_operand" "=d") ! 3637: (ltu:SI (match_operand:SI 1 "register_operand" "d") ! 3638: (match_operand:SI 2 "arith_operand" "dI")))] ! 3639: "" ! 3640: "sltu\\t%0,%1,%2" ! 3641: [(set_attr "type" "arith") ! 3642: (set_attr "mode" "SI") ! 3643: (set_attr "length" "1")]) ! 3644: ! 3645: (define_expand "sleu" ! 3646: [(set (match_operand:SI 0 "register_operand" "=d") ! 3647: (leu:SI (match_dup 1) ! 3648: (match_dup 2)))] ! 3649: "" ! 3650: " ! 3651: { ! 3652: if (branch_type != CMP_SI) ! 3653: FAIL; ! 3654: ! 3655: /* set up operands from compare. */ ! 3656: operands[1] = branch_cmp[0]; ! 3657: operands[2] = branch_cmp[1]; ! 3658: ! 3659: if (!TARGET_DEBUG_C_MODE) ! 3660: { ! 3661: gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0); ! 3662: DONE; ! 3663: } ! 3664: ! 3665: if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767) ! 3666: operands[2] = force_reg (SImode, operands[2]); ! 3667: ! 3668: /* fall through and generate default code */ ! 3669: }") ! 3670: ! 3671: (define_insn "sleu_si_const" ! 3672: [(set (match_operand:SI 0 "register_operand" "=d") ! 3673: (leu:SI (match_operand:SI 1 "register_operand" "d") ! 3674: (match_operand:SI 2 "small_int" "I")))] ! 3675: "INTVAL (operands[2]) < 32767" ! 3676: "* ! 3677: { ! 3678: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1); ! 3679: return \"sltu\\t%0,%1,%2\"; ! 3680: }" ! 3681: [(set_attr "type" "arith") ! 3682: (set_attr "mode" "SI") ! 3683: (set_attr "length" "1")]) ! 3684: ! 3685: (define_insn "sleu_si_reg" ! 3686: [(set (match_operand:SI 0 "register_operand" "=d") ! 3687: (leu:SI (match_operand:SI 1 "register_operand" "d") ! 3688: (match_operand:SI 2 "register_operand" "d")))] ! 3689: "TARGET_DEBUG_C_MODE" ! 3690: "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001" ! 3691: [(set_attr "type" "arith") ! 3692: (set_attr "mode" "SI") ! 3693: (set_attr "length" "2")]) ! 3694: ! 3695: (define_split ! 3696: [(set (match_operand:SI 0 "register_operand" "") ! 3697: (leu:SI (match_operand:SI 1 "register_operand" "") ! 3698: (match_operand:SI 2 "register_operand" "")))] ! 3699: "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE" ! 3700: [(set (match_dup 0) ! 3701: (ltu:SI (match_dup 2) ! 3702: (match_dup 1))) ! 3703: (set (match_dup 0) ! 3704: (xor:SI (match_dup 0) ! 3705: (const_int 1)))] ! 3706: "") ! 3707: ! 3708: ! 3709: ;; ! 3710: ;; .................... ! 3711: ;; ! 3712: ;; FLOATING POINT COMPARISONS ! 3713: ;; ! 3714: ;; .................... ! 3715: ! 3716: (define_insn "seq_df" ! 3717: [(set (reg:CC_FP 66) ! 3718: (eq:CC_FP (match_operand:DF 0 "register_operand" "f") ! 3719: (match_operand:DF 1 "register_operand" "f")))] ! 3720: "" ! 3721: "* ! 3722: { ! 3723: rtx xoperands[10]; ! 3724: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); ! 3725: xoperands[1] = operands[0]; ! 3726: xoperands[2] = operands[1]; ! 3727: ! 3728: return mips_fill_delay_slot (\"c.eq.d\\t%0,%1\", DELAY_FCMP, xoperands, insn); ! 3729: }" ! 3730: [(set_attr "type" "fcmp") ! 3731: (set_attr "mode" "FPSW") ! 3732: (set_attr "length" "1")]) ! 3733: ! 3734: (define_insn "sne_df" ! 3735: [(set (reg:CC_REV_FP 66) ! 3736: (ne:CC_REV_FP (match_operand:DF 0 "register_operand" "f") ! 3737: (match_operand:DF 1 "register_operand" "f")))] ! 3738: "" ! 3739: "* ! 3740: { ! 3741: rtx xoperands[10]; ! 3742: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); ! 3743: xoperands[1] = operands[0]; ! 3744: xoperands[2] = operands[1]; ! 3745: ! 3746: return mips_fill_delay_slot (\"c.eq.d\\t%0,%1\", DELAY_FCMP, xoperands, insn); ! 3747: }" ! 3748: [(set_attr "type" "fcmp") ! 3749: (set_attr "mode" "FPSW") ! 3750: (set_attr "length" "1")]) ! 3751: ! 3752: (define_insn "slt_df" ! 3753: [(set (reg:CC_FP 66) ! 3754: (lt:CC_FP (match_operand:DF 0 "register_operand" "f") ! 3755: (match_operand:DF 1 "register_operand" "f")))] ! 3756: "" ! 3757: "* ! 3758: { ! 3759: rtx xoperands[10]; ! 3760: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); ! 3761: xoperands[1] = operands[0]; ! 3762: xoperands[2] = operands[1]; ! 3763: ! 3764: return mips_fill_delay_slot (\"c.lt.d\\t%0,%1\", DELAY_FCMP, xoperands, insn); ! 3765: }" ! 3766: [(set_attr "type" "fcmp") ! 3767: (set_attr "mode" "FPSW") ! 3768: (set_attr "length" "1")]) ! 3769: ! 3770: (define_insn "sle_df" ! 3771: [(set (reg:CC_FP 66) ! 3772: (le:CC_FP (match_operand:DF 0 "register_operand" "f") ! 3773: (match_operand:DF 1 "register_operand" "f")))] ! 3774: "" ! 3775: "* ! 3776: { ! 3777: rtx xoperands[10]; ! 3778: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); ! 3779: xoperands[1] = operands[0]; ! 3780: xoperands[2] = operands[1]; ! 3781: ! 3782: return mips_fill_delay_slot (\"c.le.d\\t%0,%1\", DELAY_FCMP, xoperands, insn); ! 3783: }" ! 3784: [(set_attr "type" "fcmp") ! 3785: (set_attr "mode" "FPSW") ! 3786: (set_attr "length" "1")]) ! 3787: ! 3788: (define_insn "sgt_df" ! 3789: [(set (reg:CC_FP 66) ! 3790: (gt:CC_FP (match_operand:DF 0 "register_operand" "f") ! 3791: (match_operand:DF 1 "register_operand" "f")))] ! 3792: "" ! 3793: "* ! 3794: { ! 3795: rtx xoperands[10]; ! 3796: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); ! 3797: xoperands[1] = operands[0]; ! 3798: xoperands[2] = operands[1]; ! 3799: ! 3800: return mips_fill_delay_slot (\"c.lt.d\\t%1,%0\", DELAY_FCMP, xoperands, insn); ! 3801: }" ! 3802: [(set_attr "type" "fcmp") ! 3803: (set_attr "mode" "FPSW") ! 3804: (set_attr "length" "1")]) ! 3805: ! 3806: (define_insn "sge_df" ! 3807: [(set (reg:CC_FP 66) ! 3808: (ge:CC_FP (match_operand:DF 0 "register_operand" "f") ! 3809: (match_operand:DF 1 "register_operand" "f")))] ! 3810: "" ! 3811: "* ! 3812: { ! 3813: rtx xoperands[10]; ! 3814: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); ! 3815: xoperands[1] = operands[0]; ! 3816: xoperands[2] = operands[1]; ! 3817: ! 3818: return mips_fill_delay_slot (\"c.le.d\\t%1,%0\", DELAY_FCMP, xoperands, insn); ! 3819: }" ! 3820: [(set_attr "type" "fcmp") ! 3821: (set_attr "mode" "FPSW") ! 3822: (set_attr "length" "1")]) ! 3823: ! 3824: (define_insn "seq_sf" ! 3825: [(set (reg:CC_FP 66) ! 3826: (eq:CC_FP (match_operand:SF 0 "register_operand" "f") ! 3827: (match_operand:SF 1 "register_operand" "f")))] ! 3828: "" ! 3829: "* ! 3830: { ! 3831: rtx xoperands[10]; ! 3832: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); ! 3833: xoperands[1] = operands[0]; ! 3834: xoperands[2] = operands[1]; ! 3835: ! 3836: return mips_fill_delay_slot (\"c.eq.s\\t%0,%1\", DELAY_FCMP, xoperands, insn); ! 3837: }" ! 3838: [(set_attr "type" "fcmp") ! 3839: (set_attr "mode" "FPSW") ! 3840: (set_attr "length" "1")]) ! 3841: ! 3842: (define_insn "sne_sf" ! 3843: [(set (reg:CC_REV_FP 66) ! 3844: (ne:CC_REV_FP (match_operand:SF 0 "register_operand" "f") ! 3845: (match_operand:SF 1 "register_operand" "f")))] ! 3846: "" ! 3847: "* ! 3848: { ! 3849: rtx xoperands[10]; ! 3850: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); ! 3851: xoperands[1] = operands[0]; ! 3852: xoperands[2] = operands[1]; ! 3853: ! 3854: return mips_fill_delay_slot (\"c.eq.s\\t%0,%1\", DELAY_FCMP, xoperands, insn); ! 3855: }" ! 3856: [(set_attr "type" "fcmp") ! 3857: (set_attr "mode" "FPSW") ! 3858: (set_attr "length" "1")]) ! 3859: ! 3860: (define_insn "slt_sf" ! 3861: [(set (reg:CC_FP 66) ! 3862: (lt:CC_FP (match_operand:SF 0 "register_operand" "f") ! 3863: (match_operand:SF 1 "register_operand" "f")))] ! 3864: "" ! 3865: "* ! 3866: { ! 3867: rtx xoperands[10]; ! 3868: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); ! 3869: xoperands[1] = operands[0]; ! 3870: xoperands[2] = operands[1]; ! 3871: ! 3872: return mips_fill_delay_slot (\"c.lt.s\\t%0,%1\", DELAY_FCMP, xoperands, insn); ! 3873: }" ! 3874: [(set_attr "type" "fcmp") ! 3875: (set_attr "mode" "FPSW") ! 3876: (set_attr "length" "1")]) ! 3877: ! 3878: (define_insn "sle_sf" ! 3879: [(set (reg:CC_FP 66) ! 3880: (le:CC_FP (match_operand:SF 0 "register_operand" "f") ! 3881: (match_operand:SF 1 "register_operand" "f")))] ! 3882: "" ! 3883: "* ! 3884: { ! 3885: rtx xoperands[10]; ! 3886: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); ! 3887: xoperands[1] = operands[0]; ! 3888: xoperands[2] = operands[1]; ! 3889: ! 3890: return mips_fill_delay_slot (\"c.le.s\\t%0,%1\", DELAY_FCMP, xoperands, insn); ! 3891: }" ! 3892: [(set_attr "type" "fcmp") ! 3893: (set_attr "mode" "FPSW") ! 3894: (set_attr "length" "1")]) ! 3895: ! 3896: (define_insn "sgt_sf" ! 3897: [(set (reg:CC_FP 66) ! 3898: (gt:CC_FP (match_operand:SF 0 "register_operand" "f") ! 3899: (match_operand:SF 1 "register_operand" "f")))] ! 3900: "" ! 3901: "* ! 3902: { ! 3903: rtx xoperands[10]; ! 3904: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); ! 3905: xoperands[1] = operands[0]; ! 3906: xoperands[2] = operands[1]; ! 3907: ! 3908: return mips_fill_delay_slot (\"c.lt.s\\t%1,%0\", DELAY_FCMP, xoperands, insn); ! 3909: }" ! 3910: [(set_attr "type" "fcmp") ! 3911: (set_attr "mode" "FPSW") ! 3912: (set_attr "length" "1")]) ! 3913: ! 3914: (define_insn "sge_sf" ! 3915: [(set (reg:CC_FP 66) ! 3916: (ge:CC_FP (match_operand:SF 0 "register_operand" "f") ! 3917: (match_operand:SF 1 "register_operand" "f")))] ! 3918: "" ! 3919: "* ! 3920: { ! 3921: rtx xoperands[10]; ! 3922: xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM); ! 3923: xoperands[1] = operands[0]; ! 3924: xoperands[2] = operands[1]; ! 3925: ! 3926: return mips_fill_delay_slot (\"c.le.s\\t%1,%0\", DELAY_FCMP, xoperands, insn); ! 3927: }" ! 3928: [(set_attr "type" "fcmp") ! 3929: (set_attr "mode" "FPSW") ! 3930: (set_attr "length" "1")]) ! 3931: ! 3932: ! 3933: ;; ! 3934: ;; .................... ! 3935: ;; ! 3936: ;; UNCONDITIONAL BRANCHES ! 3937: ;; ! 3938: ;; .................... ! 3939: ! 3940: ;; Unconditional branches. ! 3941: ! 3942: (define_insn "jump" ! 3943: [(set (pc) ! 3944: (label_ref (match_operand 0 "" "")))] ! 3945: "" ! 3946: "* ! 3947: { ! 3948: if (GET_CODE (operands[0]) == REG) ! 3949: return \"%*j\\t%0\"; ! 3950: else ! 3951: return \"%*j\\t%l0\"; ! 3952: }" ! 3953: [(set_attr "type" "jump") ! 3954: (set_attr "mode" "none") ! 3955: (set_attr "length" "1")]) ! 3956: ! 3957: (define_insn "indirect_jump" ! 3958: [(set (pc) (match_operand:SI 0 "register_operand" "d"))] ! 3959: "" ! 3960: "%*j\\t%0" ! 3961: [(set_attr "type" "jump") ! 3962: (set_attr "mode" "none") ! 3963: (set_attr "length" "1")]) ! 3964: ! 3965: (define_insn "tablejump" ! 3966: [(set (pc) ! 3967: (match_operand:SI 0 "register_operand" "d")) ! 3968: (use (label_ref (match_operand 1 "" "")))] ! 3969: "" ! 3970: "%*j\\t%0" ! 3971: [(set_attr "type" "jump") ! 3972: (set_attr "mode" "none") ! 3973: (set_attr "length" "1")]) ! 3974: ! 3975: ;; Function return, only allow after optimization, so that we can ! 3976: ;; eliminate jumps to jumps if no stack space is used. ! 3977: ! 3978: ;; (define_expand "return" ! 3979: ;; [(set (pc) (reg:SI 31))] ! 3980: ;; "simple_epilogue_p ()" ! 3981: ;; "") ! 3982: ! 3983: (define_expand "return" ! 3984: [(parallel [(return) ! 3985: (use (reg:SI 31))])] ! 3986: "simple_epilogue_p ()" ! 3987: "") ! 3988: ! 3989: (define_insn "return_internal" ! 3990: [(parallel [(return) ! 3991: (use (match_operand:SI 0 "register_operand" "d"))])] ! 3992: "" ! 3993: "%*j\\t%0" ! 3994: [(set_attr "type" "jump") ! 3995: (set_attr "mode" "none") ! 3996: (set_attr "length" "1")]) ! 3997: ! 3998: ! 3999: ;; ! 4000: ;; .................... ! 4001: ;; ! 4002: ;; Function prologue/epilogue ! 4003: ;; ! 4004: ;; .................... ! 4005: ;; ! 4006: ! 4007: (define_expand "prologue" ! 4008: [(const_int 1)] ! 4009: "" ! 4010: " ! 4011: { ! 4012: if (mips_isa >= 0) /* avoid unused code warnings */ ! 4013: { ! 4014: mips_expand_prologue (); ! 4015: DONE; ! 4016: } ! 4017: }") ! 4018: ! 4019: ;; Block any insns from being moved before this point, since the ! 4020: ;; profiling call to mcount can use various registers that aren't ! 4021: ;; saved or used to pass arguments. ! 4022: ! 4023: (define_insn "blockage" ! 4024: [(unspec_volatile [(const_int 0)] 0)] ! 4025: "" ! 4026: "" ! 4027: [(set_attr "type" "unknown") ! 4028: (set_attr "mode" "none") ! 4029: (set_attr "length" "0")]) ! 4030: ! 4031: ;; At present, don't expand the epilogue, reorg.c will clobber the ! 4032: ;; return register in compiling gen_lowpart (emit-rtl.c). ! 4033: ;; ! 4034: ;; (define_expand "epilogue" ! 4035: ;; [(const_int 2)] ! 4036: ;; "" ! 4037: ;; " ! 4038: ;; { ! 4039: ;; if (mips_isa >= 0) /* avoid unused code warnings */ ! 4040: ;; { ! 4041: ;; mips_expand_epilogue (); ! 4042: ;; DONE; ! 4043: ;; } ! 4044: ;; }") ! 4045: ! 4046: ! 4047: ;; ! 4048: ;; .................... ! 4049: ;; ! 4050: ;; FUNCTION CALLS ! 4051: ;; ! 4052: ;; .................... ! 4053: ! 4054: ;; calls.c now passes a third argument, make saber happy ! 4055: ! 4056: (define_expand "call" ! 4057: [(parallel [(call (match_operand 0 "memory_operand" "m") ! 4058: (match_operand 1 "" "i")) ! 4059: (clobber (reg:SI 31)) ! 4060: (use (match_operand 2 "" "")) ;; next_arg_reg ! 4061: (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx ! 4062: "" ! 4063: " ! 4064: { ! 4065: rtx addr; ! 4066: ! 4067: if (operands[0]) /* eliminate unused code warnings */ ! 4068: { ! 4069: addr = XEXP (operands[0], 0); ! 4070: if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS)) ! 4071: || ! call_insn_operand (operands[0], VOIDmode)) ! 4072: XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr); ! 4073: ! 4074: /* In order to pass small structures by value in registers ! 4075: compatibly with the MIPS compiler, we need to shift the value ! 4076: into the high part of the register. Function_arg has encoded ! 4077: a PARALLEL rtx, holding a vector of adjustments to be made ! 4078: as the next_arg_reg variable, so we split up the insns, ! 4079: and emit them separately. */ ! 4080: ! 4081: if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL) ! 4082: { ! 4083: rtvec adjust = XVEC (operands[2], 0); ! 4084: int num = GET_NUM_ELEM (adjust); ! 4085: int i; ! 4086: ! 4087: for (i = 0; i < num; i++) ! 4088: emit_insn (RTVEC_ELT (adjust, i)); ! 4089: } ! 4090: ! 4091: emit_call_insn (gen_call_internal1 (operands[0], operands[1], ! 4092: gen_rtx (REG, Pmode, GP_REG_FIRST + 31))); ! 4093: DONE; ! 4094: } ! 4095: }") ! 4096: ! 4097: (define_insn "call_internal1" ! 4098: [(call (match_operand 0 "call_insn_operand" "m") ! 4099: (match_operand 1 "" "i")) ! 4100: (clobber (match_operand:SI 2 "register_operand" "=d"))] ! 4101: "!TARGET_ABICALLS && !TARGET_LONG_CALLS" ! 4102: "* ! 4103: { ! 4104: register rtx target = XEXP (operands[0], 0); ! 4105: ! 4106: if (GET_CODE (target) == SYMBOL_REF) ! 4107: return \"%*jal\\t%0\"; ! 4108: ! 4109: else if (GET_CODE (target) == CONST_INT) ! 4110: { ! 4111: operands[0] = target; ! 4112: return \"%*%[li\\t%@,%0\\n\\tjal\\t%2,%@%]\"; ! 4113: } ! 4114: ! 4115: else ! 4116: { ! 4117: operands[0] = target; ! 4118: return \"%*jal\\t%2,%0\"; ! 4119: } ! 4120: }" ! 4121: [(set_attr "type" "call") ! 4122: (set_attr "mode" "none") ! 4123: (set_attr "length" "1")]) ! 4124: ! 4125: (define_insn "call_internal2" ! 4126: [(call (match_operand 0 "call_insn_operand" "m") ! 4127: (match_operand 1 "" "i")) ! 4128: (clobber (match_operand:SI 2 "register_operand" "=d"))] ! 4129: "TARGET_ABICALLS && !TARGET_LONG_CALLS" ! 4130: "* ! 4131: { ! 4132: register rtx target = XEXP (operands[0], 0); ! 4133: ! 4134: if (GET_CODE (target) == SYMBOL_REF) ! 4135: return \"jal\\t%0\"; ! 4136: ! 4137: else if (GET_CODE (target) == CONST_INT) ! 4138: { ! 4139: operands[0] = target; ! 4140: return \"li\\t%^,%0\\n\\tjal\\t%2,%^\"; ! 4141: } ! 4142: ! 4143: else ! 4144: { ! 4145: operands[0] = target; ! 4146: if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM) ! 4147: return \"move\\t%^,%0\\n\\tjal\\t%2,%^\"; ! 4148: else ! 4149: return \"jal\\t%2,%0\"; ! 4150: } ! 4151: }" ! 4152: [(set_attr "type" "call") ! 4153: (set_attr "mode" "none") ! 4154: (set_attr "length" "2")]) ! 4155: ! 4156: (define_insn "call_internal3" ! 4157: [(call (mem:SI (match_operand:SI 0 "register_operand" "r")) ! 4158: (match_operand 1 "" "i")) ! 4159: (clobber (match_operand:SI 2 "register_operand" "=d"))] ! 4160: "!TARGET_ABICALLS && TARGET_LONG_CALLS" ! 4161: "%*jal\\t%2,%0" ! 4162: [(set_attr "type" "call") ! 4163: (set_attr "mode" "none") ! 4164: (set_attr "length" "1")]) ! 4165: ! 4166: (define_insn "call_internal4" ! 4167: [(call (mem:SI (match_operand:SI 0 "register_operand" "r")) ! 4168: (match_operand 1 "" "i")) ! 4169: (clobber (match_operand:SI 2 "register_operand" "=d"))] ! 4170: "TARGET_ABICALLS && TARGET_LONG_CALLS" ! 4171: "* ! 4172: { ! 4173: if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM) ! 4174: return \"move\\t%^,%0\\n\\tjal\\t%2,%^\"; ! 4175: else ! 4176: return \"jal\\t%2,%0\"; ! 4177: }" ! 4178: [(set_attr "type" "call") ! 4179: (set_attr "mode" "none") ! 4180: (set_attr "length" "2")]) ! 4181: ! 4182: ! 4183: ;; calls.c now passes a fourth argument, make saber happy ! 4184: ! 4185: (define_expand "call_value" ! 4186: [(parallel [(set (match_operand 0 "register_operand" "=df") ! 4187: (call (match_operand 1 "memory_operand" "m") ! 4188: (match_operand 2 "" "i"))) ! 4189: (clobber (reg:SI 31)) ! 4190: (use (match_operand 3 "" ""))])] ;; next_arg_reg ! 4191: "" ! 4192: " ! 4193: { ! 4194: rtx addr; ! 4195: ! 4196: if (operands[0]) /* eliminate unused code warning */ ! 4197: { ! 4198: addr = XEXP (operands[1], 0); ! 4199: if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS)) ! 4200: || ! call_insn_operand (operands[1], VOIDmode)) ! 4201: XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr); ! 4202: ! 4203: /* In order to pass small structures by value in registers ! 4204: compatibly with the MIPS compiler, we need to shift the value ! 4205: into the high part of the register. Function_arg has encoded ! 4206: a PARALLEL rtx, holding a vector of adjustments to be made ! 4207: as the next_arg_reg variable, so we split up the insns, ! 4208: and emit them separately. */ ! 4209: ! 4210: if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL) ! 4211: { ! 4212: rtvec adjust = XVEC (operands[3], 0); ! 4213: int num = GET_NUM_ELEM (adjust); ! 4214: int i; ! 4215: ! 4216: for (i = 0; i < num; i++) ! 4217: emit_insn (RTVEC_ELT (adjust, i)); ! 4218: } ! 4219: ! 4220: emit_call_insn (gen_call_value_internal1 (operands[0], operands[1], operands[2], ! 4221: gen_rtx (REG, Pmode, GP_REG_FIRST + 31))); ! 4222: ! 4223: DONE; ! 4224: } ! 4225: ! 4226: }") ! 4227: ! 4228: (define_insn "call_value_internal1" ! 4229: [(set (match_operand 0 "register_operand" "=df") ! 4230: (call (match_operand 1 "call_insn_operand" "m") ! 4231: (match_operand 2 "" "i"))) ! 4232: (clobber (match_operand:SI 3 "register_operand" "=d"))] ! 4233: "!TARGET_ABICALLS && !TARGET_LONG_CALLS" ! 4234: "* ! 4235: { ! 4236: register rtx target = XEXP (operands[1], 0); ! 4237: ! 4238: if (GET_CODE (target) == SYMBOL_REF) ! 4239: return \"%*jal\\t%1\"; ! 4240: ! 4241: else if (GET_CODE (target) == CONST_INT) ! 4242: { ! 4243: operands[1] = target; ! 4244: return \"%*%[li\\t%@,%1\\n\\tjal\\t%3,%@%]\"; ! 4245: } ! 4246: ! 4247: else ! 4248: { ! 4249: operands[1] = target; ! 4250: return \"%*jal\\t%3,%1\"; ! 4251: } ! 4252: }" ! 4253: [(set_attr "type" "call") ! 4254: (set_attr "mode" "none") ! 4255: (set_attr "length" "1")]) ! 4256: ! 4257: (define_insn "call_value_internal2" ! 4258: [(set (match_operand 0 "register_operand" "=df") ! 4259: (call (match_operand 1 "call_insn_operand" "m") ! 4260: (match_operand 2 "" "i"))) ! 4261: (clobber (match_operand:SI 3 "register_operand" "=d"))] ! 4262: "TARGET_ABICALLS && !TARGET_LONG_CALLS" ! 4263: "* ! 4264: { ! 4265: register rtx target = XEXP (operands[1], 0); ! 4266: ! 4267: if (GET_CODE (target) == SYMBOL_REF) ! 4268: return \"jal\\t%1\"; ! 4269: ! 4270: else if (GET_CODE (target) == CONST_INT) ! 4271: { ! 4272: operands[1] = target; ! 4273: return \"li\\t%^,%1\\n\\tjal\\t%3,%^\"; ! 4274: } ! 4275: ! 4276: else ! 4277: { ! 4278: operands[1] = target; ! 4279: if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM) ! 4280: return \"move\\t%^,%1\\n\\tjal\\t%3,%^\"; ! 4281: else ! 4282: return \"jal\\t%3,%1\"; ! 4283: } ! 4284: }" ! 4285: [(set_attr "type" "call") ! 4286: (set_attr "mode" "none") ! 4287: (set_attr "length" "2")]) ! 4288: ! 4289: (define_insn "call_value_internal3" ! 4290: [(set (match_operand 0 "register_operand" "=df") ! 4291: (call (mem:SI (match_operand:SI 1 "register_operand" "r")) ! 4292: (match_operand 2 "" "i"))) ! 4293: (clobber (match_operand:SI 3 "register_operand" "=d"))] ! 4294: "!TARGET_ABICALLS && TARGET_LONG_CALLS" ! 4295: "%*jal\\t%3,%1" ! 4296: [(set_attr "type" "call") ! 4297: (set_attr "mode" "none") ! 4298: (set_attr "length" "1")]) ! 4299: ! 4300: (define_insn "call_value_internal4" ! 4301: [(set (match_operand 0 "register_operand" "=df") ! 4302: (call (mem:SI (match_operand:SI 1 "register_operand" "r")) ! 4303: (match_operand 2 "" "i"))) ! 4304: (clobber (match_operand:SI 3 "register_operand" "=d"))] ! 4305: "TARGET_ABICALLS && TARGET_LONG_CALLS" ! 4306: "* ! 4307: { ! 4308: if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM) ! 4309: return \"move\\t%^,%1\\n\\tjal\\t%3,%^\"; ! 4310: else ! 4311: return \"jal\\t%3,%1\"; ! 4312: }" ! 4313: [(set_attr "type" "call") ! 4314: (set_attr "mode" "none") ! 4315: (set_attr "length" "2")]) ! 4316: ! 4317: ;; Call subroutine returning any type. ! 4318: ! 4319: (define_expand "untyped_call" ! 4320: [(parallel [(call (match_operand 0 "" "") ! 4321: (const_int 0)) ! 4322: (match_operand 1 "" "") ! 4323: (match_operand 2 "" "")])] ! 4324: "" ! 4325: " ! 4326: { ! 4327: if (operands[0]) /* silence statement not reached warnings */ ! 4328: { ! 4329: int i; ! 4330: ! 4331: emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); ! 4332: ! 4333: for (i = 0; i < XVECLEN (operands[2], 0); i++) ! 4334: { ! 4335: rtx set = XVECEXP (operands[2], 0, i); ! 4336: emit_move_insn (SET_DEST (set), SET_SRC (set)); ! 4337: } ! 4338: ! 4339: emit_insn (gen_blockage ()); ! 4340: DONE; ! 4341: } ! 4342: }") ! 4343: ! 4344: ;; ! 4345: ;; .................... ! 4346: ;; ! 4347: ;; MISC. ! 4348: ;; ! 4349: ;; .................... ! 4350: ;; ! 4351: ! 4352: (define_insn "nop" ! 4353: [(const_int 0)] ! 4354: "" ! 4355: "%(nop%)" ! 4356: [(set_attr "type" "nop") ! 4357: (set_attr "mode" "none") ! 4358: (set_attr "length" "1")]) ! 4359: ! 4360: (define_expand "probe" ! 4361: [(set (match_dup 0) ! 4362: (match_dup 1))] ! 4363: "" ! 4364: " ! 4365: { ! 4366: operands[0] = gen_reg_rtx (SImode); ! 4367: operands[1] = gen_rtx (MEM, SImode, stack_pointer_rtx); ! 4368: MEM_VOLATILE_P (operands[1]) = TRUE; ! 4369: ! 4370: /* fall through and generate default code */ ! 4371: }")
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.