|
|
1.1 ! root 1: ;;- Machine description for GNU compiler ! 2: ;;- Motorola 68000 Version ! 3: ;; Copyright (C) 1987, 1988 Free Software Foundation, Inc. ! 4: ! 5: ;; This file is part of GNU CC. ! 6: ! 7: ;; GNU CC is free software; you can redistribute it and/or modify ! 8: ;; it under the terms of the GNU General Public License as published by ! 9: ;; the Free Software Foundation; either version 2, or (at your option) ! 10: ;; any later version. ! 11: ! 12: ;; GNU CC is distributed in the hope that it will be useful, ! 13: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 15: ;; GNU General Public License for more details. ! 16: ! 17: ;; You should have received a copy of the GNU General Public License ! 18: ;; along with GNU CC; see the file COPYING. If not, write to ! 19: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ! 20: ! 21: ! 22: ;;- instruction definitions ! 23: ! 24: ;;- @@The original PO technology requires these to be ordered by speed, ! 25: ;;- @@ so that assigner will pick the fastest. ! 26: ! 27: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. ! 28: ! 29: ;;- When naming insn's (operand 0 of define_insn) be careful about using ! 30: ;;- names from other targets machine descriptions. ! 31: ! 32: ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code ! 33: ;;- updates for most instructions. ! 34: ! 35: ;;- Operand classes for the register allocator: ! 36: ;;- 'a' one of the address registers can be used. ! 37: ;;- 'd' one of the data registers can be used. ! 38: ;;- 'f' one of the m68881 registers can be used ! 39: ;;- 'r' either a data or an address register can be used. ! 40: ;;- 'x' if one of the Sun FPA registers ! 41: ;;- 'y' if one of the Low Sun FPA registers (fpa0-fpa15). ! 42: ! 43: ;;- Immediate Floating point operator constraints ! 44: ;;- 'G' a floating point constant that is *NOT* one of the standard ! 45: ;; 68881 constant values (to force calling output_move_const_double ! 46: ;; to get it from rom if it is a 68881 constant). ! 47: ;;- 'H' one of the standard FPA constant values ! 48: ;; ! 49: ;; See the functions standard_XXX_constant_p in output-m68k.c for more ! 50: ;; info. ! 51: ! 52: ;;- Immediate integer operand constraints: ! 53: ;;- 'I' 1 .. 8 ! 54: ;;- 'J' -32768 .. 32767 ! 55: ;;- 'K' all integers EXCEPT -128 .. 127 ! 56: ;;- 'L' -8 .. -1 ! 57: ! 58: ;;- Assembler specs: ! 59: ;;- "%." size separator ("." or "") move%.l d0,d1 ! 60: ;;- "%#" immediate separator ("#" or "") move%.l %#0,d0 ! 61: ;;- "%-" push operand "sp@-" move%.l d0,%- ! 62: ;;- "%+" pop operand "sp@+" move%.l d0,%+ ! 63: ;;- "%@" top of stack "sp@" move%.l d0,%@ ! 64: ;;- "%!" ??? "cc" (not used) ! 65: ;;- "%$" single-precision fp specifier ("s" or "") f%$add.x fp0,fp1 ! 66: ;;- "%&" double-precision fp specifier ("d" or "") f%&add.x fp0,fp1 ! 67: ! 68: ;;- Information about 68040 port. ! 69: ! 70: ;;- The 68040 executes all 68030 and 68881/2 instructions, but some must ! 71: ;;- be emulated in software by the OS. It is faster to avoid these ! 72: ;;- instructions and issue a library call rather than trapping into ! 73: ;;- the kernel. The affected instructions are fintrz and fscale. The ! 74: ;;- TARGET_68040 flag turns the use of the opcodes off. ! 75: ! 76: ;;- The '040 also implements a set of new floating-point instructions ! 77: ;;- which specify the rounding precision in the opcode. This finally ! 78: ;;- permit the 68k series to be truly IEEE compliant, and solves all ! 79: ;;- issues of excess precision accumulating in the extended registers. ! 80: ;;- By default, GCC does not use these instructions, since such code will ! 81: ;;- not run on an '030. To use these instructions, use the -m68040-only ! 82: ;;- switch. By changing TARGET_DEFAULT to include TARGET_68040_ONLY, ! 83: ;;- you can make these instructions the default. ! 84: ! 85: ;;- These new instructions aren't directly in the md. They are brought ! 86: ;;- into play by defining "%$" and "%&" to expand to "s" and "d" rather ! 87: ;;- than "". ! 88: ! 89: ! 90: ;;- FPA port explanation: ! 91: ! 92: ;;- Usage of the Sun FPA and the 68881 together ! 93: ! 94: ;;- The current port of gcc to the sun fpa disallows use of the m68881 ! 95: ;;- instructions completely if code is targeted for the fpa. This is ! 96: ;;- for the following reasons: ! 97: ! 98: ;;- 1) Expressing the preference hierarchy (ie. use the fpa if you ! 99: ;;- can, the 68881 otherwise, and data registers only if you are ! 100: ;;- forced to it) is a bitch with the current constraint scheme, ! 101: ;;- especially since it would have to work for any combination of ! 102: ;;- -mfpa, -m68881. ! 103: ! 104: ;;- 2) There are no instructions to move between the two types of ! 105: ;;- registers; the stack must be used as an intermediary. ! 106: ! 107: ;;- It could indeed be done; I think the best way would be to have ! 108: ;;- separate patterns for TARGET_FPA (which implies a 68881), ! 109: ;;- TARGET_68881, and no floating point co-processor. Use ! 110: ;;- define_expands for all of the named instruction patterns, and ! 111: ;;- include code in the FPA instruction to deal with the 68881 with ! 112: ;;- preferences specifically set to favor the fpa. Some of this has ! 113: ;;- already been done: ! 114: ;;- ! 115: ;;- 1) Separation of most of the patterns out into a TARGET_FPA ! 116: ;;- case and a TARGET_68881 case (the exceptions are the patterns ! 117: ;;- which would need one define_expand and three define_insn's under ! 118: ;;- it (with a lot of duplicate code between them) to replace the ! 119: ;;- current single define_insn. These are mov{[ds]f,[ds]i} and the ! 120: ;;- first two patterns in the md. ! 121: ;;- ! 122: ;;- Some would still have to be done: ! 123: ;;- ! 124: ;;- 1) Add code to the fpa patterns which correspond to 68881 ! 125: ;;- patterns to deal with the 68881 case (including preferences!). ! 126: ;;- What you might actually do here is combine the fpa and 68881 code ! 127: ;;- back together into one pattern for those instructions where it's ! 128: ;;- absolutely necessary and save yourself some duplicate code. I'm ! 129: ;;- not completely sure as to whether you could get away with doing ! 130: ;;- this only for the mov* insns, or if you'd have to do it for all ! 131: ;;- named insns. ! 132: ;;- 2) Add code to the mov{[ds]f,[ds]i} instructions to handle ! 133: ;;- moving between fpa regs and 68881 regs. ! 134: ! 135: ;;- Since the fpa is more powerful than the 68881 and also has more ! 136: ;;- registers, and since I think the resultant md would be medium ugly ! 137: ;;- (lot's of duplicate code, ugly constraint strings), I elected not ! 138: ;;- to do this change. ! 139: ! 140: ;;- Another reason why someone *might* want to do the change is to ! 141: ;;- control which register classes are accessed in a slightly cleaner ! 142: ;;- way than I have. See the blurb on CONDITIONAL_REGISTER_USAGE in ! 143: ;;- the internals manual. ! 144: ! 145: ;;- Yet another reason why someone might want to do this change is to ! 146: ;;- allow use of some of the 68881 insns which have no equivalent on ! 147: ;;- the fpa. The sqrt instruction comes fairly quickly to mind. ! 148: ! 149: ;;- If this is ever done, don't forget to change sun3.h so that ! 150: ;;- it *will* define __HAVE_68881__ when the FPA is in use. ! 151: ! 152: ;;- Condition code hack ! 153: ! 154: ;;- When a floating point compare is done in the fpa, the resulting ! 155: ;;- condition codes are left in the fpastatus register. The values in ! 156: ;;- this register must be moved into the 68000 cc register before any ! 157: ;;- jump is executed. Once this has been done, regular jump ! 158: ;;- instructions are fine (ie. floating point jumps are not necessary. ! 159: ;;- They are only done if the cc is in the 68881). ! 160: ! 161: ;;- The instructions that move the fpastatus register to the 68000 ! 162: ;;- register clobber a data register (the move cannot be done direct). ! 163: ;;- These instructions might be bundled either with the compare ! 164: ;;- instruction, or the branch instruction. If we were using both the ! 165: ;;- fpa and the 68881 together, we would wish to only mark the ! 166: ;;- register clobbered if we were doing the compare in the fpa, but I ! 167: ;;- think that that decision (whether to clobber the register or not) ! 168: ;;- must be done before register allocation (makes sense) and hence we ! 169: ;;- can't know if the floating point compare will be done in the fpa ! 170: ;;- or the fp. So whenever we are asked for code that uses the fpa, ! 171: ;;- we will mark a data register as clobbered. This is reasonable, as ! 172: ;;- almost all floating point compare operations done with fpa code ! 173: ;;- enabled will be done in the fpa. It's even more reasonable since ! 174: ;;- we decided to make the 68881 and the fpa mutually exclusive. ! 175: ! 176: ;;- We place to code to move the fpastatus register inside of a ! 177: ;;- define_expand so that we can do it conditionally based on whether ! 178: ;;- we are targeting an fpa or not. ! 179: ! 180: ;;- This still leaves us with the question of where we wish to put the ! 181: ;;- code to move the fpastatus reg. If we put it in the compare ! 182: ;;- instruction, we can restrict the clobbering of the register to ! 183: ;;- floating point compares, but we can't take advantage of floating ! 184: ;;- point subtracts & etc. that alter the fpastatus register. If we ! 185: ;;- put it in the branch instruction, all branches compiled with fpa ! 186: ;;- code enabled will clobber a data register, but we will be able to ! 187: ;;- take advantage of fpa subtracts. This balance favors putting the ! 188: ;;- code in with the compare instruction. ! 189: ! 190: ;;- Note that if some enterprising hacker should decide to switch ! 191: ;;- this, he'll need to modify the code in NOTICE_UPDATE_CC. ! 192: ! 193: ;;- Usage of the top 16 fpa registers ! 194: ! 195: ;;- The only locations which we may transfer fpa registers 16-31 from ! 196: ;;- or to are the fpa registers 0-15. (68000 registers and memory ! 197: ;;- locations are impossible). This causes problems in gcc, which ! 198: ;;- assumes that mov?? instructions require no additional registers ! 199: ;;- (see section 11.7) and since floating point moves *must* be ! 200: ;;- supported into general registers (see section 12.3 under ! 201: ;;- HARD_REGNO_OK_FOR_MODE_P) from anywhere. ! 202: ! 203: ;;- My solution was to reserve fpa0 for moves into or out of these top ! 204: ;;- 16 registers and to disparage the choice to reload into or out of ! 205: ;;- these registers as much as I could. That alternative is always ! 206: ;;- last in the list, so it will not be used unless all else fails. I ! 207: ;;- will note that according to my current information, sun's compiler ! 208: ;;- doesn't use these top 16 registers at all. ! 209: ! 210: ;;- There is another possible way to do it. I *believe* that if you ! 211: ;;- make absolutely sure that the code will not be executed in the ! 212: ;;- reload pass, you can support the mov?? names with define_expands ! 213: ;;- which require new registers. This may be possible by the ! 214: ;;- appropriate juggling of constraints. I may come back to this later. ! 215: ! 216: ;;- Usage of constant RAM ! 217: ! 218: ;;- This has been handled correctly (I believe) but the way I've done ! 219: ;;- it could use a little explanation. The constant RAM can only be ! 220: ;;- accessed when the instruction is in "command register" mode. ! 221: ;;- "command register" mode means that no accessing of memory or the ! 222: ;;- 68000 registers is being done. This can be expressed easily in ! 223: ;;- constraints, so generally the mode of the instruction is ! 224: ;;- determined by a branch off of which_alternative. In outputing ! 225: ;;- instructions, a 'w' means to output an access to the constant ram ! 226: ;;- (if the arg is CONST_DOUBLE and is one of the available ! 227: ;;- constants), and 'x' means to output a register pair (if the arg is ! 228: ;;- a 68000 register) and a 'y' is the combination of the above two ! 229: ;;- processes. You use a 'y' in two operand DF instructions where you ! 230: ;;- *know* the other operand is an fpa register, you use an 'x' in DF ! 231: ;;- instructions where the arg might be a 68000 register and the ! 232: ;;- instruction is *not* in "command register" mode, and you use a 'w' ! 233: ;;- in two situations: 1) The instruction *is* in command register ! 234: ;;- mode (and hence won't be accessing 68000 registers), or 2) The ! 235: ;;- instruction is a two operand SF instruction where you know the ! 236: ;;- other operand is an fpa register. ! 237: ! 238: ;;- Optimization issues ! 239: ! 240: ;;- I actually think that I've included all of the fpa instructions ! 241: ;;- that should be included. Note that if someone is interested in ! 242: ;;- doing serious floating point work on the sun fpa, I would advise ! 243: ;;- the use of the "asm" instruction in gcc to allow you to use the ! 244: ;;- sin, cos, and exponential functions on the fpa board. ! 245: ! 246: ;;- END FPA Explanation Section. ! 247: ! 248: ! 249: ;;- Some of these insn's are composites of several m68000 op codes. ! 250: ;;- The assembler (or final @@??) insures that the appropriate one is ! 251: ;;- selected. ! 252: ! 253: (define_insn "" ! 254: [(set (match_operand:DF 0 "push_operand" "=m") ! 255: (match_operand:DF 1 "general_operand" "ro<>fyE"))] ! 256: "" ! 257: "* ! 258: { ! 259: if (FP_REG_P (operands[1])) ! 260: return \"fmove%.d %f1,%0\"; ! 261: if (FPA_REG_P (operands[1])) ! 262: return \"fpmove%.d %1, %x0\"; ! 263: return output_move_double (operands); ! 264: }") ! 265: ! 266: (define_insn "" ! 267: [(set (match_operand:DI 0 "push_operand" "=m") ! 268: (match_operand:DI 1 "general_operand" "ro<>Fy"))] ! 269: "" ! 270: "* ! 271: { ! 272: return output_move_double (operands); ! 273: }") ! 274: ! 275: ;; We don't want to allow a constant operand for test insns because ! 276: ;; (set (cc0) (const_int foo)) has no mode information. Such insns will ! 277: ;; be folded while optimizing anyway. ! 278: (define_insn "tstsi" ! 279: [(set (cc0) ! 280: (match_operand:SI 0 "nonimmediate_operand" "rm"))] ! 281: "" ! 282: "* ! 283: { ! 284: #ifdef ISI_OV ! 285: /* ISI's assembler fails to handle tstl a0. */ ! 286: if (! ADDRESS_REG_P (operands[0])) ! 287: #else ! 288: if (TARGET_68020 || ! ADDRESS_REG_P (operands[0])) ! 289: #endif ! 290: return \"tst%.l %0\"; ! 291: /* If you think that the 68020 does not support tstl a0, ! 292: reread page B-167 of the 68020 manual more carefully. */ ! 293: /* On an address reg, cmpw may replace cmpl. */ ! 294: #ifdef SGS_CMP_ORDER ! 295: return \"cmp%.w %0,%#0\"; ! 296: #else ! 297: return \"cmp%.w %#0,%0\"; ! 298: #endif ! 299: }") ! 300: ! 301: ;; This can't use an address register, because comparisons ! 302: ;; with address registers as second operand always test the whole word. ! 303: (define_insn "tsthi" ! 304: [(set (cc0) ! 305: (match_operand:HI 0 "nonimmediate_operand" "dm"))] ! 306: "" ! 307: "tst%.w %0") ! 308: ! 309: (define_insn "tstqi" ! 310: [(set (cc0) ! 311: (match_operand:QI 0 "nonimmediate_operand" "dm"))] ! 312: "" ! 313: "tst%.b %0") ! 314: ! 315: (define_expand "tstsf" ! 316: [(set (cc0) ! 317: (match_operand:SF 0 "general_operand" ""))] ! 318: "TARGET_68881 || TARGET_FPA" ! 319: " ! 320: { ! 321: if (TARGET_FPA) ! 322: { ! 323: emit_insn (gen_tstsf_fpa (operands[0])); ! 324: DONE; ! 325: } ! 326: }") ! 327: ! 328: (define_insn "tstsf_fpa" ! 329: [(set (cc0) ! 330: (match_operand:SF 0 "general_operand" "xmdF")) ! 331: (clobber (match_scratch:SI 1 "=d"))] ! 332: "TARGET_FPA" ! 333: "fptst%.s %x0\;fpmove fpastatus,%1\;movw %1,cc") ! 334: ! 335: (define_insn "" ! 336: [(set (cc0) ! 337: (match_operand:SF 0 "general_operand" "fdm"))] ! 338: "TARGET_68881" ! 339: "* ! 340: { ! 341: cc_status.flags = CC_IN_68881; ! 342: if (FP_REG_P (operands[0])) ! 343: return \"ftst%.x %0\"; ! 344: return \"ftst%.s %0\"; ! 345: }") ! 346: ! 347: (define_expand "tstdf" ! 348: [(set (cc0) ! 349: (match_operand:DF 0 "general_operand" ""))] ! 350: "TARGET_68881 || TARGET_FPA" ! 351: " ! 352: { ! 353: if (TARGET_FPA) ! 354: { ! 355: emit_insn (gen_tstsf_fpa (operands[0])); ! 356: DONE; ! 357: } ! 358: }") ! 359: ! 360: (define_insn "tstdf_fpa" ! 361: [(set (cc0) ! 362: (match_operand:DF 0 "general_operand" "xrmF")) ! 363: (clobber (match_scratch:SI 1 "=d"))] ! 364: "TARGET_FPA" ! 365: "fptst%.d %x0\;fpmove fpastatus,%1\;movw %1,cc") ! 366: ! 367: (define_insn "" ! 368: [(set (cc0) ! 369: (match_operand:DF 0 "general_operand" "fm"))] ! 370: "TARGET_68881" ! 371: "* ! 372: { ! 373: cc_status.flags = CC_IN_68881; ! 374: if (FP_REG_P (operands[0])) ! 375: return \"ftst%.x %0\"; ! 376: return \"ftst%.d %0\"; ! 377: }") ! 378: ! 379: ;; compare instructions. ! 380: ! 381: ;; A composite of the cmp, cmpa, & cmpi m68000 op codes. ! 382: (define_insn "cmpsi" ! 383: [(set (cc0) ! 384: (compare (match_operand:SI 0 "nonimmediate_operand" "rKs,mr,>") ! 385: (match_operand:SI 1 "general_operand" "mr,Ksr,>")))] ! 386: "" ! 387: "* ! 388: { ! 389: if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) ! 390: return \"cmpm%.l %1,%0\"; ! 391: if (REG_P (operands[1]) ! 392: || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) ! 393: { cc_status.flags |= CC_REVERSED; ! 394: #ifdef SGS_CMP_ORDER ! 395: return \"cmp%.l %d1,%d0\"; ! 396: #else ! 397: return \"cmp%.l %d0,%d1\"; ! 398: #endif ! 399: } ! 400: #ifdef SGS_CMP_ORDER ! 401: return \"cmp%.l %d0,%d1\"; ! 402: #else ! 403: return \"cmp%.l %d1,%d0\"; ! 404: #endif ! 405: }") ! 406: ! 407: (define_insn "cmphi" ! 408: [(set (cc0) ! 409: (compare (match_operand:HI 0 "nonimmediate_operand" "rnm,d,n,m") ! 410: (match_operand:HI 1 "general_operand" "d,rnm,m,n")))] ! 411: "" ! 412: "* ! 413: { ! 414: if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) ! 415: return \"cmpm%.w %1,%0\"; ! 416: if ((REG_P (operands[1]) && !ADDRESS_REG_P (operands[1])) ! 417: || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) ! 418: { cc_status.flags |= CC_REVERSED; ! 419: #ifdef SGS_CMP_ORDER ! 420: return \"cmp%.w %d1,%d0\"; ! 421: #else ! 422: return \"cmp%.w %d0,%d1\"; ! 423: #endif ! 424: } ! 425: #ifdef SGS_CMP_ORDER ! 426: return \"cmp%.w %d0,%d1\"; ! 427: #else ! 428: return \"cmp%.w %d1,%d0\"; ! 429: #endif ! 430: }") ! 431: ! 432: (define_insn "cmpqi" ! 433: [(set (cc0) ! 434: (compare (match_operand:QI 0 "nonimmediate_operand" "dn,md,>") ! 435: (match_operand:QI 1 "general_operand" "dm,nd,>")))] ! 436: "" ! 437: "* ! 438: { ! 439: if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) ! 440: return \"cmpm%.b %1,%0\"; ! 441: if (REG_P (operands[1]) ! 442: || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) ! 443: { cc_status.flags |= CC_REVERSED; ! 444: #ifdef SGS_CMP_ORDER ! 445: return \"cmp%.b %d1,%d0\"; ! 446: #else ! 447: return \"cmp%.b %d0,%d1\"; ! 448: #endif ! 449: } ! 450: #ifdef SGS_CMP_ORDER ! 451: return \"cmp%.b %d0,%d1\"; ! 452: #else ! 453: return \"cmp%.b %d1,%d0\"; ! 454: #endif ! 455: }") ! 456: ! 457: (define_expand "cmpdf" ! 458: [(set (cc0) ! 459: (compare (match_operand:DF 0 "general_operand" "") ! 460: (match_operand:DF 1 "general_operand" "")))] ! 461: "TARGET_68881 || TARGET_FPA" ! 462: " ! 463: { ! 464: if (TARGET_FPA) ! 465: { ! 466: emit_insn (gen_cmpdf_fpa (operands[0], operands[1])); ! 467: DONE; ! 468: } ! 469: }") ! 470: ! 471: (define_insn "cmpdf_fpa" ! 472: [(set (cc0) ! 473: (compare (match_operand:DF 0 "general_operand" "x,y") ! 474: (match_operand:DF 1 "general_operand" "xH,rmF"))) ! 475: (clobber (match_scratch:SI 2 "=d,d"))] ! 476: "TARGET_FPA" ! 477: "fpcmp%.d %y1,%0\;fpmove fpastatus,%2\;movw %2,cc") ! 478: ! 479: (define_insn "" ! 480: [(set (cc0) ! 481: (compare (match_operand:DF 0 "general_operand" "f,mG") ! 482: (match_operand:DF 1 "general_operand" "fmG,f")))] ! 483: "TARGET_68881" ! 484: "* ! 485: { ! 486: cc_status.flags = CC_IN_68881; ! 487: #ifdef SGS_CMP_ORDER ! 488: if (REG_P (operands[0])) ! 489: { ! 490: if (REG_P (operands[1])) ! 491: return \"fcmp%.x %0,%1\"; ! 492: else ! 493: return \"fcmp%.d %0,%f1\"; ! 494: } ! 495: cc_status.flags |= CC_REVERSED; ! 496: return \"fcmp%.d %1,%f0\"; ! 497: #else ! 498: if (REG_P (operands[0])) ! 499: { ! 500: if (REG_P (operands[1])) ! 501: return \"fcmp%.x %1,%0\"; ! 502: else ! 503: return \"fcmp%.d %f1,%0\"; ! 504: } ! 505: cc_status.flags |= CC_REVERSED; ! 506: return \"fcmp%.d %f0,%1\"; ! 507: #endif ! 508: }") ! 509: ! 510: (define_expand "cmpsf" ! 511: [(set (cc0) ! 512: (compare (match_operand:SF 0 "general_operand" "") ! 513: (match_operand:SF 1 "general_operand" "")))] ! 514: "TARGET_68881 || TARGET_FPA" ! 515: " ! 516: { ! 517: if (TARGET_FPA) ! 518: { ! 519: emit_insn (gen_cmpsf_fpa (operands[0], operands[1])); ! 520: DONE; ! 521: } ! 522: }") ! 523: ! 524: (define_insn "cmpsf_fpa" ! 525: [(set (cc0) ! 526: (compare (match_operand:SF 0 "general_operand" "x,y") ! 527: (match_operand:SF 1 "general_operand" "xH,rmF"))) ! 528: (clobber (match_scratch:SI 2 "=d,d"))] ! 529: "TARGET_FPA" ! 530: "fpcmp%.s %w1,%x0\;fpmove fpastatus,%2\;movw %2,cc") ! 531: ! 532: (define_insn "" ! 533: [(set (cc0) ! 534: (compare (match_operand:SF 0 "general_operand" "f,mdG") ! 535: (match_operand:SF 1 "general_operand" "fmdG,f")))] ! 536: "TARGET_68881" ! 537: "* ! 538: { ! 539: cc_status.flags = CC_IN_68881; ! 540: #ifdef SGS_CMP_ORDER ! 541: if (FP_REG_P (operands[0])) ! 542: { ! 543: if (FP_REG_P (operands[1])) ! 544: return \"fcmp%.x %0,%1\"; ! 545: else ! 546: return \"fcmp%.s %0,%f1\"; ! 547: } ! 548: cc_status.flags |= CC_REVERSED; ! 549: return \"fcmp%.s %1,%f0\"; ! 550: #else ! 551: if (FP_REG_P (operands[0])) ! 552: { ! 553: if (FP_REG_P (operands[1])) ! 554: return \"fcmp%.x %1,%0\"; ! 555: else ! 556: return \"fcmp%.s %f1,%0\"; ! 557: } ! 558: cc_status.flags |= CC_REVERSED; ! 559: return \"fcmp%.s %f0,%1\"; ! 560: #endif ! 561: }") ! 562: ! 563: ;; Recognizers for btst instructions. ! 564: ! 565: (define_insn "" ! 566: [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "do") ! 567: (const_int 1) ! 568: (minus:SI (const_int 7) ! 569: (match_operand:SI 1 "general_operand" "di"))))] ! 570: "" ! 571: "* { return output_btst (operands, operands[1], operands[0], insn, 7); }") ! 572: ! 573: (define_insn "" ! 574: [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "d") ! 575: (const_int 1) ! 576: (minus:SI (const_int 31) ! 577: (match_operand:SI 1 "general_operand" "di"))))] ! 578: "" ! 579: "* { return output_btst (operands, operands[1], operands[0], insn, 31); }") ! 580: ! 581: ;; The following two patterns are like the previous two ! 582: ;; except that they use the fact that bit-number operands ! 583: ;; are automatically masked to 3 or 5 bits. ! 584: ! 585: (define_insn "" ! 586: [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "do") ! 587: (const_int 1) ! 588: (minus:SI (const_int 7) ! 589: (and:SI ! 590: (match_operand:SI 1 "general_operand" "d") ! 591: (const_int 7)))))] ! 592: "" ! 593: "* { return output_btst (operands, operands[1], operands[0], insn, 7); }") ! 594: ! 595: (define_insn "" ! 596: [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "d") ! 597: (const_int 1) ! 598: (minus:SI (const_int 31) ! 599: (and:SI ! 600: (match_operand:SI 1 "general_operand" "d") ! 601: (const_int 31)))))] ! 602: "" ! 603: "* { return output_btst (operands, operands[1], operands[0], insn, 31); }") ! 604: ! 605: ;; Nonoffsettable mem refs are ok in this one pattern ! 606: ;; since we don't try to adjust them. ! 607: (define_insn "" ! 608: [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "md") ! 609: (const_int 1) ! 610: (match_operand:SI 1 "general_operand" "i")))] ! 611: "GET_CODE (operands[1]) == CONST_INT ! 612: && (unsigned) INTVAL (operands[1]) < 8" ! 613: "* ! 614: { ! 615: operands[1] = gen_rtx (CONST_INT, VOIDmode, 7 - INTVAL (operands[1])); ! 616: return output_btst (operands, operands[1], operands[0], insn, 7); ! 617: }") ! 618: ! 619: (define_insn "" ! 620: [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "do") ! 621: (const_int 1) ! 622: (match_operand:SI 1 "general_operand" "i")))] ! 623: "GET_CODE (operands[1]) == CONST_INT" ! 624: "* ! 625: { ! 626: if (GET_CODE (operands[0]) == MEM) ! 627: { ! 628: operands[0] = adj_offsettable_operand (operands[0], ! 629: INTVAL (operands[1]) / 8); ! 630: operands[1] = gen_rtx (CONST_INT, VOIDmode, ! 631: 7 - INTVAL (operands[1]) % 8); ! 632: return output_btst (operands, operands[1], operands[0], insn, 7); ! 633: } ! 634: operands[1] = gen_rtx (CONST_INT, VOIDmode, ! 635: 31 - INTVAL (operands[1])); ! 636: return output_btst (operands, operands[1], operands[0], insn, 31); ! 637: }") ! 638: ! 639: ! 640: ;; move instructions ! 641: ! 642: ;; A special case in which it is not desirable ! 643: ;; to reload the constant into a data register. ! 644: (define_insn "" ! 645: [(set (match_operand:SI 0 "push_operand" "=m") ! 646: (match_operand:SI 1 "general_operand" "J"))] ! 647: "GET_CODE (operands[1]) == CONST_INT ! 648: && INTVAL (operands[1]) >= -0x8000 ! 649: && INTVAL (operands[1]) < 0x8000" ! 650: "* ! 651: { ! 652: if (operands[1] == const0_rtx) ! 653: return \"clr%.l %0\"; ! 654: return \"pea %a1\"; ! 655: }") ! 656: ! 657: ;This is never used. ! 658: ;(define_insn "swapsi" ! 659: ; [(set (match_operand:SI 0 "general_operand" "r") ! 660: ; (match_operand:SI 1 "general_operand" "r")) ! 661: ; (set (match_dup 1) (match_dup 0))] ! 662: ; "" ! 663: ; "exg %1,%0") ! 664: ! 665: ;; Special case of fullword move when source is zero. ! 666: ;; The reason this is special is to avoid loading a zero ! 667: ;; into a data reg with moveq in order to store it elsewhere. ! 668: ! 669: (define_insn "" ! 670: [(set (match_operand:SI 0 "general_operand" "=g") ! 671: (const_int 0))] ! 672: ;; clr insns on 68000 read before writing. ! 673: ;; This isn't so on the 68010, but we have no alternative for it. ! 674: "(TARGET_68020 ! 675: || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))" ! 676: "* ! 677: { ! 678: if (ADDRESS_REG_P (operands[0])) ! 679: return \"sub%.l %0,%0\"; ! 680: /* moveq is faster on the 68000. */ ! 681: if (DATA_REG_P (operands[0]) && !TARGET_68020) ! 682: #if defined(MOTOROLA) && !defined(CRDS) ! 683: return \"moveq%.l %#0,%0\"; ! 684: #else ! 685: return \"moveq %#0,%0\"; ! 686: #endif ! 687: return \"clr%.l %0\"; ! 688: }") ! 689: ! 690: ;; General case of fullword move. ! 691: ;; ! 692: ;; This is the main "hook" for PIC code. When generating ! 693: ;; PIC, movsi is responsible for determining when the source address ! 694: ;; needs PIC relocation and appropriatly calling legitimize_pic_address ! 695: ;; to perform the actual relocation. ! 696: ;; ! 697: ;; In both the PIC and non-PIC cases the patterns generated will ! 698: ;; matched by the next define_insn. ! 699: (define_expand "movsi" ! 700: [(set (match_operand:SI 0 "general_operand" "") ! 701: (match_operand:SI 1 "general_operand" ""))] ! 702: "" ! 703: " ! 704: { ! 705: if (flag_pic && symbolic_operand (operands[1], SImode)) ! 706: { ! 707: /* The source is an address which requires PIC relocation. ! 708: Call legitimize_pic_address with the source, mode, and a relocation ! 709: register (a new pseudo, or the final destination if reload_in_progress ! 710: is set). Then fall through normally */ ! 711: extern rtx legitimize_pic_address(); ! 712: rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode); ! 713: operands[1] = legitimize_pic_address (operands[1], SImode, temp); ! 714: } ! 715: }") ! 716: ! 717: ;; General case of fullword move. The register constraints ! 718: ;; force integer constants in range for a moveq to be reloaded ! 719: ;; if they are headed for memory. ! 720: (define_insn "" ! 721: ;; Notes: make sure no alternative allows g vs g. ! 722: ;; We don't allow f-regs since fixed point cannot go in them. ! 723: ;; We do allow y and x regs since fixed point is allowed in them. ! 724: [(set (match_operand:SI 0 "general_operand" "=g,da,y,!*x*r*m") ! 725: (match_operand:SI 1 "general_operand" "daymKs,i,g,*x*r*m"))] ! 726: "" ! 727: "* ! 728: { ! 729: if (which_alternative == 3) ! 730: return \"fpmove%.l %x1,fpa0\;fpmove%.l fpa0,%x0\"; ! 731: if (FPA_REG_P (operands[1]) || FPA_REG_P (operands[0])) ! 732: return \"fpmove%.l %x1,%x0\"; ! 733: if (GET_CODE (operands[1]) == CONST_INT) ! 734: { ! 735: if (operands[1] == const0_rtx ! 736: && (DATA_REG_P (operands[0]) ! 737: || GET_CODE (operands[0]) == MEM) ! 738: /* clr insns on 68000 read before writing. ! 739: This isn't so on the 68010, but we have no alternative for it. */ ! 740: && (TARGET_68020 ! 741: || !(GET_CODE (operands[0]) == MEM ! 742: && MEM_VOLATILE_P (operands[0])))) ! 743: return \"clr%.l %0\"; ! 744: else if (DATA_REG_P (operands[0]) ! 745: && INTVAL (operands[1]) < 128 ! 746: && INTVAL (operands[1]) >= -128) ! 747: { ! 748: #if defined(MOTOROLA) && !defined(CRDS) ! 749: return \"moveq%.l %1,%0\"; ! 750: #else ! 751: return \"moveq %1,%0\"; ! 752: #endif ! 753: } ! 754: #ifndef NO_ADDSUB_Q ! 755: else if (DATA_REG_P (operands[0]) ! 756: /* Do this with a moveq #N-8, dreg; addq #8,dreg */ ! 757: && INTVAL (operands[1]) < 136 ! 758: && INTVAL (operands[1]) >= 128) ! 759: { ! 760: operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8); ! 761: #if defined(MOTOROLA) && !defined(CRDS) ! 762: return \"moveq%.l %1,%0;addq%.w %#8,%0\"; ! 763: #else ! 764: return \"moveq %1,%0;addq%.w %#8,%0\"; ! 765: #endif ! 766: } ! 767: else if (DATA_REG_P (operands[0]) ! 768: /* Do this with a moveq #N+8, dreg; subq #8,dreg */ ! 769: && INTVAL (operands[1]) < -128 ! 770: && INTVAL (operands[1]) >= -136) ! 771: { ! 772: operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) + 8); ! 773: #if defined(MOTOROLA) && !defined(CRDS) ! 774: return \"moveq%.l %1,%0;subq%.w %#8,%0\"; ! 775: #else ! 776: return \"moveq %1,%0;subq%.w %#8,%0\"; ! 777: #endif ! 778: } ! 779: #endif ! 780: else if (DATA_REG_P (operands[0]) ! 781: /* If N is in the right range and is even, then use ! 782: moveq #N/2, dreg; addl dreg,dreg */ ! 783: && INTVAL (operands[1]) > 127 ! 784: && INTVAL (operands[1]) <= 254 ! 785: && INTVAL (operands[1]) % 2 == 0) ! 786: { ! 787: operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) / 2); ! 788: #if defined(MOTOROLA) && !defined(CRDS) ! 789: return \"moveq%.l %1,%0;add%.w %0,%0\"; ! 790: #else ! 791: return \"moveq %1,%0;add%.w %0,%0\"; ! 792: #endif ! 793: } ! 794: else if (ADDRESS_REG_P (operands[0]) ! 795: && INTVAL (operands[1]) < 0x8000 ! 796: && INTVAL (operands[1]) >= -0x8000) ! 797: return \"move%.w %1,%0\"; ! 798: else if (push_operand (operands[0], SImode) ! 799: && INTVAL (operands[1]) < 0x8000 ! 800: && INTVAL (operands[1]) >= -0x8000) ! 801: return \"pea %a1\"; ! 802: } ! 803: else if ((GET_CODE (operands[1]) == SYMBOL_REF ! 804: || GET_CODE (operands[1]) == CONST) ! 805: && push_operand (operands[0], SImode)) ! 806: return \"pea %a1\"; ! 807: else if ((GET_CODE (operands[1]) == SYMBOL_REF ! 808: || GET_CODE (operands[1]) == CONST) ! 809: && ADDRESS_REG_P (operands[0])) ! 810: return \"lea %a1,%0\"; ! 811: return \"move%.l %1,%0\"; ! 812: }") ! 813: ! 814: (define_insn "movhi" ! 815: [(set (match_operand:HI 0 "general_operand" "=g") ! 816: (match_operand:HI 1 "general_operand" "g"))] ! 817: "" ! 818: "* ! 819: { ! 820: if (GET_CODE (operands[1]) == CONST_INT) ! 821: { ! 822: if (operands[1] == const0_rtx ! 823: && (DATA_REG_P (operands[0]) ! 824: || GET_CODE (operands[0]) == MEM) ! 825: /* clr insns on 68000 read before writing. ! 826: This isn't so on the 68010, but we have no alternative for it. */ ! 827: && (TARGET_68020 ! 828: || !(GET_CODE (operands[0]) == MEM ! 829: && MEM_VOLATILE_P (operands[0])))) ! 830: return \"clr%.w %0\"; ! 831: else if (DATA_REG_P (operands[0]) ! 832: && INTVAL (operands[1]) < 128 ! 833: && INTVAL (operands[1]) >= -128) ! 834: { ! 835: #if defined(MOTOROLA) && !defined(CRDS) ! 836: return \"moveq%.l %1,%0\"; ! 837: #else ! 838: return \"moveq %1,%0\"; ! 839: #endif ! 840: } ! 841: else if (INTVAL (operands[1]) < 0x8000 ! 842: && INTVAL (operands[1]) >= -0x8000) ! 843: return \"move%.w %1,%0\"; ! 844: } ! 845: else if (CONSTANT_P (operands[1])) ! 846: return \"move%.l %1,%0\"; ! 847: #ifndef SGS_NO_LI ! 848: /* Recognize the insn before a tablejump, one that refers ! 849: to a table of offsets. Such an insn will need to refer ! 850: to a label on the insn. So output one. Use the label-number ! 851: of the table of offsets to generate this label. */ ! 852: if (GET_CODE (operands[1]) == MEM ! 853: && GET_CODE (XEXP (operands[1], 0)) == PLUS ! 854: && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF ! 855: || GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF) ! 856: && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS ! 857: && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) != PLUS) ! 858: { ! 859: rtx labelref; ! 860: if (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF) ! 861: labelref = XEXP (XEXP (operands[1], 0), 0); ! 862: else ! 863: labelref = XEXP (XEXP (operands[1], 0), 1); ! 864: #if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES) ! 865: #ifdef SGS ! 866: asm_fprintf (asm_out_file, \"\\tset %LLI%d,.+2\\n\", ! 867: CODE_LABEL_NUMBER (XEXP (labelref, 0))); ! 868: #else /* not SGS */ ! 869: asm_fprintf (asm_out_file, \"\\t.set %LLI%d,.+2\\n\", ! 870: CODE_LABEL_NUMBER (XEXP (labelref, 0))); ! 871: #endif /* not SGS */ ! 872: #else /* SGS_SWITCH_TABLES or not MOTOROLA */ ! 873: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LI\", ! 874: CODE_LABEL_NUMBER (XEXP (labelref, 0))); ! 875: /* For sake of 3b1, set flag saying we need to define the symbol ! 876: LD%n (with value L%n-LI%n) at the end of the switch table. */ ! 877: RTX_INTEGRATED_P (next_real_insn (XEXP (labelref, 0))) = 1; ! 878: #endif /* SGS_SWITCH_TABLES or not MOTOROLA */ ! 879: } ! 880: #endif /* SGS_NO_LI */ ! 881: return \"move%.w %1,%0\"; ! 882: }") ! 883: ! 884: (define_insn "movstricthi" ! 885: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm")) ! 886: (match_operand:HI 1 "general_operand" "rmn"))] ! 887: "" ! 888: "* ! 889: { ! 890: if (GET_CODE (operands[1]) == CONST_INT) ! 891: { ! 892: if (operands[1] == const0_rtx ! 893: && (DATA_REG_P (operands[0]) ! 894: || GET_CODE (operands[0]) == MEM) ! 895: /* clr insns on 68000 read before writing. ! 896: This isn't so on the 68010, but we have no alternative for it. */ ! 897: && (TARGET_68020 ! 898: || !(GET_CODE (operands[0]) == MEM ! 899: && MEM_VOLATILE_P (operands[0])))) ! 900: return \"clr%.w %0\"; ! 901: } ! 902: return \"move%.w %1,%0\"; ! 903: }") ! 904: ! 905: (define_insn "movqi" ! 906: [(set (match_operand:QI 0 "general_operand" "=d,*a,m,m,?*a") ! 907: (match_operand:QI 1 "general_operand" "dmi*a,d*a,dmi,?*a,m"))] ! 908: "" ! 909: "* ! 910: { ! 911: rtx xoperands[4]; ! 912: ! 913: /* This is probably useless, since it loses for pushing a struct ! 914: of several bytes a byte at a time. */ ! 915: if (GET_CODE (operands[0]) == MEM ! 916: && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC ! 917: && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx) ! 918: { ! 919: xoperands[1] = operands[1]; ! 920: xoperands[2] ! 921: = gen_rtx (MEM, QImode, ! 922: gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx)); ! 923: xoperands[3] = stack_pointer_rtx; ! 924: /* Just pushing a byte puts it in the high byte of the halfword. */ ! 925: /* We must put it in the low-order, high-numbered byte. */ ! 926: output_asm_insn (\"subq%.w %#2,%3\;move%.b %1,%2\", xoperands); ! 927: return \"\"; ! 928: } ! 929: ! 930: if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM) ! 931: { ! 932: xoperands[1] = operands[1]; ! 933: xoperands[2] ! 934: = gen_rtx (MEM, QImode, ! 935: gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx)); ! 936: xoperands[3] = stack_pointer_rtx; ! 937: /* Just pushing a byte puts it in the high byte of the halfword. */ ! 938: /* We must put it in the low half, the second byte. */ ! 939: output_asm_insn (\"subq%.w %#2,%3\;move%.b %1,%2\", xoperands); ! 940: return \"move%.w %+,%0\"; ! 941: } ! 942: if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM) ! 943: { ! 944: xoperands[0] = operands[0]; ! 945: xoperands[1] = operands[1]; ! 946: xoperands[2] ! 947: = gen_rtx (MEM, QImode, ! 948: gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx)); ! 949: xoperands[3] = stack_pointer_rtx; ! 950: output_asm_insn (\"move%.w %1,%-\;move%.b %2,%0\;addq%.w %#2,%3\", xoperands); ! 951: return \"\"; ! 952: } ! 953: /* clr and st insns on 68000 read before writing. ! 954: This isn't so on the 68010, but we have no alternative for it. */ ! 955: if (TARGET_68020 ! 956: || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) ! 957: { ! 958: if (operands[1] == const0_rtx) ! 959: return \"clr%.b %0\"; ! 960: if (GET_CODE (operands[1]) == CONST_INT ! 961: && INTVAL (operands[1]) == -1) ! 962: { ! 963: CC_STATUS_INIT; ! 964: return \"st %0\"; ! 965: } ! 966: } ! 967: if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1])) ! 968: return \"move%.l %1,%0\"; ! 969: if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1])) ! 970: return \"move%.w %1,%0\"; ! 971: return \"move%.b %1,%0\"; ! 972: }") ! 973: ! 974: (define_insn "movstrictqi" ! 975: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm")) ! 976: (match_operand:QI 1 "general_operand" "dmn"))] ! 977: "" ! 978: "* ! 979: { ! 980: if (operands[1] == const0_rtx ! 981: /* clr insns on 68000 read before writing. ! 982: This isn't so on the 68010, but we have no alternative for it. */ ! 983: && (TARGET_68020 ! 984: || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))) ! 985: return \"clr%.b %0\"; ! 986: return \"move%.b %1,%0\"; ! 987: }") ! 988: ! 989: (define_insn "movsf" ! 990: [(set (match_operand:SF 0 "general_operand" "=rmf,x,y,rm,!x,!rm") ! 991: (match_operand:SF 1 "general_operand" "rmfF,xH,rmF,y,rm,x"))] ! 992: ; [(set (match_operand:SF 0 "general_operand" "=rmf") ! 993: ; (match_operand:SF 1 "general_operand" "rmfF"))] ! 994: "" ! 995: "* ! 996: { ! 997: if (which_alternative >= 4) ! 998: return \"fpmove%.s %1,fpa0\;fpmove%.s fpa0,%0\"; ! 999: if (FPA_REG_P (operands[0])) ! 1000: { ! 1001: if (FPA_REG_P (operands[1])) ! 1002: return \"fpmove%.s %x1,%x0\"; ! 1003: else if (GET_CODE (operands[1]) == CONST_DOUBLE) ! 1004: return output_move_const_single (operands); ! 1005: else if (FP_REG_P (operands[1])) ! 1006: return \"fmove%.s %1,sp@-\;fpmove%.d sp@+, %0\"; ! 1007: return \"fpmove%.s %x1,%x0\"; ! 1008: } ! 1009: if (FPA_REG_P (operands[1])) ! 1010: { ! 1011: if (FP_REG_P (operands[0])) ! 1012: return \"fpmove%.s %x1,sp@-\;fmove%.s sp@+,%0\"; ! 1013: else ! 1014: return \"fpmove%.s %x1,%x0\"; ! 1015: } ! 1016: if (FP_REG_P (operands[0])) ! 1017: { ! 1018: if (FP_REG_P (operands[1])) ! 1019: return \"f%$move%.x %1,%0\"; ! 1020: else if (ADDRESS_REG_P (operands[1])) ! 1021: return \"move%.l %1,%-\;f%$move%.s %+,%0\"; ! 1022: else if (GET_CODE (operands[1]) == CONST_DOUBLE) ! 1023: return output_move_const_single (operands); ! 1024: return \"f%$move%.s %f1,%0\"; ! 1025: } ! 1026: if (FP_REG_P (operands[1])) ! 1027: { ! 1028: if (ADDRESS_REG_P (operands[0])) ! 1029: return \"fmove%.s %1,%-\;move%.l %+,%0\"; ! 1030: return \"fmove%.s %f1,%0\"; ! 1031: } ! 1032: return \"move%.l %1,%0\"; ! 1033: }") ! 1034: ! 1035: (define_insn "movdf" ! 1036: [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>,y,rm,x,!x,!rm") ! 1037: (match_operand:DF 1 "general_operand" "rf,m,rofE<>,rmE,y,xH,rm,x"))] ! 1038: ; [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>") ! 1039: ; (match_operand:DF 1 "general_operand" "rf,m,rofF<>"))] ! 1040: "" ! 1041: "* ! 1042: { ! 1043: if (which_alternative == 6) ! 1044: return \"fpmove%.d %x1,fpa0\;fpmove%.d fpa0,%x0\"; ! 1045: if (FPA_REG_P (operands[0])) ! 1046: { ! 1047: if (GET_CODE (operands[1]) == CONST_DOUBLE) ! 1048: return output_move_const_double (operands); ! 1049: if (FP_REG_P (operands[1])) ! 1050: return \"fmove%.d %1,sp@-\;fpmove%.d sp@+,%x0\"; ! 1051: return \"fpmove%.d %x1,%x0\"; ! 1052: } ! 1053: else if (FPA_REG_P (operands[1])) ! 1054: { ! 1055: if (FP_REG_P(operands[0])) ! 1056: return \"fpmove%.d %x1,sp@-\;fmoved sp@+,%0\"; ! 1057: else ! 1058: return \"fpmove%.d %x1,%x0\"; ! 1059: } ! 1060: if (FP_REG_P (operands[0])) ! 1061: { ! 1062: if (FP_REG_P (operands[1])) ! 1063: return \"f%&move%.x %1,%0\"; ! 1064: if (REG_P (operands[1])) ! 1065: { ! 1066: rtx xoperands[2]; ! 1067: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); ! 1068: output_asm_insn (\"move%.l %1,%-\", xoperands); ! 1069: output_asm_insn (\"move%.l %1,%-\", operands); ! 1070: return \"f%&move%.d %+,%0\"; ! 1071: } ! 1072: if (GET_CODE (operands[1]) == CONST_DOUBLE) ! 1073: return output_move_const_double (operands); ! 1074: return \"f%&move%.d %f1,%0\"; ! 1075: } ! 1076: else if (FP_REG_P (operands[1])) ! 1077: { ! 1078: if (REG_P (operands[0])) ! 1079: { ! 1080: output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands); ! 1081: operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); ! 1082: return \"move%.l %+,%0\"; ! 1083: } ! 1084: else ! 1085: return \"fmove%.d %f1,%0\"; ! 1086: } ! 1087: return output_move_double (operands); ! 1088: } ! 1089: ") ! 1090: ! 1091: ;; movdi can apply to fp regs in some cases ! 1092: (define_insn "movdi" ! 1093: ;; Let's see if it really still needs to handle fp regs, and, if so, why. ! 1094: [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>,y,rm,!*x,!rm") ! 1095: (match_operand:DI 1 "general_operand" "rF,m,roi<>F,rmiF,y,rmF,*x"))] ! 1096: ; [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>,!&rm,!&f,y,rm,x,!x,!rm") ! 1097: ; (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfmF,rmi,y,rm,x"))] ! 1098: ; [(set (match_operand:DI 0 "general_operand" "=rm,&rf,&ro<>,!&rm,!&f") ! 1099: ; (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfF"))] ! 1100: "" ! 1101: "* ! 1102: { ! 1103: if (which_alternative == 8) ! 1104: return \"fpmove%.d %x1,fpa0\;fpmove%.d fpa0,%x0\"; ! 1105: if (FPA_REG_P (operands[0]) || FPA_REG_P (operands[1])) ! 1106: return \"fpmove%.d %x1,%x0\"; ! 1107: if (FP_REG_P (operands[0])) ! 1108: { ! 1109: if (FP_REG_P (operands[1])) ! 1110: return \"fmove%.x %1,%0\"; ! 1111: if (REG_P (operands[1])) ! 1112: { ! 1113: rtx xoperands[2]; ! 1114: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); ! 1115: output_asm_insn (\"move%.l %1,%-\", xoperands); ! 1116: output_asm_insn (\"move%.l %1,%-\", operands); ! 1117: return \"fmove%.d %+,%0\"; ! 1118: } ! 1119: if (GET_CODE (operands[1]) == CONST_DOUBLE) ! 1120: return output_move_const_double (operands); ! 1121: return \"fmove%.d %f1,%0\"; ! 1122: } ! 1123: else if (FP_REG_P (operands[1])) ! 1124: { ! 1125: if (REG_P (operands[0])) ! 1126: { ! 1127: output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands); ! 1128: operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); ! 1129: return \"move%.l %+,%0\"; ! 1130: } ! 1131: else ! 1132: return \"fmove%.d %f1,%0\"; ! 1133: } ! 1134: return output_move_double (operands); ! 1135: } ! 1136: ") ! 1137: ! 1138: ;; Thus goes after the move instructions ! 1139: ;; because the move instructions are better (require no spilling) ! 1140: ;; when they can apply. It goes before the add/sub insns ! 1141: ;; so we will prefer it to them. ! 1142: ! 1143: (define_insn "pushasi" ! 1144: [(set (match_operand:SI 0 "push_operand" "=m") ! 1145: (match_operand:SI 1 "address_operand" "p"))] ! 1146: "" ! 1147: "pea %a1") ! 1148: ! 1149: ;; truncation instructions ! 1150: (define_insn "truncsiqi2" ! 1151: [(set (match_operand:QI 0 "general_operand" "=dm,d") ! 1152: (truncate:QI ! 1153: (match_operand:SI 1 "general_operand" "doJ,i")))] ! 1154: "" ! 1155: "* ! 1156: { ! 1157: if (GET_CODE (operands[0]) == REG) ! 1158: { ! 1159: /* Must clear condition codes, since the mov.l bases them on ! 1160: the entire 32 bits, not just the desired 8 bits. */ ! 1161: CC_STATUS_INIT; ! 1162: return \"move%.l %1,%0\"; ! 1163: } ! 1164: if (GET_CODE (operands[1]) == MEM) ! 1165: operands[1] = adj_offsettable_operand (operands[1], 3); ! 1166: return \"move%.b %1,%0\"; ! 1167: }") ! 1168: ! 1169: (define_insn "trunchiqi2" ! 1170: [(set (match_operand:QI 0 "general_operand" "=dm,d") ! 1171: (truncate:QI ! 1172: (match_operand:HI 1 "general_operand" "doJ,i")))] ! 1173: "" ! 1174: "* ! 1175: { ! 1176: if (GET_CODE (operands[0]) == REG ! 1177: && (GET_CODE (operands[1]) == MEM ! 1178: || GET_CODE (operands[1]) == CONST_INT)) ! 1179: { ! 1180: /* Must clear condition codes, since the mov.w bases them on ! 1181: the entire 16 bits, not just the desired 8 bits. */ ! 1182: CC_STATUS_INIT; ! 1183: return \"move%.w %1,%0\"; ! 1184: } ! 1185: if (GET_CODE (operands[0]) == REG) ! 1186: { ! 1187: /* Must clear condition codes, since the mov.l bases them on ! 1188: the entire 32 bits, not just the desired 8 bits. */ ! 1189: CC_STATUS_INIT; ! 1190: return \"move%.l %1,%0\"; ! 1191: } ! 1192: if (GET_CODE (operands[1]) == MEM) ! 1193: operands[1] = adj_offsettable_operand (operands[1], 1); ! 1194: return \"move%.b %1,%0\"; ! 1195: }") ! 1196: ! 1197: (define_insn "truncsihi2" ! 1198: [(set (match_operand:HI 0 "general_operand" "=dm,d") ! 1199: (truncate:HI ! 1200: (match_operand:SI 1 "general_operand" "roJ,i")))] ! 1201: "" ! 1202: "* ! 1203: { ! 1204: if (GET_CODE (operands[0]) == REG) ! 1205: { ! 1206: /* Must clear condition codes, since the mov.l bases them on ! 1207: the entire 32 bits, not just the desired 8 bits. */ ! 1208: CC_STATUS_INIT; ! 1209: return \"move%.l %1,%0\"; ! 1210: } ! 1211: if (GET_CODE (operands[1]) == MEM) ! 1212: operands[1] = adj_offsettable_operand (operands[1], 2); ! 1213: return \"move%.w %1,%0\"; ! 1214: }") ! 1215: ! 1216: ;; zero extension instructions ! 1217: ! 1218: (define_expand "zero_extendhisi2" ! 1219: [(set (match_operand:SI 0 "register_operand" "") ! 1220: (const_int 0)) ! 1221: (set (strict_low_part (match_dup 2)) ! 1222: (match_operand:HI 1 "general_operand" ""))] ! 1223: "" ! 1224: " ! 1225: { ! 1226: operands[1] = make_safe_from (operands[1], operands[0]); ! 1227: if (GET_CODE (operands[0]) == SUBREG) ! 1228: operands[2] = gen_rtx (SUBREG, HImode, SUBREG_REG (operands[0]), ! 1229: SUBREG_WORD (operands[0])); ! 1230: else ! 1231: operands[2] = gen_rtx (SUBREG, HImode, operands[0], 0); ! 1232: }") ! 1233: ! 1234: (define_expand "zero_extendqihi2" ! 1235: [(set (match_operand:HI 0 "register_operand" "") ! 1236: (const_int 0)) ! 1237: (set (strict_low_part (match_dup 2)) ! 1238: (match_operand:QI 1 "general_operand" ""))] ! 1239: "" ! 1240: " ! 1241: { ! 1242: operands[1] = make_safe_from (operands[1], operands[0]); ! 1243: if (GET_CODE (operands[0]) == SUBREG) ! 1244: operands[2] = gen_rtx (SUBREG, QImode, SUBREG_REG (operands[0]), ! 1245: SUBREG_WORD (operands[0])); ! 1246: else ! 1247: operands[2] = gen_rtx (SUBREG, QImode, operands[0], 0); ! 1248: }") ! 1249: ! 1250: (define_expand "zero_extendqisi2" ! 1251: [(set (match_operand:SI 0 "register_operand" "") ! 1252: (const_int 0)) ! 1253: (set (strict_low_part (match_dup 2)) ! 1254: (match_operand:QI 1 "general_operand" ""))] ! 1255: "" ! 1256: " ! 1257: { ! 1258: operands[1] = make_safe_from (operands[1], operands[0]); ! 1259: if (GET_CODE (operands[0]) == SUBREG) ! 1260: operands[2] = gen_rtx (SUBREG, QImode, SUBREG_REG (operands[0]), ! 1261: SUBREG_WORD (operands[0])); ! 1262: else ! 1263: operands[2] = gen_rtx (SUBREG, QImode, operands[0], 0); ! 1264: }") ! 1265: ! 1266: ;; Patterns to recognize zero-extend insns produced by the combiner. ! 1267: ;; We don't allow both operands in memory, because of aliasing problems. ! 1268: ! 1269: (define_insn "" ! 1270: [(set (match_operand:SI 0 "general_operand" "=do<>,d<") ! 1271: (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rn,m")))] ! 1272: "" ! 1273: "* ! 1274: { ! 1275: if (DATA_REG_P (operands[0])) ! 1276: { ! 1277: if (GET_CODE (operands[1]) == REG ! 1278: && REGNO (operands[0]) == REGNO (operands[1])) ! 1279: return \"and%.l %#0xFFFF,%0\"; ! 1280: if (reg_mentioned_p (operands[0], operands[1])) ! 1281: return \"move%.w %1,%0\;and%.l %#0xFFFF,%0\"; ! 1282: return \"clr%.l %0\;move%.w %1,%0\"; ! 1283: } ! 1284: else if (GET_CODE (operands[0]) == MEM ! 1285: && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) ! 1286: return \"move%.w %1,%0\;clr%.w %0\"; ! 1287: else if (GET_CODE (operands[0]) == MEM ! 1288: && GET_CODE (XEXP (operands[0], 0)) == POST_INC) ! 1289: return \"clr%.w %0\;move%.w %1,%0\"; ! 1290: else ! 1291: { ! 1292: output_asm_insn (\"clr%.w %0\", operands); ! 1293: operands[0] = adj_offsettable_operand (operands[0], 2); ! 1294: return \"move%.w %1,%0\"; ! 1295: } ! 1296: }") ! 1297: ! 1298: (define_insn "" ! 1299: [(set (match_operand:HI 0 "general_operand" "=do<>,d") ! 1300: (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "dn,m")))] ! 1301: "" ! 1302: "* ! 1303: { ! 1304: if (DATA_REG_P (operands[0])) ! 1305: { ! 1306: if (GET_CODE (operands[1]) == REG ! 1307: && REGNO (operands[0]) == REGNO (operands[1])) ! 1308: return \"and%.w %#0xFF,%0\"; ! 1309: if (reg_mentioned_p (operands[0], operands[1])) ! 1310: return \"move%.b %1,%0\;and%.w %#0xFF,%0\"; ! 1311: return \"clr%.w %0\;move%.b %1,%0\"; ! 1312: } ! 1313: else if (GET_CODE (operands[0]) == MEM ! 1314: && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) ! 1315: { ! 1316: if (REGNO (XEXP (XEXP (operands[0], 0), 0)) ! 1317: == STACK_POINTER_REGNUM) ! 1318: { ! 1319: output_asm_insn (\"clr%.w %-\", operands); ! 1320: operands[0] = gen_rtx (MEM, GET_MODE (operands[0]), ! 1321: plus_constant (stack_pointer_rtx, 1)); ! 1322: return \"move%.b %1,%0\"; ! 1323: } ! 1324: else ! 1325: return \"move%.b %1,%0\;clr%.b %0\"; ! 1326: } ! 1327: else if (GET_CODE (operands[0]) == MEM ! 1328: && GET_CODE (XEXP (operands[0], 0)) == POST_INC) ! 1329: return \"clr%.b %0\;move%.b %1,%0\"; ! 1330: else ! 1331: { ! 1332: output_asm_insn (\"clr%.b %0\", operands); ! 1333: operands[0] = adj_offsettable_operand (operands[0], 1); ! 1334: return \"move%.b %1,%0\"; ! 1335: } ! 1336: }") ! 1337: ! 1338: (define_insn "" ! 1339: [(set (match_operand:SI 0 "general_operand" "=do<>,d") ! 1340: (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "dn,m")))] ! 1341: "" ! 1342: "* ! 1343: { ! 1344: if (DATA_REG_P (operands[0])) ! 1345: { ! 1346: if (GET_CODE (operands[1]) == REG ! 1347: && REGNO (operands[0]) == REGNO (operands[1])) ! 1348: return \"and%.l %#0xFF,%0\"; ! 1349: if (reg_mentioned_p (operands[0], operands[1])) ! 1350: return \"move%.b %1,%0\;and%.l %#0xFF,%0\"; ! 1351: return \"clr%.l %0\;move%.b %1,%0\"; ! 1352: } ! 1353: else if (GET_CODE (operands[0]) == MEM ! 1354: && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) ! 1355: { ! 1356: operands[0] = XEXP (XEXP (operands[0], 0), 0); ! 1357: #ifdef MOTOROLA ! 1358: #ifdef SGS ! 1359: return \"clr%.l -(%0)\;move%.b %1,3(%0)\"; ! 1360: #else ! 1361: return \"clr%.l -(%0)\;move%.b %1,(3,%0)\"; ! 1362: #endif ! 1363: #else ! 1364: return \"clrl %0@-\;moveb %1,%0@(3)\"; ! 1365: #endif ! 1366: } ! 1367: else if (GET_CODE (operands[0]) == MEM ! 1368: && GET_CODE (XEXP (operands[0], 0)) == POST_INC) ! 1369: { ! 1370: operands[0] = XEXP (XEXP (operands[0], 0), 0); ! 1371: #ifdef MOTOROLA ! 1372: #ifdef SGS ! 1373: return \"clr%.l (%0)+\;move%.b %1,-1(%0)\"; ! 1374: #else ! 1375: return \"clr%.l (%0)+\;move%.b %1,(-1,%0)\"; ! 1376: #endif ! 1377: #else ! 1378: return \"clrl %0@+\;moveb %1,%0@(-1)\"; ! 1379: #endif ! 1380: } ! 1381: else ! 1382: { ! 1383: output_asm_insn (\"clr%.l %0\", operands); ! 1384: operands[0] = adj_offsettable_operand (operands[0], 3); ! 1385: return \"move%.b %1,%0\"; ! 1386: } ! 1387: }") ! 1388: ! 1389: ;; sign extension instructions ! 1390: ! 1391: (define_insn "extendhisi2" ! 1392: [(set (match_operand:SI 0 "general_operand" "=*d,a") ! 1393: (sign_extend:SI ! 1394: (match_operand:HI 1 "nonimmediate_operand" "0,rmn")))] ! 1395: "" ! 1396: "* ! 1397: { ! 1398: if (ADDRESS_REG_P (operands[0])) ! 1399: return \"move%.w %1,%0\"; ! 1400: return \"ext%.l %0\"; ! 1401: }") ! 1402: ! 1403: (define_insn "extendqihi2" ! 1404: [(set (match_operand:HI 0 "general_operand" "=d") ! 1405: (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))] ! 1406: "" ! 1407: "ext%.w %0") ! 1408: ! 1409: (define_insn "extendqisi2" ! 1410: [(set (match_operand:SI 0 "general_operand" "=d") ! 1411: (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))] ! 1412: "TARGET_68020" ! 1413: "extb%.l %0") ! 1414: ! 1415: ;; Conversions between float and double. ! 1416: ! 1417: (define_expand "extendsfdf2" ! 1418: [(set (match_operand:DF 0 "general_operand" "") ! 1419: (float_extend:DF ! 1420: (match_operand:SF 1 "general_operand" "")))] ! 1421: "TARGET_68881 || TARGET_FPA" ! 1422: "") ! 1423: ! 1424: (define_insn "" ! 1425: [(set (match_operand:DF 0 "general_operand" "=x,y") ! 1426: (float_extend:DF ! 1427: (match_operand:SF 1 "general_operand" "xH,rmF")))] ! 1428: "TARGET_FPA" ! 1429: "fpstod %w1,%0") ! 1430: ! 1431: (define_insn "" ! 1432: [(set (match_operand:DF 0 "general_operand" "=*fdm,f") ! 1433: (float_extend:DF ! 1434: (match_operand:SF 1 "general_operand" "f,dmF")))] ! 1435: "TARGET_68881" ! 1436: "* ! 1437: { ! 1438: if (FP_REG_P (operands[0]) && FP_REG_P (operands[1])) ! 1439: { ! 1440: if (REGNO (operands[0]) == REGNO (operands[1])) ! 1441: { ! 1442: /* Extending float to double in an fp-reg is a no-op. ! 1443: NOTICE_UPDATE_CC has already assumed that the ! 1444: cc will be set. So cancel what it did. */ ! 1445: cc_status = cc_prev_status; ! 1446: return \"\"; ! 1447: } ! 1448: return \"f%&move%.x %1,%0\"; ! 1449: } ! 1450: if (FP_REG_P (operands[0])) ! 1451: return \"f%&move%.s %f1,%0\"; ! 1452: if (DATA_REG_P (operands[0]) && FP_REG_P (operands[1])) ! 1453: { ! 1454: output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands); ! 1455: operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); ! 1456: return \"move%.l %+,%0\"; ! 1457: } ! 1458: return \"fmove%.d %f1,%0\"; ! 1459: }") ! 1460: ! 1461: ;; This cannot output into an f-reg because there is no way to be ! 1462: ;; sure of truncating in that case. ! 1463: ;; But on the Sun FPA, we can be sure. ! 1464: (define_expand "truncdfsf2" ! 1465: [(set (match_operand:SF 0 "general_operand" "") ! 1466: (float_truncate:SF ! 1467: (match_operand:DF 1 "general_operand" "")))] ! 1468: "TARGET_68881 || TARGET_FPA" ! 1469: "") ! 1470: ! 1471: (define_insn "" ! 1472: [(set (match_operand:SF 0 "general_operand" "=x,y") ! 1473: (float_truncate:SF ! 1474: (match_operand:DF 1 "general_operand" "xH,rmF")))] ! 1475: "TARGET_FPA" ! 1476: "fpdtos %y1,%0") ! 1477: ! 1478: ;; On the '040 we can truncate in a register accurately and easily. ! 1479: (define_insn "" ! 1480: [(set (match_operand:SF 0 "general_operand" "=f") ! 1481: (float_truncate:SF ! 1482: (match_operand:DF 1 "general_operand" "fmG")))] ! 1483: "TARGET_68040_ONLY" ! 1484: "* ! 1485: { ! 1486: if (FP_REG_P (operands[1])) ! 1487: return \"fsmove%.x %1,%0\"; ! 1488: return \"fsmove%.d %f1,%0\"; ! 1489: }") ! 1490: ! 1491: (define_insn "" ! 1492: [(set (match_operand:SF 0 "general_operand" "=dm") ! 1493: (float_truncate:SF ! 1494: (match_operand:DF 1 "general_operand" "f")))] ! 1495: "TARGET_68881" ! 1496: "fmove%.s %f1,%0") ! 1497: ! 1498: ;; Conversion between fixed point and floating point. ! 1499: ;; Note that among the fix-to-float insns ! 1500: ;; the ones that start with SImode come first. ! 1501: ;; That is so that an operand that is a CONST_INT ! 1502: ;; (and therefore lacks a specific machine mode). ! 1503: ;; will be recognized as SImode (which is always valid) ! 1504: ;; rather than as QImode or HImode. ! 1505: ! 1506: (define_expand "floatsisf2" ! 1507: [(set (match_operand:SF 0 "general_operand" "") ! 1508: (float:SF (match_operand:SI 1 "general_operand" "")))] ! 1509: "TARGET_68881 || TARGET_FPA" ! 1510: "") ! 1511: ! 1512: (define_insn "" ! 1513: [(set (match_operand:SF 0 "general_operand" "=y,x") ! 1514: (float:SF (match_operand:SI 1 "general_operand" "rmi,x")))] ! 1515: "TARGET_FPA" ! 1516: "fpltos %1,%0") ! 1517: ! 1518: (define_insn "" ! 1519: [(set (match_operand:SF 0 "general_operand" "=f") ! 1520: (float:SF (match_operand:SI 1 "general_operand" "dmi")))] ! 1521: "TARGET_68881" ! 1522: "f%$move%.l %1,%0") ! 1523: ! 1524: (define_expand "floatsidf2" ! 1525: [(set (match_operand:DF 0 "general_operand" "") ! 1526: (float:DF (match_operand:SI 1 "general_operand" "")))] ! 1527: "TARGET_68881 || TARGET_FPA" ! 1528: "") ! 1529: ! 1530: (define_insn "" ! 1531: [(set (match_operand:DF 0 "general_operand" "=y,x") ! 1532: (float:DF (match_operand:SI 1 "general_operand" "rmi,x")))] ! 1533: "TARGET_FPA" ! 1534: "fpltod %1,%0") ! 1535: ! 1536: (define_insn "" ! 1537: [(set (match_operand:DF 0 "general_operand" "=f") ! 1538: (float:DF (match_operand:SI 1 "general_operand" "dmi")))] ! 1539: "TARGET_68881" ! 1540: "f%&move%.l %1,%0") ! 1541: ! 1542: (define_insn "floathisf2" ! 1543: [(set (match_operand:SF 0 "general_operand" "=f") ! 1544: (float:SF (match_operand:HI 1 "general_operand" "dmn")))] ! 1545: "TARGET_68881" ! 1546: "f%$move%.w %1,%0") ! 1547: ! 1548: (define_insn "floathidf2" ! 1549: [(set (match_operand:DF 0 "general_operand" "=f") ! 1550: (float:DF (match_operand:HI 1 "general_operand" "dmn")))] ! 1551: "TARGET_68881" ! 1552: "fmove%.w %1,%0") ! 1553: ! 1554: (define_insn "floatqisf2" ! 1555: [(set (match_operand:SF 0 "general_operand" "=f") ! 1556: (float:SF (match_operand:QI 1 "general_operand" "dmn")))] ! 1557: "TARGET_68881" ! 1558: "fmove%.b %1,%0") ! 1559: ! 1560: (define_insn "floatqidf2" ! 1561: [(set (match_operand:DF 0 "general_operand" "=f") ! 1562: (float:DF (match_operand:QI 1 "general_operand" "dmn")))] ! 1563: "TARGET_68881" ! 1564: "f%&move%.b %1,%0") ! 1565: ! 1566: ;; New routines to convert floating-point values to integers ! 1567: ;; to be used on the '040. These should be faster than trapping ! 1568: ;; into the kernel to emulate fintrz. They should also be faster ! 1569: ;; than calling the subroutines fixsfsi() or fixdfsi(). ! 1570: ! 1571: (define_insn "fix_truncdfsi2" ! 1572: [(set (match_operand:SI 0 "general_operand" "=dm") ! 1573: (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f")))) ! 1574: (clobber (match_scratch:SI 2 "=d")) ! 1575: (clobber (match_scratch:SI 3 "=d"))] ! 1576: "TARGET_68040" ! 1577: "* ! 1578: { ! 1579: CC_STATUS_INIT; ! 1580: return \"fmovem%.l fpcr,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,fpcr\;fmove%.l %1,%0\;fmovem%.l %2,fpcr\"; ! 1581: }") ! 1582: ! 1583: (define_insn "fix_truncdfhi2" ! 1584: [(set (match_operand:HI 0 "general_operand" "=dm") ! 1585: (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "f")))) ! 1586: (clobber (match_scratch:SI 2 "=d")) ! 1587: (clobber (match_scratch:SI 3 "=d"))] ! 1588: "TARGET_68040" ! 1589: "* ! 1590: { ! 1591: CC_STATUS_INIT; ! 1592: return \"fmovem%.l fpcr,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,fpcr\;fmove%.w %1,%0\;fmovem%.l %2,fpcr\"; ! 1593: }") ! 1594: ! 1595: (define_insn "fix_truncdfqi2" ! 1596: [(set (match_operand:QI 0 "general_operand" "=dm") ! 1597: (fix:QI (fix:DF (match_operand:DF 1 "register_operand" "f")))) ! 1598: (clobber (match_scratch:SI 2 "=d")) ! 1599: (clobber (match_scratch:SI 3 "=d"))] ! 1600: "TARGET_68040" ! 1601: "* ! 1602: { ! 1603: CC_STATUS_INIT; ! 1604: return \"fmovem%.l fpcr,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,fpcr\;fmove%.b %1,%0\;fmovem%.l %2,fpcr\"; ! 1605: }") ! 1606: ! 1607: ;; Convert a float to a float whose value is an integer. ! 1608: ;; This is the first stage of converting it to an integer type. ! 1609: ! 1610: (define_insn "ftruncdf2" ! 1611: [(set (match_operand:DF 0 "general_operand" "=f") ! 1612: (fix:DF (match_operand:DF 1 "general_operand" "fFm")))] ! 1613: "TARGET_68881 && !TARGET_68040" ! 1614: "* ! 1615: { ! 1616: if (FP_REG_P (operands[1])) ! 1617: return \"fintrz%.x %f1,%0\"; ! 1618: return \"fintrz%.d %f1,%0\"; ! 1619: }") ! 1620: ! 1621: (define_insn "ftruncsf2" ! 1622: [(set (match_operand:SF 0 "general_operand" "=f") ! 1623: (fix:SF (match_operand:SF 1 "general_operand" "dfFm")))] ! 1624: "TARGET_68881 && !TARGET_68040" ! 1625: "* ! 1626: { ! 1627: if (FP_REG_P (operands[1])) ! 1628: return \"fintrz%.x %f1,%0\"; ! 1629: return \"fintrz%.s %f1,%0\"; ! 1630: }") ! 1631: ! 1632: ;; Convert a float whose value is an integer ! 1633: ;; to an actual integer. Second stage of converting float to integer type. ! 1634: (define_insn "fixsfqi2" ! 1635: [(set (match_operand:QI 0 "general_operand" "=dm") ! 1636: (fix:QI (match_operand:SF 1 "general_operand" "f")))] ! 1637: "TARGET_68881" ! 1638: "fmove%.b %1,%0") ! 1639: ! 1640: (define_insn "fixsfhi2" ! 1641: [(set (match_operand:HI 0 "general_operand" "=dm") ! 1642: (fix:HI (match_operand:SF 1 "general_operand" "f")))] ! 1643: "TARGET_68881" ! 1644: "fmove%.w %1,%0") ! 1645: ! 1646: (define_insn "fixsfsi2" ! 1647: [(set (match_operand:SI 0 "general_operand" "=dm") ! 1648: (fix:SI (match_operand:SF 1 "general_operand" "f")))] ! 1649: "TARGET_68881" ! 1650: "fmove%.l %1,%0") ! 1651: ! 1652: (define_insn "fixdfqi2" ! 1653: [(set (match_operand:QI 0 "general_operand" "=dm") ! 1654: (fix:QI (match_operand:DF 1 "general_operand" "f")))] ! 1655: "TARGET_68881" ! 1656: "fmove%.b %1,%0") ! 1657: ! 1658: (define_insn "fixdfhi2" ! 1659: [(set (match_operand:HI 0 "general_operand" "=dm") ! 1660: (fix:HI (match_operand:DF 1 "general_operand" "f")))] ! 1661: "TARGET_68881" ! 1662: "fmove%.w %1,%0") ! 1663: ! 1664: (define_insn "fixdfsi2" ! 1665: [(set (match_operand:SI 0 "general_operand" "=dm") ! 1666: (fix:SI (match_operand:DF 1 "general_operand" "f")))] ! 1667: "TARGET_68881" ! 1668: "fmove%.l %1,%0") ! 1669: ! 1670: ;; Convert a float to an integer. ! 1671: ;; On the Sun FPA, this is done in one step. ! 1672: ! 1673: (define_insn "" ! 1674: [(set (match_operand:SI 0 "general_operand" "=x,y") ! 1675: (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "xH,rmF"))))] ! 1676: "TARGET_FPA" ! 1677: "fpstol %w1,%0") ! 1678: ! 1679: (define_insn "" ! 1680: [(set (match_operand:SI 0 "general_operand" "=x,y") ! 1681: (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "xH,rmF"))))] ! 1682: "TARGET_FPA" ! 1683: "fpdtol %y1,%0") ! 1684: ! 1685: ;; add instructions ! 1686: ! 1687: ;; Note that the middle two alternatives are near-duplicates ! 1688: ;; in order to handle insns generated by reload. ! 1689: ;; This is needed since they are not themselves reloaded, ! 1690: ;; so commutativity won't apply to them. ! 1691: (define_insn "addsi3" ! 1692: [(set (match_operand:SI 0 "general_operand" "=m,?a,?a,r") ! 1693: (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0") ! 1694: (match_operand:SI 2 "general_operand" "dIKLs,rJK,a,mrIKLs")))] ! 1695: "" ! 1696: "* ! 1697: { ! 1698: if (! operands_match_p (operands[0], operands[1])) ! 1699: { ! 1700: if (!ADDRESS_REG_P (operands[1])) ! 1701: { ! 1702: rtx tmp = operands[1]; ! 1703: ! 1704: operands[1] = operands[2]; ! 1705: operands[2] = tmp; ! 1706: } ! 1707: ! 1708: /* These insns can result from reloads to access ! 1709: stack slots over 64k from the frame pointer. */ ! 1710: if (GET_CODE (operands[2]) == CONST_INT ! 1711: && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000) ! 1712: return \"move%.l %2,%0\;add%.l %1,%0\"; ! 1713: #ifdef SGS ! 1714: if (GET_CODE (operands[2]) == REG) ! 1715: return \"lea 0(%1,%2.l),%0\"; ! 1716: else ! 1717: return \"lea %c2(%1),%0\"; ! 1718: #else /* not SGS */ ! 1719: #ifdef MOTOROLA ! 1720: if (GET_CODE (operands[2]) == REG) ! 1721: return \"lea (%1,%2.l),%0\"; ! 1722: else ! 1723: return \"lea (%c2,%1),%0\"; ! 1724: #else /* not MOTOROLA (MIT syntax) */ ! 1725: if (GET_CODE (operands[2]) == REG) ! 1726: return \"lea %1@(0,%2:l),%0\"; ! 1727: else ! 1728: return \"lea %1@(%c2),%0\"; ! 1729: #endif /* not MOTOROLA */ ! 1730: #endif /* not SGS */ ! 1731: } ! 1732: if (GET_CODE (operands[2]) == CONST_INT) ! 1733: { ! 1734: #ifndef NO_ADDSUB_Q ! 1735: if (INTVAL (operands[2]) > 0 ! 1736: && INTVAL (operands[2]) <= 8) ! 1737: return (ADDRESS_REG_P (operands[0]) ! 1738: ? \"addq%.w %2,%0\" ! 1739: : \"addq%.l %2,%0\"); ! 1740: if (INTVAL (operands[2]) < 0 ! 1741: && INTVAL (operands[2]) >= -8) ! 1742: { ! 1743: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1744: - INTVAL (operands[2])); ! 1745: return (ADDRESS_REG_P (operands[0]) ! 1746: ? \"subq%.w %2,%0\" ! 1747: : \"subq%.l %2,%0\"); ! 1748: } ! 1749: /* On everything except the 68000 it is faster to use two ! 1750: addqw instuctions to add a small integer (8 < N <= 16) ! 1751: to an address register. Likewise for subqw.*/ ! 1752: if (INTVAL (operands[2]) > 8 ! 1753: && INTVAL (operands[2]) <= 16 ! 1754: && ADDRESS_REG_P (operands[0]) ! 1755: && TARGET_68020) ! 1756: { ! 1757: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8); ! 1758: return \"addq%.w %#8,%0; addq%.w %2,%0\"; ! 1759: } ! 1760: if (INTVAL (operands[2]) < -8 ! 1761: && INTVAL (operands[2]) >= -16 ! 1762: && ADDRESS_REG_P (operands[0]) ! 1763: && TARGET_68020) ! 1764: { ! 1765: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1766: - INTVAL (operands[2]) - 8); ! 1767: return \"subq%.w %#8,%0; subq%.w %2,%0\"; ! 1768: } ! 1769: #endif ! 1770: if (ADDRESS_REG_P (operands[0]) ! 1771: && INTVAL (operands[2]) >= -0x8000 ! 1772: && INTVAL (operands[2]) < 0x8000) ! 1773: return \"add%.w %2,%0\"; ! 1774: } ! 1775: return \"add%.l %2,%0\"; ! 1776: }") ! 1777: ! 1778: (define_insn "" ! 1779: [(set (match_operand:SI 0 "general_operand" "=a") ! 1780: (plus:SI (match_operand:SI 1 "general_operand" "0") ! 1781: (sign_extend:SI ! 1782: (match_operand:HI 2 "nonimmediate_operand" "rm"))))] ! 1783: "" ! 1784: "add%.w %2,%0") ! 1785: ! 1786: (define_insn "addhi3" ! 1787: [(set (match_operand:HI 0 "general_operand" "=m,r") ! 1788: (plus:HI (match_operand:HI 1 "general_operand" "%0,0") ! 1789: (match_operand:HI 2 "general_operand" "dn,rmn")))] ! 1790: "" ! 1791: "* ! 1792: { ! 1793: #ifndef NO_ADDSUB_Q ! 1794: if (GET_CODE (operands[2]) == CONST_INT) ! 1795: { ! 1796: if (INTVAL (operands[2]) > 0 ! 1797: && INTVAL (operands[2]) <= 8) ! 1798: return \"addq%.w %2,%0\"; ! 1799: if (INTVAL (operands[2]) < 0 ! 1800: && INTVAL (operands[2]) >= -8) ! 1801: { ! 1802: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1803: - INTVAL (operands[2])); ! 1804: return \"subq%.w %2,%0\"; ! 1805: } ! 1806: /* On everything except the 68000 it is faster to use two ! 1807: addqw instuctions to add a small integer (8 < N <= 16) ! 1808: to an address register. Likewise for subqw. */ ! 1809: if (INTVAL (operands[2]) > 8 ! 1810: && INTVAL (operands[2]) <= 16 ! 1811: && ADDRESS_REG_P (operands[0]) ! 1812: && TARGET_68020) ! 1813: { ! 1814: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8); ! 1815: return \"addq%.w %#8,%0; addq%.w %2,%0\"; ! 1816: } ! 1817: if (INTVAL (operands[2]) < -8 ! 1818: && INTVAL (operands[2]) >= -16 ! 1819: && ADDRESS_REG_P (operands[0]) ! 1820: && TARGET_68020) ! 1821: { ! 1822: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1823: - INTVAL (operands[2]) - 8); ! 1824: return \"subq%.w %#8,%0; subq%.w %2,%0\"; ! 1825: } ! 1826: } ! 1827: #endif ! 1828: return \"add%.w %2,%0\"; ! 1829: }") ! 1830: ! 1831: (define_insn "" ! 1832: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) ! 1833: (plus:HI (match_dup 0) ! 1834: (match_operand:HI 1 "general_operand" "dn,rmn")))] ! 1835: "" ! 1836: "add%.w %1,%0") ! 1837: ! 1838: (define_insn "addqi3" ! 1839: [(set (match_operand:QI 0 "general_operand" "=m,d") ! 1840: (plus:QI (match_operand:QI 1 "general_operand" "%0,0") ! 1841: (match_operand:QI 2 "general_operand" "dn,dmn")))] ! 1842: "" ! 1843: "* ! 1844: { ! 1845: #ifndef NO_ADDSUB_Q ! 1846: if (GET_CODE (operands[2]) == CONST_INT) ! 1847: { ! 1848: if (INTVAL (operands[2]) > 0 ! 1849: && INTVAL (operands[2]) <= 8) ! 1850: return \"addq%.b %2,%0\"; ! 1851: } ! 1852: if (GET_CODE (operands[2]) == CONST_INT) ! 1853: { ! 1854: if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) >= -8) ! 1855: { ! 1856: operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2])); ! 1857: return \"subq%.b %2,%0\"; ! 1858: } ! 1859: } ! 1860: #endif ! 1861: return \"add%.b %2,%0\"; ! 1862: }") ! 1863: ! 1864: (define_insn "" ! 1865: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) ! 1866: (plus:QI (match_dup 0) ! 1867: (match_operand:QI 1 "general_operand" "dn,dmn")))] ! 1868: "" ! 1869: "add%.b %1,%0") ! 1870: ! 1871: (define_expand "adddf3" ! 1872: [(set (match_operand:DF 0 "general_operand" "") ! 1873: (plus:DF (match_operand:DF 1 "general_operand" "") ! 1874: (match_operand:DF 2 "general_operand" "")))] ! 1875: "TARGET_68881 || TARGET_FPA" ! 1876: "") ! 1877: ! 1878: (define_insn "" ! 1879: [(set (match_operand:DF 0 "general_operand" "=x,y") ! 1880: (plus:DF (match_operand:DF 1 "general_operand" "%xH,y") ! 1881: (match_operand:DF 2 "general_operand" "xH,dmF")))] ! 1882: "TARGET_FPA" ! 1883: "* ! 1884: { ! 1885: if (rtx_equal_p (operands[0], operands[1])) ! 1886: return \"fpadd%.d %y2,%0\"; ! 1887: if (rtx_equal_p (operands[0], operands[2])) ! 1888: return \"fpadd%.d %y1,%0\"; ! 1889: if (which_alternative == 0) ! 1890: return \"fpadd3%.d %w2,%w1,%0\"; ! 1891: return \"fpadd3%.d %x2,%x1,%0\"; ! 1892: }") ! 1893: ! 1894: (define_insn "" ! 1895: [(set (match_operand:DF 0 "general_operand" "=f") ! 1896: (plus:DF (match_operand:DF 1 "general_operand" "%0") ! 1897: (match_operand:DF 2 "general_operand" "fmG")))] ! 1898: "TARGET_68881" ! 1899: "* ! 1900: { ! 1901: if (REG_P (operands[2])) ! 1902: return \"f%&add%.x %2,%0\"; ! 1903: return \"f%&add%.d %f2,%0\"; ! 1904: }") ! 1905: ! 1906: (define_expand "addsf3" ! 1907: [(set (match_operand:SF 0 "general_operand" "") ! 1908: (plus:SF (match_operand:SF 1 "general_operand" "") ! 1909: (match_operand:SF 2 "general_operand" "")))] ! 1910: "TARGET_68881 || TARGET_FPA" ! 1911: "") ! 1912: ! 1913: (define_insn "" ! 1914: [(set (match_operand:SF 0 "general_operand" "=x,y") ! 1915: (plus:SF (match_operand:SF 1 "general_operand" "%xH,y") ! 1916: (match_operand:SF 2 "general_operand" "xH,rmF")))] ! 1917: "TARGET_FPA" ! 1918: "* ! 1919: { ! 1920: if (rtx_equal_p (operands[0], operands[1])) ! 1921: return \"fpadd%.s %w2,%0\"; ! 1922: if (rtx_equal_p (operands[0], operands[2])) ! 1923: return \"fpadd%.s %w1,%0\"; ! 1924: if (which_alternative == 0) ! 1925: return \"fpadd3%.s %w2,%w1,%0\"; ! 1926: return \"fpadd3%.s %2,%1,%0\"; ! 1927: }") ! 1928: ! 1929: (define_insn "" ! 1930: [(set (match_operand:SF 0 "general_operand" "=f") ! 1931: (plus:SF (match_operand:SF 1 "general_operand" "%0") ! 1932: (match_operand:SF 2 "general_operand" "fdmF")))] ! 1933: "TARGET_68881" ! 1934: "* ! 1935: { ! 1936: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) ! 1937: return \"f%$add%.x %2,%0\"; ! 1938: return \"f%$add%.s %f2,%0\"; ! 1939: }") ! 1940: ! 1941: ;; subtract instructions ! 1942: ! 1943: (define_insn "subsi3" ! 1944: [(set (match_operand:SI 0 "general_operand" "=m,r,!a,?d") ! 1945: (minus:SI (match_operand:SI 1 "general_operand" "0,0,a,mrIKs") ! 1946: (match_operand:SI 2 "general_operand" "dIKs,mrIKs,J,0")))] ! 1947: "" ! 1948: "* ! 1949: { ! 1950: if (! operands_match_p (operands[0], operands[1])) ! 1951: { ! 1952: if (operands_match_p (operands[0], operands[2])) ! 1953: { ! 1954: #ifndef NO_ADDSUB_Q ! 1955: if (GET_CODE (operands[1]) == CONST_INT) ! 1956: { ! 1957: if (INTVAL (operands[1]) > 0 ! 1958: && INTVAL (operands[1]) <= 8) ! 1959: return \"subq%.l %1,%0\;neg%.l %0\"; ! 1960: } ! 1961: #endif ! 1962: return \"sub%.l %1,%0\;neg%.l %0\"; ! 1963: } ! 1964: /* This case is matched by J, but negating -0x8000 ! 1965: in an lea would give an invalid displacement. ! 1966: So do this specially. */ ! 1967: if (INTVAL (operands[2]) == -0x8000) ! 1968: return \"move%.l %1,%0\;sub%.l %2,%0\"; ! 1969: #ifdef SGS ! 1970: return \"lea %n2(%1),%0\"; ! 1971: #else ! 1972: #ifdef MOTOROLA ! 1973: return \"lea (%n2,%1),%0\"; ! 1974: #else /* not MOTOROLA (MIT syntax) */ ! 1975: return \"lea %1@(%n2),%0\"; ! 1976: #endif /* not MOTOROLA */ ! 1977: #endif /* not SGS */ ! 1978: } ! 1979: if (GET_CODE (operands[2]) == CONST_INT) ! 1980: { ! 1981: #ifndef NO_ADDSUB_Q ! 1982: if (INTVAL (operands[2]) > 0 ! 1983: && INTVAL (operands[2]) <= 8) ! 1984: return \"subq%.l %2,%0\"; ! 1985: /* Using two subqw for 8 < N <= 16 being subtracted from an ! 1986: address register is faster on all but 68000 */ ! 1987: if (INTVAL (operands[2]) > 8 ! 1988: && INTVAL (operands[2]) <= 16 ! 1989: && ADDRESS_REG_P (operands[0]) ! 1990: && TARGET_68020) ! 1991: { ! 1992: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8); ! 1993: return \"subq%.w %#8,%0; subq%.w %2,%0\"; ! 1994: } ! 1995: #endif ! 1996: if (ADDRESS_REG_P (operands[0]) ! 1997: && INTVAL (operands[2]) >= -0x8000 ! 1998: && INTVAL (operands[2]) < 0x8000) ! 1999: return \"sub%.w %2,%0\"; ! 2000: } ! 2001: return \"sub%.l %2,%0\"; ! 2002: }") ! 2003: ! 2004: (define_insn "" ! 2005: [(set (match_operand:SI 0 "general_operand" "=a") ! 2006: (minus:SI (match_operand:SI 1 "general_operand" "0") ! 2007: (sign_extend:SI ! 2008: (match_operand:HI 2 "nonimmediate_operand" "rmn"))))] ! 2009: "" ! 2010: "sub%.w %2,%0") ! 2011: ! 2012: (define_insn "subhi3" ! 2013: [(set (match_operand:HI 0 "general_operand" "=m,r") ! 2014: (minus:HI (match_operand:HI 1 "general_operand" "0,0") ! 2015: (match_operand:HI 2 "general_operand" "dn,rmn")))] ! 2016: "" ! 2017: "sub%.w %2,%0") ! 2018: ! 2019: (define_insn "" ! 2020: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) ! 2021: (minus:HI (match_dup 0) ! 2022: (match_operand:HI 1 "general_operand" "dn,rmn")))] ! 2023: "" ! 2024: "sub%.w %1,%0") ! 2025: ! 2026: (define_insn "subqi3" ! 2027: [(set (match_operand:QI 0 "general_operand" "=m,d") ! 2028: (minus:QI (match_operand:QI 1 "general_operand" "0,0") ! 2029: (match_operand:QI 2 "general_operand" "dn,dmn")))] ! 2030: "" ! 2031: "sub%.b %2,%0") ! 2032: ! 2033: (define_insn "" ! 2034: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) ! 2035: (minus:QI (match_dup 0) ! 2036: (match_operand:QI 1 "general_operand" "dn,dmn")))] ! 2037: "" ! 2038: "sub%.b %1,%0") ! 2039: ! 2040: (define_expand "subdf3" ! 2041: [(set (match_operand:DF 0 "general_operand" "") ! 2042: (minus:DF (match_operand:DF 1 "general_operand" "") ! 2043: (match_operand:DF 2 "general_operand" "")))] ! 2044: "TARGET_68881 || TARGET_FPA" ! 2045: "") ! 2046: ! 2047: (define_insn "" ! 2048: [(set (match_operand:DF 0 "general_operand" "=x,y,y") ! 2049: (minus:DF (match_operand:DF 1 "general_operand" "xH,y,dmF") ! 2050: (match_operand:DF 2 "general_operand" "xH,dmF,0")))] ! 2051: "TARGET_FPA" ! 2052: "* ! 2053: { ! 2054: if (rtx_equal_p (operands[0], operands[2])) ! 2055: return \"fprsub%.d %y1,%0\"; ! 2056: if (rtx_equal_p (operands[0], operands[1])) ! 2057: return \"fpsub%.d %y2,%0\"; ! 2058: if (which_alternative == 0) ! 2059: return \"fpsub3%.d %w2,%w1,%0\"; ! 2060: return \"fpsub3%.d %x2,%x1,%0\"; ! 2061: }") ! 2062: ! 2063: (define_insn "" ! 2064: [(set (match_operand:DF 0 "general_operand" "=f") ! 2065: (minus:DF (match_operand:DF 1 "general_operand" "0") ! 2066: (match_operand:DF 2 "general_operand" "fmG")))] ! 2067: "TARGET_68881" ! 2068: "* ! 2069: { ! 2070: if (REG_P (operands[2])) ! 2071: return \"f%&sub%.x %2,%0\"; ! 2072: return \"f%&sub%.d %f2,%0\"; ! 2073: }") ! 2074: ! 2075: (define_expand "subsf3" ! 2076: [(set (match_operand:SF 0 "general_operand" "") ! 2077: (minus:SF (match_operand:SF 1 "general_operand" "") ! 2078: (match_operand:SF 2 "general_operand" "")))] ! 2079: "TARGET_68881 || TARGET_FPA" ! 2080: "") ! 2081: ! 2082: (define_insn "" ! 2083: [(set (match_operand:SF 0 "general_operand" "=x,y,y") ! 2084: (minus:SF (match_operand:SF 1 "general_operand" "xH,y,rmF") ! 2085: (match_operand:SF 2 "general_operand" "xH,rmF,0")))] ! 2086: "TARGET_FPA" ! 2087: "* ! 2088: { ! 2089: if (rtx_equal_p (operands[0], operands[2])) ! 2090: return \"fprsub%.s %w1,%0\"; ! 2091: if (rtx_equal_p (operands[0], operands[1])) ! 2092: return \"fpsub%.s %w2,%0\"; ! 2093: if (which_alternative == 0) ! 2094: return \"fpsub3%.s %w2,%w1,%0\"; ! 2095: return \"fpsub3%.s %2,%1,%0\"; ! 2096: }") ! 2097: ! 2098: (define_insn "" ! 2099: [(set (match_operand:SF 0 "general_operand" "=f") ! 2100: (minus:SF (match_operand:SF 1 "general_operand" "0") ! 2101: (match_operand:SF 2 "general_operand" "fdmF")))] ! 2102: "TARGET_68881" ! 2103: "* ! 2104: { ! 2105: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) ! 2106: return \"f%$sub%.x %2,%0\"; ! 2107: return \"f%$sub%.s %f2,%0\"; ! 2108: }") ! 2109: ! 2110: ;; multiply instructions ! 2111: ! 2112: (define_insn "mulhi3" ! 2113: [(set (match_operand:HI 0 "general_operand" "=d") ! 2114: (mult:HI (match_operand:HI 1 "general_operand" "%0") ! 2115: (match_operand:HI 2 "general_operand" "dmn")))] ! 2116: "" ! 2117: "* ! 2118: { ! 2119: #if defined(MOTOROLA) && !defined(CRDS) ! 2120: return \"muls%.w %2,%0\"; ! 2121: #else ! 2122: return \"muls %2,%0\"; ! 2123: #endif ! 2124: }") ! 2125: ! 2126: (define_insn "mulhisi3" ! 2127: [(set (match_operand:SI 0 "general_operand" "=d") ! 2128: (mult:SI (sign_extend:SI ! 2129: (match_operand:HI 1 "nonimmediate_operand" "%0")) ! 2130: (sign_extend:SI ! 2131: (match_operand:HI 2 "nonimmediate_operand" "dmn"))))] ! 2132: "" ! 2133: "* ! 2134: { ! 2135: #if defined(MOTOROLA) && !defined(CRDS) ! 2136: return \"muls%.w %2,%0\"; ! 2137: #else ! 2138: return \"muls %2,%0\"; ! 2139: #endif ! 2140: }") ! 2141: ! 2142: (define_insn "" ! 2143: [(set (match_operand:SI 0 "general_operand" "=d") ! 2144: (mult:SI (sign_extend:SI ! 2145: (match_operand:HI 1 "nonimmediate_operand" "%0")) ! 2146: (match_operand:SI 2 "const_int_operand" "n")))] ! 2147: "" ! 2148: "* ! 2149: { ! 2150: #if defined(MOTOROLA) && !defined(CRDS) ! 2151: return \"muls%.w %2,%0\"; ! 2152: #else ! 2153: return \"muls %2,%0\"; ! 2154: #endif ! 2155: }") ! 2156: ! 2157: (define_insn "mulsi3" ! 2158: [(set (match_operand:SI 0 "general_operand" "=d") ! 2159: (mult:SI (match_operand:SI 1 "general_operand" "%0") ! 2160: (match_operand:SI 2 "general_operand" "dmsK")))] ! 2161: "TARGET_68020" ! 2162: "muls%.l %2,%0") ! 2163: ! 2164: (define_insn "umulhisi3" ! 2165: [(set (match_operand:SI 0 "general_operand" "=d") ! 2166: (mult:SI (zero_extend:SI ! 2167: (match_operand:HI 1 "nonimmediate_operand" "%0")) ! 2168: (zero_extend:SI ! 2169: (match_operand:HI 2 "nonimmediate_operand" "dmn"))))] ! 2170: "" ! 2171: "* ! 2172: { ! 2173: #if defined(MOTOROLA) && !defined(CRDS) ! 2174: return \"mulu%.w %2,%0\"; ! 2175: #else ! 2176: return \"mulu %2,%0\"; ! 2177: #endif ! 2178: }") ! 2179: ! 2180: (define_insn "" ! 2181: [(set (match_operand:SI 0 "general_operand" "=d") ! 2182: (mult:SI (zero_extend:SI ! 2183: (match_operand:HI 1 "nonimmediate_operand" "%0")) ! 2184: (match_operand:SI 2 "const_int_operand" "n")))] ! 2185: "" ! 2186: "* ! 2187: { ! 2188: #if defined(MOTOROLA) && !defined(CRDS) ! 2189: return \"mulu%.w %2,%0\"; ! 2190: #else ! 2191: return \"mulu %2,%0\"; ! 2192: #endif ! 2193: }") ! 2194: ! 2195: ;; We need a separate DEFINE_EXPAND for u?mulsidi3 to be able to use the ! 2196: ;; proper matching constraint. This is because the matching is between ! 2197: ;; the high-numbered word of the DImode operand[0] and operand[1]. ! 2198: (define_expand "umulsidi3" ! 2199: [(parallel ! 2200: [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 1) ! 2201: (subreg:SI ! 2202: (mult:DI (zero_extend:DI ! 2203: (match_operand:SI 1 "register_operand" "")) ! 2204: (zero_extend:DI ! 2205: (match_operand:SI 2 "general_operand" ""))) 1)) ! 2206: (set (subreg:SI (match_dup 0) 0) ! 2207: (subreg:SI ! 2208: (mult:DI (zero_extend:DI ! 2209: (match_dup 1)) ! 2210: (zero_extend:DI ! 2211: (match_dup 2))) 0))])] ! 2212: "TARGET_68020" ! 2213: "") ! 2214: ! 2215: (define_insn "" ! 2216: [(set (match_operand:SI 0 "register_operand" "=d") ! 2217: (subreg:SI ! 2218: (mult:DI (zero_extend:DI ! 2219: (match_operand:SI 1 "register_operand" "%0")) ! 2220: (zero_extend:DI ! 2221: (match_operand:SI 2 "general_operand" "dmsK"))) 1)) ! 2222: (set (match_operand:SI 3 "register_operand" "=d") ! 2223: (subreg:SI ! 2224: (mult:DI (zero_extend:DI ! 2225: (match_dup 1)) ! 2226: (zero_extend:DI ! 2227: (match_dup 2))) 0))] ! 2228: "TARGET_68020" ! 2229: "mulu%.l %2,%3:%0") ! 2230: ! 2231: (define_expand "mulsidi3" ! 2232: [(parallel ! 2233: [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 1) ! 2234: (subreg:SI ! 2235: (mult:DI (sign_extend:DI ! 2236: (match_operand:SI 1 "register_operand" "")) ! 2237: (sign_extend:DI ! 2238: (match_operand:SI 2 "general_operand" ""))) 1)) ! 2239: (set (subreg:SI (match_dup 0) 0) ! 2240: (subreg:SI ! 2241: (mult:DI (sign_extend:DI ! 2242: (match_dup 1)) ! 2243: (sign_extend:DI ! 2244: (match_dup 2))) 0))])] ! 2245: "TARGET_68020" ! 2246: "") ! 2247: ! 2248: (define_insn "" ! 2249: [(set (match_operand:SI 0 "register_operand" "=d") ! 2250: (subreg:SI ! 2251: (mult:DI (sign_extend:DI ! 2252: (match_operand:SI 1 "register_operand" "%0")) ! 2253: (sign_extend:DI ! 2254: (match_operand:SI 2 "general_operand" "dmKs"))) 1)) ! 2255: (set (match_operand:SI 3 "register_operand" "=d") ! 2256: (subreg:SI ! 2257: (mult:DI (sign_extend:DI ! 2258: (match_dup 1)) ! 2259: (sign_extend:DI ! 2260: (match_dup 2))) 0))] ! 2261: "TARGET_68020" ! 2262: "muls%.l %2,%3:%0") ! 2263: ! 2264: (define_expand "muldf3" ! 2265: [(set (match_operand:DF 0 "general_operand" "") ! 2266: (mult:DF (match_operand:DF 1 "general_operand" "") ! 2267: (match_operand:DF 2 "general_operand" "")))] ! 2268: "TARGET_68881 || TARGET_FPA" ! 2269: "") ! 2270: ! 2271: (define_insn "" ! 2272: [(set (match_operand:DF 0 "general_operand" "=x,y") ! 2273: (mult:DF (match_operand:DF 1 "general_operand" "%xH,y") ! 2274: (match_operand:DF 2 "general_operand" "xH,rmF")))] ! 2275: "TARGET_FPA" ! 2276: "* ! 2277: { ! 2278: if (rtx_equal_p (operands[1], operands[2])) ! 2279: return \"fpsqr%.d %y1,%0\"; ! 2280: if (rtx_equal_p (operands[0], operands[1])) ! 2281: return \"fpmul%.d %y2,%0\"; ! 2282: if (rtx_equal_p (operands[0], operands[2])) ! 2283: return \"fpmul%.d %y1,%0\"; ! 2284: if (which_alternative == 0) ! 2285: return \"fpmul3%.d %w2,%w1,%0\"; ! 2286: return \"fpmul3%.d %x2,%x1,%0\"; ! 2287: }") ! 2288: ! 2289: (define_insn "" ! 2290: [(set (match_operand:DF 0 "general_operand" "=f") ! 2291: (mult:DF (match_operand:DF 1 "general_operand" "%0") ! 2292: (match_operand:DF 2 "general_operand" "fmG")))] ! 2293: "TARGET_68881" ! 2294: "* ! 2295: { ! 2296: if (GET_CODE (operands[2]) == CONST_DOUBLE ! 2297: && floating_exact_log2 (operands[2]) && !TARGET_68040) ! 2298: { ! 2299: int i = floating_exact_log2 (operands[2]); ! 2300: operands[2] = gen_rtx (CONST_INT, VOIDmode, i); ! 2301: return \"fscale%.l %2,%0\"; ! 2302: } ! 2303: if (REG_P (operands[2])) ! 2304: return \"f%&mul%.x %2,%0\"; ! 2305: return \"f%&mul%.d %f2,%0\"; ! 2306: }") ! 2307: ! 2308: (define_expand "mulsf3" ! 2309: [(set (match_operand:SF 0 "general_operand" "") ! 2310: (mult:SF (match_operand:SF 1 "general_operand" "") ! 2311: (match_operand:SF 2 "general_operand" "")))] ! 2312: "TARGET_68881 || TARGET_FPA" ! 2313: "") ! 2314: ! 2315: (define_insn "" ! 2316: [(set (match_operand:SF 0 "general_operand" "=x,y") ! 2317: (mult:SF (match_operand:SF 1 "general_operand" "%xH,y") ! 2318: (match_operand:SF 2 "general_operand" "xH,rmF")))] ! 2319: "TARGET_FPA" ! 2320: "* ! 2321: { ! 2322: if (rtx_equal_p (operands[1], operands[2])) ! 2323: return \"fpsqr%.s %w1,%0\"; ! 2324: if (rtx_equal_p (operands[0], operands[1])) ! 2325: return \"fpmul%.s %w2,%0\"; ! 2326: if (rtx_equal_p (operands[0], operands[2])) ! 2327: return \"fpmul%.s %w1,%0\"; ! 2328: if (which_alternative == 0) ! 2329: return \"fpmul3%.s %w2,%w1,%0\"; ! 2330: return \"fpmul3%.s %2,%1,%0\"; ! 2331: }") ! 2332: ! 2333: (define_insn "" ! 2334: [(set (match_operand:SF 0 "general_operand" "=f") ! 2335: (mult:SF (match_operand:SF 1 "general_operand" "%0") ! 2336: (match_operand:SF 2 "general_operand" "fdmF")))] ! 2337: "TARGET_68881" ! 2338: "* ! 2339: { ! 2340: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) ! 2341: return (TARGET_68040_ONLY ! 2342: ? \"fsmul%.x %2,%0\" ! 2343: : \"fsglmul%.x %2,%0\"); ! 2344: return (TARGET_68040_ONLY ! 2345: ? \"fsmul%.s %f2,%0\" ! 2346: : \"fsglmul%.s %f2,%0\"); ! 2347: }") ! 2348: ! 2349: ;; divide instructions ! 2350: ! 2351: (define_insn "divhi3" ! 2352: [(set (match_operand:HI 0 "general_operand" "=d") ! 2353: (div:HI (match_operand:HI 1 "general_operand" "0") ! 2354: (match_operand:HI 2 "general_operand" "dmn")))] ! 2355: "" ! 2356: "* ! 2357: { ! 2358: #ifdef MOTOROLA ! 2359: return \"ext%.l %0\;divs%.w %2,%0\"; ! 2360: #else ! 2361: return \"extl %0\;divs %2,%0\"; ! 2362: #endif ! 2363: }") ! 2364: ! 2365: (define_insn "divhisi3" ! 2366: [(set (match_operand:HI 0 "general_operand" "=d") ! 2367: (truncate:HI ! 2368: (div:SI ! 2369: (match_operand:SI 1 "general_operand" "0") ! 2370: (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))] ! 2371: "" ! 2372: "* ! 2373: { ! 2374: #ifdef MOTOROLA ! 2375: return \"divs%.w %2,%0\"; ! 2376: #else ! 2377: return \"divs %2,%0\"; ! 2378: #endif ! 2379: }") ! 2380: ! 2381: (define_insn "" ! 2382: [(set (match_operand:HI 0 "general_operand" "=d") ! 2383: (truncate:HI (div:SI (match_operand:SI 1 "general_operand" "0") ! 2384: (match_operand:SI 2 "const_int_operand" "n"))))] ! 2385: "" ! 2386: "* ! 2387: { ! 2388: #ifdef MOTOROLA ! 2389: return \"divs%.w %2,%0\"; ! 2390: #else ! 2391: return \"divs %2,%0\"; ! 2392: #endif ! 2393: }") ! 2394: ! 2395: (define_insn "udivhi3" ! 2396: [(set (match_operand:HI 0 "general_operand" "=d") ! 2397: (udiv:HI (match_operand:HI 1 "general_operand" "0") ! 2398: (match_operand:HI 2 "general_operand" "dmn")))] ! 2399: "" ! 2400: "* ! 2401: { ! 2402: #ifdef MOTOROLA ! 2403: return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\"; ! 2404: #else ! 2405: return \"andl %#0xFFFF,%0\;divu %2,%0\"; ! 2406: #endif ! 2407: }") ! 2408: ! 2409: (define_insn "udivhisi3" ! 2410: [(set (match_operand:HI 0 "general_operand" "=d") ! 2411: (truncate:HI ! 2412: (udiv:SI ! 2413: (match_operand:SI 1 "general_operand" "0") ! 2414: (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))] ! 2415: "" ! 2416: "* ! 2417: { ! 2418: #ifdef MOTOROLA ! 2419: return \"divu%.w %2,%0\"; ! 2420: #else ! 2421: return \"divu %2,%0\"; ! 2422: #endif ! 2423: }") ! 2424: ! 2425: (define_insn "" ! 2426: [(set (match_operand:HI 0 "general_operand" "=d") ! 2427: (truncate:HI (udiv:SI (match_operand:SI 1 "general_operand" "0") ! 2428: (match_operand:SI 2 "const_int_operand" "n"))))] ! 2429: "" ! 2430: "* ! 2431: { ! 2432: #ifdef MOTOROLA ! 2433: return \"divu%.w %2,%0\"; ! 2434: #else ! 2435: return \"divu %2,%0\"; ! 2436: #endif ! 2437: }") ! 2438: ! 2439: (define_expand "divdf3" ! 2440: [(set (match_operand:DF 0 "general_operand" "") ! 2441: (div:DF (match_operand:DF 1 "general_operand" "") ! 2442: (match_operand:DF 2 "general_operand" "")))] ! 2443: "TARGET_68881 || TARGET_FPA" ! 2444: "") ! 2445: ! 2446: (define_insn "" ! 2447: [(set (match_operand:DF 0 "general_operand" "=x,y,y") ! 2448: (div:DF (match_operand:DF 1 "general_operand" "xH,y,rmF") ! 2449: (match_operand:DF 2 "general_operand" "xH,rmF,0")))] ! 2450: "TARGET_FPA" ! 2451: "* ! 2452: { ! 2453: if (rtx_equal_p (operands[0], operands[2])) ! 2454: return \"fprdiv%.d %y1,%0\"; ! 2455: if (rtx_equal_p (operands[0], operands[1])) ! 2456: return \"fpdiv%.d %y2,%0\"; ! 2457: if (which_alternative == 0) ! 2458: return \"fpdiv3%.d %w2,%w1,%0\"; ! 2459: return \"fpdiv3%.d %x2,%x1,%x0\"; ! 2460: }") ! 2461: ! 2462: (define_insn "" ! 2463: [(set (match_operand:DF 0 "general_operand" "=f") ! 2464: (div:DF (match_operand:DF 1 "general_operand" "0") ! 2465: (match_operand:DF 2 "general_operand" "fmG")))] ! 2466: "TARGET_68881" ! 2467: "* ! 2468: { ! 2469: if (REG_P (operands[2])) ! 2470: return \"f%&div%.x %2,%0\"; ! 2471: return \"f%&div%.d %f2,%0\"; ! 2472: }") ! 2473: ! 2474: (define_expand "divsf3" ! 2475: [(set (match_operand:SF 0 "general_operand" "") ! 2476: (div:SF (match_operand:SF 1 "general_operand" "") ! 2477: (match_operand:SF 2 "general_operand" "")))] ! 2478: "TARGET_68881 || TARGET_FPA" ! 2479: "") ! 2480: ! 2481: (define_insn "" ! 2482: [(set (match_operand:SF 0 "general_operand" "=x,y,y") ! 2483: (div:SF (match_operand:SF 1 "general_operand" "xH,y,rmF") ! 2484: (match_operand:SF 2 "general_operand" "xH,rmF,0")))] ! 2485: "TARGET_FPA" ! 2486: "* ! 2487: { ! 2488: if (rtx_equal_p (operands[0], operands[1])) ! 2489: return \"fpdiv%.s %w2,%0\"; ! 2490: if (rtx_equal_p (operands[0], operands[2])) ! 2491: return \"fprdiv%.s %w1,%0\"; ! 2492: if (which_alternative == 0) ! 2493: return \"fpdiv3%.s %w2,%w1,%0\"; ! 2494: return \"fpdiv3%.s %2,%1,%0\"; ! 2495: }") ! 2496: ! 2497: (define_insn "" ! 2498: [(set (match_operand:SF 0 "general_operand" "=f") ! 2499: (div:SF (match_operand:SF 1 "general_operand" "0") ! 2500: (match_operand:SF 2 "general_operand" "fdmF")))] ! 2501: "TARGET_68881" ! 2502: "* ! 2503: { ! 2504: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) ! 2505: return (TARGET_68040_ONLY ! 2506: ? \"fsdiv%.x %2,%0\" ! 2507: : \"fsgldiv%.x %2,%0\"); ! 2508: return (TARGET_68040_ONLY ! 2509: ? \"fsdiv%.s %f2,%0\" ! 2510: : \"fsgldiv%.s %f2,%0\"); ! 2511: }") ! 2512: ! 2513: ;; Remainder instructions. ! 2514: ! 2515: (define_insn "modhi3" ! 2516: [(set (match_operand:HI 0 "general_operand" "=d") ! 2517: (mod:HI (match_operand:HI 1 "general_operand" "0") ! 2518: (match_operand:HI 2 "general_operand" "dmn")))] ! 2519: "" ! 2520: "* ! 2521: { ! 2522: /* The swap insn produces cc's that don't correspond to the result. */ ! 2523: CC_STATUS_INIT; ! 2524: #ifdef MOTOROLA ! 2525: #ifdef SGS_SWAP_W ! 2526: return \"ext%.l %0\;divs%.w %2,%0\;swap%.w %0\"; ! 2527: #else ! 2528: return \"ext%.l %0\;divs%.w %2,%0\;swap %0\"; ! 2529: #endif ! 2530: #else ! 2531: return \"extl %0\;divs %2,%0\;swap %0\"; ! 2532: #endif ! 2533: }") ! 2534: ! 2535: (define_insn "modhisi3" ! 2536: [(set (match_operand:HI 0 "general_operand" "=d") ! 2537: (truncate:HI ! 2538: (mod:SI ! 2539: (match_operand:SI 1 "general_operand" "0") ! 2540: (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))] ! 2541: "" ! 2542: "* ! 2543: { ! 2544: /* The swap insn produces cc's that don't correspond to the result. */ ! 2545: CC_STATUS_INIT; ! 2546: #ifdef MOTOROLA ! 2547: #ifdef SGS_SWAP_W ! 2548: return \"divs%.w %2,%0\;swap%.w %0\"; ! 2549: #else ! 2550: return \"divs%.w %2,%0\;swap %0\"; ! 2551: #endif ! 2552: #else ! 2553: return \"divs %2,%0\;swap %0\"; ! 2554: #endif ! 2555: }") ! 2556: ! 2557: (define_insn "" ! 2558: [(set (match_operand:HI 0 "general_operand" "=d") ! 2559: (truncate:HI (mod:SI (match_operand:SI 1 "general_operand" "0") ! 2560: (match_operand:SI 2 "const_int_operand" "n"))))] ! 2561: "" ! 2562: "* ! 2563: { ! 2564: /* The swap insn produces cc's that don't correspond to the result. */ ! 2565: CC_STATUS_INIT; ! 2566: #ifdef MOTOROLA ! 2567: #ifdef SGS_SWAP_W ! 2568: return \"divs%.w %2,%0\;swap%.w %0\"; ! 2569: #else ! 2570: return \"divs%.w %2,%0\;swap %0\"; ! 2571: #endif ! 2572: #else ! 2573: return \"divs %2,%0\;swap %0\"; ! 2574: #endif ! 2575: }") ! 2576: ! 2577: (define_insn "umodhi3" ! 2578: [(set (match_operand:HI 0 "general_operand" "=d") ! 2579: (umod:HI (match_operand:HI 1 "general_operand" "0") ! 2580: (match_operand:HI 2 "general_operand" "dmn")))] ! 2581: "" ! 2582: "* ! 2583: { ! 2584: /* The swap insn produces cc's that don't correspond to the result. */ ! 2585: CC_STATUS_INIT; ! 2586: #ifdef MOTOROLA ! 2587: #ifdef SGS_SWAP_W ! 2588: return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\;swap%.w %0\"; ! 2589: #else ! 2590: return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\;swap %0\"; ! 2591: #endif ! 2592: #else ! 2593: return \"andl %#0xFFFF,%0\;divu %2,%0\;swap %0\"; ! 2594: #endif ! 2595: }") ! 2596: ! 2597: (define_insn "umodhisi3" ! 2598: [(set (match_operand:HI 0 "general_operand" "=d") ! 2599: (truncate:HI ! 2600: (umod:SI ! 2601: (match_operand:SI 1 "general_operand" "0") ! 2602: (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))] ! 2603: "" ! 2604: "* ! 2605: { ! 2606: /* The swap insn produces cc's that don't correspond to the result. */ ! 2607: CC_STATUS_INIT; ! 2608: #ifdef MOTOROLA ! 2609: #ifdef SGS_SWAP_W ! 2610: return \"divu%.w %2,%0\;swap%.w %0\"; ! 2611: #else ! 2612: return \"divu%.w %2,%0\;swap %0\"; ! 2613: #endif ! 2614: #else ! 2615: return \"divu %2,%0\;swap %0\"; ! 2616: #endif ! 2617: }") ! 2618: ! 2619: (define_insn "" ! 2620: [(set (match_operand:HI 0 "general_operand" "=d") ! 2621: (truncate:HI (umod:SI (match_operand:SI 1 "general_operand" "0") ! 2622: (match_operand:SI 2 "const_int_operand" "n"))))] ! 2623: "" ! 2624: "* ! 2625: { ! 2626: /* The swap insn produces cc's that don't correspond to the result. */ ! 2627: CC_STATUS_INIT; ! 2628: #ifdef MOTOROLA ! 2629: #ifdef SGS_SWAP_W ! 2630: return \"divu%.w %2,%0\;swap%.w %0\"; ! 2631: #else ! 2632: return \"divu%.w %2,%0\;swap %0\"; ! 2633: #endif ! 2634: #else ! 2635: return \"divu %2,%0\;swap %0\"; ! 2636: #endif ! 2637: }") ! 2638: ! 2639: (define_insn "divmodsi4" ! 2640: [(set (match_operand:SI 0 "general_operand" "=d") ! 2641: (div:SI (match_operand:SI 1 "general_operand" "0") ! 2642: (match_operand:SI 2 "general_operand" "dmsK"))) ! 2643: (set (match_operand:SI 3 "general_operand" "=d") ! 2644: (mod:SI (match_dup 1) (match_dup 2)))] ! 2645: "TARGET_68020" ! 2646: "* ! 2647: { ! 2648: if (find_reg_note (insn, REG_UNUSED, operands[3])) ! 2649: return \"divs%.l %2,%0\"; ! 2650: else ! 2651: return \"divsl%.l %2,%3:%0\"; ! 2652: }") ! 2653: ! 2654: (define_insn "udivmodsi4" ! 2655: [(set (match_operand:SI 0 "general_operand" "=d") ! 2656: (udiv:SI (match_operand:SI 1 "general_operand" "0") ! 2657: (match_operand:SI 2 "general_operand" "dmsK"))) ! 2658: (set (match_operand:SI 3 "general_operand" "=d") ! 2659: (umod:SI (match_dup 1) (match_dup 2)))] ! 2660: "TARGET_68020" ! 2661: "* ! 2662: { ! 2663: if (find_reg_note (insn, REG_UNUSED, operands[3])) ! 2664: return \"divu%.l %2,%0\"; ! 2665: else ! 2666: return \"divul%.l %2,%3:%0\"; ! 2667: }") ! 2668: ! 2669: ;; logical-and instructions ! 2670: ! 2671: ;; Prevent AND from being made with sp. This doesn't exist in the machine ! 2672: ;; and reload will cause inefficient code. Since sp is a FIXED_REG, we ! 2673: ;; can't allocate psuedos into it. ! 2674: (define_insn "andsi3" ! 2675: [(set (match_operand:SI 0 "not_sp_operand" "=m,d") ! 2676: (and:SI (match_operand:SI 1 "general_operand" "%0,0") ! 2677: (match_operand:SI 2 "general_operand" "dKs,dmKs")))] ! 2678: "" ! 2679: "* ! 2680: { ! 2681: int logval; ! 2682: if (GET_CODE (operands[2]) == CONST_INT ! 2683: && (INTVAL (operands[2]) | 0xffff) == 0xffffffff ! 2684: && (DATA_REG_P (operands[0]) ! 2685: || offsettable_memref_p (operands[0]))) ! 2686: { ! 2687: if (GET_CODE (operands[0]) != REG) ! 2688: operands[0] = adj_offsettable_operand (operands[0], 2); ! 2689: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 2690: INTVAL (operands[2]) & 0xffff); ! 2691: /* Do not delete a following tstl %0 insn; that would be incorrect. */ ! 2692: CC_STATUS_INIT; ! 2693: if (operands[2] == const0_rtx) ! 2694: return \"clr%.w %0\"; ! 2695: return \"and%.w %2,%0\"; ! 2696: } ! 2697: if (GET_CODE (operands[2]) == CONST_INT ! 2698: && (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0 ! 2699: && (DATA_REG_P (operands[0]) ! 2700: || offsettable_memref_p (operands[0]))) ! 2701: { ! 2702: if (DATA_REG_P (operands[0])) ! 2703: { ! 2704: operands[1] = gen_rtx (CONST_INT, VOIDmode, logval); ! 2705: } ! 2706: else ! 2707: { ! 2708: operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8)); operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8); ! 2709: } ! 2710: /* This does not set condition codes in a standard way. */ ! 2711: CC_STATUS_INIT; ! 2712: return \"bclr %1,%0\"; ! 2713: } ! 2714: return \"and%.l %2,%0\"; ! 2715: }") ! 2716: ! 2717: (define_insn "andhi3" ! 2718: [(set (match_operand:HI 0 "general_operand" "=m,d") ! 2719: (and:HI (match_operand:HI 1 "general_operand" "%0,0") ! 2720: (match_operand:HI 2 "general_operand" "dn,dmn")))] ! 2721: "" ! 2722: "and%.w %2,%0") ! 2723: ! 2724: (define_insn "andqi3" ! 2725: [(set (match_operand:QI 0 "general_operand" "=m,d") ! 2726: (and:QI (match_operand:QI 1 "general_operand" "%0,0") ! 2727: (match_operand:QI 2 "general_operand" "dn,dmn")))] ! 2728: "" ! 2729: "and%.b %2,%0") ! 2730: ! 2731: ! 2732: ;; inclusive-or instructions ! 2733: ! 2734: (define_insn "iorsi3" ! 2735: [(set (match_operand:SI 0 "general_operand" "=m,d") ! 2736: (ior:SI (match_operand:SI 1 "general_operand" "%0,0") ! 2737: (match_operand:SI 2 "general_operand" "dKs,dmKs")))] ! 2738: "" ! 2739: "* ! 2740: { ! 2741: register int logval; ! 2742: if (GET_CODE (operands[2]) == CONST_INT ! 2743: && INTVAL (operands[2]) >> 16 == 0 ! 2744: && (DATA_REG_P (operands[0]) ! 2745: || offsettable_memref_p (operands[0]))) ! 2746: { ! 2747: if (GET_CODE (operands[0]) != REG) ! 2748: operands[0] = adj_offsettable_operand (operands[0], 2); ! 2749: /* Do not delete a following tstl %0 insn; that would be incorrect. */ ! 2750: CC_STATUS_INIT; ! 2751: return \"or%.w %2,%0\"; ! 2752: } ! 2753: if (GET_CODE (operands[2]) == CONST_INT ! 2754: && (logval = exact_log2 (INTVAL (operands[2]))) >= 0 ! 2755: && (DATA_REG_P (operands[0]) ! 2756: || offsettable_memref_p (operands[0]))) ! 2757: { ! 2758: if (DATA_REG_P (operands[0])) ! 2759: { ! 2760: operands[1] = gen_rtx (CONST_INT, VOIDmode, logval); ! 2761: } ! 2762: else ! 2763: { ! 2764: operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8)); ! 2765: operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8); ! 2766: } ! 2767: return \"bset %1,%0\"; ! 2768: } ! 2769: return \"or%.l %2,%0\"; ! 2770: }") ! 2771: ! 2772: (define_insn "iorhi3" ! 2773: [(set (match_operand:HI 0 "general_operand" "=m,d") ! 2774: (ior:HI (match_operand:HI 1 "general_operand" "%0,0") ! 2775: (match_operand:HI 2 "general_operand" "dn,dmn")))] ! 2776: "" ! 2777: "or%.w %2,%0") ! 2778: ! 2779: (define_insn "iorqi3" ! 2780: [(set (match_operand:QI 0 "general_operand" "=m,d") ! 2781: (ior:QI (match_operand:QI 1 "general_operand" "%0,0") ! 2782: (match_operand:QI 2 "general_operand" "dn,dmn")))] ! 2783: "" ! 2784: "or%.b %2,%0") ! 2785: ! 2786: ;; xor instructions ! 2787: ! 2788: (define_insn "xorsi3" ! 2789: [(set (match_operand:SI 0 "general_operand" "=do,m") ! 2790: (xor:SI (match_operand:SI 1 "general_operand" "%0,0") ! 2791: (match_operand:SI 2 "general_operand" "di,dKs")))] ! 2792: "" ! 2793: "* ! 2794: { ! 2795: if (GET_CODE (operands[2]) == CONST_INT ! 2796: && INTVAL (operands[2]) >> 16 == 0 ! 2797: && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0]))) ! 2798: { ! 2799: if (! DATA_REG_P (operands[0])) ! 2800: operands[0] = adj_offsettable_operand (operands[0], 2); ! 2801: /* Do not delete a following tstl %0 insn; that would be incorrect. */ ! 2802: CC_STATUS_INIT; ! 2803: return \"eor%.w %2,%0\"; ! 2804: } ! 2805: return \"eor%.l %2,%0\"; ! 2806: }") ! 2807: ! 2808: (define_insn "xorhi3" ! 2809: [(set (match_operand:HI 0 "general_operand" "=dm") ! 2810: (xor:HI (match_operand:HI 1 "general_operand" "%0") ! 2811: (match_operand:HI 2 "general_operand" "dn")))] ! 2812: "" ! 2813: "eor%.w %2,%0") ! 2814: ! 2815: (define_insn "xorqi3" ! 2816: [(set (match_operand:QI 0 "general_operand" "=dm") ! 2817: (xor:QI (match_operand:QI 1 "general_operand" "%0") ! 2818: (match_operand:QI 2 "general_operand" "dn")))] ! 2819: "" ! 2820: "eor%.b %2,%0") ! 2821: ! 2822: ;; negation instructions ! 2823: ! 2824: (define_insn "negsi2" ! 2825: [(set (match_operand:SI 0 "general_operand" "=dm") ! 2826: (neg:SI (match_operand:SI 1 "general_operand" "0")))] ! 2827: "" ! 2828: "neg%.l %0") ! 2829: ! 2830: (define_insn "neghi2" ! 2831: [(set (match_operand:HI 0 "general_operand" "=dm") ! 2832: (neg:HI (match_operand:HI 1 "general_operand" "0")))] ! 2833: "" ! 2834: "neg%.w %0") ! 2835: ! 2836: (define_insn "negqi2" ! 2837: [(set (match_operand:QI 0 "general_operand" "=dm") ! 2838: (neg:QI (match_operand:QI 1 "general_operand" "0")))] ! 2839: "" ! 2840: "neg%.b %0") ! 2841: ! 2842: (define_expand "negsf2" ! 2843: [(set (match_operand:SF 0 "general_operand" "") ! 2844: (neg:SF (match_operand:SF 1 "general_operand" "")))] ! 2845: "TARGET_68881 || TARGET_FPA" ! 2846: "") ! 2847: ! 2848: (define_insn "" ! 2849: [(set (match_operand:SF 0 "general_operand" "=x,y") ! 2850: (neg:SF (match_operand:SF 1 "general_operand" "xH,rmF")))] ! 2851: "TARGET_FPA" ! 2852: "fpneg%.s %w1,%0") ! 2853: ! 2854: (define_insn "" ! 2855: [(set (match_operand:SF 0 "general_operand" "=f,d") ! 2856: (neg:SF (match_operand:SF 1 "general_operand" "fdmF,0")))] ! 2857: "TARGET_68881" ! 2858: "* ! 2859: { ! 2860: if (DATA_REG_P (operands[0])) ! 2861: { ! 2862: operands[1] = gen_rtx (CONST_INT, VOIDmode, 31); ! 2863: return \"bchg %1,%0\"; ! 2864: } ! 2865: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) ! 2866: return \"f%$neg%.x %1,%0\"; ! 2867: return \"f%$neg%.s %f1,%0\"; ! 2868: }") ! 2869: ! 2870: (define_expand "negdf2" ! 2871: [(set (match_operand:DF 0 "general_operand" "") ! 2872: (neg:DF (match_operand:DF 1 "general_operand" "")))] ! 2873: "TARGET_68881 || TARGET_FPA" ! 2874: "") ! 2875: ! 2876: (define_insn "" ! 2877: [(set (match_operand:DF 0 "general_operand" "=x,y") ! 2878: (neg:DF (match_operand:DF 1 "general_operand" "xH,rmF")))] ! 2879: "TARGET_FPA" ! 2880: "fpneg%.d %y1, %0") ! 2881: ! 2882: (define_insn "" ! 2883: [(set (match_operand:DF 0 "general_operand" "=f,d") ! 2884: (neg:DF (match_operand:DF 1 "general_operand" "fmF,0")))] ! 2885: "TARGET_68881" ! 2886: "* ! 2887: { ! 2888: if (DATA_REG_P (operands[0])) ! 2889: { ! 2890: operands[1] = gen_rtx (CONST_INT, VOIDmode, 31); ! 2891: return \"bchg %1,%0\"; ! 2892: } ! 2893: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) ! 2894: return \"f%&neg%.x %1,%0\"; ! 2895: return \"f%&neg%.d %f1,%0\"; ! 2896: }") ! 2897: ! 2898: ;; Absolute value instructions ! 2899: ! 2900: (define_expand "abssf2" ! 2901: [(set (match_operand:SF 0 "general_operand" "") ! 2902: (abs:SF (match_operand:SF 1 "general_operand" "")))] ! 2903: "TARGET_68881 || TARGET_FPA" ! 2904: "") ! 2905: ! 2906: (define_insn "" ! 2907: [(set (match_operand:SF 0 "general_operand" "=x,y") ! 2908: (abs:SF (match_operand:SF 1 "general_operand" "xH,rmF")))] ! 2909: "TARGET_FPA" ! 2910: "fpabs%.s %y1,%0") ! 2911: ! 2912: (define_insn "" ! 2913: [(set (match_operand:SF 0 "general_operand" "=f") ! 2914: (abs:SF (match_operand:SF 1 "general_operand" "fdmF")))] ! 2915: "TARGET_68881" ! 2916: "* ! 2917: { ! 2918: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) ! 2919: return \"f%$abs%.x %1,%0\"; ! 2920: return \"f%$abs%.s %f1,%0\"; ! 2921: }") ! 2922: ! 2923: (define_expand "absdf2" ! 2924: [(set (match_operand:DF 0 "general_operand" "") ! 2925: (abs:DF (match_operand:DF 1 "general_operand" "")))] ! 2926: "TARGET_68881 || TARGET_FPA" ! 2927: "") ! 2928: ! 2929: (define_insn "" ! 2930: [(set (match_operand:DF 0 "general_operand" "=x,y") ! 2931: (abs:DF (match_operand:DF 1 "general_operand" "xH,rmF")))] ! 2932: "TARGET_FPA" ! 2933: "fpabs%.d %y1,%0") ! 2934: ! 2935: (define_insn "" ! 2936: [(set (match_operand:DF 0 "general_operand" "=f") ! 2937: (abs:DF (match_operand:DF 1 "general_operand" "fmF")))] ! 2938: "TARGET_68881" ! 2939: "* ! 2940: { ! 2941: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) ! 2942: return \"f%&abs%.x %1,%0\"; ! 2943: return \"f%&abs%.d %f1,%0\"; ! 2944: }") ! 2945: ! 2946: ;; one complement instructions ! 2947: ! 2948: (define_insn "one_cmplsi2" ! 2949: [(set (match_operand:SI 0 "general_operand" "=dm") ! 2950: (not:SI (match_operand:SI 1 "general_operand" "0")))] ! 2951: "" ! 2952: "not%.l %0") ! 2953: ! 2954: (define_insn "one_cmplhi2" ! 2955: [(set (match_operand:HI 0 "general_operand" "=dm") ! 2956: (not:HI (match_operand:HI 1 "general_operand" "0")))] ! 2957: "" ! 2958: "not%.w %0") ! 2959: ! 2960: (define_insn "one_cmplqi2" ! 2961: [(set (match_operand:QI 0 "general_operand" "=dm") ! 2962: (not:QI (match_operand:QI 1 "general_operand" "0")))] ! 2963: "" ! 2964: "not%.b %0") ! 2965: ! 2966: ;; arithmetic shift instructions ! 2967: ;; We don't need the shift memory by 1 bit instruction ! 2968: ! 2969: ;; On the 68000, this makes faster code in a special case. ! 2970: ! 2971: (define_insn "" ! 2972: [(set (match_operand:SI 0 "register_operand" "=d") ! 2973: (ashift:SI (match_operand:SI 1 "register_operand" "0") ! 2974: (match_operand:SI 2 "immediate_operand" "i")))] ! 2975: "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT ! 2976: && INTVAL (operands[2]) >= 16 && INTVAL (operands[2]) <= 24)" ! 2977: "* ! 2978: { ! 2979: CC_STATUS_INIT; ! 2980: ! 2981: if (INTVAL (operands[2]) == 16) ! 2982: return \"swap %0\;clrw %0\"; ! 2983: ! 2984: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); ! 2985: return \"asl%.w %2,%0\;swap %0\;clrw %0\"; ! 2986: }") ! 2987: ! 2988: (define_insn "ashlsi3" ! 2989: [(set (match_operand:SI 0 "register_operand" "=d") ! 2990: (ashift:SI (match_operand:SI 1 "register_operand" "0") ! 2991: (match_operand:SI 2 "general_operand" "dI")))] ! 2992: "" ! 2993: "* ! 2994: { ! 2995: if (operands[2] == const1_rtx) ! 2996: return \"add%.l %0,%0\"; ! 2997: return \"asl%.l %2,%0\"; ! 2998: }") ! 2999: ! 3000: (define_insn "ashlhi3" ! 3001: [(set (match_operand:HI 0 "register_operand" "=d") ! 3002: (ashift:HI (match_operand:HI 1 "register_operand" "0") ! 3003: (match_operand:HI 2 "general_operand" "dI")))] ! 3004: "" ! 3005: "asl%.w %2,%0") ! 3006: ! 3007: (define_insn "ashlqi3" ! 3008: [(set (match_operand:QI 0 "register_operand" "=d") ! 3009: (ashift:QI (match_operand:QI 1 "register_operand" "0") ! 3010: (match_operand:QI 2 "general_operand" "dI")))] ! 3011: "" ! 3012: "asl%.b %2,%0") ! 3013: ! 3014: ;; On the 68000, this makes faster code in a special case. ! 3015: ! 3016: (define_insn "" ! 3017: [(set (match_operand:SI 0 "register_operand" "=d") ! 3018: (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") ! 3019: (match_operand:SI 2 "immediate_operand" "i")))] ! 3020: "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT ! 3021: && INTVAL (operands[2]) >= 16 && INTVAL (operands[2]) <= 24)" ! 3022: "* ! 3023: { ! 3024: if (INTVAL (operands[2]) == 16) ! 3025: return \"swap %0\;ext%.l %0\"; ! 3026: ! 3027: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); ! 3028: return \"swap %0\;asr%.w %2,%0\;ext%.l %0\"; ! 3029: }") ! 3030: ! 3031: (define_insn "ashrsi3" ! 3032: [(set (match_operand:SI 0 "register_operand" "=d") ! 3033: (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") ! 3034: (match_operand:SI 2 "general_operand" "dI")))] ! 3035: "" ! 3036: "* ! 3037: { ! 3038: return \"asr%.l %2,%0\"; ! 3039: }") ! 3040: ! 3041: (define_insn "ashrhi3" ! 3042: [(set (match_operand:HI 0 "register_operand" "=d") ! 3043: (ashiftrt:HI (match_operand:HI 1 "register_operand" "0") ! 3044: (match_operand:HI 2 "general_operand" "dI")))] ! 3045: "" ! 3046: "asr%.w %2,%0") ! 3047: ! 3048: (define_insn "ashrqi3" ! 3049: [(set (match_operand:QI 0 "register_operand" "=d") ! 3050: (ashiftrt:QI (match_operand:QI 1 "register_operand" "0") ! 3051: (match_operand:QI 2 "general_operand" "dI")))] ! 3052: "" ! 3053: "asr%.b %2,%0") ! 3054: ! 3055: ;; logical shift instructions ! 3056: ! 3057: ;; On the 68000, this makes faster code in a special case. ! 3058: ! 3059: (define_insn "" ! 3060: [(set (match_operand:SI 0 "register_operand" "=d") ! 3061: (lshift:SI (match_operand:SI 1 "register_operand" "0") ! 3062: (match_operand:SI 2 "immediate_operand" "i")))] ! 3063: "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT ! 3064: && INTVAL (operands[2]) >= 16 && INTVAL (operands[2]) <= 24)" ! 3065: "* ! 3066: { ! 3067: CC_STATUS_INIT; ! 3068: ! 3069: if (INTVAL (operands[2]) == 16) ! 3070: return \"swap %0\;clrw %0\"; ! 3071: ! 3072: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); ! 3073: return \"lsl%.w %2,%0\;swap %0\;clrw %0\"; ! 3074: }") ! 3075: ! 3076: (define_insn "lshlsi3" ! 3077: [(set (match_operand:SI 0 "register_operand" "=d") ! 3078: (lshift:SI (match_operand:SI 1 "register_operand" "0") ! 3079: (match_operand:SI 2 "general_operand" "dI")))] ! 3080: "" ! 3081: "* ! 3082: { ! 3083: if (operands[2] == const1_rtx) ! 3084: return \"add%.l %0,%0\"; ! 3085: return \"lsl%.l %2,%0\"; ! 3086: }") ! 3087: ! 3088: (define_insn "lshlhi3" ! 3089: [(set (match_operand:HI 0 "register_operand" "=d") ! 3090: (lshift:HI (match_operand:HI 1 "register_operand" "0") ! 3091: (match_operand:HI 2 "general_operand" "dI")))] ! 3092: "" ! 3093: "lsl%.w %2,%0") ! 3094: ! 3095: (define_insn "lshlqi3" ! 3096: [(set (match_operand:QI 0 "register_operand" "=d") ! 3097: (lshift:QI (match_operand:QI 1 "register_operand" "0") ! 3098: (match_operand:QI 2 "general_operand" "dI")))] ! 3099: "" ! 3100: "lsl%.b %2,%0") ! 3101: ! 3102: ;; On the 68000, this makes faster code in a special case. ! 3103: ! 3104: (define_insn "" ! 3105: [(set (match_operand:SI 0 "register_operand" "=d") ! 3106: (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") ! 3107: (match_operand:SI 2 "immediate_operand" "i")))] ! 3108: "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT ! 3109: && INTVAL (operands[2]) >= 16 && INTVAL (operands[2]) <= 24)" ! 3110: "* ! 3111: { ! 3112: if (INTVAL (operands[2]) == 16) ! 3113: { ! 3114: CC_STATUS_INIT; ! 3115: return \"clrw %0\;swap %0\"; ! 3116: } ! 3117: ! 3118: /* I think lsr%.w sets the CC properly. */ ! 3119: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); ! 3120: return \"clrw %0\;swap %0\;lsr%.w %2,%0\"; ! 3121: }") ! 3122: ! 3123: (define_insn "lshrsi3" ! 3124: [(set (match_operand:SI 0 "register_operand" "=d") ! 3125: (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") ! 3126: (match_operand:SI 2 "general_operand" "dI")))] ! 3127: "" ! 3128: "* ! 3129: { ! 3130: return \"lsr%.l %2,%0\"; ! 3131: }") ! 3132: ! 3133: (define_insn "lshrhi3" ! 3134: [(set (match_operand:HI 0 "register_operand" "=d") ! 3135: (lshiftrt:HI (match_operand:HI 1 "register_operand" "0") ! 3136: (match_operand:HI 2 "general_operand" "dI")))] ! 3137: "" ! 3138: "lsr%.w %2,%0") ! 3139: ! 3140: (define_insn "lshrqi3" ! 3141: [(set (match_operand:QI 0 "register_operand" "=d") ! 3142: (lshiftrt:QI (match_operand:QI 1 "register_operand" "0") ! 3143: (match_operand:QI 2 "general_operand" "dI")))] ! 3144: "" ! 3145: "lsr%.b %2,%0") ! 3146: ! 3147: ;; rotate instructions ! 3148: ! 3149: (define_insn "rotlsi3" ! 3150: [(set (match_operand:SI 0 "register_operand" "=d") ! 3151: (rotate:SI (match_operand:SI 1 "register_operand" "0") ! 3152: (match_operand:SI 2 "general_operand" "dI")))] ! 3153: "" ! 3154: "rol%.l %2,%0") ! 3155: ! 3156: (define_insn "rotlhi3" ! 3157: [(set (match_operand:HI 0 "register_operand" "=d") ! 3158: (rotate:HI (match_operand:HI 1 "register_operand" "0") ! 3159: (match_operand:HI 2 "general_operand" "dI")))] ! 3160: "" ! 3161: "rol%.w %2,%0") ! 3162: ! 3163: (define_insn "rotlqi3" ! 3164: [(set (match_operand:QI 0 "register_operand" "=d") ! 3165: (rotate:QI (match_operand:QI 1 "register_operand" "0") ! 3166: (match_operand:QI 2 "general_operand" "dI")))] ! 3167: "" ! 3168: "rol%.b %2,%0") ! 3169: ! 3170: (define_insn "rotrsi3" ! 3171: [(set (match_operand:SI 0 "register_operand" "=d") ! 3172: (rotatert:SI (match_operand:SI 1 "register_operand" "0") ! 3173: (match_operand:SI 2 "general_operand" "dI")))] ! 3174: "" ! 3175: "ror%.l %2,%0") ! 3176: ! 3177: (define_insn "rotrhi3" ! 3178: [(set (match_operand:HI 0 "register_operand" "=d") ! 3179: (rotatert:HI (match_operand:HI 1 "register_operand" "0") ! 3180: (match_operand:HI 2 "general_operand" "dI")))] ! 3181: "" ! 3182: "ror%.w %2,%0") ! 3183: ! 3184: (define_insn "rotrqi3" ! 3185: [(set (match_operand:QI 0 "register_operand" "=d") ! 3186: (rotatert:QI (match_operand:QI 1 "register_operand" "0") ! 3187: (match_operand:QI 2 "general_operand" "dI")))] ! 3188: "" ! 3189: "ror%.b %2,%0") ! 3190: ! 3191: ;; Special cases of bit-field insns which we should ! 3192: ;; recognize in preference to the general case. ! 3193: ;; These handle aligned 8-bit and 16-bit fields, ! 3194: ;; which can usually be done with move instructions. ! 3195: ! 3196: ; ! 3197: ; Special case for 32-bit field in memory. This only occurs when 32-bit ! 3198: ; alignment of structure members is specified. ! 3199: ; ! 3200: ; The move is allowed to be odd byte aligned, because that's still faster ! 3201: ; than an odd byte aligned bit field instruction. ! 3202: ; ! 3203: (define_insn "" ! 3204: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "o") ! 3205: (match_operand:SI 1 "immediate_operand" "i") ! 3206: (match_operand:SI 2 "immediate_operand" "i")) ! 3207: (match_operand:SI 3 "general_operand" "rmi"))] ! 3208: "TARGET_68020 && TARGET_BITFIELD ! 3209: && GET_CODE (operands[1]) == CONST_INT ! 3210: && (INTVAL (operands[1]) == 32) ! 3211: && GET_CODE (operands[2]) == CONST_INT ! 3212: && (INTVAL (operands[2]) % 8) == 0 ! 3213: && ! mode_dependent_address_p (XEXP (operands[0], 0))" ! 3214: "* ! 3215: { ! 3216: operands[0] ! 3217: = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8); ! 3218: ! 3219: return \"move%.l %3,%0\"; ! 3220: }") ! 3221: ! 3222: (define_insn "" ! 3223: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+do") ! 3224: (match_operand:SI 1 "immediate_operand" "i") ! 3225: (match_operand:SI 2 "immediate_operand" "i")) ! 3226: (match_operand:SI 3 "general_operand" "d"))] ! 3227: "TARGET_68020 && TARGET_BITFIELD ! 3228: && GET_CODE (operands[1]) == CONST_INT ! 3229: && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) ! 3230: && GET_CODE (operands[2]) == CONST_INT ! 3231: && INTVAL (operands[2]) % INTVAL (operands[1]) == 0 ! 3232: && (GET_CODE (operands[0]) == REG ! 3233: || ! mode_dependent_address_p (XEXP (operands[0], 0)))" ! 3234: "* ! 3235: { ! 3236: if (REG_P (operands[0])) ! 3237: { ! 3238: if (INTVAL (operands[1]) + INTVAL (operands[2]) != 32) ! 3239: return \"bfins %3,%0{%b2:%b1}\"; ! 3240: } ! 3241: else ! 3242: operands[0] ! 3243: = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8); ! 3244: ! 3245: if (GET_CODE (operands[3]) == MEM) ! 3246: operands[3] = adj_offsettable_operand (operands[3], ! 3247: (32 - INTVAL (operands[1])) / 8); ! 3248: if (INTVAL (operands[1]) == 8) ! 3249: return \"move%.b %3,%0\"; ! 3250: return \"move%.w %3,%0\"; ! 3251: }") ! 3252: ! 3253: ! 3254: ; ! 3255: ; Special case for 32-bit field in memory. This only occurs when 32-bit ! 3256: ; alignment of structure members is specified. ! 3257: ; ! 3258: ; The move is allowed to be odd byte aligned, because that's still faster ! 3259: ; than an odd byte aligned bit field instruction. ! 3260: ; ! 3261: (define_insn "" ! 3262: [(set (match_operand:SI 0 "general_operand" "=rm") ! 3263: (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o") ! 3264: (match_operand:SI 2 "immediate_operand" "i") ! 3265: (match_operand:SI 3 "immediate_operand" "i")))] ! 3266: "TARGET_68020 && TARGET_BITFIELD ! 3267: && GET_CODE (operands[2]) == CONST_INT ! 3268: && (INTVAL (operands[2]) == 32) ! 3269: && GET_CODE (operands[3]) == CONST_INT ! 3270: && (INTVAL (operands[3]) % 8) == 0 ! 3271: && ! mode_dependent_address_p (XEXP (operands[1], 0))" ! 3272: "* ! 3273: { ! 3274: operands[1] ! 3275: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); ! 3276: ! 3277: return \"move%.l %1,%0\"; ! 3278: }") ! 3279: ! 3280: (define_insn "" ! 3281: [(set (match_operand:SI 0 "general_operand" "=&d") ! 3282: (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do") ! 3283: (match_operand:SI 2 "immediate_operand" "i") ! 3284: (match_operand:SI 3 "immediate_operand" "i")))] ! 3285: "TARGET_68020 && TARGET_BITFIELD ! 3286: && GET_CODE (operands[2]) == CONST_INT ! 3287: && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) ! 3288: && GET_CODE (operands[3]) == CONST_INT ! 3289: && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 ! 3290: && (GET_CODE (operands[1]) == REG ! 3291: || ! mode_dependent_address_p (XEXP (operands[1], 0)))" ! 3292: "* ! 3293: { ! 3294: cc_status.flags |= CC_NOT_NEGATIVE; ! 3295: if (REG_P (operands[1])) ! 3296: { ! 3297: if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32) ! 3298: return \"bfextu %1{%b3:%b2},%0\"; ! 3299: } ! 3300: else ! 3301: operands[1] ! 3302: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); ! 3303: ! 3304: output_asm_insn (\"clr%.l %0\", operands); ! 3305: if (GET_CODE (operands[0]) == MEM) ! 3306: operands[0] = adj_offsettable_operand (operands[0], ! 3307: (32 - INTVAL (operands[1])) / 8); ! 3308: if (INTVAL (operands[2]) == 8) ! 3309: return \"move%.b %1,%0\"; ! 3310: return \"move%.w %1,%0\"; ! 3311: }") ! 3312: ! 3313: ; ! 3314: ; Special case for 32-bit field in memory. This only occurs when 32-bit ! 3315: ; alignment of structure members is specified. ! 3316: ; ! 3317: ; The move is allowed to be odd byte aligned, because that's still faster ! 3318: ; than an odd byte aligned bit field instruction. ! 3319: ; ! 3320: (define_insn "" ! 3321: [(set (match_operand:SI 0 "general_operand" "=rm") ! 3322: (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o") ! 3323: (match_operand:SI 2 "immediate_operand" "i") ! 3324: (match_operand:SI 3 "immediate_operand" "i")))] ! 3325: "TARGET_68020 && TARGET_BITFIELD ! 3326: && GET_CODE (operands[2]) == CONST_INT ! 3327: && (INTVAL (operands[2]) == 32) ! 3328: && GET_CODE (operands[3]) == CONST_INT ! 3329: && (INTVAL (operands[3]) % 8) == 0 ! 3330: && ! mode_dependent_address_p (XEXP (operands[1], 0))" ! 3331: "* ! 3332: { ! 3333: operands[1] ! 3334: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); ! 3335: ! 3336: return \"move%.l %1,%0\"; ! 3337: }") ! 3338: ! 3339: (define_insn "" ! 3340: [(set (match_operand:SI 0 "general_operand" "=d") ! 3341: (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do") ! 3342: (match_operand:SI 2 "immediate_operand" "i") ! 3343: (match_operand:SI 3 "immediate_operand" "i")))] ! 3344: "TARGET_68020 && TARGET_BITFIELD ! 3345: && GET_CODE (operands[2]) == CONST_INT ! 3346: && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) ! 3347: && GET_CODE (operands[3]) == CONST_INT ! 3348: && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 ! 3349: && (GET_CODE (operands[1]) == REG ! 3350: || ! mode_dependent_address_p (XEXP (operands[1], 0)))" ! 3351: "* ! 3352: { ! 3353: if (REG_P (operands[1])) ! 3354: { ! 3355: if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32) ! 3356: return \"bfexts %1{%b3:%b2},%0\"; ! 3357: } ! 3358: else ! 3359: operands[1] ! 3360: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); ! 3361: ! 3362: if (INTVAL (operands[2]) == 8) ! 3363: return \"move%.b %1,%0\;extb%.l %0\"; ! 3364: return \"move%.w %1,%0\;ext%.l %0\"; ! 3365: }") ! 3366: ! 3367: ;; Bit field instructions, general cases. ! 3368: ;; "o,d" constraint causes a nonoffsettable memref to match the "o" ! 3369: ;; so that its address is reloaded. ! 3370: ! 3371: (define_insn "extv" ! 3372: [(set (match_operand:SI 0 "general_operand" "=d,d") ! 3373: (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d") ! 3374: (match_operand:SI 2 "general_operand" "di,di") ! 3375: (match_operand:SI 3 "general_operand" "di,di")))] ! 3376: "TARGET_68020 && TARGET_BITFIELD" ! 3377: "bfexts %1{%b3:%b2},%0") ! 3378: ! 3379: (define_insn "extzv" ! 3380: [(set (match_operand:SI 0 "general_operand" "=d,d") ! 3381: (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d") ! 3382: (match_operand:SI 2 "general_operand" "di,di") ! 3383: (match_operand:SI 3 "general_operand" "di,di")))] ! 3384: "TARGET_68020 && TARGET_BITFIELD" ! 3385: "* ! 3386: { ! 3387: cc_status.flags |= CC_NOT_NEGATIVE; ! 3388: return \"bfextu %1{%b3:%b2},%0\"; ! 3389: }") ! 3390: ! 3391: (define_insn "" ! 3392: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d") ! 3393: (match_operand:SI 1 "general_operand" "di,di") ! 3394: (match_operand:SI 2 "general_operand" "di,di")) ! 3395: (xor:SI (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)) ! 3396: (match_operand 3 "immediate_operand" "i,i")))] ! 3397: "TARGET_68020 && TARGET_BITFIELD ! 3398: && GET_CODE (operands[3]) == CONST_INT ! 3399: && (INTVAL (operands[3]) == -1 ! 3400: || (GET_CODE (operands[1]) == CONST_INT ! 3401: && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))" ! 3402: "* ! 3403: { ! 3404: CC_STATUS_INIT; ! 3405: return \"bfchg %0{%b2:%b1}\"; ! 3406: }") ! 3407: ! 3408: (define_insn "" ! 3409: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d") ! 3410: (match_operand:SI 1 "general_operand" "di,di") ! 3411: (match_operand:SI 2 "general_operand" "di,di")) ! 3412: (const_int 0))] ! 3413: "TARGET_68020 && TARGET_BITFIELD" ! 3414: "* ! 3415: { ! 3416: CC_STATUS_INIT; ! 3417: return \"bfclr %0{%b2:%b1}\"; ! 3418: }") ! 3419: ! 3420: (define_insn "" ! 3421: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d") ! 3422: (match_operand:SI 1 "general_operand" "di,di") ! 3423: (match_operand:SI 2 "general_operand" "di,di")) ! 3424: (const_int -1))] ! 3425: "TARGET_68020 && TARGET_BITFIELD" ! 3426: "* ! 3427: { ! 3428: CC_STATUS_INIT; ! 3429: return \"bfset %0{%b2:%b1}\"; ! 3430: }") ! 3431: ! 3432: (define_insn "insv" ! 3433: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d") ! 3434: (match_operand:SI 1 "general_operand" "di,di") ! 3435: (match_operand:SI 2 "general_operand" "di,di")) ! 3436: (match_operand:SI 3 "general_operand" "d,d"))] ! 3437: "TARGET_68020 && TARGET_BITFIELD" ! 3438: "bfins %3,%0{%b2:%b1}") ! 3439: ! 3440: ;; Now recognize bit field insns that operate on registers ! 3441: ;; (or at least were intended to do so). ! 3442: ! 3443: (define_insn "" ! 3444: [(set (match_operand:SI 0 "general_operand" "=d") ! 3445: (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d") ! 3446: (match_operand:SI 2 "general_operand" "di") ! 3447: (match_operand:SI 3 "general_operand" "di")))] ! 3448: "TARGET_68020 && TARGET_BITFIELD" ! 3449: "bfexts %1{%b3:%b2},%0") ! 3450: ! 3451: (define_insn "" ! 3452: [(set (match_operand:SI 0 "general_operand" "=d") ! 3453: (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d") ! 3454: (match_operand:SI 2 "general_operand" "di") ! 3455: (match_operand:SI 3 "general_operand" "di")))] ! 3456: "TARGET_68020 && TARGET_BITFIELD" ! 3457: "* ! 3458: { ! 3459: cc_status.flags |= CC_NOT_NEGATIVE; ! 3460: return \"bfextu %1{%b3:%b2},%0\"; ! 3461: }") ! 3462: ! 3463: (define_insn "" ! 3464: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d") ! 3465: (match_operand:SI 1 "general_operand" "di") ! 3466: (match_operand:SI 2 "general_operand" "di")) ! 3467: (const_int 0))] ! 3468: "TARGET_68020 && TARGET_BITFIELD" ! 3469: "* ! 3470: { ! 3471: CC_STATUS_INIT; ! 3472: return \"bfclr %0{%b2:%b1}\"; ! 3473: }") ! 3474: ! 3475: (define_insn "" ! 3476: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d") ! 3477: (match_operand:SI 1 "general_operand" "di") ! 3478: (match_operand:SI 2 "general_operand" "di")) ! 3479: (const_int -1))] ! 3480: "TARGET_68020 && TARGET_BITFIELD" ! 3481: "* ! 3482: { ! 3483: CC_STATUS_INIT; ! 3484: return \"bfset %0{%b2:%b1}\"; ! 3485: }") ! 3486: ! 3487: (define_insn "" ! 3488: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d") ! 3489: (match_operand:SI 1 "general_operand" "di") ! 3490: (match_operand:SI 2 "general_operand" "di")) ! 3491: (match_operand:SI 3 "general_operand" "d"))] ! 3492: "TARGET_68020 && TARGET_BITFIELD" ! 3493: "* ! 3494: { ! 3495: #if 0 ! 3496: /* These special cases are now recognized by a specific pattern. */ ! 3497: if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT ! 3498: && INTVAL (operands[1]) == 16 && INTVAL (operands[2]) == 16) ! 3499: return \"move%.w %3,%0\"; ! 3500: if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT ! 3501: && INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8) ! 3502: return \"move%.b %3,%0\"; ! 3503: #endif ! 3504: return \"bfins %3,%0{%b2:%b1}\"; ! 3505: }") ! 3506: ! 3507: ;; Special patterns for optimizing bit-field instructions. ! 3508: ! 3509: (define_insn "" ! 3510: [(set (cc0) ! 3511: (zero_extract:SI (match_operand:QI 0 "memory_operand" "o") ! 3512: (match_operand:SI 1 "general_operand" "di") ! 3513: (match_operand:SI 2 "general_operand" "di")))] ! 3514: "TARGET_68020 && TARGET_BITFIELD ! 3515: && GET_CODE (operands[1]) == CONST_INT" ! 3516: "* ! 3517: { ! 3518: if (operands[1] == const1_rtx ! 3519: && GET_CODE (operands[2]) == CONST_INT) ! 3520: { ! 3521: int width = GET_CODE (operands[0]) == REG ? 31 : 7; ! 3522: return output_btst (operands, ! 3523: gen_rtx (CONST_INT, VOIDmode, ! 3524: width - INTVAL (operands[2])), ! 3525: operands[0], ! 3526: insn, 1000); ! 3527: /* Pass 1000 as SIGNPOS argument so that btst will ! 3528: not think we are testing the sign bit for an `and' ! 3529: and assume that nonzero implies a negative result. */ ! 3530: } ! 3531: if (INTVAL (operands[1]) != 32) ! 3532: cc_status.flags = CC_NOT_NEGATIVE; ! 3533: return \"bftst %0{%b2:%b1}\"; ! 3534: }") ! 3535: ! 3536: ! 3537: ;;; now handle the register cases ! 3538: (define_insn "" ! 3539: [(set (cc0) ! 3540: (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "d") ! 3541: (match_operand:SI 1 "general_operand" "di") ! 3542: (match_operand:SI 2 "general_operand" "di")))] ! 3543: "TARGET_68020 && TARGET_BITFIELD ! 3544: && GET_CODE (operands[1]) == CONST_INT" ! 3545: "* ! 3546: { ! 3547: if (operands[1] == const1_rtx ! 3548: && GET_CODE (operands[2]) == CONST_INT) ! 3549: { ! 3550: int width = GET_CODE (operands[0]) == REG ? 31 : 7; ! 3551: return output_btst (operands, ! 3552: gen_rtx (CONST_INT, VOIDmode, ! 3553: width - INTVAL (operands[2])), ! 3554: operands[0], ! 3555: insn, 1000); ! 3556: /* Pass 1000 as SIGNPOS argument so that btst will ! 3557: not think we are testing the sign bit for an `and' ! 3558: and assume that nonzero implies a negative result. */ ! 3559: } ! 3560: if (INTVAL (operands[1]) != 32) ! 3561: cc_status.flags = CC_NOT_NEGATIVE; ! 3562: return \"bftst %0{%b2:%b1}\"; ! 3563: }") ! 3564: ! 3565: (define_insn "seq" ! 3566: [(set (match_operand:QI 0 "general_operand" "=d") ! 3567: (eq:QI (cc0) (const_int 0)))] ! 3568: "" ! 3569: "* ! 3570: cc_status = cc_prev_status; ! 3571: OUTPUT_JUMP (\"seq %0\", \"fseq %0\", \"seq %0\"); ! 3572: ") ! 3573: ! 3574: (define_insn "sne" ! 3575: [(set (match_operand:QI 0 "general_operand" "=d") ! 3576: (ne:QI (cc0) (const_int 0)))] ! 3577: "" ! 3578: "* ! 3579: cc_status = cc_prev_status; ! 3580: OUTPUT_JUMP (\"sne %0\", \"fsne %0\", \"sne %0\"); ! 3581: ") ! 3582: ! 3583: (define_insn "sgt" ! 3584: [(set (match_operand:QI 0 "general_operand" "=d") ! 3585: (gt:QI (cc0) (const_int 0)))] ! 3586: "" ! 3587: "* ! 3588: cc_status = cc_prev_status; ! 3589: OUTPUT_JUMP (\"sgt %0\", \"fsgt %0\", 0); ! 3590: ") ! 3591: ! 3592: (define_insn "sgtu" ! 3593: [(set (match_operand:QI 0 "general_operand" "=d") ! 3594: (gtu:QI (cc0) (const_int 0)))] ! 3595: "" ! 3596: "* cc_status = cc_prev_status; ! 3597: return \"shi %0\"; ") ! 3598: ! 3599: (define_insn "slt" ! 3600: [(set (match_operand:QI 0 "general_operand" "=d") ! 3601: (lt:QI (cc0) (const_int 0)))] ! 3602: "" ! 3603: "* cc_status = cc_prev_status; ! 3604: OUTPUT_JUMP (\"slt %0\", \"fslt %0\", \"smi %0\"); ") ! 3605: ! 3606: (define_insn "sltu" ! 3607: [(set (match_operand:QI 0 "general_operand" "=d") ! 3608: (ltu:QI (cc0) (const_int 0)))] ! 3609: "" ! 3610: "* cc_status = cc_prev_status; ! 3611: return \"scs %0\"; ") ! 3612: ! 3613: (define_insn "sge" ! 3614: [(set (match_operand:QI 0 "general_operand" "=d") ! 3615: (ge:QI (cc0) (const_int 0)))] ! 3616: "" ! 3617: "* cc_status = cc_prev_status; ! 3618: OUTPUT_JUMP (\"sge %0\", \"fsge %0\", \"spl %0\"); ") ! 3619: ! 3620: (define_insn "sgeu" ! 3621: [(set (match_operand:QI 0 "general_operand" "=d") ! 3622: (geu:QI (cc0) (const_int 0)))] ! 3623: "" ! 3624: "* cc_status = cc_prev_status; ! 3625: return \"scc %0\"; ") ! 3626: ! 3627: (define_insn "sle" ! 3628: [(set (match_operand:QI 0 "general_operand" "=d") ! 3629: (le:QI (cc0) (const_int 0)))] ! 3630: "" ! 3631: "* ! 3632: cc_status = cc_prev_status; ! 3633: OUTPUT_JUMP (\"sle %0\", \"fsle %0\", 0); ! 3634: ") ! 3635: ! 3636: (define_insn "sleu" ! 3637: [(set (match_operand:QI 0 "general_operand" "=d") ! 3638: (leu:QI (cc0) (const_int 0)))] ! 3639: "" ! 3640: "* cc_status = cc_prev_status; ! 3641: return \"sls %0\"; ") ! 3642: ! 3643: ;; Basic conditional jump instructions. ! 3644: ! 3645: (define_insn "beq" ! 3646: [(set (pc) ! 3647: (if_then_else (eq (cc0) ! 3648: (const_int 0)) ! 3649: (label_ref (match_operand 0 "" "")) ! 3650: (pc)))] ! 3651: "" ! 3652: "* ! 3653: { ! 3654: #ifdef MOTOROLA ! 3655: OUTPUT_JUMP (\"jbeq %l0\", \"fbeq %l0\", \"jbeq %l0\"); ! 3656: #else ! 3657: OUTPUT_JUMP (\"jeq %l0\", \"fjeq %l0\", \"jeq %l0\"); ! 3658: #endif ! 3659: }") ! 3660: ! 3661: (define_insn "bne" ! 3662: [(set (pc) ! 3663: (if_then_else (ne (cc0) ! 3664: (const_int 0)) ! 3665: (label_ref (match_operand 0 "" "")) ! 3666: (pc)))] ! 3667: "" ! 3668: "* ! 3669: { ! 3670: #ifdef MOTOROLA ! 3671: OUTPUT_JUMP (\"jbne %l0\", \"fbne %l0\", \"jbne %l0\"); ! 3672: #else ! 3673: OUTPUT_JUMP (\"jne %l0\", \"fjne %l0\", \"jne %l0\"); ! 3674: #endif ! 3675: }") ! 3676: ! 3677: (define_insn "bgt" ! 3678: [(set (pc) ! 3679: (if_then_else (gt (cc0) ! 3680: (const_int 0)) ! 3681: (label_ref (match_operand 0 "" "")) ! 3682: (pc)))] ! 3683: "" ! 3684: "* ! 3685: #ifdef MOTOROLA ! 3686: OUTPUT_JUMP (\"jbgt %l0\", \"fbgt %l0\", 0); ! 3687: #else ! 3688: OUTPUT_JUMP (\"jgt %l0\", \"fjgt %l0\", 0); ! 3689: #endif ! 3690: ") ! 3691: ! 3692: (define_insn "bgtu" ! 3693: [(set (pc) ! 3694: (if_then_else (gtu (cc0) ! 3695: (const_int 0)) ! 3696: (label_ref (match_operand 0 "" "")) ! 3697: (pc)))] ! 3698: "" ! 3699: "* ! 3700: #ifdef MOTOROLA ! 3701: return \"jbhi %l0\"; ! 3702: #else ! 3703: return \"jhi %l0\"; ! 3704: #endif ! 3705: ") ! 3706: ! 3707: (define_insn "blt" ! 3708: [(set (pc) ! 3709: (if_then_else (lt (cc0) ! 3710: (const_int 0)) ! 3711: (label_ref (match_operand 0 "" "")) ! 3712: (pc)))] ! 3713: "" ! 3714: "* ! 3715: #ifdef MOTOROLA ! 3716: OUTPUT_JUMP (\"jblt %l0\", \"fblt %l0\", \"jbmi %l0\"); ! 3717: #else ! 3718: OUTPUT_JUMP (\"jlt %l0\", \"fjlt %l0\", \"jmi %l0\"); ! 3719: #endif ! 3720: ") ! 3721: ! 3722: (define_insn "bltu" ! 3723: [(set (pc) ! 3724: (if_then_else (ltu (cc0) ! 3725: (const_int 0)) ! 3726: (label_ref (match_operand 0 "" "")) ! 3727: (pc)))] ! 3728: "" ! 3729: "* ! 3730: #ifdef MOTOROLA ! 3731: return \"jbcs %l0\"; ! 3732: #else ! 3733: return \"jcs %l0\"; ! 3734: #endif ! 3735: ") ! 3736: ! 3737: (define_insn "bge" ! 3738: [(set (pc) ! 3739: (if_then_else (ge (cc0) ! 3740: (const_int 0)) ! 3741: (label_ref (match_operand 0 "" "")) ! 3742: (pc)))] ! 3743: "" ! 3744: "* ! 3745: #ifdef MOTOROLA ! 3746: OUTPUT_JUMP (\"jbge %l0\", \"fbge %l0\", \"jbpl %l0\"); ! 3747: #else ! 3748: OUTPUT_JUMP (\"jge %l0\", \"fjge %l0\", \"jpl %l0\"); ! 3749: #endif ! 3750: ") ! 3751: ! 3752: (define_insn "bgeu" ! 3753: [(set (pc) ! 3754: (if_then_else (geu (cc0) ! 3755: (const_int 0)) ! 3756: (label_ref (match_operand 0 "" "")) ! 3757: (pc)))] ! 3758: "" ! 3759: "* ! 3760: #ifdef MOTOROLA ! 3761: return \"jbcc %l0\"; ! 3762: #else ! 3763: return \"jcc %l0\"; ! 3764: #endif ! 3765: ") ! 3766: ! 3767: (define_insn "ble" ! 3768: [(set (pc) ! 3769: (if_then_else (le (cc0) ! 3770: (const_int 0)) ! 3771: (label_ref (match_operand 0 "" "")) ! 3772: (pc)))] ! 3773: "" ! 3774: "* ! 3775: #ifdef MOTOROLA ! 3776: OUTPUT_JUMP (\"jble %l0\", \"fble %l0\", 0); ! 3777: #else ! 3778: OUTPUT_JUMP (\"jle %l0\", \"fjle %l0\", 0); ! 3779: #endif ! 3780: ") ! 3781: ! 3782: (define_insn "bleu" ! 3783: [(set (pc) ! 3784: (if_then_else (leu (cc0) ! 3785: (const_int 0)) ! 3786: (label_ref (match_operand 0 "" "")) ! 3787: (pc)))] ! 3788: "" ! 3789: "* ! 3790: #ifdef MOTOROLA ! 3791: return \"jbls %l0\"; ! 3792: #else ! 3793: return \"jls %l0\"; ! 3794: #endif ! 3795: ") ! 3796: ! 3797: ;; Negated conditional jump instructions. ! 3798: ! 3799: (define_insn "" ! 3800: [(set (pc) ! 3801: (if_then_else (eq (cc0) ! 3802: (const_int 0)) ! 3803: (pc) ! 3804: (label_ref (match_operand 0 "" ""))))] ! 3805: "" ! 3806: "* ! 3807: { ! 3808: #ifdef MOTOROLA ! 3809: OUTPUT_JUMP (\"jbne %l0\", \"fbne %l0\", \"jbne %l0\"); ! 3810: #else ! 3811: OUTPUT_JUMP (\"jne %l0\", \"fjne %l0\", \"jne %l0\"); ! 3812: #endif ! 3813: }") ! 3814: ! 3815: (define_insn "" ! 3816: [(set (pc) ! 3817: (if_then_else (ne (cc0) ! 3818: (const_int 0)) ! 3819: (pc) ! 3820: (label_ref (match_operand 0 "" ""))))] ! 3821: "" ! 3822: "* ! 3823: { ! 3824: #ifdef MOTOROLA ! 3825: OUTPUT_JUMP (\"jbeq %l0\", \"fbeq %l0\", \"jbeq %l0\"); ! 3826: #else ! 3827: OUTPUT_JUMP (\"jeq %l0\", \"fjeq %l0\", \"jeq %l0\"); ! 3828: #endif ! 3829: }") ! 3830: ! 3831: (define_insn "" ! 3832: [(set (pc) ! 3833: (if_then_else (gt (cc0) ! 3834: (const_int 0)) ! 3835: (pc) ! 3836: (label_ref (match_operand 0 "" ""))))] ! 3837: "" ! 3838: "* ! 3839: #ifdef MOTOROLA ! 3840: OUTPUT_JUMP (\"jble %l0\", \"fbngt %l0\", 0); ! 3841: #else ! 3842: OUTPUT_JUMP (\"jle %l0\", \"fjngt %l0\", 0); ! 3843: #endif ! 3844: ") ! 3845: ! 3846: (define_insn "" ! 3847: [(set (pc) ! 3848: (if_then_else (gtu (cc0) ! 3849: (const_int 0)) ! 3850: (pc) ! 3851: (label_ref (match_operand 0 "" ""))))] ! 3852: "" ! 3853: "* ! 3854: #ifdef MOTOROLA ! 3855: return \"jbls %l0\"; ! 3856: #else ! 3857: return \"jls %l0\"; ! 3858: #endif ! 3859: ") ! 3860: ! 3861: (define_insn "" ! 3862: [(set (pc) ! 3863: (if_then_else (lt (cc0) ! 3864: (const_int 0)) ! 3865: (pc) ! 3866: (label_ref (match_operand 0 "" ""))))] ! 3867: "" ! 3868: "* ! 3869: #ifdef MOTOROLA ! 3870: OUTPUT_JUMP (\"jbge %l0\", \"fbnlt %l0\", \"jbpl %l0\"); ! 3871: #else ! 3872: OUTPUT_JUMP (\"jge %l0\", \"fjnlt %l0\", \"jpl %l0\"); ! 3873: #endif ! 3874: ") ! 3875: ! 3876: (define_insn "" ! 3877: [(set (pc) ! 3878: (if_then_else (ltu (cc0) ! 3879: (const_int 0)) ! 3880: (pc) ! 3881: (label_ref (match_operand 0 "" ""))))] ! 3882: "" ! 3883: "* ! 3884: #ifdef MOTOROLA ! 3885: return \"jbcc %l0\"; ! 3886: #else ! 3887: return \"jcc %l0\"; ! 3888: #endif ! 3889: ") ! 3890: ! 3891: (define_insn "" ! 3892: [(set (pc) ! 3893: (if_then_else (ge (cc0) ! 3894: (const_int 0)) ! 3895: (pc) ! 3896: (label_ref (match_operand 0 "" ""))))] ! 3897: "" ! 3898: "* ! 3899: #ifdef MOTOROLA ! 3900: OUTPUT_JUMP (\"jblt %l0\", \"fbnge %l0\", \"jbmi %l0\"); ! 3901: #else ! 3902: OUTPUT_JUMP (\"jlt %l0\", \"fjnge %l0\", \"jmi %l0\"); ! 3903: #endif ! 3904: ") ! 3905: ! 3906: (define_insn "" ! 3907: [(set (pc) ! 3908: (if_then_else (geu (cc0) ! 3909: (const_int 0)) ! 3910: (pc) ! 3911: (label_ref (match_operand 0 "" ""))))] ! 3912: "" ! 3913: "* ! 3914: #ifdef MOTOROLA ! 3915: return \"jbcs %l0\"; ! 3916: #else ! 3917: return \"jcs %l0\"; ! 3918: #endif ! 3919: ") ! 3920: ! 3921: (define_insn "" ! 3922: [(set (pc) ! 3923: (if_then_else (le (cc0) ! 3924: (const_int 0)) ! 3925: (pc) ! 3926: (label_ref (match_operand 0 "" ""))))] ! 3927: "" ! 3928: "* ! 3929: #ifdef MOTOROLA ! 3930: OUTPUT_JUMP (\"jbgt %l0\", \"fbnle %l0\", 0); ! 3931: #else ! 3932: OUTPUT_JUMP (\"jgt %l0\", \"fjnle %l0\", 0); ! 3933: #endif ! 3934: ") ! 3935: ! 3936: (define_insn "" ! 3937: [(set (pc) ! 3938: (if_then_else (leu (cc0) ! 3939: (const_int 0)) ! 3940: (pc) ! 3941: (label_ref (match_operand 0 "" ""))))] ! 3942: "" ! 3943: "* ! 3944: #ifdef MOTOROLA ! 3945: return \"jbhi %l0\"; ! 3946: #else ! 3947: return \"jhi %l0\"; ! 3948: #endif ! 3949: ") ! 3950: ! 3951: ;; Unconditional and other jump instructions ! 3952: (define_insn "jump" ! 3953: [(set (pc) ! 3954: (label_ref (match_operand 0 "" "")))] ! 3955: "" ! 3956: "* ! 3957: #ifdef MOTOROLA ! 3958: return \"jbra %l0\"; ! 3959: #else ! 3960: return \"jra %l0\"; ! 3961: #endif ! 3962: ") ! 3963: ! 3964: ;; We support two different ways of handling dispatch tables. ! 3965: ;; The NeXT uses absolute tables, and other machines use relative. ! 3966: ;; This define_expand can generate either kind. ! 3967: (define_expand "tablejump" ! 3968: [(parallel [(set (pc) (match_operand 0 "" "")) ! 3969: (use (label_ref (match_operand 1 "" "")))])] ! 3970: "" ! 3971: " ! 3972: { ! 3973: #ifdef CASE_VECTOR_PC_RELATIVE ! 3974: operands[0] = gen_rtx (PLUS, SImode, pc_rtx, operands[0]); ! 3975: #endif ! 3976: }") ! 3977: ! 3978: ;; Jump to variable address from dispatch table of absolute addresses. ! 3979: (define_insn "" ! 3980: [(set (pc) (match_operand:SI 0 "register_operand" "a")) ! 3981: (use (label_ref (match_operand 1 "" "")))] ! 3982: "" ! 3983: "* ! 3984: #ifdef MOTOROLA ! 3985: return \"jmp (%0)\"; ! 3986: #else ! 3987: return \"jmp %0@\"; ! 3988: #endif ! 3989: ") ! 3990: ! 3991: ;; Jump to variable address from dispatch table of relative addresses. ! 3992: (define_insn "" ! 3993: [(set (pc) ! 3994: (plus:SI (pc) (match_operand:HI 0 "register_operand" "r"))) ! 3995: (use (label_ref (match_operand 1 "" "")))] ! 3996: "" ! 3997: "* ! 3998: #ifdef ASM_RETURN_CASE_JUMP ! 3999: ASM_RETURN_CASE_JUMP; ! 4000: #else ! 4001: #ifdef SGS ! 4002: #ifdef ASM_OUTPUT_CASE_LABEL ! 4003: return \"jmp 6(%%pc,%0.w)\"; ! 4004: #else ! 4005: #ifdef CRDS ! 4006: return \"jmp 2(pc,%0.w)\"; ! 4007: #else ! 4008: return \"jmp 2(%%pc,%0.w)\"; ! 4009: #endif /* end !CRDS */ ! 4010: #endif ! 4011: #else /* not SGS */ ! 4012: #ifdef MOTOROLA ! 4013: return \"jmp (2,pc,%0.w)\"; ! 4014: #else ! 4015: return \"jmp pc@(2,%0:w)\"; ! 4016: #endif ! 4017: #endif ! 4018: #endif ! 4019: ") ! 4020: ! 4021: ;; Decrement-and-branch insns. ! 4022: (define_insn "" ! 4023: [(set (pc) ! 4024: (if_then_else ! 4025: (ne (match_operand:HI 0 "general_operand" "+g") ! 4026: (const_int 0)) ! 4027: (label_ref (match_operand 1 "" "")) ! 4028: (pc))) ! 4029: (set (match_dup 0) ! 4030: (plus:HI (match_dup 0) ! 4031: (const_int -1)))] ! 4032: "" ! 4033: "* ! 4034: { ! 4035: CC_STATUS_INIT; ! 4036: if (DATA_REG_P (operands[0])) ! 4037: return \"dbra %0,%l1\"; ! 4038: if (GET_CODE (operands[0]) == MEM) ! 4039: { ! 4040: #ifdef MOTOROLA ! 4041: #ifdef NO_ADDSUB_Q ! 4042: return \"sub%.w %#1,%0\;jbcc %l1\"; ! 4043: #else ! 4044: return \"subq%.w %#1,%0\;jbcc %l1\"; ! 4045: #endif ! 4046: #else /* not MOTOROLA */ ! 4047: return \"subqw %#1,%0\;jcc %l1\"; ! 4048: #endif ! 4049: } ! 4050: #ifdef MOTOROLA ! 4051: #ifdef SGS_CMP_ORDER ! 4052: #ifndef NO_ADDSUB_Q ! 4053: return \"sub%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\"; ! 4054: #else ! 4055: return \"subq%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\"; ! 4056: #endif ! 4057: #else /* not SGS_CMP_ORDER */ ! 4058: return \"subq%.w %#1,%0\;cmp%.w %#-1,%0\;jbne %l1\"; ! 4059: #endif ! 4060: #else /* not MOTOROLA */ ! 4061: return \"subqw %#1,%0\;cmpw %#-1,%0\;jne %l1\"; ! 4062: #endif ! 4063: }") ! 4064: ! 4065: (define_insn "" ! 4066: [(set (pc) ! 4067: (if_then_else ! 4068: (ne (match_operand:SI 0 "general_operand" "+g") ! 4069: (const_int 0)) ! 4070: (label_ref (match_operand 1 "" "")) ! 4071: (pc))) ! 4072: (set (match_dup 0) ! 4073: (plus:SI (match_dup 0) ! 4074: (const_int -1)))] ! 4075: "" ! 4076: "* ! 4077: { ! 4078: CC_STATUS_INIT; ! 4079: #ifdef MOTOROLA ! 4080: #ifndef NO_ADDSUB_Q ! 4081: if (DATA_REG_P (operands[0])) ! 4082: return \"dbra %0,%l1\;clr%.w %0\;sub%.l %#1,%0\;jbcc %l1\"; ! 4083: if (GET_CODE (operands[0]) == MEM) ! 4084: return \"sub%.l %#1,%0\;jbcc %l1\"; ! 4085: #else ! 4086: if (DATA_REG_P (operands[0])) ! 4087: return \"dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jbcc %l1\"; ! 4088: if (GET_CODE (operands[0]) == MEM) ! 4089: return \"subq%.l %#1,%0\;jbcc %l1\"; ! 4090: #endif /* not NO_ADDSUB_Q */ ! 4091: #ifdef SGS_CMP_ORDER ! 4092: #ifndef NO_ADDSUB_Q ! 4093: return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; ! 4094: #else ! 4095: return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; ! 4096: #endif ! 4097: #else /* not SGS_CMP_ORDER */ ! 4098: return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\"; ! 4099: #endif /* not SGS_CMP_ORDER */ ! 4100: #else /* not MOTOROLA */ ! 4101: if (DATA_REG_P (operands[0])) ! 4102: return \"dbra %0,%l1\;clrw %0\;subql %#1,%0\;jcc %l1\"; ! 4103: if (GET_CODE (operands[0]) == MEM) ! 4104: return \"subql %#1,%0\;jcc %l1\"; ! 4105: return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\"; ! 4106: #endif /* not MOTOROLA */ ! 4107: }") ! 4108: ! 4109: ;; dbra patterns that use REG_NOTES info generated by strength_reduce. ! 4110: ! 4111: (define_insn "decrement_and_branch_until_zero" ! 4112: [(set (pc) ! 4113: (if_then_else ! 4114: (gt (match_operand:SI 0 "general_operand" "+g") ! 4115: (const_int 0)) ! 4116: (label_ref (match_operand 1 "" "")) ! 4117: (pc))) ! 4118: (set (match_dup 0) ! 4119: (plus:SI (match_dup 0) ! 4120: (const_int -1)))] ! 4121: "find_reg_note (insn, REG_NONNEG, 0)" ! 4122: "* ! 4123: { ! 4124: CC_STATUS_INIT; ! 4125: #ifdef MOTOROLA ! 4126: #ifndef NO_ADDSUB_Q ! 4127: if (DATA_REG_P (operands[0])) ! 4128: return \"dbra %0,%l1\;clr%.w %0\;sub%.l %#1,%0\;jbcc %l1\"; ! 4129: if (GET_CODE (operands[0]) == MEM) ! 4130: return \"sub%.l %#1,%0\;jbcc %l1\"; ! 4131: #else ! 4132: if (DATA_REG_P (operands[0])) ! 4133: return \"dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jbcc %l1\"; ! 4134: if (GET_CODE (operands[0]) == MEM) ! 4135: return \"subq%.l %#1,%0\;jbcc %l1\"; ! 4136: #endif ! 4137: #ifdef SGS_CMP_ORDER ! 4138: #ifndef NO_ADDSUB_Q ! 4139: return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; ! 4140: #else ! 4141: return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; ! 4142: #endif ! 4143: #else /* not SGS_CMP_ORDER */ ! 4144: return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\"; ! 4145: #endif /* not SGS_CMP_ORDER */ ! 4146: #else /* not MOTOROLA */ ! 4147: if (DATA_REG_P (operands[0])) ! 4148: return \"dbra %0,%l1\;clrw %0\;subql %#1,%0\;jcc %l1\"; ! 4149: if (GET_CODE (operands[0]) == MEM) ! 4150: return \"subql %#1,%0\;jcc %l1\"; ! 4151: return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\"; ! 4152: #endif /* not MOTOROLA */ ! 4153: }") ! 4154: ! 4155: ! 4156: ;; PIC calls are handled by loading the address of the function into a ! 4157: ;; register (via movsi), then emitting a register indirect call using ! 4158: ;; the "jsr" function call syntax. ! 4159: ;; ! 4160: ;; It is important to note that the "jsr" syntax is always used for ! 4161: ;; PIC calls, even on machines in which GCC normally uses the "jbsr" ! 4162: ;; syntax for non-PIC calls. This keeps at least 1 assembler (Sun) ! 4163: ;; from emitting incorrect code for a PIC call. ! 4164: ;; ! 4165: ;; We have different patterns for PIC calls and non-PIC calls. The ! 4166: ;; different patterns are only used to choose the right syntax ! 4167: ;; ("jsr" vs "jbsr"). ! 4168: ! 4169: ;; Call subroutine with no return value. ! 4170: (define_expand "call" ! 4171: [(call (match_operand:QI 0 "memory_operand" "") ! 4172: (match_operand:SI 1 "general_operand" ""))] ! 4173: ;; Operand 1 not really used on the m68000. ! 4174: ! 4175: "" ! 4176: " ! 4177: { ! 4178: if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) ! 4179: operands[0] = gen_rtx (MEM, GET_MODE (operands[0]), ! 4180: force_reg (Pmode, XEXP (operands[0], 0))); ! 4181: }") ! 4182: ! 4183: ;; This is a normal call sequence. ! 4184: (define_insn "" ! 4185: [(call (match_operand:QI 0 "memory_operand" "o") ! 4186: (match_operand:SI 1 "general_operand" "g"))] ! 4187: ;; Operand 1 not really used on the m68000. ! 4188: ! 4189: "! flag_pic" ! 4190: "* ! 4191: #ifdef MOTOROLA ! 4192: return \"jsr %0\"; ! 4193: #else ! 4194: return \"jbsr %0\"; ! 4195: #endif ! 4196: ") ! 4197: ! 4198: ;; This is a PIC call sequence. ! 4199: (define_insn "" ! 4200: [(call (match_operand:QI 0 "memory_operand" "o") ! 4201: (match_operand:SI 1 "general_operand" "g"))] ! 4202: ;; Operand 1 not really used on the m68000. ! 4203: ! 4204: "flag_pic" ! 4205: "* ! 4206: return \"jsr %0\"; ! 4207: ") ! 4208: ! 4209: ;; Call subroutine, returning value in operand 0 ! 4210: ;; (which must be a hard register). ! 4211: ;; See comments before "call" regarding PIC calls. ! 4212: (define_expand "call_value" ! 4213: [(set (match_operand 0 "" "") ! 4214: (call (match_operand:QI 1 "memory_operand" "") ! 4215: (match_operand:SI 2 "general_operand" "")))] ! 4216: ;; Operand 2 not really used on the m68000. ! 4217: "" ! 4218: " ! 4219: { ! 4220: if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) ! 4221: operands[1] = gen_rtx (MEM, GET_MODE (operands[1]), ! 4222: force_reg (Pmode, XEXP (operands[1], 0))); ! 4223: }") ! 4224: ! 4225: ;; This is a normal call_value ! 4226: (define_insn "" ! 4227: [(set (match_operand 0 "" "=rf") ! 4228: (call (match_operand:QI 1 "memory_operand" "o") ! 4229: (match_operand:SI 2 "general_operand" "g")))] ! 4230: ;; Operand 2 not really used on the m68000. ! 4231: "! flag_pic" ! 4232: "* ! 4233: #ifdef MOTOROLA ! 4234: return \"jsr %1\"; ! 4235: #else ! 4236: return \"jbsr %1\"; ! 4237: #endif ! 4238: ") ! 4239: ! 4240: ;; This is a PIC call_value ! 4241: (define_insn "" ! 4242: [(set (match_operand 0 "" "=rf") ! 4243: (call (match_operand:QI 1 "memory_operand" "o") ! 4244: (match_operand:SI 2 "general_operand" "g")))] ! 4245: ;; Operand 2 not really used on the m68000. ! 4246: "flag_pic" ! 4247: "* ! 4248: return \"jsr %1\"; ! 4249: ") ! 4250: ! 4251: (define_insn "nop" ! 4252: [(const_int 0)] ! 4253: "" ! 4254: "nop") ! 4255: ! 4256: (define_insn "probe" ! 4257: [(reg:SI 15)] ! 4258: "NEED_PROBE" ! 4259: "* ! 4260: { ! 4261: operands[0] = gen_rtx (PLUS, SImode, stack_pointer_rtx, ! 4262: gen_rtx (CONST_INT, VOIDmode, NEED_PROBE)); ! 4263: return \"tstl %0\"; ! 4264: }") ! 4265: ! 4266: ;; Used for framless functions which save no regs and allocate no locals. ! 4267: (define_insn "return" ! 4268: [(return)] ! 4269: "USE_RETURN_INSN" ! 4270: "* ! 4271: { ! 4272: if (current_function_pops_args == 0) ! 4273: return \"rts\"; ! 4274: operands[0] = gen_rtx (CONST_INT, VOIDmode, current_function_pops_args); ! 4275: return \"rtd %0\"; ! 4276: }") ! 4277: ! 4278: (define_insn "indirect_jump" ! 4279: [(set (pc) (match_operand:SI 0 "register_operand" "a"))] ! 4280: "" ! 4281: "* ! 4282: #ifdef MOTOROLA ! 4283: return \"jmp (%0)\"; ! 4284: #else ! 4285: return \"jmp %0@\"; ! 4286: #endif ! 4287: ") ! 4288: ! 4289: ;; This should not be used unless the add/sub insns can't be. ! 4290: ! 4291: (define_insn "" ! 4292: [(set (match_operand:SI 0 "general_operand" "=a") ! 4293: (match_operand:QI 1 "address_operand" "p"))] ! 4294: "" ! 4295: "lea %a1,%0") ! 4296: ! 4297: ;; This is the first machine-dependent peephole optimization. ! 4298: ;; It is useful when a floating value is returned from a function call ! 4299: ;; and then is moved into an FP register. ! 4300: ;; But it is mainly intended to test the support for these optimizations. ! 4301: ! 4302: (define_peephole ! 4303: [(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int 4))) ! 4304: (set (match_operand:DF 0 "register_operand" "f") ! 4305: (match_operand:DF 1 "register_operand" "ad"))] ! 4306: "FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])" ! 4307: "* ! 4308: { ! 4309: rtx xoperands[2]; ! 4310: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); ! 4311: output_asm_insn (\"move%.l %1,%@\", xoperands); ! 4312: output_asm_insn (\"move%.l %1,%-\", operands); ! 4313: return \"fmove%.d %+,%0\"; ! 4314: } ! 4315: ") ! 4316: ! 4317: ;; Optimize a stack-adjust followed by a push of an argument. ! 4318: ;; This is said to happen frequently with -msoft-float ! 4319: ;; when there are consecutive library calls. ! 4320: ! 4321: (define_peephole ! 4322: [(set (reg:SI 15) (plus:SI (reg:SI 15) ! 4323: (match_operand:SI 0 "immediate_operand" "n"))) ! 4324: (set (match_operand:SF 1 "push_operand" "=m") ! 4325: (match_operand:SF 2 "general_operand" "rmfF"))] ! 4326: "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) >= 4 ! 4327: && ! reg_mentioned_p (stack_pointer_rtx, operands[2])" ! 4328: "* ! 4329: { ! 4330: if (INTVAL (operands[0]) > 4) ! 4331: { ! 4332: rtx xoperands[2]; ! 4333: xoperands[0] = stack_pointer_rtx; ! 4334: xoperands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[0]) - 4); ! 4335: #ifndef NO_ADDSUB_Q ! 4336: if (INTVAL (xoperands[1]) <= 8) ! 4337: output_asm_insn (\"addq%.w %1,%0\", xoperands); ! 4338: else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020) ! 4339: { ! 4340: xoperands[1] = gen_rtx (CONST_INT, VOIDmode, ! 4341: INTVAL (xoperands[1]) - 8); ! 4342: output_asm_insn (\"addq%.w %#8,%0; addq%.w %1,%0\", xoperands); ! 4343: } ! 4344: else ! 4345: #endif ! 4346: if (INTVAL (xoperands[1]) <= 0x7FFF) ! 4347: output_asm_insn (\"add%.w %1,%0\", xoperands); ! 4348: else ! 4349: output_asm_insn (\"add%.l %1,%0\", xoperands); ! 4350: } ! 4351: if (FP_REG_P (operands[2])) ! 4352: return \"fmove%.s %2,%@\"; ! 4353: return \"move%.l %2,%@\"; ! 4354: }") ! 4355: ! 4356: ;; Speed up stack adjust followed by a fullword fixedpoint push. ! 4357: ! 4358: (define_peephole ! 4359: [(set (reg:SI 15) (plus:SI (reg:SI 15) ! 4360: (match_operand:SI 0 "immediate_operand" "n"))) ! 4361: (set (match_operand:SI 1 "push_operand" "=m") ! 4362: (match_operand:SI 2 "general_operand" "g"))] ! 4363: "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) >= 4 ! 4364: && ! reg_mentioned_p (stack_pointer_rtx, operands[2])" ! 4365: "* ! 4366: { ! 4367: if (INTVAL (operands[0]) > 4) ! 4368: { ! 4369: rtx xoperands[2]; ! 4370: xoperands[0] = stack_pointer_rtx; ! 4371: xoperands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[0]) - 4); ! 4372: #ifndef NO_ADDSUB_Q ! 4373: if (INTVAL (xoperands[1]) <= 8) ! 4374: output_asm_insn (\"addq%.w %1,%0\", xoperands); ! 4375: else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020) ! 4376: { ! 4377: xoperands[1] = gen_rtx (CONST_INT, VOIDmode, ! 4378: INTVAL (xoperands[1]) - 8); ! 4379: output_asm_insn (\"addq%.w %#8,%0; addq%.w %1,%0\", xoperands); ! 4380: } ! 4381: else ! 4382: #endif ! 4383: if (INTVAL (xoperands[1]) <= 0x7FFF) ! 4384: output_asm_insn (\"add%.w %1,%0\", xoperands); ! 4385: else ! 4386: output_asm_insn (\"add%.l %1,%0\", xoperands); ! 4387: } ! 4388: if (operands[2] == const0_rtx) ! 4389: return \"clr%.l %@\"; ! 4390: return \"move%.l %2,%@\"; ! 4391: }") ! 4392: ! 4393: ;; Speed up pushing a single byte but leaving four bytes of space. ! 4394: ! 4395: (define_peephole ! 4396: [(set (mem:QI (pre_dec:SI (reg:SI 15))) ! 4397: (match_operand:QI 1 "general_operand" "dami")) ! 4398: (set (reg:SI 15) (minus:SI (reg:SI 15) (const_int 2)))] ! 4399: "! reg_mentioned_p (stack_pointer_rtx, operands[1])" ! 4400: "* ! 4401: { ! 4402: rtx xoperands[4]; ! 4403: ! 4404: if (GET_CODE (operands[1]) == REG) ! 4405: return \"move%.l %1,%-\"; ! 4406: ! 4407: xoperands[1] = operands[1]; ! 4408: xoperands[2] ! 4409: = gen_rtx (MEM, QImode, ! 4410: gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, ! 4411: gen_rtx (CONST_INT, VOIDmode, 3))); ! 4412: xoperands[3] = stack_pointer_rtx; ! 4413: output_asm_insn (\"subq%.w %#4,%3\;move%.b %1,%2\", xoperands); ! 4414: return \"\"; ! 4415: }") ! 4416: ! 4417: ;; FPA multiply and add. ! 4418: (define_insn "" ! 4419: [(set (match_operand:DF 0 "register_operand" "=x,y,y") ! 4420: (plus:DF (mult:DF (match_operand:DF 1 "general_operand" "%x,dmF,y") ! 4421: (match_operand:DF 2 "general_operand" "xH,y,y")) ! 4422: (match_operand:DF 3 "general_operand" "xH,y,dmF")))] ! 4423: "TARGET_FPA" ! 4424: "@ ! 4425: fpma%.d %1,%w2,%w3,%0 ! 4426: fpma%.d %x1,%x2,%x3,%0 ! 4427: fpma%.d %x1,%x2,%x3,%0") ! 4428: ! 4429: (define_insn "" ! 4430: [(set (match_operand:SF 0 "register_operand" "=x,y,y") ! 4431: (plus:SF (mult:SF (match_operand:SF 1 "general_operand" "%x,ydmF,y") ! 4432: (match_operand:SF 2 "general_operand" "xH,y,ydmF")) ! 4433: (match_operand:SF 3 "general_operand" "xH,ydmF,ydmF")))] ! 4434: "TARGET_FPA" ! 4435: "@ ! 4436: fpma%.s %1,%w2,%w3,%0 ! 4437: fpma%.s %1,%2,%3,%0 ! 4438: fpma%.s %1,%2,%3,%0") ! 4439: ! 4440: ;; FPA Multiply and subtract ! 4441: (define_insn "" ! 4442: [(set (match_operand:DF 0 "register_operand" "=x,y,y") ! 4443: (minus:DF (match_operand:DF 1 "general_operand" "xH,rmF,y") ! 4444: (mult:DF (match_operand:DF 2 "general_operand" "%xH,y,y") ! 4445: (match_operand:DF 3 "general_operand" "x,y,rmF"))))] ! 4446: "TARGET_FPA" ! 4447: "@ ! 4448: fpms%.d %3,%w2,%w1,%0 ! 4449: fpms%.d %x3,%2,%x1,%0 ! 4450: fpms%.d %x3,%2,%x1,%0") ! 4451: ! 4452: (define_insn "" ! 4453: [(set (match_operand:SF 0 "register_operand" "=x,y,y") ! 4454: (minus:SF (match_operand:SF 1 "general_operand" "xH,rmF,yrmF") ! 4455: (mult:SF (match_operand:SF 2 "general_operand" "%xH,rmF,y") ! 4456: (match_operand:SF 3 "general_operand" "x,y,yrmF"))))] ! 4457: "TARGET_FPA" ! 4458: "@ ! 4459: fpms%.s %3,%w2,%w1,%0 ! 4460: fpms%.s %3,%2,%1,%0 ! 4461: fpms%.s %3,%2,%1,%0") ! 4462: ! 4463: (define_insn "" ! 4464: [(set (match_operand:DF 0 "register_operand" "=x,y,y") ! 4465: (minus:DF (mult:DF (match_operand:DF 1 "general_operand" "%xH,y,y") ! 4466: (match_operand:DF 2 "general_operand" "x,y,rmF")) ! 4467: (match_operand:DF 3 "general_operand" "xH,rmF,y")))] ! 4468: "TARGET_FPA" ! 4469: "@ ! 4470: fpmr%.d %2,%w1,%w3,%0 ! 4471: fpmr%.d %x2,%1,%x3,%0 ! 4472: fpmr%.d %x2,%1,%x3,%0") ! 4473: ! 4474: (define_insn "" ! 4475: [(set (match_operand:SF 0 "register_operand" "=x,y,y") ! 4476: (minus:SF (mult:SF (match_operand:SF 1 "general_operand" "%xH,rmF,y") ! 4477: (match_operand:SF 2 "general_operand" "x,y,yrmF")) ! 4478: (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))] ! 4479: "TARGET_FPA" ! 4480: "@ ! 4481: fpmr%.s %2,%w1,%w3,%0 ! 4482: fpmr%.s %x2,%1,%x3,%0 ! 4483: fpmr%.s %x2,%1,%x3,%0") ! 4484: ! 4485: ;; FPA Add and multiply ! 4486: (define_insn "" ! 4487: [(set (match_operand:DF 0 "register_operand" "=x,y,y") ! 4488: (mult:DF (plus:DF (match_operand:DF 1 "general_operand" "%xH,y,y") ! 4489: (match_operand:DF 2 "general_operand" "x,y,rmF")) ! 4490: (match_operand:DF 3 "general_operand" "xH,rmF,y")))] ! 4491: "TARGET_FPA" ! 4492: "@ ! 4493: fpam%.d %2,%w1,%w3,%0 ! 4494: fpam%.d %x2,%1,%x3,%0 ! 4495: fpam%.d %x2,%1,%x3,%0") ! 4496: ! 4497: (define_insn "" ! 4498: [(set (match_operand:SF 0 "register_operand" "=x,y,y") ! 4499: (mult:SF (plus:SF (match_operand:SF 1 "general_operand" "%xH,rmF,y") ! 4500: (match_operand:SF 2 "general_operand" "x,y,yrmF")) ! 4501: (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))] ! 4502: "TARGET_FPA" ! 4503: "@ ! 4504: fpam%.s %2,%w1,%w3,%0 ! 4505: fpam%.s %x2,%1,%x3,%0 ! 4506: fpam%.s %x2,%1,%x3,%0") ! 4507: ! 4508: ;;FPA Subtract and multiply ! 4509: (define_insn "" ! 4510: [(set (match_operand:DF 0 "register_operand" "=x,y,y") ! 4511: (mult:DF (minus:DF (match_operand:DF 1 "general_operand" "xH,y,y") ! 4512: (match_operand:DF 2 "general_operand" "x,y,rmF")) ! 4513: (match_operand:DF 3 "general_operand" "xH,rmF,y")))] ! 4514: "TARGET_FPA" ! 4515: "@ ! 4516: fpsm%.d %2,%w1,%w3,%0 ! 4517: fpsm%.d %x2,%1,%x3,%0 ! 4518: fpsm%.d %x2,%1,%x3,%0") ! 4519: ! 4520: (define_insn "" ! 4521: [(set (match_operand:DF 0 "register_operand" "=x,y,y") ! 4522: (mult:DF (match_operand:DF 1 "general_operand" "xH,rmF,y") ! 4523: (minus:DF (match_operand:DF 2 "general_operand" "xH,y,y") ! 4524: (match_operand:DF 3 "general_operand" "x,y,rmF"))))] ! 4525: "TARGET_FPA" ! 4526: "@ ! 4527: fpsm%.d %3,%w2,%w1,%0 ! 4528: fpsm%.d %x3,%2,%x1,%0 ! 4529: fpsm%.d %x3,%2,%x1,%0") ! 4530: ! 4531: (define_insn "" ! 4532: [(set (match_operand:SF 0 "register_operand" "=x,y,y") ! 4533: (mult:SF (minus:SF (match_operand:SF 1 "general_operand" "xH,rmF,y") ! 4534: (match_operand:SF 2 "general_operand" "x,y,yrmF")) ! 4535: (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))] ! 4536: "TARGET_FPA" ! 4537: "@ ! 4538: fpsm%.s %2,%w1,%w3,%0 ! 4539: fpsm%.s %x2,%1,%x3,%0 ! 4540: fpsm%.s %x2,%1,%x3,%0") ! 4541: ! 4542: (define_insn "" ! 4543: [(set (match_operand:SF 0 "register_operand" "=x,y,y") ! 4544: (mult:SF (match_operand:SF 1 "general_operand" "xH,rmF,yrmF") ! 4545: (minus:SF (match_operand:SF 2 "general_operand" "xH,rmF,y") ! 4546: (match_operand:SF 3 "general_operand" "x,y,yrmF"))))] ! 4547: "TARGET_FPA" ! 4548: "@ ! 4549: fpsm%.s %3,%w2,%w1,%0 ! 4550: fpsm%.s %x3,%2,%x1,%0 ! 4551: fpsm%.s %x3,%2,%x1,%0") ! 4552: ! 4553: ;;- Local variables: ! 4554: ;;- mode:emacs-lisp ! 4555: ;;- comment-start: ";;- " ! 4556: ;;- comment-start-skip: ";+- *" ! 4557: ;;- eval: (set-syntax-table (copy-sequence (syntax-table))) ! 4558: ;;- eval: (modify-syntax-entry ?[ "(]") ! 4559: ;;- eval: (modify-syntax-entry ?] ")[") ! 4560: ;;- eval: (modify-syntax-entry ?{ "(}") ! 4561: ;;- eval: (modify-syntax-entry ?} "){") ! 4562: ;;- End:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.