|
|
1.1 ! root 1: ;;- Machine description for GNU compiler ! 2: ;;- Motorola 68000 Version ! 3: ;; Copyright (C) 1987, 1988, 1993 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: ;;- "%!" fpcr register ! 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 outputting ! 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 appropriately 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: #ifdef SGS_SWITCH_TABLES ! 876: /* Set flag saying we need to define the symbol ! 877: LD%n (with value L%n-LI%n) at the end of the switch table. */ ! 878: switch_table_difference_label_flag = 1; ! 879: #endif /* SGS_SWITCH_TABLES */ ! 880: #endif /* SGS_SWITCH_TABLES or not MOTOROLA */ ! 881: } ! 882: #endif /* SGS_NO_LI */ ! 883: return \"move%.w %1,%0\"; ! 884: }") ! 885: ! 886: (define_insn "movstricthi" ! 887: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm")) ! 888: (match_operand:HI 1 "general_operand" "rmn"))] ! 889: "" ! 890: "* ! 891: { ! 892: if (GET_CODE (operands[1]) == CONST_INT) ! 893: { ! 894: if (operands[1] == const0_rtx ! 895: && (DATA_REG_P (operands[0]) ! 896: || GET_CODE (operands[0]) == MEM) ! 897: /* clr insns on 68000 read before writing. ! 898: This isn't so on the 68010, but we have no alternative for it. */ ! 899: && (TARGET_68020 ! 900: || !(GET_CODE (operands[0]) == MEM ! 901: && MEM_VOLATILE_P (operands[0])))) ! 902: return \"clr%.w %0\"; ! 903: } ! 904: return \"move%.w %1,%0\"; ! 905: }") ! 906: ! 907: (define_insn "movqi" ! 908: [(set (match_operand:QI 0 "general_operand" "=d,*a,m,m,?*a") ! 909: (match_operand:QI 1 "general_operand" "dmi*a,d*a,dmi,?*a,m"))] ! 910: "" ! 911: "* ! 912: { ! 913: rtx xoperands[4]; ! 914: ! 915: /* This is probably useless, since it loses for pushing a struct ! 916: of several bytes a byte at a time. */ ! 917: if (GET_CODE (operands[0]) == MEM ! 918: && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC ! 919: && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx) ! 920: { ! 921: xoperands[1] = operands[1]; ! 922: xoperands[2] ! 923: = gen_rtx (MEM, QImode, ! 924: gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx)); ! 925: /* Just pushing a byte puts it in the high byte of the halfword. */ ! 926: /* We must put it in the low-order, high-numbered byte. */ ! 927: output_asm_insn (\"move%.b %1,%-\;move%.b %@,%2\", xoperands); ! 928: return \"\"; ! 929: } ! 930: ! 931: /* Moving a byte into an address register is not possible. */ ! 932: /* Use d0 as an intermediate, but don't clobber its contents. */ ! 933: if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM) ! 934: { ! 935: /* ??? For 2.5, don't allow this choice and use secondary reloads ! 936: instead. ! 937: ! 938: See if the address register is used in the address. If it ! 939: is, we have to generate a more complex sequence than those below. */ ! 940: if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, ! 941: operands[1], NULL_RTX)) ! 942: { ! 943: /* See if the stack pointer is used in the address. If it isn't, ! 944: we can push d0 or d1 (the insn can't use both of them) on ! 945: the stack, perform our move into d0/d1, copy the byte from d0/1, ! 946: and pop d0/1. */ ! 947: if (! reg_mentioned_p (stack_pointer_rtx, operands[1])) ! 948: { ! 949: if (refers_to_regno_p (0, 1, operands[1], NULL_RTX)) ! 950: return \"move%.l %/d0,%-\;move%.b %1,%/d0\;move%.l %/d0,%0\;move%.l %+,%/d0\"; ! 951: else ! 952: return \"move%.l %/d1,%-\;move%.b %1,%/d1\;move%.l %/d1,%0\;move%.l %+,%/d1\"; ! 953: } ! 954: else ! 955: { ! 956: /* Otherwise, we know that d0 cannot be used in the address ! 957: (since sp and one address register is). Assume that sp is ! 958: being used as a base register and replace the address ! 959: register that is our operand[0] with d0. */ ! 960: rtx reg_map[FIRST_PSEUDO_REGISTER]; ! 961: int i; ! 962: ! 963: for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) ! 964: reg_map[i] = 0; ! 965: ! 966: reg_map[REGNO (operands[0])] = gen_rtx (REG, Pmode, 0); ! 967: operands[1] = copy_rtx (operands[1]); ! 968: replace_regs (operands[1], reg_map, FIRST_PSEUDO_REGISTER, 0); ! 969: return \"exg %/d0,%0\;move%.b %1,%/d0\;exg %/d0,%0\"; ! 970: } ! 971: } ! 972: ! 973: /* If the address of operand 1 uses d0, choose d1 as intermediate. */ ! 974: if (refers_to_regno_p (0, 1, operands[1], NULL_RTX)) ! 975: return \"exg %/d1,%0\;move%.b %1,%/d1\;exg %/d1,%0\"; ! 976: /* Otherwise d0 is usable. ! 977: (An effective address on the 68k can't use two d-regs.) */ ! 978: else ! 979: return \"exg %/d0,%0\;move%.b %1,%/d0\;exg %/d0,%0\"; ! 980: } ! 981: ! 982: /* Likewise for moving from an address reg. */ ! 983: if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM) ! 984: { ! 985: /* ??? For 2.5, don't allow this choice and use secondary reloads ! 986: instead. ! 987: ! 988: See if the address register is used in the address. If it ! 989: is, we have to generate a more complex sequence than those below. */ ! 990: if (refers_to_regno_p (REGNO (operands[1]), REGNO (operands[1]) + 1, ! 991: operands[0], NULL_RTX)) ! 992: { ! 993: /* See if the stack pointer is used in the address. If it isn't, ! 994: we can push d0 or d1 (the insn can't use both of them) on ! 995: the stack, copy the byte to d0/1, perform our move from d0/d1, ! 996: and pop d0/1. */ ! 997: if (! reg_mentioned_p (stack_pointer_rtx, operands[0])) ! 998: { ! 999: if (refers_to_regno_p (0, 1, operands[0], NULL_RTX)) ! 1000: return \"move%.l %/d0,%-\;move%.l %1,%/d0\;move%.b %/d0,%0\;move%.l %+,%/d0\"; ! 1001: else ! 1002: return \"move%.l %/d1,%-\;move%.l %1,%/d1\;move%.b %/d1,%0\;move%.l %+,%/d1\"; ! 1003: } ! 1004: else ! 1005: { ! 1006: /* Otherwise, we know that d0 cannot be used in the address ! 1007: (since sp and one address register is). Assume that sp is ! 1008: being used as a base register and replace the address ! 1009: register that is our operand[1] with d0. */ ! 1010: rtx reg_map[FIRST_PSEUDO_REGISTER]; ! 1011: int i; ! 1012: ! 1013: for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) ! 1014: reg_map[i] = 0; ! 1015: ! 1016: reg_map[REGNO (operands[1])] = gen_rtx (REG, Pmode, 0); ! 1017: operands[0] = copy_rtx (operands[0]); ! 1018: replace_regs (operands[0], reg_map, FIRST_PSEUDO_REGISTER, 0); ! 1019: return \"exg %/d0,%1\;move%.b %/d0,%0\;exg %/d0,%1\"; ! 1020: } ! 1021: } ! 1022: ! 1023: if (refers_to_regno_p (0, 1, operands[0], NULL_RTX)) ! 1024: return \"exg %/d1,%1\;move%.b %/d1,%0\;exg %/d1,%1\"; ! 1025: else ! 1026: return \"exg %/d0,%1\;move%.b %/d0,%0\;exg %/d0,%1\"; ! 1027: } ! 1028: ! 1029: /* clr and st insns on 68000 read before writing. ! 1030: This isn't so on the 68010, but we have no alternative for it. */ ! 1031: if (TARGET_68020 ! 1032: || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) ! 1033: { ! 1034: if (operands[1] == const0_rtx) ! 1035: return \"clr%.b %0\"; ! 1036: if (GET_CODE (operands[1]) == CONST_INT ! 1037: && INTVAL (operands[1]) == -1) ! 1038: { ! 1039: CC_STATUS_INIT; ! 1040: return \"st %0\"; ! 1041: } ! 1042: } ! 1043: if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1])) ! 1044: return \"move%.l %1,%0\"; ! 1045: if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1])) ! 1046: return \"move%.w %1,%0\"; ! 1047: return \"move%.b %1,%0\"; ! 1048: }") ! 1049: ! 1050: (define_insn "movstrictqi" ! 1051: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm")) ! 1052: (match_operand:QI 1 "general_operand" "dmn"))] ! 1053: "" ! 1054: "* ! 1055: { ! 1056: if (operands[1] == const0_rtx ! 1057: /* clr insns on 68000 read before writing. ! 1058: This isn't so on the 68010, but we have no alternative for it. */ ! 1059: && (TARGET_68020 ! 1060: || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))) ! 1061: return \"clr%.b %0\"; ! 1062: return \"move%.b %1,%0\"; ! 1063: }") ! 1064: ! 1065: (define_insn "movsf" ! 1066: [(set (match_operand:SF 0 "general_operand" "=rmf,x,y,rm,!x,!rm") ! 1067: (match_operand:SF 1 "general_operand" "rmfF,xH,rmF,y,rm,x"))] ! 1068: ; [(set (match_operand:SF 0 "general_operand" "=rmf") ! 1069: ; (match_operand:SF 1 "general_operand" "rmfF"))] ! 1070: "" ! 1071: "* ! 1072: { ! 1073: if (which_alternative >= 4) ! 1074: return \"fpmove%.s %1,fpa0\;fpmove%.s fpa0,%0\"; ! 1075: if (FPA_REG_P (operands[0])) ! 1076: { ! 1077: if (FPA_REG_P (operands[1])) ! 1078: return \"fpmove%.s %x1,%x0\"; ! 1079: else if (GET_CODE (operands[1]) == CONST_DOUBLE) ! 1080: return output_move_const_single (operands); ! 1081: else if (FP_REG_P (operands[1])) ! 1082: return \"fmove%.s %1,sp@-\;fpmove%.d sp@+, %0\"; ! 1083: return \"fpmove%.s %x1,%x0\"; ! 1084: } ! 1085: if (FPA_REG_P (operands[1])) ! 1086: { ! 1087: if (FP_REG_P (operands[0])) ! 1088: return \"fpmove%.s %x1,sp@-\;fmove%.s sp@+,%0\"; ! 1089: else ! 1090: return \"fpmove%.s %x1,%x0\"; ! 1091: } ! 1092: if (FP_REG_P (operands[0])) ! 1093: { ! 1094: if (FP_REG_P (operands[1])) ! 1095: return \"f%$move%.x %1,%0\"; ! 1096: else if (ADDRESS_REG_P (operands[1])) ! 1097: return \"move%.l %1,%-\;f%$move%.s %+,%0\"; ! 1098: else if (GET_CODE (operands[1]) == CONST_DOUBLE) ! 1099: return output_move_const_single (operands); ! 1100: return \"f%$move%.s %f1,%0\"; ! 1101: } ! 1102: if (FP_REG_P (operands[1])) ! 1103: { ! 1104: if (ADDRESS_REG_P (operands[0])) ! 1105: return \"fmove%.s %1,%-\;move%.l %+,%0\"; ! 1106: return \"fmove%.s %f1,%0\"; ! 1107: } ! 1108: return \"move%.l %1,%0\"; ! 1109: }") ! 1110: ! 1111: (define_insn "movdf" ! 1112: [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>,y,rm,x,!x,!rm") ! 1113: (match_operand:DF 1 "general_operand" "rf,m,rofE<>,rmE,y,xH,rm,x"))] ! 1114: ; [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>") ! 1115: ; (match_operand:DF 1 "general_operand" "rf,m,rofF<>"))] ! 1116: "" ! 1117: "* ! 1118: { ! 1119: if (which_alternative == 6) ! 1120: return \"fpmove%.d %x1,fpa0\;fpmove%.d fpa0,%x0\"; ! 1121: if (FPA_REG_P (operands[0])) ! 1122: { ! 1123: if (GET_CODE (operands[1]) == CONST_DOUBLE) ! 1124: return output_move_const_double (operands); ! 1125: if (FP_REG_P (operands[1])) ! 1126: return \"fmove%.d %1,sp@-\;fpmove%.d sp@+,%x0\"; ! 1127: return \"fpmove%.d %x1,%x0\"; ! 1128: } ! 1129: else if (FPA_REG_P (operands[1])) ! 1130: { ! 1131: if (FP_REG_P(operands[0])) ! 1132: return \"fpmove%.d %x1,sp@-\;fmoved sp@+,%0\"; ! 1133: else ! 1134: return \"fpmove%.d %x1,%x0\"; ! 1135: } ! 1136: if (FP_REG_P (operands[0])) ! 1137: { ! 1138: if (FP_REG_P (operands[1])) ! 1139: return \"f%&move%.x %1,%0\"; ! 1140: if (REG_P (operands[1])) ! 1141: { ! 1142: rtx xoperands[2]; ! 1143: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); ! 1144: output_asm_insn (\"move%.l %1,%-\", xoperands); ! 1145: output_asm_insn (\"move%.l %1,%-\", operands); ! 1146: return \"f%&move%.d %+,%0\"; ! 1147: } ! 1148: if (GET_CODE (operands[1]) == CONST_DOUBLE) ! 1149: return output_move_const_double (operands); ! 1150: return \"f%&move%.d %f1,%0\"; ! 1151: } ! 1152: else if (FP_REG_P (operands[1])) ! 1153: { ! 1154: if (REG_P (operands[0])) ! 1155: { ! 1156: output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands); ! 1157: operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); ! 1158: return \"move%.l %+,%0\"; ! 1159: } ! 1160: else ! 1161: return \"fmove%.d %f1,%0\"; ! 1162: } ! 1163: return output_move_double (operands); ! 1164: } ! 1165: ") ! 1166: ! 1167: (define_expand "movxf" ! 1168: [(set (match_operand:XF 0 "nonimmediate_operand" "") ! 1169: (match_operand:XF 1 "general_operand" ""))] ! 1170: "" ! 1171: " ! 1172: { ! 1173: if (CONSTANT_P (operands[1])) ! 1174: { ! 1175: operands[1] = force_const_mem (XFmode, operands[1]); ! 1176: if (! memory_address_p (XFmode, XEXP (operands[1], 0)) ! 1177: && ! reload_in_progress) ! 1178: operands[1] = change_address (operands[1], XFmode, ! 1179: XEXP (operands[1], 0)); ! 1180: } ! 1181: }") ! 1182: ! 1183: (define_insn "" ! 1184: [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,!r,!f") ! 1185: (match_operand:XF 1 "nonimmediate_operand" "m,f,f,f,r"))] ! 1186: "TARGET_68881" ! 1187: "* ! 1188: { ! 1189: if (FP_REG_P (operands[0])) ! 1190: { ! 1191: if (FP_REG_P (operands[1])) ! 1192: return \"fmove%.x %1,%0\"; ! 1193: if (REG_P (operands[1])) ! 1194: { ! 1195: rtx xoperands[2]; ! 1196: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2); ! 1197: output_asm_insn (\"move%.l %1,%-\", xoperands); ! 1198: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); ! 1199: output_asm_insn (\"move%.l %1,%-\", xoperands); ! 1200: output_asm_insn (\"move%.l %1,%-\", operands); ! 1201: return \"fmove%.x %+,%0\"; ! 1202: } ! 1203: if (GET_CODE (operands[1]) == CONST_DOUBLE) ! 1204: return \"fmove%.x %1,%0\"; ! 1205: return \"fmove%.x %f1,%0\"; ! 1206: } ! 1207: if (REG_P (operands[0])) ! 1208: { ! 1209: output_asm_insn (\"fmove%.x %f1,%-\;move%.l %+,%0\", operands); ! 1210: operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); ! 1211: output_asm_insn (\"move%.l %+,%0\", operands); ! 1212: operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); ! 1213: return \"move%.l %+,%0\"; ! 1214: } ! 1215: return \"fmove%.x %f1,%0\"; ! 1216: } ! 1217: ") ! 1218: ! 1219: (define_insn "" ! 1220: [(set (match_operand:XF 0 "nonimmediate_operand" "=rm,&rf,&rof<>") ! 1221: (match_operand:XF 1 "nonimmediate_operand" "rf,m,rof<>"))] ! 1222: "! TARGET_68881" ! 1223: "* ! 1224: { ! 1225: if (FP_REG_P (operands[0])) ! 1226: { ! 1227: if (FP_REG_P (operands[1])) ! 1228: return \"fmove%.x %1,%0\"; ! 1229: if (REG_P (operands[1])) ! 1230: { ! 1231: rtx xoperands[2]; ! 1232: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2); ! 1233: output_asm_insn (\"move%.l %1,%-\", xoperands); ! 1234: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); ! 1235: output_asm_insn (\"move%.l %1,%-\", xoperands); ! 1236: output_asm_insn (\"move%.l %1,%-\", operands); ! 1237: return \"fmove%.x %+,%0\"; ! 1238: } ! 1239: if (GET_CODE (operands[1]) == CONST_DOUBLE) ! 1240: return \"fmove%.x %1,%0\"; ! 1241: return \"fmove%.x %f1,%0\"; ! 1242: } ! 1243: if (FP_REG_P (operands[1])) ! 1244: { ! 1245: if (REG_P (operands[0])) ! 1246: { ! 1247: output_asm_insn (\"fmove%.x %f1,%-\;move%.l %+,%0\", operands); ! 1248: operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); ! 1249: output_asm_insn (\"move%.l %+,%0\", operands); ! 1250: operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); ! 1251: return \"move%.l %+,%0\"; ! 1252: } ! 1253: else ! 1254: return \"fmove%.x %f1,%0\"; ! 1255: } ! 1256: return output_move_double (operands); ! 1257: } ! 1258: ") ! 1259: ! 1260: ;; movdi can apply to fp regs in some cases ! 1261: (define_insn "movdi" ! 1262: ;; Let's see if it really still needs to handle fp regs, and, if so, why. ! 1263: [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>,y,rm,!*x,!rm") ! 1264: (match_operand:DI 1 "general_operand" "rF,m,roi<>F,rmiF,y,rmF,*x"))] ! 1265: ; [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>,!&rm,!&f,y,rm,x,!x,!rm") ! 1266: ; (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfmF,rmi,y,rm,x"))] ! 1267: ; [(set (match_operand:DI 0 "general_operand" "=rm,&rf,&ro<>,!&rm,!&f") ! 1268: ; (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfF"))] ! 1269: "" ! 1270: "* ! 1271: { ! 1272: if (which_alternative == 8) ! 1273: return \"fpmove%.d %x1,fpa0\;fpmove%.d fpa0,%x0\"; ! 1274: if (FPA_REG_P (operands[0]) || FPA_REG_P (operands[1])) ! 1275: return \"fpmove%.d %x1,%x0\"; ! 1276: if (FP_REG_P (operands[0])) ! 1277: { ! 1278: if (FP_REG_P (operands[1])) ! 1279: return \"fmove%.x %1,%0\"; ! 1280: if (REG_P (operands[1])) ! 1281: { ! 1282: rtx xoperands[2]; ! 1283: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); ! 1284: output_asm_insn (\"move%.l %1,%-\", xoperands); ! 1285: output_asm_insn (\"move%.l %1,%-\", operands); ! 1286: return \"fmove%.d %+,%0\"; ! 1287: } ! 1288: if (GET_CODE (operands[1]) == CONST_DOUBLE) ! 1289: return output_move_const_double (operands); ! 1290: return \"fmove%.d %f1,%0\"; ! 1291: } ! 1292: else if (FP_REG_P (operands[1])) ! 1293: { ! 1294: if (REG_P (operands[0])) ! 1295: { ! 1296: output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands); ! 1297: operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); ! 1298: return \"move%.l %+,%0\"; ! 1299: } ! 1300: else ! 1301: return \"fmove%.d %f1,%0\"; ! 1302: } ! 1303: return output_move_double (operands); ! 1304: } ! 1305: ") ! 1306: ! 1307: ;; Thus goes after the move instructions ! 1308: ;; because the move instructions are better (require no spilling) ! 1309: ;; when they can apply. It goes before the add/sub insns ! 1310: ;; so we will prefer it to them. ! 1311: ! 1312: (define_insn "pushasi" ! 1313: [(set (match_operand:SI 0 "push_operand" "=m") ! 1314: (match_operand:SI 1 "address_operand" "p"))] ! 1315: "" ! 1316: "pea %a1") ! 1317: ! 1318: ;; truncation instructions ! 1319: (define_insn "truncsiqi2" ! 1320: [(set (match_operand:QI 0 "general_operand" "=dm,d") ! 1321: (truncate:QI ! 1322: (match_operand:SI 1 "general_operand" "doJ,i")))] ! 1323: "" ! 1324: "* ! 1325: { ! 1326: if (GET_CODE (operands[0]) == REG) ! 1327: { ! 1328: /* Must clear condition codes, since the move.l bases them on ! 1329: the entire 32 bits, not just the desired 8 bits. */ ! 1330: CC_STATUS_INIT; ! 1331: return \"move%.l %1,%0\"; ! 1332: } ! 1333: if (GET_CODE (operands[1]) == MEM) ! 1334: operands[1] = adj_offsettable_operand (operands[1], 3); ! 1335: return \"move%.b %1,%0\"; ! 1336: }") ! 1337: ! 1338: (define_insn "trunchiqi2" ! 1339: [(set (match_operand:QI 0 "general_operand" "=dm,d") ! 1340: (truncate:QI ! 1341: (match_operand:HI 1 "general_operand" "doJ,i")))] ! 1342: "" ! 1343: "* ! 1344: { ! 1345: if (GET_CODE (operands[0]) == REG ! 1346: && (GET_CODE (operands[1]) == MEM ! 1347: || GET_CODE (operands[1]) == CONST_INT)) ! 1348: { ! 1349: /* Must clear condition codes, since the move.w bases them on ! 1350: the entire 16 bits, not just the desired 8 bits. */ ! 1351: CC_STATUS_INIT; ! 1352: return \"move%.w %1,%0\"; ! 1353: } ! 1354: if (GET_CODE (operands[0]) == REG) ! 1355: { ! 1356: /* Must clear condition codes, since the move.l bases them on ! 1357: the entire 32 bits, not just the desired 8 bits. */ ! 1358: CC_STATUS_INIT; ! 1359: return \"move%.l %1,%0\"; ! 1360: } ! 1361: if (GET_CODE (operands[1]) == MEM) ! 1362: operands[1] = adj_offsettable_operand (operands[1], 1); ! 1363: return \"move%.b %1,%0\"; ! 1364: }") ! 1365: ! 1366: (define_insn "truncsihi2" ! 1367: [(set (match_operand:HI 0 "general_operand" "=dm,d") ! 1368: (truncate:HI ! 1369: (match_operand:SI 1 "general_operand" "roJ,i")))] ! 1370: "" ! 1371: "* ! 1372: { ! 1373: if (GET_CODE (operands[0]) == REG) ! 1374: { ! 1375: /* Must clear condition codes, since the move.l bases them on ! 1376: the entire 32 bits, not just the desired 8 bits. */ ! 1377: CC_STATUS_INIT; ! 1378: return \"move%.l %1,%0\"; ! 1379: } ! 1380: if (GET_CODE (operands[1]) == MEM) ! 1381: operands[1] = adj_offsettable_operand (operands[1], 2); ! 1382: return \"move%.w %1,%0\"; ! 1383: }") ! 1384: ! 1385: ;; zero extension instructions ! 1386: ! 1387: (define_expand "zero_extendhisi2" ! 1388: [(set (match_operand:SI 0 "register_operand" "") ! 1389: (const_int 0)) ! 1390: (set (strict_low_part (match_dup 2)) ! 1391: (match_operand:HI 1 "general_operand" ""))] ! 1392: "" ! 1393: " ! 1394: { ! 1395: operands[1] = make_safe_from (operands[1], operands[0]); ! 1396: if (GET_CODE (operands[0]) == SUBREG) ! 1397: operands[2] = gen_rtx (SUBREG, HImode, SUBREG_REG (operands[0]), ! 1398: SUBREG_WORD (operands[0])); ! 1399: else ! 1400: operands[2] = gen_rtx (SUBREG, HImode, operands[0], 0); ! 1401: }") ! 1402: ! 1403: (define_expand "zero_extendqihi2" ! 1404: [(set (match_operand:HI 0 "register_operand" "") ! 1405: (const_int 0)) ! 1406: (set (strict_low_part (match_dup 2)) ! 1407: (match_operand:QI 1 "general_operand" ""))] ! 1408: "" ! 1409: " ! 1410: { ! 1411: operands[1] = make_safe_from (operands[1], operands[0]); ! 1412: if (GET_CODE (operands[0]) == SUBREG) ! 1413: operands[2] = gen_rtx (SUBREG, QImode, SUBREG_REG (operands[0]), ! 1414: SUBREG_WORD (operands[0])); ! 1415: else ! 1416: operands[2] = gen_rtx (SUBREG, QImode, operands[0], 0); ! 1417: }") ! 1418: ! 1419: (define_expand "zero_extendqisi2" ! 1420: [(set (match_operand:SI 0 "register_operand" "") ! 1421: (const_int 0)) ! 1422: (set (strict_low_part (match_dup 2)) ! 1423: (match_operand:QI 1 "general_operand" ""))] ! 1424: "" ! 1425: " ! 1426: { ! 1427: operands[1] = make_safe_from (operands[1], operands[0]); ! 1428: if (GET_CODE (operands[0]) == SUBREG) ! 1429: operands[2] = gen_rtx (SUBREG, QImode, SUBREG_REG (operands[0]), ! 1430: SUBREG_WORD (operands[0])); ! 1431: else ! 1432: operands[2] = gen_rtx (SUBREG, QImode, operands[0], 0); ! 1433: }") ! 1434: ! 1435: ;; Patterns to recognize zero-extend insns produced by the combiner. ! 1436: ;; We don't allow both operands in memory, because of aliasing problems. ! 1437: ;; Explicitly disallow two memory operands via the condition since reloading ! 1438: ;; of this case will result in worse code than the uncombined patterns. ! 1439: ! 1440: (define_insn "" ! 1441: [(set (match_operand:SI 0 "general_operand" "=do<>,d<") ! 1442: (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))] ! 1443: "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" ! 1444: "* ! 1445: { ! 1446: if (DATA_REG_P (operands[0])) ! 1447: { ! 1448: if (GET_CODE (operands[1]) == REG ! 1449: && REGNO (operands[0]) == REGNO (operands[1])) ! 1450: return \"and%.l %#0xFFFF,%0\"; ! 1451: if (reg_mentioned_p (operands[0], operands[1])) ! 1452: return \"move%.w %1,%0\;and%.l %#0xFFFF,%0\"; ! 1453: return \"clr%.l %0\;move%.w %1,%0\"; ! 1454: } ! 1455: else if (GET_CODE (operands[0]) == MEM ! 1456: && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) ! 1457: return \"move%.w %1,%0\;clr%.w %0\"; ! 1458: else if (GET_CODE (operands[0]) == MEM ! 1459: && GET_CODE (XEXP (operands[0], 0)) == POST_INC) ! 1460: return \"clr%.w %0\;move%.w %1,%0\"; ! 1461: else ! 1462: { ! 1463: output_asm_insn (\"clr%.w %0\", operands); ! 1464: operands[0] = adj_offsettable_operand (operands[0], 2); ! 1465: return \"move%.w %1,%0\"; ! 1466: } ! 1467: }") ! 1468: ! 1469: (define_insn "" ! 1470: [(set (match_operand:HI 0 "general_operand" "=do<>,d") ! 1471: (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))] ! 1472: "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" ! 1473: "* ! 1474: { ! 1475: if (DATA_REG_P (operands[0])) ! 1476: { ! 1477: if (GET_CODE (operands[1]) == REG ! 1478: && REGNO (operands[0]) == REGNO (operands[1])) ! 1479: return \"and%.w %#0xFF,%0\"; ! 1480: if (reg_mentioned_p (operands[0], operands[1])) ! 1481: return \"move%.b %1,%0\;and%.w %#0xFF,%0\"; ! 1482: return \"clr%.w %0\;move%.b %1,%0\"; ! 1483: } ! 1484: else if (GET_CODE (operands[0]) == MEM ! 1485: && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) ! 1486: { ! 1487: if (REGNO (XEXP (XEXP (operands[0], 0), 0)) ! 1488: == STACK_POINTER_REGNUM) ! 1489: { ! 1490: output_asm_insn (\"clr%.w %-\", operands); ! 1491: operands[0] = gen_rtx (MEM, GET_MODE (operands[0]), ! 1492: plus_constant (stack_pointer_rtx, 1)); ! 1493: return \"move%.b %1,%0\"; ! 1494: } ! 1495: else ! 1496: return \"move%.b %1,%0\;clr%.b %0\"; ! 1497: } ! 1498: else if (GET_CODE (operands[0]) == MEM ! 1499: && GET_CODE (XEXP (operands[0], 0)) == POST_INC) ! 1500: return \"clr%.b %0\;move%.b %1,%0\"; ! 1501: else ! 1502: { ! 1503: output_asm_insn (\"clr%.b %0\", operands); ! 1504: operands[0] = adj_offsettable_operand (operands[0], 1); ! 1505: return \"move%.b %1,%0\"; ! 1506: } ! 1507: }") ! 1508: ! 1509: (define_insn "" ! 1510: [(set (match_operand:SI 0 "general_operand" "=do<>,d") ! 1511: (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))] ! 1512: "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" ! 1513: "* ! 1514: { ! 1515: if (DATA_REG_P (operands[0])) ! 1516: { ! 1517: if (GET_CODE (operands[1]) == REG ! 1518: && REGNO (operands[0]) == REGNO (operands[1])) ! 1519: return \"and%.l %#0xFF,%0\"; ! 1520: if (reg_mentioned_p (operands[0], operands[1])) ! 1521: return \"move%.b %1,%0\;and%.l %#0xFF,%0\"; ! 1522: return \"clr%.l %0\;move%.b %1,%0\"; ! 1523: } ! 1524: else if (GET_CODE (operands[0]) == MEM ! 1525: && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) ! 1526: { ! 1527: operands[0] = XEXP (XEXP (operands[0], 0), 0); ! 1528: #ifdef MOTOROLA ! 1529: #ifdef SGS ! 1530: return \"clr%.l -(%0)\;move%.b %1,3(%0)\"; ! 1531: #else ! 1532: return \"clr%.l -(%0)\;move%.b %1,(3,%0)\"; ! 1533: #endif ! 1534: #else ! 1535: return \"clrl %0@-\;moveb %1,%0@(3)\"; ! 1536: #endif ! 1537: } ! 1538: else if (GET_CODE (operands[0]) == MEM ! 1539: && GET_CODE (XEXP (operands[0], 0)) == POST_INC) ! 1540: { ! 1541: operands[0] = XEXP (XEXP (operands[0], 0), 0); ! 1542: #ifdef MOTOROLA ! 1543: #ifdef SGS ! 1544: return \"clr%.l (%0)+\;move%.b %1,-1(%0)\"; ! 1545: #else ! 1546: return \"clr%.l (%0)+\;move%.b %1,(-1,%0)\"; ! 1547: #endif ! 1548: #else ! 1549: return \"clrl %0@+\;moveb %1,%0@(-1)\"; ! 1550: #endif ! 1551: } ! 1552: else ! 1553: { ! 1554: output_asm_insn (\"clr%.l %0\", operands); ! 1555: operands[0] = adj_offsettable_operand (operands[0], 3); ! 1556: return \"move%.b %1,%0\"; ! 1557: } ! 1558: }") ! 1559: ! 1560: ;; sign extension instructions ! 1561: ! 1562: (define_insn "extendhisi2" ! 1563: [(set (match_operand:SI 0 "general_operand" "=*d,a") ! 1564: (sign_extend:SI ! 1565: (match_operand:HI 1 "nonimmediate_operand" "0,rm")))] ! 1566: "" ! 1567: "* ! 1568: { ! 1569: if (ADDRESS_REG_P (operands[0])) ! 1570: return \"move%.w %1,%0\"; ! 1571: return \"ext%.l %0\"; ! 1572: }") ! 1573: ! 1574: (define_insn "extendqihi2" ! 1575: [(set (match_operand:HI 0 "general_operand" "=d") ! 1576: (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))] ! 1577: "" ! 1578: "ext%.w %0") ! 1579: ! 1580: (define_insn "extendqisi2" ! 1581: [(set (match_operand:SI 0 "general_operand" "=d") ! 1582: (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))] ! 1583: "TARGET_68020" ! 1584: "extb%.l %0") ! 1585: ! 1586: ;; Conversions between float and double. ! 1587: ! 1588: (define_expand "extendsfdf2" ! 1589: [(set (match_operand:DF 0 "general_operand" "") ! 1590: (float_extend:DF ! 1591: (match_operand:SF 1 "general_operand" "")))] ! 1592: "TARGET_68881 || TARGET_FPA" ! 1593: "") ! 1594: ! 1595: (define_insn "" ! 1596: [(set (match_operand:DF 0 "general_operand" "=x,y") ! 1597: (float_extend:DF ! 1598: (match_operand:SF 1 "general_operand" "xH,rmF")))] ! 1599: "TARGET_FPA" ! 1600: "fpstod %w1,%0") ! 1601: ! 1602: (define_insn "" ! 1603: [(set (match_operand:DF 0 "general_operand" "=*fdm,f") ! 1604: (float_extend:DF ! 1605: (match_operand:SF 1 "general_operand" "f,dmF")))] ! 1606: "TARGET_68881" ! 1607: "* ! 1608: { ! 1609: if (FP_REG_P (operands[0]) && FP_REG_P (operands[1])) ! 1610: { ! 1611: if (REGNO (operands[0]) == REGNO (operands[1])) ! 1612: { ! 1613: /* Extending float to double in an fp-reg is a no-op. ! 1614: NOTICE_UPDATE_CC has already assumed that the ! 1615: cc will be set. So cancel what it did. */ ! 1616: cc_status = cc_prev_status; ! 1617: return \"\"; ! 1618: } ! 1619: return \"f%&move%.x %1,%0\"; ! 1620: } ! 1621: if (FP_REG_P (operands[0])) ! 1622: return \"f%&move%.s %f1,%0\"; ! 1623: if (DATA_REG_P (operands[0]) && FP_REG_P (operands[1])) ! 1624: { ! 1625: output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands); ! 1626: operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); ! 1627: return \"move%.l %+,%0\"; ! 1628: } ! 1629: return \"fmove%.d %f1,%0\"; ! 1630: }") ! 1631: ! 1632: ;; This cannot output into an f-reg because there is no way to be ! 1633: ;; sure of truncating in that case. ! 1634: ;; But on the Sun FPA, we can be sure. ! 1635: (define_expand "truncdfsf2" ! 1636: [(set (match_operand:SF 0 "general_operand" "") ! 1637: (float_truncate:SF ! 1638: (match_operand:DF 1 "general_operand" "")))] ! 1639: "TARGET_68881 || TARGET_FPA" ! 1640: "") ! 1641: ! 1642: (define_insn "" ! 1643: [(set (match_operand:SF 0 "general_operand" "=x,y") ! 1644: (float_truncate:SF ! 1645: (match_operand:DF 1 "general_operand" "xH,rmF")))] ! 1646: "TARGET_FPA" ! 1647: "fpdtos %y1,%0") ! 1648: ! 1649: ;; On the '040 we can truncate in a register accurately and easily. ! 1650: (define_insn "" ! 1651: [(set (match_operand:SF 0 "general_operand" "=f") ! 1652: (float_truncate:SF ! 1653: (match_operand:DF 1 "general_operand" "fmG")))] ! 1654: "TARGET_68040_ONLY" ! 1655: "* ! 1656: { ! 1657: if (FP_REG_P (operands[1])) ! 1658: return \"f%$move%.x %1,%0\"; ! 1659: return \"f%$move%.d %f1,%0\"; ! 1660: }") ! 1661: ! 1662: (define_insn "" ! 1663: [(set (match_operand:SF 0 "general_operand" "=dm") ! 1664: (float_truncate:SF ! 1665: (match_operand:DF 1 "general_operand" "f")))] ! 1666: "TARGET_68881" ! 1667: "fmove%.s %f1,%0") ! 1668: ! 1669: ;; Conversion between fixed point and floating point. ! 1670: ;; Note that among the fix-to-float insns ! 1671: ;; the ones that start with SImode come first. ! 1672: ;; That is so that an operand that is a CONST_INT ! 1673: ;; (and therefore lacks a specific machine mode). ! 1674: ;; will be recognized as SImode (which is always valid) ! 1675: ;; rather than as QImode or HImode. ! 1676: ! 1677: (define_expand "floatsisf2" ! 1678: [(set (match_operand:SF 0 "general_operand" "") ! 1679: (float:SF (match_operand:SI 1 "general_operand" "")))] ! 1680: "TARGET_68881 || TARGET_FPA" ! 1681: "") ! 1682: ! 1683: (define_insn "" ! 1684: [(set (match_operand:SF 0 "general_operand" "=y,x") ! 1685: (float:SF (match_operand:SI 1 "general_operand" "rmi,x")))] ! 1686: "TARGET_FPA" ! 1687: "fpltos %1,%0") ! 1688: ! 1689: (define_insn "" ! 1690: [(set (match_operand:SF 0 "general_operand" "=f") ! 1691: (float:SF (match_operand:SI 1 "general_operand" "dmi")))] ! 1692: "TARGET_68881" ! 1693: "f%$move%.l %1,%0") ! 1694: ! 1695: (define_expand "floatsidf2" ! 1696: [(set (match_operand:DF 0 "general_operand" "") ! 1697: (float:DF (match_operand:SI 1 "general_operand" "")))] ! 1698: "TARGET_68881 || TARGET_FPA" ! 1699: "") ! 1700: ! 1701: (define_insn "" ! 1702: [(set (match_operand:DF 0 "general_operand" "=y,x") ! 1703: (float:DF (match_operand:SI 1 "general_operand" "rmi,x")))] ! 1704: "TARGET_FPA" ! 1705: "fpltod %1,%0") ! 1706: ! 1707: (define_insn "" ! 1708: [(set (match_operand:DF 0 "general_operand" "=f") ! 1709: (float:DF (match_operand:SI 1 "general_operand" "dmi")))] ! 1710: "TARGET_68881" ! 1711: "f%&move%.l %1,%0") ! 1712: ! 1713: (define_insn "floathisf2" ! 1714: [(set (match_operand:SF 0 "general_operand" "=f") ! 1715: (float:SF (match_operand:HI 1 "general_operand" "dmn")))] ! 1716: "TARGET_68881" ! 1717: "f%$move%.w %1,%0") ! 1718: ! 1719: (define_insn "floathidf2" ! 1720: [(set (match_operand:DF 0 "general_operand" "=f") ! 1721: (float:DF (match_operand:HI 1 "general_operand" "dmn")))] ! 1722: "TARGET_68881" ! 1723: "fmove%.w %1,%0") ! 1724: ! 1725: (define_insn "floatqisf2" ! 1726: [(set (match_operand:SF 0 "general_operand" "=f") ! 1727: (float:SF (match_operand:QI 1 "general_operand" "dmn")))] ! 1728: "TARGET_68881" ! 1729: "fmove%.b %1,%0") ! 1730: ! 1731: (define_insn "floatqidf2" ! 1732: [(set (match_operand:DF 0 "general_operand" "=f") ! 1733: (float:DF (match_operand:QI 1 "general_operand" "dmn")))] ! 1734: "TARGET_68881" ! 1735: "f%&move%.b %1,%0") ! 1736: ! 1737: ;; New routines to convert floating-point values to integers ! 1738: ;; to be used on the '040. These should be faster than trapping ! 1739: ;; into the kernel to emulate fintrz. They should also be faster ! 1740: ;; than calling the subroutines fixsfsi or fixdfsi. ! 1741: ! 1742: (define_insn "fix_truncdfsi2" ! 1743: [(set (match_operand:SI 0 "general_operand" "=dm") ! 1744: (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f")))) ! 1745: (clobber (match_scratch:SI 2 "=d")) ! 1746: (clobber (match_scratch:SI 3 "=d"))] ! 1747: "TARGET_68040" ! 1748: "* ! 1749: { ! 1750: CC_STATUS_INIT; ! 1751: return \"fmovem%.l %!,%2\;moveq %#16,%3\;or%.l %2,%3\;and%.w %#-33,%3\;fmovem%.l %3,%!\;fmove%.l %1,%0\;fmovem%.l %2,%!\"; ! 1752: }") ! 1753: ! 1754: (define_insn "fix_truncdfhi2" ! 1755: [(set (match_operand:HI 0 "general_operand" "=dm") ! 1756: (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "f")))) ! 1757: (clobber (match_scratch:SI 2 "=d")) ! 1758: (clobber (match_scratch:SI 3 "=d"))] ! 1759: "TARGET_68040" ! 1760: "* ! 1761: { ! 1762: CC_STATUS_INIT; ! 1763: return \"fmovem%.l %!,%2\;moveq %#16,%3\;or%.l %2,%3\;and%.w %#-33,%3\;fmovem%.l %3,%!\;fmove%.w %1,%0\;fmovem%.l %2,%!\"; ! 1764: }") ! 1765: ! 1766: (define_insn "fix_truncdfqi2" ! 1767: [(set (match_operand:QI 0 "general_operand" "=dm") ! 1768: (fix:QI (fix:DF (match_operand:DF 1 "register_operand" "f")))) ! 1769: (clobber (match_scratch:SI 2 "=d")) ! 1770: (clobber (match_scratch:SI 3 "=d"))] ! 1771: "TARGET_68040" ! 1772: "* ! 1773: { ! 1774: CC_STATUS_INIT; ! 1775: return \"fmovem%.l %!,%2\;moveq %#16,%3\;or%.l %2,%3\;and%.w %#-33,%3\;fmovem%.l %3,%!\;fmove%.b %1,%0\;fmovem%.l %2,%!\"; ! 1776: }") ! 1777: ! 1778: ;; Convert a float to a float whose value is an integer. ! 1779: ;; This is the first stage of converting it to an integer type. ! 1780: ! 1781: (define_insn "ftruncdf2" ! 1782: [(set (match_operand:DF 0 "general_operand" "=f") ! 1783: (fix:DF (match_operand:DF 1 "general_operand" "fFm")))] ! 1784: "TARGET_68881 && !TARGET_68040" ! 1785: "* ! 1786: { ! 1787: if (FP_REG_P (operands[1])) ! 1788: return \"fintrz%.x %f1,%0\"; ! 1789: return \"fintrz%.d %f1,%0\"; ! 1790: }") ! 1791: ! 1792: (define_insn "ftruncsf2" ! 1793: [(set (match_operand:SF 0 "general_operand" "=f") ! 1794: (fix:SF (match_operand:SF 1 "general_operand" "dfFm")))] ! 1795: "TARGET_68881 && !TARGET_68040" ! 1796: "* ! 1797: { ! 1798: if (FP_REG_P (operands[1])) ! 1799: return \"fintrz%.x %f1,%0\"; ! 1800: return \"fintrz%.s %f1,%0\"; ! 1801: }") ! 1802: ! 1803: ;; Convert a float whose value is an integer ! 1804: ;; to an actual integer. Second stage of converting float to integer type. ! 1805: (define_insn "fixsfqi2" ! 1806: [(set (match_operand:QI 0 "general_operand" "=dm") ! 1807: (fix:QI (match_operand:SF 1 "general_operand" "f")))] ! 1808: "TARGET_68881" ! 1809: "fmove%.b %1,%0") ! 1810: ! 1811: (define_insn "fixsfhi2" ! 1812: [(set (match_operand:HI 0 "general_operand" "=dm") ! 1813: (fix:HI (match_operand:SF 1 "general_operand" "f")))] ! 1814: "TARGET_68881" ! 1815: "fmove%.w %1,%0") ! 1816: ! 1817: (define_insn "fixsfsi2" ! 1818: [(set (match_operand:SI 0 "general_operand" "=dm") ! 1819: (fix:SI (match_operand:SF 1 "general_operand" "f")))] ! 1820: "TARGET_68881" ! 1821: "fmove%.l %1,%0") ! 1822: ! 1823: (define_insn "fixdfqi2" ! 1824: [(set (match_operand:QI 0 "general_operand" "=dm") ! 1825: (fix:QI (match_operand:DF 1 "general_operand" "f")))] ! 1826: "TARGET_68881" ! 1827: "fmove%.b %1,%0") ! 1828: ! 1829: (define_insn "fixdfhi2" ! 1830: [(set (match_operand:HI 0 "general_operand" "=dm") ! 1831: (fix:HI (match_operand:DF 1 "general_operand" "f")))] ! 1832: "TARGET_68881" ! 1833: "fmove%.w %1,%0") ! 1834: ! 1835: (define_insn "fixdfsi2" ! 1836: [(set (match_operand:SI 0 "general_operand" "=dm") ! 1837: (fix:SI (match_operand:DF 1 "general_operand" "f")))] ! 1838: "TARGET_68881" ! 1839: "fmove%.l %1,%0") ! 1840: ! 1841: ;; Convert a float to an integer. ! 1842: ;; On the Sun FPA, this is done in one step. ! 1843: ! 1844: (define_insn "" ! 1845: [(set (match_operand:SI 0 "general_operand" "=x,y") ! 1846: (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "xH,rmF"))))] ! 1847: "TARGET_FPA" ! 1848: "fpstol %w1,%0") ! 1849: ! 1850: (define_insn "" ! 1851: [(set (match_operand:SI 0 "general_operand" "=x,y") ! 1852: (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "xH,rmF"))))] ! 1853: "TARGET_FPA" ! 1854: "fpdtol %y1,%0") ! 1855: ! 1856: ;; add instructions ! 1857: ! 1858: ;; Note that the middle two alternatives are near-duplicates ! 1859: ;; in order to handle insns generated by reload. ! 1860: ;; This is needed since they are not themselves reloaded, ! 1861: ;; so commutativity won't apply to them. ! 1862: (define_insn "addsi3" ! 1863: [(set (match_operand:SI 0 "general_operand" "=m,?a,?a,r") ! 1864: (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0") ! 1865: (match_operand:SI 2 "general_operand" "dIKLs,rJK,a,mrIKLs")))] ! 1866: "" ! 1867: "* ! 1868: { ! 1869: if (! operands_match_p (operands[0], operands[1])) ! 1870: { ! 1871: if (!ADDRESS_REG_P (operands[1])) ! 1872: { ! 1873: rtx tmp = operands[1]; ! 1874: ! 1875: operands[1] = operands[2]; ! 1876: operands[2] = tmp; ! 1877: } ! 1878: ! 1879: /* These insns can result from reloads to access ! 1880: stack slots over 64k from the frame pointer. */ ! 1881: if (GET_CODE (operands[2]) == CONST_INT ! 1882: && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000) ! 1883: return \"move%.l %2,%0\;add%.l %1,%0\"; ! 1884: #ifdef SGS ! 1885: if (GET_CODE (operands[2]) == REG) ! 1886: return \"lea 0(%1,%2.l),%0\"; ! 1887: else ! 1888: return \"lea %c2(%1),%0\"; ! 1889: #else /* not SGS */ ! 1890: #ifdef MOTOROLA ! 1891: if (GET_CODE (operands[2]) == REG) ! 1892: return \"lea (%1,%2.l),%0\"; ! 1893: else ! 1894: return \"lea (%c2,%1),%0\"; ! 1895: #else /* not MOTOROLA (MIT syntax) */ ! 1896: if (GET_CODE (operands[2]) == REG) ! 1897: return \"lea %1@(0,%2:l),%0\"; ! 1898: else ! 1899: return \"lea %1@(%c2),%0\"; ! 1900: #endif /* not MOTOROLA */ ! 1901: #endif /* not SGS */ ! 1902: } ! 1903: if (GET_CODE (operands[2]) == CONST_INT) ! 1904: { ! 1905: #ifndef NO_ADDSUB_Q ! 1906: if (INTVAL (operands[2]) > 0 ! 1907: && INTVAL (operands[2]) <= 8) ! 1908: return (ADDRESS_REG_P (operands[0]) ! 1909: ? \"addq%.w %2,%0\" ! 1910: : \"addq%.l %2,%0\"); ! 1911: if (INTVAL (operands[2]) < 0 ! 1912: && INTVAL (operands[2]) >= -8) ! 1913: { ! 1914: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1915: - INTVAL (operands[2])); ! 1916: return (ADDRESS_REG_P (operands[0]) ! 1917: ? \"subq%.w %2,%0\" ! 1918: : \"subq%.l %2,%0\"); ! 1919: } ! 1920: /* On everything except the 68000 it is faster to use two ! 1921: addqw instructions to add a small integer (8 < N <= 16) ! 1922: to an address register. Likewise for subqw.*/ ! 1923: if (INTVAL (operands[2]) > 8 ! 1924: && INTVAL (operands[2]) <= 16 ! 1925: && ADDRESS_REG_P (operands[0]) ! 1926: && TARGET_68020) ! 1927: { ! 1928: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8); ! 1929: return \"addq%.w %#8,%0\;addq%.w %2,%0\"; ! 1930: } ! 1931: if (INTVAL (operands[2]) < -8 ! 1932: && INTVAL (operands[2]) >= -16 ! 1933: && ADDRESS_REG_P (operands[0]) ! 1934: && TARGET_68020) ! 1935: { ! 1936: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1937: - INTVAL (operands[2]) - 8); ! 1938: return \"subq%.w %#8,%0\;subq%.w %2,%0\"; ! 1939: } ! 1940: #endif ! 1941: if (ADDRESS_REG_P (operands[0]) ! 1942: && INTVAL (operands[2]) >= -0x8000 ! 1943: && INTVAL (operands[2]) < 0x8000) ! 1944: return \"add%.w %2,%0\"; ! 1945: } ! 1946: return \"add%.l %2,%0\"; ! 1947: }") ! 1948: ! 1949: (define_insn "" ! 1950: [(set (match_operand:SI 0 "general_operand" "=a") ! 1951: (plus:SI (match_operand:SI 1 "general_operand" "0") ! 1952: (sign_extend:SI ! 1953: (match_operand:HI 2 "nonimmediate_operand" "rm"))))] ! 1954: "" ! 1955: "add%.w %2,%0") ! 1956: ! 1957: (define_insn "addhi3" ! 1958: [(set (match_operand:HI 0 "general_operand" "=m,r") ! 1959: (plus:HI (match_operand:HI 1 "general_operand" "%0,0") ! 1960: (match_operand:HI 2 "general_operand" "dn,rmn")))] ! 1961: "" ! 1962: "* ! 1963: { ! 1964: #ifndef NO_ADDSUB_Q ! 1965: if (GET_CODE (operands[2]) == CONST_INT) ! 1966: { ! 1967: /* If the constant would be a negative number when interpreted as ! 1968: HImode, make it negative. This is usually, but not always, done ! 1969: elsewhere in the compiler. First check for constants out of range, ! 1970: which could confuse us. */ ! 1971: ! 1972: if (INTVAL (operands[2]) >= 32768) ! 1973: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1974: INTVAL (operands[2]) - 65536); ! 1975: ! 1976: if (INTVAL (operands[2]) > 0 ! 1977: && INTVAL (operands[2]) <= 8) ! 1978: return \"addq%.w %2,%0\"; ! 1979: if (INTVAL (operands[2]) < 0 ! 1980: && INTVAL (operands[2]) >= -8) ! 1981: { ! 1982: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 1983: - INTVAL (operands[2])); ! 1984: return \"subq%.w %2,%0\"; ! 1985: } ! 1986: /* On everything except the 68000 it is faster to use two ! 1987: addqw instructions to add a small integer (8 < N <= 16) ! 1988: to an address register. Likewise for subqw. */ ! 1989: if (INTVAL (operands[2]) > 8 ! 1990: && INTVAL (operands[2]) <= 16 ! 1991: && ADDRESS_REG_P (operands[0]) ! 1992: && TARGET_68020) ! 1993: { ! 1994: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8); ! 1995: return \"addq%.w %#8,%0\;addq%.w %2,%0\"; ! 1996: } ! 1997: if (INTVAL (operands[2]) < -8 ! 1998: && INTVAL (operands[2]) >= -16 ! 1999: && ADDRESS_REG_P (operands[0]) ! 2000: && TARGET_68020) ! 2001: { ! 2002: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 2003: - INTVAL (operands[2]) - 8); ! 2004: return \"subq%.w %#8,%0\;subq%.w %2,%0\"; ! 2005: } ! 2006: } ! 2007: #endif ! 2008: return \"add%.w %2,%0\"; ! 2009: }") ! 2010: ! 2011: ;; These insns must use MATCH_DUP instead of the more expected ! 2012: ;; use of a matching constraint because the "output" here is also ! 2013: ;; an input, so you can't use the matching constraint. That also means ! 2014: ;; that you can't use the "%", so you need patterns with the matched ! 2015: ;; operand in both positions. ! 2016: ! 2017: (define_insn "" ! 2018: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) ! 2019: (plus:HI (match_dup 0) ! 2020: (match_operand:HI 1 "general_operand" "dn,rmn")))] ! 2021: "" ! 2022: "* ! 2023: { ! 2024: #ifndef NO_ADDSUB_Q ! 2025: if (GET_CODE (operands[1]) == CONST_INT) ! 2026: { ! 2027: /* If the constant would be a negative number when interpreted as ! 2028: HImode, make it negative. This is usually, but not always, done ! 2029: elsewhere in the compiler. First check for constants out of range, ! 2030: which could confuse us. */ ! 2031: ! 2032: if (INTVAL (operands[1]) >= 32768) ! 2033: operands[1] = gen_rtx (CONST_INT, VOIDmode, ! 2034: INTVAL (operands[1]) - 65536); ! 2035: ! 2036: if (INTVAL (operands[1]) > 0 ! 2037: && INTVAL (operands[1]) <= 8) ! 2038: return \"addq%.w %1,%0\"; ! 2039: if (INTVAL (operands[1]) < 0 ! 2040: && INTVAL (operands[1]) >= -8) ! 2041: { ! 2042: operands[1] = gen_rtx (CONST_INT, VOIDmode, ! 2043: - INTVAL (operands[1])); ! 2044: return \"subq%.w %1,%0\"; ! 2045: } ! 2046: /* On everything except the 68000 it is faster to use two ! 2047: addqw instructions to add a small integer (8 < N <= 16) ! 2048: to an address register. Likewise for subqw. */ ! 2049: if (INTVAL (operands[1]) > 8 ! 2050: && INTVAL (operands[1]) <= 16 ! 2051: && ADDRESS_REG_P (operands[0]) ! 2052: && TARGET_68020) ! 2053: { ! 2054: operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8); ! 2055: return \"addq%.w %#8,%0\;addq%.w %1,%0\"; ! 2056: } ! 2057: if (INTVAL (operands[1]) < -8 ! 2058: && INTVAL (operands[1]) >= -16 ! 2059: && ADDRESS_REG_P (operands[0]) ! 2060: && TARGET_68020) ! 2061: { ! 2062: operands[1] = gen_rtx (CONST_INT, VOIDmode, ! 2063: - INTVAL (operands[1]) - 8); ! 2064: return \"subq%.w %#8,%0\;subq%.w %1,%0\"; ! 2065: } ! 2066: } ! 2067: #endif ! 2068: return \"add%.w %1,%0\"; ! 2069: }") ! 2070: ! 2071: (define_insn "" ! 2072: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) ! 2073: (plus:HI (match_operand:HI 1 "general_operand" "dn,rmn") ! 2074: (match_dup 0)))] ! 2075: "" ! 2076: "* ! 2077: { ! 2078: #ifndef NO_ADDSUB_Q ! 2079: if (GET_CODE (operands[1]) == CONST_INT) ! 2080: { ! 2081: /* If the constant would be a negative number when interpreted as ! 2082: HImode, make it negative. This is usually, but not always, done ! 2083: elsewhere in the compiler. First check for constants out of range, ! 2084: which could confuse us. */ ! 2085: ! 2086: if (INTVAL (operands[1]) >= 32768) ! 2087: operands[1] = gen_rtx (CONST_INT, VOIDmode, ! 2088: INTVAL (operands[1]) - 65536); ! 2089: ! 2090: if (INTVAL (operands[1]) > 0 ! 2091: && INTVAL (operands[1]) <= 8) ! 2092: return \"addq%.w %1,%0\"; ! 2093: if (INTVAL (operands[1]) < 0 ! 2094: && INTVAL (operands[1]) >= -8) ! 2095: { ! 2096: operands[1] = gen_rtx (CONST_INT, VOIDmode, ! 2097: - INTVAL (operands[1])); ! 2098: return \"subq%.w %1,%0\"; ! 2099: } ! 2100: /* On everything except the 68000 it is faster to use two ! 2101: addqw instructions to add a small integer (8 < N <= 16) ! 2102: to an address register. Likewise for subqw. */ ! 2103: if (INTVAL (operands[1]) > 8 ! 2104: && INTVAL (operands[1]) <= 16 ! 2105: && ADDRESS_REG_P (operands[0]) ! 2106: && TARGET_68020) ! 2107: { ! 2108: operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8); ! 2109: return \"addq%.w %#8,%0\;addq%.w %1,%0\"; ! 2110: } ! 2111: if (INTVAL (operands[1]) < -8 ! 2112: && INTVAL (operands[1]) >= -16 ! 2113: && ADDRESS_REG_P (operands[0]) ! 2114: && TARGET_68020) ! 2115: { ! 2116: operands[1] = gen_rtx (CONST_INT, VOIDmode, ! 2117: - INTVAL (operands[1]) - 8); ! 2118: return \"subq%.w %#8,%0\;subq%.w %1,%0\"; ! 2119: } ! 2120: } ! 2121: #endif ! 2122: return \"add%.w %1,%0\"; ! 2123: }") ! 2124: ! 2125: (define_insn "addqi3" ! 2126: [(set (match_operand:QI 0 "general_operand" "=m,d") ! 2127: (plus:QI (match_operand:QI 1 "general_operand" "%0,0") ! 2128: (match_operand:QI 2 "general_operand" "dn,dmn")))] ! 2129: "" ! 2130: "* ! 2131: { ! 2132: #ifndef NO_ADDSUB_Q ! 2133: if (GET_CODE (operands[2]) == CONST_INT) ! 2134: { ! 2135: if (INTVAL (operands[2]) >= 128) ! 2136: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 2137: INTVAL (operands[2]) - 256); ! 2138: ! 2139: if (INTVAL (operands[2]) > 0 ! 2140: && INTVAL (operands[2]) <= 8) ! 2141: return \"addq%.b %2,%0\"; ! 2142: if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) >= -8) ! 2143: { ! 2144: operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2])); ! 2145: return \"subq%.b %2,%0\"; ! 2146: } ! 2147: } ! 2148: #endif ! 2149: return \"add%.b %2,%0\"; ! 2150: }") ! 2151: ! 2152: (define_insn "" ! 2153: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) ! 2154: (plus:QI (match_dup 0) ! 2155: (match_operand:QI 1 "general_operand" "dn,dmn")))] ! 2156: "" ! 2157: "* ! 2158: { ! 2159: #ifndef NO_ADDSUB_Q ! 2160: if (GET_CODE (operands[1]) == CONST_INT) ! 2161: { ! 2162: if (INTVAL (operands[1]) >= 128) ! 2163: operands[1] = gen_rtx (CONST_INT, VOIDmode, ! 2164: INTVAL (operands[1]) - 256); ! 2165: ! 2166: if (INTVAL (operands[1]) > 0 ! 2167: && INTVAL (operands[1]) <= 8) ! 2168: return \"addq%.b %1,%0\"; ! 2169: if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8) ! 2170: { ! 2171: operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1])); ! 2172: return \"subq%.b %1,%0\"; ! 2173: } ! 2174: } ! 2175: #endif ! 2176: return \"add%.b %1,%0\"; ! 2177: }") ! 2178: ! 2179: (define_insn "" ! 2180: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) ! 2181: (plus:QI (match_operand:QI 1 "general_operand" "dn,dmn") ! 2182: (match_dup 0)))] ! 2183: "" ! 2184: "* ! 2185: { ! 2186: #ifndef NO_ADDSUB_Q ! 2187: if (GET_CODE (operands[1]) == CONST_INT) ! 2188: { ! 2189: if (INTVAL (operands[1]) >= 128) ! 2190: operands[1] = gen_rtx (CONST_INT, VOIDmode, ! 2191: INTVAL (operands[1]) - 256); ! 2192: ! 2193: if (INTVAL (operands[1]) > 0 ! 2194: && INTVAL (operands[1]) <= 8) ! 2195: return \"addq%.b %1,%0\"; ! 2196: if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8) ! 2197: { ! 2198: operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1])); ! 2199: return \"subq%.b %1,%0\"; ! 2200: } ! 2201: } ! 2202: #endif ! 2203: return \"add%.b %1,%0\"; ! 2204: }") ! 2205: ! 2206: (define_expand "adddf3" ! 2207: [(set (match_operand:DF 0 "general_operand" "") ! 2208: (plus:DF (match_operand:DF 1 "general_operand" "") ! 2209: (match_operand:DF 2 "general_operand" "")))] ! 2210: "TARGET_68881 || TARGET_FPA" ! 2211: "") ! 2212: ! 2213: (define_insn "" ! 2214: [(set (match_operand:DF 0 "general_operand" "=x,y") ! 2215: (plus:DF (match_operand:DF 1 "general_operand" "%xH,y") ! 2216: (match_operand:DF 2 "general_operand" "xH,dmF")))] ! 2217: "TARGET_FPA" ! 2218: "* ! 2219: { ! 2220: if (rtx_equal_p (operands[0], operands[1])) ! 2221: return \"fpadd%.d %y2,%0\"; ! 2222: if (rtx_equal_p (operands[0], operands[2])) ! 2223: return \"fpadd%.d %y1,%0\"; ! 2224: if (which_alternative == 0) ! 2225: return \"fpadd3%.d %w2,%w1,%0\"; ! 2226: return \"fpadd3%.d %x2,%x1,%0\"; ! 2227: }") ! 2228: ! 2229: (define_insn "" ! 2230: [(set (match_operand:DF 0 "general_operand" "=f") ! 2231: (plus:DF (match_operand:DF 1 "general_operand" "%0") ! 2232: (match_operand:DF 2 "general_operand" "fmG")))] ! 2233: "TARGET_68881" ! 2234: "* ! 2235: { ! 2236: if (REG_P (operands[2])) ! 2237: return \"f%&add%.x %2,%0\"; ! 2238: return \"f%&add%.d %f2,%0\"; ! 2239: }") ! 2240: ! 2241: (define_expand "addsf3" ! 2242: [(set (match_operand:SF 0 "general_operand" "") ! 2243: (plus:SF (match_operand:SF 1 "general_operand" "") ! 2244: (match_operand:SF 2 "general_operand" "")))] ! 2245: "TARGET_68881 || TARGET_FPA" ! 2246: "") ! 2247: ! 2248: (define_insn "" ! 2249: [(set (match_operand:SF 0 "general_operand" "=x,y") ! 2250: (plus:SF (match_operand:SF 1 "general_operand" "%xH,y") ! 2251: (match_operand:SF 2 "general_operand" "xH,rmF")))] ! 2252: "TARGET_FPA" ! 2253: "* ! 2254: { ! 2255: if (rtx_equal_p (operands[0], operands[1])) ! 2256: return \"fpadd%.s %w2,%0\"; ! 2257: if (rtx_equal_p (operands[0], operands[2])) ! 2258: return \"fpadd%.s %w1,%0\"; ! 2259: if (which_alternative == 0) ! 2260: return \"fpadd3%.s %w2,%w1,%0\"; ! 2261: return \"fpadd3%.s %2,%1,%0\"; ! 2262: }") ! 2263: ! 2264: (define_insn "" ! 2265: [(set (match_operand:SF 0 "general_operand" "=f") ! 2266: (plus:SF (match_operand:SF 1 "general_operand" "%0") ! 2267: (match_operand:SF 2 "general_operand" "fdmF")))] ! 2268: "TARGET_68881" ! 2269: "* ! 2270: { ! 2271: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) ! 2272: return \"f%$add%.x %2,%0\"; ! 2273: return \"f%$add%.s %f2,%0\"; ! 2274: }") ! 2275: ! 2276: ;; subtract instructions ! 2277: ! 2278: (define_insn "subsi3" ! 2279: [(set (match_operand:SI 0 "general_operand" "=m,r,!a,?d") ! 2280: (minus:SI (match_operand:SI 1 "general_operand" "0,0,a,mrIKs") ! 2281: (match_operand:SI 2 "general_operand" "dIKs,mrIKs,J,0")))] ! 2282: "" ! 2283: "* ! 2284: { ! 2285: if (! operands_match_p (operands[0], operands[1])) ! 2286: { ! 2287: if (operands_match_p (operands[0], operands[2])) ! 2288: { ! 2289: #ifndef NO_ADDSUB_Q ! 2290: if (GET_CODE (operands[1]) == CONST_INT) ! 2291: { ! 2292: if (INTVAL (operands[1]) > 0 ! 2293: && INTVAL (operands[1]) <= 8) ! 2294: return \"subq%.l %1,%0\;neg%.l %0\"; ! 2295: } ! 2296: #endif ! 2297: return \"sub%.l %1,%0\;neg%.l %0\"; ! 2298: } ! 2299: /* This case is matched by J, but negating -0x8000 ! 2300: in an lea would give an invalid displacement. ! 2301: So do this specially. */ ! 2302: if (INTVAL (operands[2]) == -0x8000) ! 2303: return \"move%.l %1,%0\;sub%.l %2,%0\"; ! 2304: #ifdef SGS ! 2305: return \"lea %n2(%1),%0\"; ! 2306: #else ! 2307: #ifdef MOTOROLA ! 2308: return \"lea (%n2,%1),%0\"; ! 2309: #else /* not MOTOROLA (MIT syntax) */ ! 2310: return \"lea %1@(%n2),%0\"; ! 2311: #endif /* not MOTOROLA */ ! 2312: #endif /* not SGS */ ! 2313: } ! 2314: if (GET_CODE (operands[2]) == CONST_INT) ! 2315: { ! 2316: #ifndef NO_ADDSUB_Q ! 2317: if (INTVAL (operands[2]) > 0 ! 2318: && INTVAL (operands[2]) <= 8) ! 2319: return \"subq%.l %2,%0\"; ! 2320: /* Using two subqw for 8 < N <= 16 being subtracted from an ! 2321: address register is faster on all but 68000 */ ! 2322: if (INTVAL (operands[2]) > 8 ! 2323: && INTVAL (operands[2]) <= 16 ! 2324: && ADDRESS_REG_P (operands[0]) ! 2325: && TARGET_68020) ! 2326: { ! 2327: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8); ! 2328: return \"subq%.w %#8,%0\;subq%.w %2,%0\"; ! 2329: } ! 2330: #endif ! 2331: if (ADDRESS_REG_P (operands[0]) ! 2332: && INTVAL (operands[2]) >= -0x8000 ! 2333: && INTVAL (operands[2]) < 0x8000) ! 2334: return \"sub%.w %2,%0\"; ! 2335: } ! 2336: return \"sub%.l %2,%0\"; ! 2337: }") ! 2338: ! 2339: (define_insn "" ! 2340: [(set (match_operand:SI 0 "general_operand" "=a") ! 2341: (minus:SI (match_operand:SI 1 "general_operand" "0") ! 2342: (sign_extend:SI ! 2343: (match_operand:HI 2 "nonimmediate_operand" "rm"))))] ! 2344: "" ! 2345: "sub%.w %2,%0") ! 2346: ! 2347: (define_insn "subhi3" ! 2348: [(set (match_operand:HI 0 "general_operand" "=m,r") ! 2349: (minus:HI (match_operand:HI 1 "general_operand" "0,0") ! 2350: (match_operand:HI 2 "general_operand" "dn,rmn")))] ! 2351: "" ! 2352: "sub%.w %2,%0") ! 2353: ! 2354: (define_insn "" ! 2355: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) ! 2356: (minus:HI (match_dup 0) ! 2357: (match_operand:HI 1 "general_operand" "dn,rmn")))] ! 2358: "" ! 2359: "sub%.w %1,%0") ! 2360: ! 2361: (define_insn "subqi3" ! 2362: [(set (match_operand:QI 0 "general_operand" "=m,d") ! 2363: (minus:QI (match_operand:QI 1 "general_operand" "0,0") ! 2364: (match_operand:QI 2 "general_operand" "dn,dmn")))] ! 2365: "" ! 2366: "sub%.b %2,%0") ! 2367: ! 2368: (define_insn "" ! 2369: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) ! 2370: (minus:QI (match_dup 0) ! 2371: (match_operand:QI 1 "general_operand" "dn,dmn")))] ! 2372: "" ! 2373: "sub%.b %1,%0") ! 2374: ! 2375: (define_expand "subdf3" ! 2376: [(set (match_operand:DF 0 "general_operand" "") ! 2377: (minus:DF (match_operand:DF 1 "general_operand" "") ! 2378: (match_operand:DF 2 "general_operand" "")))] ! 2379: "TARGET_68881 || TARGET_FPA" ! 2380: "") ! 2381: ! 2382: (define_insn "" ! 2383: [(set (match_operand:DF 0 "general_operand" "=x,y,y") ! 2384: (minus:DF (match_operand:DF 1 "general_operand" "xH,y,dmF") ! 2385: (match_operand:DF 2 "general_operand" "xH,dmF,0")))] ! 2386: "TARGET_FPA" ! 2387: "* ! 2388: { ! 2389: if (rtx_equal_p (operands[0], operands[2])) ! 2390: return \"fprsub%.d %y1,%0\"; ! 2391: if (rtx_equal_p (operands[0], operands[1])) ! 2392: return \"fpsub%.d %y2,%0\"; ! 2393: if (which_alternative == 0) ! 2394: return \"fpsub3%.d %w2,%w1,%0\"; ! 2395: return \"fpsub3%.d %x2,%x1,%0\"; ! 2396: }") ! 2397: ! 2398: (define_insn "" ! 2399: [(set (match_operand:DF 0 "general_operand" "=f") ! 2400: (minus:DF (match_operand:DF 1 "general_operand" "0") ! 2401: (match_operand:DF 2 "general_operand" "fmG")))] ! 2402: "TARGET_68881" ! 2403: "* ! 2404: { ! 2405: if (REG_P (operands[2])) ! 2406: return \"f%&sub%.x %2,%0\"; ! 2407: return \"f%&sub%.d %f2,%0\"; ! 2408: }") ! 2409: ! 2410: (define_expand "subsf3" ! 2411: [(set (match_operand:SF 0 "general_operand" "") ! 2412: (minus:SF (match_operand:SF 1 "general_operand" "") ! 2413: (match_operand:SF 2 "general_operand" "")))] ! 2414: "TARGET_68881 || TARGET_FPA" ! 2415: "") ! 2416: ! 2417: (define_insn "" ! 2418: [(set (match_operand:SF 0 "general_operand" "=x,y,y") ! 2419: (minus:SF (match_operand:SF 1 "general_operand" "xH,y,rmF") ! 2420: (match_operand:SF 2 "general_operand" "xH,rmF,0")))] ! 2421: "TARGET_FPA" ! 2422: "* ! 2423: { ! 2424: if (rtx_equal_p (operands[0], operands[2])) ! 2425: return \"fprsub%.s %w1,%0\"; ! 2426: if (rtx_equal_p (operands[0], operands[1])) ! 2427: return \"fpsub%.s %w2,%0\"; ! 2428: if (which_alternative == 0) ! 2429: return \"fpsub3%.s %w2,%w1,%0\"; ! 2430: return \"fpsub3%.s %2,%1,%0\"; ! 2431: }") ! 2432: ! 2433: (define_insn "" ! 2434: [(set (match_operand:SF 0 "general_operand" "=f") ! 2435: (minus:SF (match_operand:SF 1 "general_operand" "0") ! 2436: (match_operand:SF 2 "general_operand" "fdmF")))] ! 2437: "TARGET_68881" ! 2438: "* ! 2439: { ! 2440: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) ! 2441: return \"f%$sub%.x %2,%0\"; ! 2442: return \"f%$sub%.s %f2,%0\"; ! 2443: }") ! 2444: ! 2445: ;; multiply instructions ! 2446: ! 2447: (define_insn "mulhi3" ! 2448: [(set (match_operand:HI 0 "general_operand" "=d") ! 2449: (mult:HI (match_operand:HI 1 "general_operand" "%0") ! 2450: (match_operand:HI 2 "general_operand" "dmn")))] ! 2451: "" ! 2452: "* ! 2453: { ! 2454: #if defined(MOTOROLA) && !defined(CRDS) ! 2455: return \"muls%.w %2,%0\"; ! 2456: #else ! 2457: return \"muls %2,%0\"; ! 2458: #endif ! 2459: }") ! 2460: ! 2461: (define_insn "mulhisi3" ! 2462: [(set (match_operand:SI 0 "general_operand" "=d") ! 2463: (mult:SI (sign_extend:SI ! 2464: (match_operand:HI 1 "nonimmediate_operand" "%0")) ! 2465: (sign_extend:SI ! 2466: (match_operand:HI 2 "nonimmediate_operand" "dm"))))] ! 2467: "" ! 2468: "* ! 2469: { ! 2470: #if defined(MOTOROLA) && !defined(CRDS) ! 2471: return \"muls%.w %2,%0\"; ! 2472: #else ! 2473: return \"muls %2,%0\"; ! 2474: #endif ! 2475: }") ! 2476: ! 2477: (define_insn "" ! 2478: [(set (match_operand:SI 0 "general_operand" "=d") ! 2479: (mult:SI (sign_extend:SI ! 2480: (match_operand:HI 1 "nonimmediate_operand" "%0")) ! 2481: (match_operand:SI 2 "const_int_operand" "n")))] ! 2482: "INTVAL (operands[2]) >= -0x8000 && INTVAL (operands[2]) <= 0x7fff" ! 2483: "* ! 2484: { ! 2485: #if defined(MOTOROLA) && !defined(CRDS) ! 2486: return \"muls%.w %2,%0\"; ! 2487: #else ! 2488: return \"muls %2,%0\"; ! 2489: #endif ! 2490: }") ! 2491: ! 2492: (define_insn "mulsi3" ! 2493: [(set (match_operand:SI 0 "general_operand" "=d") ! 2494: (mult:SI (match_operand:SI 1 "general_operand" "%0") ! 2495: (match_operand:SI 2 "general_operand" "dmsK")))] ! 2496: "TARGET_68020" ! 2497: "muls%.l %2,%0") ! 2498: ! 2499: (define_insn "umulhisi3" ! 2500: [(set (match_operand:SI 0 "general_operand" "=d") ! 2501: (mult:SI (zero_extend:SI ! 2502: (match_operand:HI 1 "nonimmediate_operand" "%0")) ! 2503: (zero_extend:SI ! 2504: (match_operand:HI 2 "nonimmediate_operand" "dm"))))] ! 2505: "" ! 2506: "* ! 2507: { ! 2508: #if defined(MOTOROLA) && !defined(CRDS) ! 2509: return \"mulu%.w %2,%0\"; ! 2510: #else ! 2511: return \"mulu %2,%0\"; ! 2512: #endif ! 2513: }") ! 2514: ! 2515: (define_insn "" ! 2516: [(set (match_operand:SI 0 "general_operand" "=d") ! 2517: (mult:SI (zero_extend:SI ! 2518: (match_operand:HI 1 "nonimmediate_operand" "%0")) ! 2519: (match_operand:SI 2 "const_int_operand" "n")))] ! 2520: "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 0xffff" ! 2521: "* ! 2522: { ! 2523: #if defined(MOTOROLA) && !defined(CRDS) ! 2524: return \"mulu%.w %2,%0\"; ! 2525: #else ! 2526: return \"mulu %2,%0\"; ! 2527: #endif ! 2528: }") ! 2529: ! 2530: ;; We need a separate DEFINE_EXPAND for u?mulsidi3 to be able to use the ! 2531: ;; proper matching constraint. This is because the matching is between ! 2532: ;; the high-numbered word of the DImode operand[0] and operand[1]. ! 2533: (define_expand "umulsidi3" ! 2534: [(parallel ! 2535: [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 1) ! 2536: (mult:SI (match_operand:SI 1 "register_operand" "") ! 2537: (match_operand:SI 2 "nonimmediate_operand" ""))) ! 2538: (set (subreg:SI (match_dup 0) 0) ! 2539: (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1)) ! 2540: (zero_extend:DI (match_dup 2))) ! 2541: (const_int 32))))])] ! 2542: "TARGET_68020" ! 2543: "") ! 2544: ! 2545: (define_insn "" ! 2546: [(set (match_operand:SI 0 "register_operand" "=d") ! 2547: (mult:SI (match_operand:SI 1 "register_operand" "%0") ! 2548: (match_operand:SI 2 "nonimmediate_operand" "dm"))) ! 2549: (set (match_operand:SI 3 "register_operand" "=d") ! 2550: (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1)) ! 2551: (zero_extend:DI (match_dup 2))) ! 2552: (const_int 32))))] ! 2553: "TARGET_68020" ! 2554: "mulu%.l %2,%3:%0") ! 2555: ! 2556: ; Match immediate case. For 2.4 only match things < 2^31. ! 2557: ; It's tricky with larger values in these patterns since we need to match ! 2558: ; values between the two parallel multiplies, between a CONST_DOUBLE and ! 2559: ; a CONST_INT. ! 2560: (define_insn "" ! 2561: [(set (match_operand:SI 0 "register_operand" "=d") ! 2562: (mult:SI (match_operand:SI 1 "register_operand" "%0") ! 2563: (match_operand:SI 2 "const_int_operand" "n"))) ! 2564: (set (match_operand:SI 3 "register_operand" "=d") ! 2565: (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1)) ! 2566: (match_dup 2)) ! 2567: (const_int 32))))] ! 2568: "TARGET_68020 ! 2569: && (unsigned) INTVAL (operands[2]) <= 0x7fffffff" ! 2570: "mulu%.l %2,%3:%0") ! 2571: ! 2572: (define_expand "mulsidi3" ! 2573: [(parallel ! 2574: [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 1) ! 2575: (mult:SI (match_operand:SI 1 "register_operand" "") ! 2576: (match_operand:SI 2 "nonimmediate_operand" ""))) ! 2577: (set (subreg:SI (match_dup 0) 0) ! 2578: (truncate:SI (ashift:DI (mult:DI (sign_extend:DI (match_dup 1)) ! 2579: (sign_extend:DI (match_dup 2))) ! 2580: (const_int 32))))])] ! 2581: "TARGET_68020" ! 2582: "") ! 2583: ! 2584: (define_insn "" ! 2585: [(set (match_operand:SI 0 "register_operand" "=d") ! 2586: (mult:SI (match_operand:SI 1 "register_operand" "%0") ! 2587: (match_operand:SI 2 "nonimmediate_operand" "dm"))) ! 2588: (set (match_operand:SI 3 "register_operand" "=d") ! 2589: (truncate:SI (ashift:DI (mult:DI (sign_extend:DI (match_dup 1)) ! 2590: (sign_extend:DI (match_dup 2))) ! 2591: (const_int 32))))] ! 2592: "TARGET_68020" ! 2593: "muls%.l %2,%3:%0") ! 2594: ! 2595: (define_insn "" ! 2596: [(set (match_operand:SI 0 "register_operand" "=d") ! 2597: (mult:SI (match_operand:SI 1 "register_operand" "%0") ! 2598: (match_operand:SI 2 "const_int_operand" "n"))) ! 2599: (set (match_operand:SI 3 "register_operand" "=d") ! 2600: (truncate:SI (ashift:DI (mult:DI (sign_extend:DI (match_dup 1)) ! 2601: (match_dup 2)) ! 2602: (const_int 32))))] ! 2603: "TARGET_68020 ! 2604: /* This test is a noop on 32 bit machines, ! 2605: but important for a cross-compiler hosted on 64-bit machines. */ ! 2606: && INTVAL (operands[2]) <= 0x7fffffff ! 2607: && INTVAL (operands[2]) >= -0x80000000" ! 2608: "muls%.l %2,%3:%0") ! 2609: ! 2610: (define_expand "muldf3" ! 2611: [(set (match_operand:DF 0 "general_operand" "") ! 2612: (mult:DF (match_operand:DF 1 "general_operand" "") ! 2613: (match_operand:DF 2 "general_operand" "")))] ! 2614: "TARGET_68881 || TARGET_FPA" ! 2615: "") ! 2616: ! 2617: (define_insn "" ! 2618: [(set (match_operand:DF 0 "general_operand" "=x,y") ! 2619: (mult:DF (match_operand:DF 1 "general_operand" "%xH,y") ! 2620: (match_operand:DF 2 "general_operand" "xH,rmF")))] ! 2621: "TARGET_FPA" ! 2622: "* ! 2623: { ! 2624: if (rtx_equal_p (operands[1], operands[2])) ! 2625: return \"fpsqr%.d %y1,%0\"; ! 2626: if (rtx_equal_p (operands[0], operands[1])) ! 2627: return \"fpmul%.d %y2,%0\"; ! 2628: if (rtx_equal_p (operands[0], operands[2])) ! 2629: return \"fpmul%.d %y1,%0\"; ! 2630: if (which_alternative == 0) ! 2631: return \"fpmul3%.d %w2,%w1,%0\"; ! 2632: return \"fpmul3%.d %x2,%x1,%0\"; ! 2633: }") ! 2634: ! 2635: (define_insn "" ! 2636: [(set (match_operand:DF 0 "general_operand" "=f") ! 2637: (mult:DF (match_operand:DF 1 "general_operand" "%0") ! 2638: (match_operand:DF 2 "general_operand" "fmG")))] ! 2639: "TARGET_68881" ! 2640: "* ! 2641: { ! 2642: if (GET_CODE (operands[2]) == CONST_DOUBLE ! 2643: && floating_exact_log2 (operands[2]) && !TARGET_68040) ! 2644: { ! 2645: int i = floating_exact_log2 (operands[2]); ! 2646: operands[2] = gen_rtx (CONST_INT, VOIDmode, i); ! 2647: return \"fscale%.l %2,%0\"; ! 2648: } ! 2649: if (REG_P (operands[2])) ! 2650: return \"f%&mul%.x %2,%0\"; ! 2651: return \"f%&mul%.d %f2,%0\"; ! 2652: }") ! 2653: ! 2654: (define_expand "mulsf3" ! 2655: [(set (match_operand:SF 0 "general_operand" "") ! 2656: (mult:SF (match_operand:SF 1 "general_operand" "") ! 2657: (match_operand:SF 2 "general_operand" "")))] ! 2658: "TARGET_68881 || TARGET_FPA" ! 2659: "") ! 2660: ! 2661: (define_insn "" ! 2662: [(set (match_operand:SF 0 "general_operand" "=x,y") ! 2663: (mult:SF (match_operand:SF 1 "general_operand" "%xH,y") ! 2664: (match_operand:SF 2 "general_operand" "xH,rmF")))] ! 2665: "TARGET_FPA" ! 2666: "* ! 2667: { ! 2668: if (rtx_equal_p (operands[1], operands[2])) ! 2669: return \"fpsqr%.s %w1,%0\"; ! 2670: if (rtx_equal_p (operands[0], operands[1])) ! 2671: return \"fpmul%.s %w2,%0\"; ! 2672: if (rtx_equal_p (operands[0], operands[2])) ! 2673: return \"fpmul%.s %w1,%0\"; ! 2674: if (which_alternative == 0) ! 2675: return \"fpmul3%.s %w2,%w1,%0\"; ! 2676: return \"fpmul3%.s %2,%1,%0\"; ! 2677: }") ! 2678: ! 2679: (define_insn "" ! 2680: [(set (match_operand:SF 0 "general_operand" "=f") ! 2681: (mult:SF (match_operand:SF 1 "general_operand" "%0") ! 2682: (match_operand:SF 2 "general_operand" "fdmF")))] ! 2683: "TARGET_68881" ! 2684: "* ! 2685: { ! 2686: #ifdef FSGLMUL_USE_S ! 2687: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) ! 2688: return (TARGET_68040_ONLY ! 2689: ? \"fsmul%.s %2,%0\" ! 2690: : \"fsglmul%.s %2,%0\"); ! 2691: #else ! 2692: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) ! 2693: return (TARGET_68040_ONLY ! 2694: ? \"fsmul%.x %2,%0\" ! 2695: : \"fsglmul%.x %2,%0\"); ! 2696: #endif ! 2697: return (TARGET_68040_ONLY ! 2698: ? \"fsmul%.s %f2,%0\" ! 2699: : \"fsglmul%.s %f2,%0\"); ! 2700: }") ! 2701: ! 2702: ;; divide instructions ! 2703: ! 2704: (define_insn "divhi3" ! 2705: [(set (match_operand:HI 0 "general_operand" "=d") ! 2706: (div:HI (match_operand:HI 1 "general_operand" "0") ! 2707: (match_operand:HI 2 "general_operand" "dmn")))] ! 2708: "" ! 2709: "* ! 2710: { ! 2711: #ifdef MOTOROLA ! 2712: return \"ext%.l %0\;divs%.w %2,%0\"; ! 2713: #else ! 2714: return \"extl %0\;divs %2,%0\"; ! 2715: #endif ! 2716: }") ! 2717: ! 2718: (define_insn "divhisi3" ! 2719: [(set (match_operand:HI 0 "general_operand" "=d") ! 2720: (truncate:HI ! 2721: (div:SI ! 2722: (match_operand:SI 1 "general_operand" "0") ! 2723: (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))] ! 2724: "" ! 2725: "* ! 2726: { ! 2727: #ifdef MOTOROLA ! 2728: return \"divs%.w %2,%0\"; ! 2729: #else ! 2730: return \"divs %2,%0\"; ! 2731: #endif ! 2732: }") ! 2733: ! 2734: (define_insn "" ! 2735: [(set (match_operand:HI 0 "general_operand" "=d") ! 2736: (truncate:HI (div:SI (match_operand:SI 1 "general_operand" "0") ! 2737: (match_operand:SI 2 "const_int_operand" "n"))))] ! 2738: "" ! 2739: "* ! 2740: { ! 2741: #ifdef MOTOROLA ! 2742: return \"divs%.w %2,%0\"; ! 2743: #else ! 2744: return \"divs %2,%0\"; ! 2745: #endif ! 2746: }") ! 2747: ! 2748: (define_insn "udivhi3" ! 2749: [(set (match_operand:HI 0 "general_operand" "=d") ! 2750: (udiv:HI (match_operand:HI 1 "general_operand" "0") ! 2751: (match_operand:HI 2 "general_operand" "dmn")))] ! 2752: "" ! 2753: "* ! 2754: { ! 2755: #ifdef MOTOROLA ! 2756: return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\"; ! 2757: #else ! 2758: return \"andl %#0xFFFF,%0\;divu %2,%0\"; ! 2759: #endif ! 2760: }") ! 2761: ! 2762: (define_insn "udivhisi3" ! 2763: [(set (match_operand:HI 0 "general_operand" "=d") ! 2764: (truncate:HI ! 2765: (udiv:SI ! 2766: (match_operand:SI 1 "general_operand" "0") ! 2767: (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))] ! 2768: "" ! 2769: "* ! 2770: { ! 2771: #ifdef MOTOROLA ! 2772: return \"divu%.w %2,%0\"; ! 2773: #else ! 2774: return \"divu %2,%0\"; ! 2775: #endif ! 2776: }") ! 2777: ! 2778: (define_insn "" ! 2779: [(set (match_operand:HI 0 "general_operand" "=d") ! 2780: (truncate:HI (udiv:SI (match_operand:SI 1 "general_operand" "0") ! 2781: (match_operand:SI 2 "const_int_operand" "n"))))] ! 2782: "" ! 2783: "* ! 2784: { ! 2785: #ifdef MOTOROLA ! 2786: return \"divu%.w %2,%0\"; ! 2787: #else ! 2788: return \"divu %2,%0\"; ! 2789: #endif ! 2790: }") ! 2791: ! 2792: (define_expand "divdf3" ! 2793: [(set (match_operand:DF 0 "general_operand" "") ! 2794: (div:DF (match_operand:DF 1 "general_operand" "") ! 2795: (match_operand:DF 2 "general_operand" "")))] ! 2796: "TARGET_68881 || TARGET_FPA" ! 2797: "") ! 2798: ! 2799: (define_insn "" ! 2800: [(set (match_operand:DF 0 "general_operand" "=x,y,y") ! 2801: (div:DF (match_operand:DF 1 "general_operand" "xH,y,rmF") ! 2802: (match_operand:DF 2 "general_operand" "xH,rmF,0")))] ! 2803: "TARGET_FPA" ! 2804: "* ! 2805: { ! 2806: if (rtx_equal_p (operands[0], operands[2])) ! 2807: return \"fprdiv%.d %y1,%0\"; ! 2808: if (rtx_equal_p (operands[0], operands[1])) ! 2809: return \"fpdiv%.d %y2,%0\"; ! 2810: if (which_alternative == 0) ! 2811: return \"fpdiv3%.d %w2,%w1,%0\"; ! 2812: return \"fpdiv3%.d %x2,%x1,%x0\"; ! 2813: }") ! 2814: ! 2815: (define_insn "" ! 2816: [(set (match_operand:DF 0 "general_operand" "=f") ! 2817: (div:DF (match_operand:DF 1 "general_operand" "0") ! 2818: (match_operand:DF 2 "general_operand" "fmG")))] ! 2819: "TARGET_68881" ! 2820: "* ! 2821: { ! 2822: if (REG_P (operands[2])) ! 2823: return \"f%&div%.x %2,%0\"; ! 2824: return \"f%&div%.d %f2,%0\"; ! 2825: }") ! 2826: ! 2827: (define_expand "divsf3" ! 2828: [(set (match_operand:SF 0 "general_operand" "") ! 2829: (div:SF (match_operand:SF 1 "general_operand" "") ! 2830: (match_operand:SF 2 "general_operand" "")))] ! 2831: "TARGET_68881 || TARGET_FPA" ! 2832: "") ! 2833: ! 2834: (define_insn "" ! 2835: [(set (match_operand:SF 0 "general_operand" "=x,y,y") ! 2836: (div:SF (match_operand:SF 1 "general_operand" "xH,y,rmF") ! 2837: (match_operand:SF 2 "general_operand" "xH,rmF,0")))] ! 2838: "TARGET_FPA" ! 2839: "* ! 2840: { ! 2841: if (rtx_equal_p (operands[0], operands[1])) ! 2842: return \"fpdiv%.s %w2,%0\"; ! 2843: if (rtx_equal_p (operands[0], operands[2])) ! 2844: return \"fprdiv%.s %w1,%0\"; ! 2845: if (which_alternative == 0) ! 2846: return \"fpdiv3%.s %w2,%w1,%0\"; ! 2847: return \"fpdiv3%.s %2,%1,%0\"; ! 2848: }") ! 2849: ! 2850: (define_insn "" ! 2851: [(set (match_operand:SF 0 "general_operand" "=f") ! 2852: (div:SF (match_operand:SF 1 "general_operand" "0") ! 2853: (match_operand:SF 2 "general_operand" "fdmF")))] ! 2854: "TARGET_68881" ! 2855: "* ! 2856: { ! 2857: #ifdef FSGLDIV_USE_S ! 2858: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) ! 2859: return (TARGET_68040_ONLY ! 2860: ? \"fsdiv%.s %2,%0\" ! 2861: : \"fsgldiv%.s %2,%0\"); ! 2862: #else ! 2863: if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) ! 2864: return (TARGET_68040_ONLY ! 2865: ? \"fsdiv%.x %2,%0\" ! 2866: : \"fsgldiv%.x %2,%0\"); ! 2867: #endif ! 2868: return (TARGET_68040_ONLY ! 2869: ? \"fsdiv%.s %f2,%0\" ! 2870: : \"fsgldiv%.s %f2,%0\"); ! 2871: }") ! 2872: ! 2873: ;; Remainder instructions. ! 2874: ! 2875: (define_insn "modhi3" ! 2876: [(set (match_operand:HI 0 "general_operand" "=d") ! 2877: (mod:HI (match_operand:HI 1 "general_operand" "0") ! 2878: (match_operand:HI 2 "general_operand" "dmn")))] ! 2879: "" ! 2880: "* ! 2881: { ! 2882: /* The swap insn produces cc's that don't correspond to the result. */ ! 2883: CC_STATUS_INIT; ! 2884: #ifdef MOTOROLA ! 2885: return \"ext%.l %0\;divs%.w %2,%0\;swap %0\"; ! 2886: #else ! 2887: return \"extl %0\;divs %2,%0\;swap %0\"; ! 2888: #endif ! 2889: }") ! 2890: ! 2891: (define_insn "modhisi3" ! 2892: [(set (match_operand:HI 0 "general_operand" "=d") ! 2893: (truncate:HI ! 2894: (mod:SI ! 2895: (match_operand:SI 1 "general_operand" "0") ! 2896: (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))] ! 2897: "" ! 2898: "* ! 2899: { ! 2900: /* The swap insn produces cc's that don't correspond to the result. */ ! 2901: CC_STATUS_INIT; ! 2902: #ifdef MOTOROLA ! 2903: return \"divs%.w %2,%0\;swap %0\"; ! 2904: #else ! 2905: return \"divs %2,%0\;swap %0\"; ! 2906: #endif ! 2907: }") ! 2908: ! 2909: (define_insn "" ! 2910: [(set (match_operand:HI 0 "general_operand" "=d") ! 2911: (truncate:HI (mod:SI (match_operand:SI 1 "general_operand" "0") ! 2912: (match_operand:SI 2 "const_int_operand" "n"))))] ! 2913: "" ! 2914: "* ! 2915: { ! 2916: /* The swap insn produces cc's that don't correspond to the result. */ ! 2917: CC_STATUS_INIT; ! 2918: #ifdef MOTOROLA ! 2919: return \"divs%.w %2,%0\;swap %0\"; ! 2920: #else ! 2921: return \"divs %2,%0\;swap %0\"; ! 2922: #endif ! 2923: }") ! 2924: ! 2925: (define_insn "umodhi3" ! 2926: [(set (match_operand:HI 0 "general_operand" "=d") ! 2927: (umod:HI (match_operand:HI 1 "general_operand" "0") ! 2928: (match_operand:HI 2 "general_operand" "dmn")))] ! 2929: "" ! 2930: "* ! 2931: { ! 2932: /* The swap insn produces cc's that don't correspond to the result. */ ! 2933: CC_STATUS_INIT; ! 2934: #ifdef MOTOROLA ! 2935: return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\;swap %0\"; ! 2936: #else ! 2937: return \"andl %#0xFFFF,%0\;divu %2,%0\;swap %0\"; ! 2938: #endif ! 2939: }") ! 2940: ! 2941: (define_insn "umodhisi3" ! 2942: [(set (match_operand:HI 0 "general_operand" "=d") ! 2943: (truncate:HI ! 2944: (umod:SI ! 2945: (match_operand:SI 1 "general_operand" "0") ! 2946: (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))] ! 2947: "" ! 2948: "* ! 2949: { ! 2950: /* The swap insn produces cc's that don't correspond to the result. */ ! 2951: CC_STATUS_INIT; ! 2952: #ifdef MOTOROLA ! 2953: return \"divu%.w %2,%0\;swap %0\"; ! 2954: #else ! 2955: return \"divu %2,%0\;swap %0\"; ! 2956: #endif ! 2957: }") ! 2958: ! 2959: (define_insn "" ! 2960: [(set (match_operand:HI 0 "general_operand" "=d") ! 2961: (truncate:HI (umod:SI (match_operand:SI 1 "general_operand" "0") ! 2962: (match_operand:SI 2 "const_int_operand" "n"))))] ! 2963: "" ! 2964: "* ! 2965: { ! 2966: /* The swap insn produces cc's that don't correspond to the result. */ ! 2967: CC_STATUS_INIT; ! 2968: #ifdef MOTOROLA ! 2969: return \"divu%.w %2,%0\;swap %0\"; ! 2970: #else ! 2971: return \"divu %2,%0\;swap %0\"; ! 2972: #endif ! 2973: }") ! 2974: ! 2975: (define_insn "divmodsi4" ! 2976: [(set (match_operand:SI 0 "general_operand" "=d") ! 2977: (div:SI (match_operand:SI 1 "general_operand" "0") ! 2978: (match_operand:SI 2 "general_operand" "dmsK"))) ! 2979: (set (match_operand:SI 3 "general_operand" "=d") ! 2980: (mod:SI (match_dup 1) (match_dup 2)))] ! 2981: "TARGET_68020" ! 2982: "* ! 2983: { ! 2984: if (find_reg_note (insn, REG_UNUSED, operands[3])) ! 2985: return \"divs%.l %2,%0\"; ! 2986: else ! 2987: return \"divsl%.l %2,%3:%0\"; ! 2988: }") ! 2989: ! 2990: (define_insn "udivmodsi4" ! 2991: [(set (match_operand:SI 0 "general_operand" "=d") ! 2992: (udiv:SI (match_operand:SI 1 "general_operand" "0") ! 2993: (match_operand:SI 2 "general_operand" "dmsK"))) ! 2994: (set (match_operand:SI 3 "general_operand" "=d") ! 2995: (umod:SI (match_dup 1) (match_dup 2)))] ! 2996: "TARGET_68020" ! 2997: "* ! 2998: { ! 2999: if (find_reg_note (insn, REG_UNUSED, operands[3])) ! 3000: return \"divu%.l %2,%0\"; ! 3001: else ! 3002: return \"divul%.l %2,%3:%0\"; ! 3003: }") ! 3004: ! 3005: ;; logical-and instructions ! 3006: ! 3007: ;; Prevent AND from being made with sp. This doesn't exist in the machine ! 3008: ;; and reload will cause inefficient code. Since sp is a FIXED_REG, we ! 3009: ;; can't allocate pseudos into it. ! 3010: (define_insn "andsi3" ! 3011: [(set (match_operand:SI 0 "not_sp_operand" "=m,d") ! 3012: (and:SI (match_operand:SI 1 "general_operand" "%0,0") ! 3013: (match_operand:SI 2 "general_operand" "dKs,dmKs")))] ! 3014: "" ! 3015: "* ! 3016: { ! 3017: int logval; ! 3018: if (GET_CODE (operands[2]) == CONST_INT ! 3019: && (INTVAL (operands[2]) | 0xffff) == 0xffffffff ! 3020: && (DATA_REG_P (operands[0]) ! 3021: || offsettable_memref_p (operands[0]))) ! 3022: { ! 3023: if (GET_CODE (operands[0]) != REG) ! 3024: operands[0] = adj_offsettable_operand (operands[0], 2); ! 3025: operands[2] = gen_rtx (CONST_INT, VOIDmode, ! 3026: INTVAL (operands[2]) & 0xffff); ! 3027: /* Do not delete a following tstl %0 insn; that would be incorrect. */ ! 3028: CC_STATUS_INIT; ! 3029: if (operands[2] == const0_rtx) ! 3030: return \"clr%.w %0\"; ! 3031: return \"and%.w %2,%0\"; ! 3032: } ! 3033: if (GET_CODE (operands[2]) == CONST_INT ! 3034: && (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0 ! 3035: && (DATA_REG_P (operands[0]) ! 3036: || offsettable_memref_p (operands[0]))) ! 3037: { ! 3038: if (DATA_REG_P (operands[0])) ! 3039: { ! 3040: operands[1] = gen_rtx (CONST_INT, VOIDmode, logval); ! 3041: } ! 3042: else ! 3043: { ! 3044: operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8)); operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8); ! 3045: } ! 3046: /* This does not set condition codes in a standard way. */ ! 3047: CC_STATUS_INIT; ! 3048: return \"bclr %1,%0\"; ! 3049: } ! 3050: return \"and%.l %2,%0\"; ! 3051: }") ! 3052: ! 3053: (define_insn "andhi3" ! 3054: [(set (match_operand:HI 0 "general_operand" "=m,d") ! 3055: (and:HI (match_operand:HI 1 "general_operand" "%0,0") ! 3056: (match_operand:HI 2 "general_operand" "dn,dmn")))] ! 3057: "" ! 3058: "and%.w %2,%0") ! 3059: ! 3060: (define_insn "" ! 3061: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) ! 3062: (and:HI (match_dup 0) ! 3063: (match_operand:HI 1 "general_operand" "dn,dmn")))] ! 3064: "" ! 3065: "and%.w %1,%0") ! 3066: ! 3067: (define_insn "" ! 3068: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) ! 3069: (and:HI (match_operand:HI 1 "general_operand" "dn,dmn") ! 3070: (match_dup 0)))] ! 3071: "" ! 3072: "and%.w %1,%0") ! 3073: ! 3074: (define_insn "andqi3" ! 3075: [(set (match_operand:QI 0 "general_operand" "=m,d") ! 3076: (and:QI (match_operand:QI 1 "general_operand" "%0,0") ! 3077: (match_operand:QI 2 "general_operand" "dn,dmn")))] ! 3078: "" ! 3079: "and%.b %2,%0") ! 3080: ! 3081: (define_insn "" ! 3082: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) ! 3083: (and:QI (match_dup 0) ! 3084: (match_operand:QI 1 "general_operand" "dn,dmn")))] ! 3085: "" ! 3086: "and%.b %1,%0") ! 3087: ! 3088: (define_insn "" ! 3089: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) ! 3090: (and:QI (match_operand:QI 1 "general_operand" "dn,dmn") ! 3091: (match_dup 0)))] ! 3092: "" ! 3093: "and%.b %1,%0") ! 3094: ! 3095: ;; inclusive-or instructions ! 3096: ! 3097: (define_insn "iorsi3" ! 3098: [(set (match_operand:SI 0 "general_operand" "=m,d") ! 3099: (ior:SI (match_operand:SI 1 "general_operand" "%0,0") ! 3100: (match_operand:SI 2 "general_operand" "dKs,dmKs")))] ! 3101: "" ! 3102: "* ! 3103: { ! 3104: register int logval; ! 3105: if (GET_CODE (operands[2]) == CONST_INT ! 3106: && INTVAL (operands[2]) >> 16 == 0 ! 3107: && (DATA_REG_P (operands[0]) ! 3108: || offsettable_memref_p (operands[0]))) ! 3109: { ! 3110: if (GET_CODE (operands[0]) != REG) ! 3111: operands[0] = adj_offsettable_operand (operands[0], 2); ! 3112: /* Do not delete a following tstl %0 insn; that would be incorrect. */ ! 3113: CC_STATUS_INIT; ! 3114: return \"or%.w %2,%0\"; ! 3115: } ! 3116: if (GET_CODE (operands[2]) == CONST_INT ! 3117: && (logval = exact_log2 (INTVAL (operands[2]))) >= 0 ! 3118: && (DATA_REG_P (operands[0]) ! 3119: || offsettable_memref_p (operands[0]))) ! 3120: { ! 3121: if (DATA_REG_P (operands[0])) ! 3122: { ! 3123: operands[1] = gen_rtx (CONST_INT, VOIDmode, logval); ! 3124: } ! 3125: else ! 3126: { ! 3127: operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8)); ! 3128: operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8); ! 3129: } ! 3130: CC_STATUS_INIT; ! 3131: return \"bset %1,%0\"; ! 3132: } ! 3133: return \"or%.l %2,%0\"; ! 3134: }") ! 3135: ! 3136: (define_insn "iorhi3" ! 3137: [(set (match_operand:HI 0 "general_operand" "=m,d") ! 3138: (ior:HI (match_operand:HI 1 "general_operand" "%0,0") ! 3139: (match_operand:HI 2 "general_operand" "dn,dmn")))] ! 3140: "" ! 3141: "or%.w %2,%0") ! 3142: ! 3143: (define_insn "" ! 3144: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) ! 3145: (ior:HI (match_dup 0) ! 3146: (match_operand:HI 1 "general_operand" "dn,dmn")))] ! 3147: "" ! 3148: "or%.w %1,%0") ! 3149: ! 3150: (define_insn "" ! 3151: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) ! 3152: (ior:HI (match_operand:HI 1 "general_operand" "dn,dmn") ! 3153: (match_dup 0)))] ! 3154: "" ! 3155: "or%.w %1,%0") ! 3156: ! 3157: (define_insn "iorqi3" ! 3158: [(set (match_operand:QI 0 "general_operand" "=m,d") ! 3159: (ior:QI (match_operand:QI 1 "general_operand" "%0,0") ! 3160: (match_operand:QI 2 "general_operand" "dn,dmn")))] ! 3161: "" ! 3162: "or%.b %2,%0") ! 3163: ! 3164: (define_insn "" ! 3165: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) ! 3166: (ior:QI (match_dup 0) ! 3167: (match_operand:QI 1 "general_operand" "dn,dmn")))] ! 3168: "" ! 3169: "or%.b %1,%0") ! 3170: ! 3171: (define_insn "" ! 3172: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) ! 3173: (ior:QI (match_operand:QI 1 "general_operand" "dn,dmn") ! 3174: (match_dup 0)))] ! 3175: "" ! 3176: "or%.b %1,%0") ! 3177: ! 3178: ;; xor instructions ! 3179: ! 3180: (define_insn "xorsi3" ! 3181: [(set (match_operand:SI 0 "general_operand" "=do,m") ! 3182: (xor:SI (match_operand:SI 1 "general_operand" "%0,0") ! 3183: (match_operand:SI 2 "general_operand" "di,dKs")))] ! 3184: "" ! 3185: "* ! 3186: { ! 3187: if (GET_CODE (operands[2]) == CONST_INT ! 3188: && INTVAL (operands[2]) >> 16 == 0 ! 3189: && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0]))) ! 3190: { ! 3191: if (! DATA_REG_P (operands[0])) ! 3192: operands[0] = adj_offsettable_operand (operands[0], 2); ! 3193: /* Do not delete a following tstl %0 insn; that would be incorrect. */ ! 3194: CC_STATUS_INIT; ! 3195: return \"eor%.w %2,%0\"; ! 3196: } ! 3197: return \"eor%.l %2,%0\"; ! 3198: }") ! 3199: ! 3200: (define_insn "xorhi3" ! 3201: [(set (match_operand:HI 0 "general_operand" "=dm") ! 3202: (xor:HI (match_operand:HI 1 "general_operand" "%0") ! 3203: (match_operand:HI 2 "general_operand" "dn")))] ! 3204: "" ! 3205: "eor%.w %2,%0") ! 3206: ! 3207: (define_insn "" ! 3208: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm")) ! 3209: (xor:HI (match_dup 0) ! 3210: (match_operand:HI 1 "general_operand" "dn")))] ! 3211: "" ! 3212: "eor%.w %1,%0") ! 3213: ! 3214: ! 3215: (define_insn "" ! 3216: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm")) ! 3217: (xor:HI (match_operand:HI 1 "general_operand" "dn") ! 3218: (match_dup 0)))] ! 3219: "" ! 3220: "eor%.w %1,%0") ! 3221: ! 3222: (define_insn "xorqi3" ! 3223: [(set (match_operand:QI 0 "general_operand" "=dm") ! 3224: (xor:QI (match_operand:QI 1 "general_operand" "%0") ! 3225: (match_operand:QI 2 "general_operand" "dn")))] ! 3226: "" ! 3227: "eor%.b %2,%0") ! 3228: ! 3229: (define_insn "" ! 3230: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm")) ! 3231: (xor:QI (match_dup 0) ! 3232: (match_operand:QI 1 "general_operand" "dn")))] ! 3233: "" ! 3234: "eor%.b %1,%0") ! 3235: ! 3236: (define_insn "" ! 3237: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm")) ! 3238: (xor:QI (match_operand:QI 1 "general_operand" "dn") ! 3239: (match_dup 0)))] ! 3240: "" ! 3241: "eor%.b %1,%0") ! 3242: ! 3243: ;; negation instructions ! 3244: ! 3245: (define_insn "negsi2" ! 3246: [(set (match_operand:SI 0 "general_operand" "=dm") ! 3247: (neg:SI (match_operand:SI 1 "general_operand" "0")))] ! 3248: "" ! 3249: "neg%.l %0") ! 3250: ! 3251: (define_insn "neghi2" ! 3252: [(set (match_operand:HI 0 "general_operand" "=dm") ! 3253: (neg:HI (match_operand:HI 1 "general_operand" "0")))] ! 3254: "" ! 3255: "neg%.w %0") ! 3256: ! 3257: (define_insn "" ! 3258: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm")) ! 3259: (neg:HI (match_dup 0)))] ! 3260: "" ! 3261: "neg%.w %0") ! 3262: ! 3263: (define_insn "negqi2" ! 3264: [(set (match_operand:QI 0 "general_operand" "=dm") ! 3265: (neg:QI (match_operand:QI 1 "general_operand" "0")))] ! 3266: "" ! 3267: "neg%.b %0") ! 3268: ! 3269: (define_insn "" ! 3270: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm")) ! 3271: (neg:QI (match_dup 0)))] ! 3272: "" ! 3273: "neg%.b %0") ! 3274: ! 3275: (define_expand "negsf2" ! 3276: [(set (match_operand:SF 0 "general_operand" "") ! 3277: (neg:SF (match_operand:SF 1 "general_operand" "")))] ! 3278: "TARGET_68881 || TARGET_FPA" ! 3279: "") ! 3280: ! 3281: (define_insn "" ! 3282: [(set (match_operand:SF 0 "general_operand" "=x,y") ! 3283: (neg:SF (match_operand:SF 1 "general_operand" "xH,rmF")))] ! 3284: "TARGET_FPA" ! 3285: "fpneg%.s %w1,%0") ! 3286: ! 3287: (define_insn "" ! 3288: [(set (match_operand:SF 0 "general_operand" "=f,d") ! 3289: (neg:SF (match_operand:SF 1 "general_operand" "fdmF,0")))] ! 3290: "TARGET_68881" ! 3291: "* ! 3292: { ! 3293: if (DATA_REG_P (operands[0])) ! 3294: { ! 3295: operands[1] = gen_rtx (CONST_INT, VOIDmode, 31); ! 3296: return \"bchg %1,%0\"; ! 3297: } ! 3298: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) ! 3299: return \"f%$neg%.x %1,%0\"; ! 3300: return \"f%$neg%.s %f1,%0\"; ! 3301: }") ! 3302: ! 3303: (define_expand "negdf2" ! 3304: [(set (match_operand:DF 0 "general_operand" "") ! 3305: (neg:DF (match_operand:DF 1 "general_operand" "")))] ! 3306: "TARGET_68881 || TARGET_FPA" ! 3307: "") ! 3308: ! 3309: (define_insn "" ! 3310: [(set (match_operand:DF 0 "general_operand" "=x,y") ! 3311: (neg:DF (match_operand:DF 1 "general_operand" "xH,rmF")))] ! 3312: "TARGET_FPA" ! 3313: "fpneg%.d %y1, %0") ! 3314: ! 3315: (define_insn "" ! 3316: [(set (match_operand:DF 0 "general_operand" "=f,d") ! 3317: (neg:DF (match_operand:DF 1 "general_operand" "fmF,0")))] ! 3318: "TARGET_68881" ! 3319: "* ! 3320: { ! 3321: if (DATA_REG_P (operands[0])) ! 3322: { ! 3323: operands[1] = gen_rtx (CONST_INT, VOIDmode, 31); ! 3324: return \"bchg %1,%0\"; ! 3325: } ! 3326: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) ! 3327: return \"f%&neg%.x %1,%0\"; ! 3328: return \"f%&neg%.d %f1,%0\"; ! 3329: }") ! 3330: ! 3331: ;; Sqrt instruction for the 68881 ! 3332: ! 3333: (define_insn "sqrtdf2" ! 3334: [(set (match_operand:DF 0 "general_operand" "=f") ! 3335: (sqrt:DF (match_operand:DF 1 "general_operand" "fm")))] ! 3336: "TARGET_68881" ! 3337: "* ! 3338: { ! 3339: if (FP_REG_P (operands[1])) ! 3340: return \"fsqrt%.x %1,%0\"; ! 3341: else ! 3342: return \"fsqrt%.d %1,%0\"; ! 3343: }") ! 3344: ! 3345: ;; Absolute value instructions ! 3346: ! 3347: (define_expand "abssf2" ! 3348: [(set (match_operand:SF 0 "general_operand" "") ! 3349: (abs:SF (match_operand:SF 1 "general_operand" "")))] ! 3350: "TARGET_68881 || TARGET_FPA" ! 3351: "") ! 3352: ! 3353: (define_insn "" ! 3354: [(set (match_operand:SF 0 "general_operand" "=x,y") ! 3355: (abs:SF (match_operand:SF 1 "general_operand" "xH,rmF")))] ! 3356: "TARGET_FPA" ! 3357: "fpabs%.s %y1,%0") ! 3358: ! 3359: (define_insn "" ! 3360: [(set (match_operand:SF 0 "general_operand" "=f") ! 3361: (abs:SF (match_operand:SF 1 "general_operand" "fdmF")))] ! 3362: "TARGET_68881" ! 3363: "* ! 3364: { ! 3365: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) ! 3366: return \"f%$abs%.x %1,%0\"; ! 3367: return \"f%$abs%.s %f1,%0\"; ! 3368: }") ! 3369: ! 3370: (define_expand "absdf2" ! 3371: [(set (match_operand:DF 0 "general_operand" "") ! 3372: (abs:DF (match_operand:DF 1 "general_operand" "")))] ! 3373: "TARGET_68881 || TARGET_FPA" ! 3374: "") ! 3375: ! 3376: (define_insn "" ! 3377: [(set (match_operand:DF 0 "general_operand" "=x,y") ! 3378: (abs:DF (match_operand:DF 1 "general_operand" "xH,rmF")))] ! 3379: "TARGET_FPA" ! 3380: "fpabs%.d %y1,%0") ! 3381: ! 3382: (define_insn "" ! 3383: [(set (match_operand:DF 0 "general_operand" "=f") ! 3384: (abs:DF (match_operand:DF 1 "general_operand" "fmF")))] ! 3385: "TARGET_68881" ! 3386: "* ! 3387: { ! 3388: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) ! 3389: return \"f%&abs%.x %1,%0\"; ! 3390: return \"f%&abs%.d %f1,%0\"; ! 3391: }") ! 3392: ! 3393: ;; one complement instructions ! 3394: ! 3395: (define_insn "one_cmplsi2" ! 3396: [(set (match_operand:SI 0 "general_operand" "=dm") ! 3397: (not:SI (match_operand:SI 1 "general_operand" "0")))] ! 3398: "" ! 3399: "not%.l %0") ! 3400: ! 3401: (define_insn "one_cmplhi2" ! 3402: [(set (match_operand:HI 0 "general_operand" "=dm") ! 3403: (not:HI (match_operand:HI 1 "general_operand" "0")))] ! 3404: "" ! 3405: "not%.w %0") ! 3406: ! 3407: (define_insn "" ! 3408: [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm")) ! 3409: (not:HI (match_dup 0)))] ! 3410: "" ! 3411: "not%.w %0") ! 3412: ! 3413: (define_insn "one_cmplqi2" ! 3414: [(set (match_operand:QI 0 "general_operand" "=dm") ! 3415: (not:QI (match_operand:QI 1 "general_operand" "0")))] ! 3416: "" ! 3417: "not%.b %0") ! 3418: ! 3419: (define_insn "" ! 3420: [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm")) ! 3421: (not:QI (match_dup 0)))] ! 3422: "" ! 3423: "not%.b %0") ! 3424: ! 3425: ;; arithmetic shift instructions ! 3426: ;; We don't need the shift memory by 1 bit instruction ! 3427: ! 3428: ;; On all 68k models, this makes faster code in a special case. ! 3429: ! 3430: (define_insn "" ! 3431: [(set (match_operand:SI 0 "register_operand" "=d") ! 3432: (ashift:SI (match_operand:SI 1 "register_operand" "0") ! 3433: (match_operand:SI 2 "immediate_operand" "i")))] ! 3434: "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)" ! 3435: "* ! 3436: { ! 3437: CC_STATUS_INIT; ! 3438: return \"swap %0\;clr%.w %0\"; ! 3439: }") ! 3440: ! 3441: ;; On the 68000, this makes faster code in a special case. ! 3442: ! 3443: (define_insn "" ! 3444: [(set (match_operand:SI 0 "register_operand" "=d") ! 3445: (ashift:SI (match_operand:SI 1 "register_operand" "0") ! 3446: (match_operand:SI 2 "immediate_operand" "i")))] ! 3447: "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT ! 3448: && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)" ! 3449: "* ! 3450: { ! 3451: CC_STATUS_INIT; ! 3452: ! 3453: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); ! 3454: return \"asl%.w %2,%0\;swap %0\;clr%.w %0\"; ! 3455: }") ! 3456: ! 3457: (define_insn "ashlsi3" ! 3458: [(set (match_operand:SI 0 "register_operand" "=d") ! 3459: (ashift:SI (match_operand:SI 1 "register_operand" "0") ! 3460: (match_operand:SI 2 "general_operand" "dI")))] ! 3461: "" ! 3462: "* ! 3463: { ! 3464: if (operands[2] == const1_rtx) ! 3465: return \"add%.l %0,%0\"; ! 3466: return \"asl%.l %2,%0\"; ! 3467: }") ! 3468: ! 3469: (define_insn "ashlhi3" ! 3470: [(set (match_operand:HI 0 "register_operand" "=d") ! 3471: (ashift:HI (match_operand:HI 1 "register_operand" "0") ! 3472: (match_operand:HI 2 "general_operand" "dI")))] ! 3473: "" ! 3474: "asl%.w %2,%0") ! 3475: ! 3476: (define_insn "" ! 3477: [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) ! 3478: (ashift:HI (match_dup 0) ! 3479: (match_operand:HI 1 "general_operand" "dI")))] ! 3480: "" ! 3481: "asl%.w %1,%0") ! 3482: ! 3483: (define_insn "ashlqi3" ! 3484: [(set (match_operand:QI 0 "register_operand" "=d") ! 3485: (ashift:QI (match_operand:QI 1 "register_operand" "0") ! 3486: (match_operand:QI 2 "general_operand" "dI")))] ! 3487: "" ! 3488: "asl%.b %2,%0") ! 3489: ! 3490: (define_insn "" ! 3491: [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) ! 3492: (ashift:QI (match_dup 0) ! 3493: (match_operand:QI 1 "general_operand" "dI")))] ! 3494: "" ! 3495: "asl%.b %1,%0") ! 3496: ! 3497: ;; On all 68k models, this makes faster code in a special case. ! 3498: ! 3499: (define_insn "" ! 3500: [(set (match_operand:SI 0 "register_operand" "=d") ! 3501: (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") ! 3502: (match_operand:SI 2 "immediate_operand" "i")))] ! 3503: "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)" ! 3504: "swap %0\;ext%.l %0") ! 3505: ! 3506: ;; On the 68000, this makes faster code in a special case. ! 3507: ! 3508: (define_insn "" ! 3509: [(set (match_operand:SI 0 "register_operand" "=d") ! 3510: (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") ! 3511: (match_operand:SI 2 "immediate_operand" "i")))] ! 3512: "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT ! 3513: && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)" ! 3514: "* ! 3515: { ! 3516: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); ! 3517: return \"swap %0\;asr%.w %2,%0\;ext%.l %0\"; ! 3518: }") ! 3519: ! 3520: (define_insn "ashrsi3" ! 3521: [(set (match_operand:SI 0 "register_operand" "=d") ! 3522: (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") ! 3523: (match_operand:SI 2 "general_operand" "dI")))] ! 3524: "" ! 3525: "* ! 3526: { ! 3527: return \"asr%.l %2,%0\"; ! 3528: }") ! 3529: ! 3530: (define_insn "ashrhi3" ! 3531: [(set (match_operand:HI 0 "register_operand" "=d") ! 3532: (ashiftrt:HI (match_operand:HI 1 "register_operand" "0") ! 3533: (match_operand:HI 2 "general_operand" "dI")))] ! 3534: "" ! 3535: "asr%.w %2,%0") ! 3536: ! 3537: (define_insn "" ! 3538: [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) ! 3539: (ashiftrt:HI (match_dup 0) ! 3540: (match_operand:HI 1 "general_operand" "dI")))] ! 3541: "" ! 3542: "asr%.w %1,%0") ! 3543: ! 3544: (define_insn "ashrqi3" ! 3545: [(set (match_operand:QI 0 "register_operand" "=d") ! 3546: (ashiftrt:QI (match_operand:QI 1 "register_operand" "0") ! 3547: (match_operand:QI 2 "general_operand" "dI")))] ! 3548: "" ! 3549: "asr%.b %2,%0") ! 3550: ! 3551: (define_insn "" ! 3552: [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) ! 3553: (ashiftrt:QI (match_dup 0) ! 3554: (match_operand:QI 1 "general_operand" "dI")))] ! 3555: "" ! 3556: "asr%.b %1,%0") ! 3557: ! 3558: ;; logical shift instructions ! 3559: ! 3560: ;; On all 68k models, this makes faster code in a special case. ! 3561: ! 3562: (define_insn "" ! 3563: [(set (match_operand:SI 0 "register_operand" "=d") ! 3564: (lshift:SI (match_operand:SI 1 "register_operand" "0") ! 3565: (match_operand:SI 2 "immediate_operand" "i")))] ! 3566: "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)" ! 3567: "* ! 3568: { ! 3569: CC_STATUS_INIT; ! 3570: return \"swap %0\;clr%.w %0\"; ! 3571: }") ! 3572: ! 3573: ;; On the 68000, this makes faster code in a special case. ! 3574: ! 3575: (define_insn "" ! 3576: [(set (match_operand:SI 0 "register_operand" "=d") ! 3577: (lshift:SI (match_operand:SI 1 "register_operand" "0") ! 3578: (match_operand:SI 2 "immediate_operand" "i")))] ! 3579: "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT ! 3580: && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)" ! 3581: "* ! 3582: { ! 3583: CC_STATUS_INIT; ! 3584: ! 3585: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); ! 3586: return \"lsl%.w %2,%0\;swap %0\;clr%.w %0\"; ! 3587: }") ! 3588: ! 3589: (define_insn "lshlsi3" ! 3590: [(set (match_operand:SI 0 "register_operand" "=d") ! 3591: (lshift:SI (match_operand:SI 1 "register_operand" "0") ! 3592: (match_operand:SI 2 "general_operand" "dI")))] ! 3593: "" ! 3594: "* ! 3595: { ! 3596: if (operands[2] == const1_rtx) ! 3597: return \"add%.l %0,%0\"; ! 3598: return \"lsl%.l %2,%0\"; ! 3599: }") ! 3600: ! 3601: (define_insn "lshlhi3" ! 3602: [(set (match_operand:HI 0 "register_operand" "=d") ! 3603: (lshift:HI (match_operand:HI 1 "register_operand" "0") ! 3604: (match_operand:HI 2 "general_operand" "dI")))] ! 3605: "" ! 3606: "lsl%.w %2,%0") ! 3607: ! 3608: (define_insn "" ! 3609: [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) ! 3610: (lshift:HI (match_dup 0) ! 3611: (match_operand:HI 1 "general_operand" "dI")))] ! 3612: "" ! 3613: "lsl%.w %1,%0") ! 3614: ! 3615: (define_insn "lshlqi3" ! 3616: [(set (match_operand:QI 0 "register_operand" "=d") ! 3617: (lshift:QI (match_operand:QI 1 "register_operand" "0") ! 3618: (match_operand:QI 2 "general_operand" "dI")))] ! 3619: "" ! 3620: "lsl%.b %2,%0") ! 3621: ! 3622: (define_insn "" ! 3623: [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) ! 3624: (lshift:QI (match_dup 0) ! 3625: (match_operand:QI 1 "general_operand" "dI")))] ! 3626: "" ! 3627: "lsl%.b %1,%0") ! 3628: ! 3629: ;; On all 68k models, this makes faster code in a special case. ! 3630: ! 3631: (define_insn "" ! 3632: [(set (match_operand:SI 0 "register_operand" "=d") ! 3633: (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") ! 3634: (match_operand:SI 2 "immediate_operand" "i")))] ! 3635: "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)" ! 3636: "* ! 3637: { ! 3638: CC_STATUS_INIT; ! 3639: return \"clr%.w %0\;swap %0\"; ! 3640: }") ! 3641: ! 3642: ;; On the 68000, this makes faster code in a special case. ! 3643: ! 3644: (define_insn "" ! 3645: [(set (match_operand:SI 0 "register_operand" "=d") ! 3646: (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") ! 3647: (match_operand:SI 2 "immediate_operand" "i")))] ! 3648: "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT ! 3649: && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)" ! 3650: "* ! 3651: { ! 3652: /* I think lsr%.w sets the CC properly. */ ! 3653: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); ! 3654: return \"clr%.w %0\;swap %0\;lsr%.w %2,%0\"; ! 3655: }") ! 3656: ! 3657: (define_insn "lshrsi3" ! 3658: [(set (match_operand:SI 0 "register_operand" "=d") ! 3659: (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") ! 3660: (match_operand:SI 2 "general_operand" "dI")))] ! 3661: "" ! 3662: "* ! 3663: { ! 3664: return \"lsr%.l %2,%0\"; ! 3665: }") ! 3666: ! 3667: (define_insn "lshrhi3" ! 3668: [(set (match_operand:HI 0 "register_operand" "=d") ! 3669: (lshiftrt:HI (match_operand:HI 1 "register_operand" "0") ! 3670: (match_operand:HI 2 "general_operand" "dI")))] ! 3671: "" ! 3672: "lsr%.w %2,%0") ! 3673: ! 3674: (define_insn "" ! 3675: [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) ! 3676: (lshiftrt:HI (match_dup 0) ! 3677: (match_operand:HI 1 "general_operand" "dI")))] ! 3678: "" ! 3679: "lsr%.w %1,%0") ! 3680: ! 3681: (define_insn "lshrqi3" ! 3682: [(set (match_operand:QI 0 "register_operand" "=d") ! 3683: (lshiftrt:QI (match_operand:QI 1 "register_operand" "0") ! 3684: (match_operand:QI 2 "general_operand" "dI")))] ! 3685: "" ! 3686: "lsr%.b %2,%0") ! 3687: ! 3688: (define_insn "" ! 3689: [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) ! 3690: (lshiftrt:QI (match_dup 0) ! 3691: (match_operand:QI 1 "general_operand" "dI")))] ! 3692: "" ! 3693: "lsr%.b %1,%0") ! 3694: ! 3695: ;; rotate instructions ! 3696: ! 3697: (define_insn "rotlsi3" ! 3698: [(set (match_operand:SI 0 "register_operand" "=d") ! 3699: (rotate:SI (match_operand:SI 1 "register_operand" "0") ! 3700: (match_operand:SI 2 "general_operand" "dI")))] ! 3701: "" ! 3702: "rol%.l %2,%0") ! 3703: ! 3704: (define_insn "rotlhi3" ! 3705: [(set (match_operand:HI 0 "register_operand" "=d") ! 3706: (rotate:HI (match_operand:HI 1 "register_operand" "0") ! 3707: (match_operand:HI 2 "general_operand" "dI")))] ! 3708: "" ! 3709: "rol%.w %2,%0") ! 3710: ! 3711: ! 3712: (define_insn "" ! 3713: [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) ! 3714: (rotate:HI (match_dup 0) ! 3715: (match_operand:HI 1 "general_operand" "dI")))] ! 3716: "" ! 3717: "rol%.w %1,%0") ! 3718: ! 3719: (define_insn "rotlqi3" ! 3720: [(set (match_operand:QI 0 "register_operand" "=d") ! 3721: (rotate:QI (match_operand:QI 1 "register_operand" "0") ! 3722: (match_operand:QI 2 "general_operand" "dI")))] ! 3723: "" ! 3724: "rol%.b %2,%0") ! 3725: ! 3726: (define_insn "" ! 3727: [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) ! 3728: (rotate:QI (match_dup 0) ! 3729: (match_operand:QI 1 "general_operand" "dI")))] ! 3730: "" ! 3731: "rol%.b %1,%0") ! 3732: ! 3733: (define_insn "rotrsi3" ! 3734: [(set (match_operand:SI 0 "register_operand" "=d") ! 3735: (rotatert:SI (match_operand:SI 1 "register_operand" "0") ! 3736: (match_operand:SI 2 "general_operand" "dI")))] ! 3737: "" ! 3738: "ror%.l %2,%0") ! 3739: ! 3740: (define_insn "rotrhi3" ! 3741: [(set (match_operand:HI 0 "register_operand" "=d") ! 3742: (rotatert:HI (match_operand:HI 1 "register_operand" "0") ! 3743: (match_operand:HI 2 "general_operand" "dI")))] ! 3744: "" ! 3745: "ror%.w %2,%0") ! 3746: ! 3747: (define_insn "" ! 3748: [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) ! 3749: (rotatert:HI (match_dup 0) ! 3750: (match_operand:HI 1 "general_operand" "dI")))] ! 3751: "" ! 3752: "ror%.w %1,%0") ! 3753: ! 3754: (define_insn "rotrqi3" ! 3755: [(set (match_operand:QI 0 "register_operand" "=d") ! 3756: (rotatert:QI (match_operand:QI 1 "register_operand" "0") ! 3757: (match_operand:QI 2 "general_operand" "dI")))] ! 3758: "" ! 3759: "ror%.b %2,%0") ! 3760: ! 3761: (define_insn "" ! 3762: [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) ! 3763: (rotatert:QI (match_dup 0) ! 3764: (match_operand:QI 1 "general_operand" "dI")))] ! 3765: "" ! 3766: "ror%.b %1,%0") ! 3767: ! 3768: ;; Special cases of bit-field insns which we should ! 3769: ;; recognize in preference to the general case. ! 3770: ;; These handle aligned 8-bit and 16-bit fields, ! 3771: ;; which can usually be done with move instructions. ! 3772: ! 3773: ; ! 3774: ; Special case for 32-bit field in memory. This only occurs when 32-bit ! 3775: ; alignment of structure members is specified. ! 3776: ; ! 3777: ; The move is allowed to be odd byte aligned, because that's still faster ! 3778: ; than an odd byte aligned bit field instruction. ! 3779: ; ! 3780: (define_insn "" ! 3781: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o") ! 3782: (match_operand:SI 1 "immediate_operand" "i") ! 3783: (match_operand:SI 2 "immediate_operand" "i")) ! 3784: (match_operand:SI 3 "general_operand" "rmi"))] ! 3785: "TARGET_68020 && TARGET_BITFIELD ! 3786: && GET_CODE (operands[1]) == CONST_INT ! 3787: && (INTVAL (operands[1]) == 32) ! 3788: && GET_CODE (operands[2]) == CONST_INT ! 3789: && (INTVAL (operands[2]) % 8) == 0 ! 3790: && ! mode_dependent_address_p (XEXP (operands[0], 0))" ! 3791: "* ! 3792: { ! 3793: operands[0] ! 3794: = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8); ! 3795: ! 3796: return \"move%.l %3,%0\"; ! 3797: }") ! 3798: ! 3799: (define_insn "" ! 3800: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+do") ! 3801: (match_operand:SI 1 "immediate_operand" "i") ! 3802: (match_operand:SI 2 "immediate_operand" "i")) ! 3803: (match_operand:SI 3 "general_operand" "d"))] ! 3804: "TARGET_68020 && TARGET_BITFIELD ! 3805: && GET_CODE (operands[1]) == CONST_INT ! 3806: && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) ! 3807: && GET_CODE (operands[2]) == CONST_INT ! 3808: && INTVAL (operands[2]) % INTVAL (operands[1]) == 0 ! 3809: && (GET_CODE (operands[0]) == REG ! 3810: || ! mode_dependent_address_p (XEXP (operands[0], 0)))" ! 3811: "* ! 3812: { ! 3813: if (REG_P (operands[0])) ! 3814: { ! 3815: if (INTVAL (operands[1]) + INTVAL (operands[2]) != 32) ! 3816: return \"bfins %3,%0{%b2:%b1}\"; ! 3817: } ! 3818: else ! 3819: operands[0] ! 3820: = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8); ! 3821: ! 3822: if (GET_CODE (operands[3]) == MEM) ! 3823: operands[3] = adj_offsettable_operand (operands[3], ! 3824: (32 - INTVAL (operands[1])) / 8); ! 3825: if (INTVAL (operands[1]) == 8) ! 3826: return \"move%.b %3,%0\"; ! 3827: return \"move%.w %3,%0\"; ! 3828: }") ! 3829: ! 3830: ! 3831: ; ! 3832: ; Special case for 32-bit field in memory. This only occurs when 32-bit ! 3833: ; alignment of structure members is specified. ! 3834: ; ! 3835: ; The move is allowed to be odd byte aligned, because that's still faster ! 3836: ; than an odd byte aligned bit field instruction. ! 3837: ; ! 3838: (define_insn "" ! 3839: [(set (match_operand:SI 0 "general_operand" "=rm") ! 3840: (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o") ! 3841: (match_operand:SI 2 "immediate_operand" "i") ! 3842: (match_operand:SI 3 "immediate_operand" "i")))] ! 3843: "TARGET_68020 && TARGET_BITFIELD ! 3844: && GET_CODE (operands[2]) == CONST_INT ! 3845: && (INTVAL (operands[2]) == 32) ! 3846: && GET_CODE (operands[3]) == CONST_INT ! 3847: && (INTVAL (operands[3]) % 8) == 0 ! 3848: && ! mode_dependent_address_p (XEXP (operands[1], 0))" ! 3849: "* ! 3850: { ! 3851: operands[1] ! 3852: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); ! 3853: ! 3854: return \"move%.l %1,%0\"; ! 3855: }") ! 3856: ! 3857: (define_insn "" ! 3858: [(set (match_operand:SI 0 "general_operand" "=&d") ! 3859: (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do") ! 3860: (match_operand:SI 2 "immediate_operand" "i") ! 3861: (match_operand:SI 3 "immediate_operand" "i")))] ! 3862: "TARGET_68020 && TARGET_BITFIELD ! 3863: && GET_CODE (operands[2]) == CONST_INT ! 3864: && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) ! 3865: && GET_CODE (operands[3]) == CONST_INT ! 3866: && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 ! 3867: && (GET_CODE (operands[1]) == REG ! 3868: || ! mode_dependent_address_p (XEXP (operands[1], 0)))" ! 3869: "* ! 3870: { ! 3871: cc_status.flags |= CC_NOT_NEGATIVE; ! 3872: if (REG_P (operands[1])) ! 3873: { ! 3874: if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32) ! 3875: return \"bfextu %1{%b3:%b2},%0\"; ! 3876: } ! 3877: else ! 3878: operands[1] ! 3879: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); ! 3880: ! 3881: output_asm_insn (\"clr%.l %0\", operands); ! 3882: if (GET_CODE (operands[0]) == MEM) ! 3883: operands[0] = adj_offsettable_operand (operands[0], ! 3884: (32 - INTVAL (operands[1])) / 8); ! 3885: if (INTVAL (operands[2]) == 8) ! 3886: return \"move%.b %1,%0\"; ! 3887: return \"move%.w %1,%0\"; ! 3888: }") ! 3889: ! 3890: ; ! 3891: ; Special case for 32-bit field in memory. This only occurs when 32-bit ! 3892: ; alignment of structure members is specified. ! 3893: ; ! 3894: ; The move is allowed to be odd byte aligned, because that's still faster ! 3895: ; than an odd byte aligned bit field instruction. ! 3896: ; ! 3897: (define_insn "" ! 3898: [(set (match_operand:SI 0 "general_operand" "=rm") ! 3899: (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o") ! 3900: (match_operand:SI 2 "immediate_operand" "i") ! 3901: (match_operand:SI 3 "immediate_operand" "i")))] ! 3902: "TARGET_68020 && TARGET_BITFIELD ! 3903: && GET_CODE (operands[2]) == CONST_INT ! 3904: && (INTVAL (operands[2]) == 32) ! 3905: && GET_CODE (operands[3]) == CONST_INT ! 3906: && (INTVAL (operands[3]) % 8) == 0 ! 3907: && ! mode_dependent_address_p (XEXP (operands[1], 0))" ! 3908: "* ! 3909: { ! 3910: operands[1] ! 3911: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); ! 3912: ! 3913: return \"move%.l %1,%0\"; ! 3914: }") ! 3915: ! 3916: (define_insn "" ! 3917: [(set (match_operand:SI 0 "general_operand" "=d") ! 3918: (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do") ! 3919: (match_operand:SI 2 "immediate_operand" "i") ! 3920: (match_operand:SI 3 "immediate_operand" "i")))] ! 3921: "TARGET_68020 && TARGET_BITFIELD ! 3922: && GET_CODE (operands[2]) == CONST_INT ! 3923: && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) ! 3924: && GET_CODE (operands[3]) == CONST_INT ! 3925: && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 ! 3926: && (GET_CODE (operands[1]) == REG ! 3927: || ! mode_dependent_address_p (XEXP (operands[1], 0)))" ! 3928: "* ! 3929: { ! 3930: if (REG_P (operands[1])) ! 3931: { ! 3932: if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32) ! 3933: return \"bfexts %1{%b3:%b2},%0\"; ! 3934: } ! 3935: else ! 3936: operands[1] ! 3937: = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); ! 3938: ! 3939: if (INTVAL (operands[2]) == 8) ! 3940: return \"move%.b %1,%0\;extb%.l %0\"; ! 3941: return \"move%.w %1,%0\;ext%.l %0\"; ! 3942: }") ! 3943: ! 3944: ;; Bit field instructions, general cases. ! 3945: ;; "o,d" constraint causes a nonoffsettable memref to match the "o" ! 3946: ;; so that its address is reloaded. ! 3947: ! 3948: (define_insn "extv" ! 3949: [(set (match_operand:SI 0 "general_operand" "=d,d") ! 3950: (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d") ! 3951: (match_operand:SI 2 "general_operand" "di,di") ! 3952: (match_operand:SI 3 "general_operand" "di,di")))] ! 3953: "TARGET_68020 && TARGET_BITFIELD" ! 3954: "bfexts %1{%b3:%b2},%0") ! 3955: ! 3956: (define_insn "extzv" ! 3957: [(set (match_operand:SI 0 "general_operand" "=d,d") ! 3958: (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d") ! 3959: (match_operand:SI 2 "general_operand" "di,di") ! 3960: (match_operand:SI 3 "general_operand" "di,di")))] ! 3961: "TARGET_68020 && TARGET_BITFIELD" ! 3962: "* ! 3963: { ! 3964: cc_status.flags |= CC_NOT_NEGATIVE; ! 3965: return \"bfextu %1{%b3:%b2},%0\"; ! 3966: }") ! 3967: ! 3968: (define_insn "" ! 3969: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d") ! 3970: (match_operand:SI 1 "general_operand" "di,di") ! 3971: (match_operand:SI 2 "general_operand" "di,di")) ! 3972: (xor:SI (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)) ! 3973: (match_operand 3 "immediate_operand" "i,i")))] ! 3974: "TARGET_68020 && TARGET_BITFIELD ! 3975: && GET_CODE (operands[3]) == CONST_INT ! 3976: && (INTVAL (operands[3]) == -1 ! 3977: || (GET_CODE (operands[1]) == CONST_INT ! 3978: && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))" ! 3979: "* ! 3980: { ! 3981: CC_STATUS_INIT; ! 3982: return \"bfchg %0{%b2:%b1}\"; ! 3983: }") ! 3984: ! 3985: (define_insn "" ! 3986: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d") ! 3987: (match_operand:SI 1 "general_operand" "di,di") ! 3988: (match_operand:SI 2 "general_operand" "di,di")) ! 3989: (const_int 0))] ! 3990: "TARGET_68020 && TARGET_BITFIELD" ! 3991: "* ! 3992: { ! 3993: CC_STATUS_INIT; ! 3994: return \"bfclr %0{%b2:%b1}\"; ! 3995: }") ! 3996: ! 3997: (define_insn "" ! 3998: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d") ! 3999: (match_operand:SI 1 "general_operand" "di,di") ! 4000: (match_operand:SI 2 "general_operand" "di,di")) ! 4001: (const_int -1))] ! 4002: "TARGET_68020 && TARGET_BITFIELD" ! 4003: "* ! 4004: { ! 4005: CC_STATUS_INIT; ! 4006: return \"bfset %0{%b2:%b1}\"; ! 4007: }") ! 4008: ! 4009: (define_insn "insv" ! 4010: [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d") ! 4011: (match_operand:SI 1 "general_operand" "di,di") ! 4012: (match_operand:SI 2 "general_operand" "di,di")) ! 4013: (match_operand:SI 3 "general_operand" "d,d"))] ! 4014: "TARGET_68020 && TARGET_BITFIELD" ! 4015: "bfins %3,%0{%b2:%b1}") ! 4016: ! 4017: ;; Now recognize bit field insns that operate on registers ! 4018: ;; (or at least were intended to do so). ! 4019: ! 4020: (define_insn "" ! 4021: [(set (match_operand:SI 0 "general_operand" "=d") ! 4022: (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d") ! 4023: (match_operand:SI 2 "general_operand" "di") ! 4024: (match_operand:SI 3 "general_operand" "di")))] ! 4025: "TARGET_68020 && TARGET_BITFIELD" ! 4026: "bfexts %1{%b3:%b2},%0") ! 4027: ! 4028: (define_insn "" ! 4029: [(set (match_operand:SI 0 "general_operand" "=d") ! 4030: (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d") ! 4031: (match_operand:SI 2 "general_operand" "di") ! 4032: (match_operand:SI 3 "general_operand" "di")))] ! 4033: "TARGET_68020 && TARGET_BITFIELD" ! 4034: "* ! 4035: { ! 4036: cc_status.flags |= CC_NOT_NEGATIVE; ! 4037: return \"bfextu %1{%b3:%b2},%0\"; ! 4038: }") ! 4039: ! 4040: (define_insn "" ! 4041: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d") ! 4042: (match_operand:SI 1 "general_operand" "di") ! 4043: (match_operand:SI 2 "general_operand" "di")) ! 4044: (const_int 0))] ! 4045: "TARGET_68020 && TARGET_BITFIELD" ! 4046: "* ! 4047: { ! 4048: CC_STATUS_INIT; ! 4049: return \"bfclr %0{%b2:%b1}\"; ! 4050: }") ! 4051: ! 4052: (define_insn "" ! 4053: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d") ! 4054: (match_operand:SI 1 "general_operand" "di") ! 4055: (match_operand:SI 2 "general_operand" "di")) ! 4056: (const_int -1))] ! 4057: "TARGET_68020 && TARGET_BITFIELD" ! 4058: "* ! 4059: { ! 4060: CC_STATUS_INIT; ! 4061: return \"bfset %0{%b2:%b1}\"; ! 4062: }") ! 4063: ! 4064: (define_insn "" ! 4065: [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d") ! 4066: (match_operand:SI 1 "general_operand" "di") ! 4067: (match_operand:SI 2 "general_operand" "di")) ! 4068: (match_operand:SI 3 "general_operand" "d"))] ! 4069: "TARGET_68020 && TARGET_BITFIELD" ! 4070: "* ! 4071: { ! 4072: #if 0 ! 4073: /* These special cases are now recognized by a specific pattern. */ ! 4074: if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT ! 4075: && INTVAL (operands[1]) == 16 && INTVAL (operands[2]) == 16) ! 4076: return \"move%.w %3,%0\"; ! 4077: if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT ! 4078: && INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8) ! 4079: return \"move%.b %3,%0\"; ! 4080: #endif ! 4081: return \"bfins %3,%0{%b2:%b1}\"; ! 4082: }") ! 4083: ! 4084: ;; Special patterns for optimizing bit-field instructions. ! 4085: ! 4086: (define_insn "" ! 4087: [(set (cc0) ! 4088: (zero_extract:SI (match_operand:QI 0 "memory_operand" "o") ! 4089: (match_operand:SI 1 "general_operand" "di") ! 4090: (match_operand:SI 2 "general_operand" "di")))] ! 4091: "TARGET_68020 && TARGET_BITFIELD ! 4092: && GET_CODE (operands[1]) == CONST_INT" ! 4093: "* ! 4094: { ! 4095: if (operands[1] == const1_rtx ! 4096: && GET_CODE (operands[2]) == CONST_INT) ! 4097: { ! 4098: int width = GET_CODE (operands[0]) == REG ? 31 : 7; ! 4099: return output_btst (operands, ! 4100: gen_rtx (CONST_INT, VOIDmode, ! 4101: width - INTVAL (operands[2])), ! 4102: operands[0], ! 4103: insn, 1000); ! 4104: /* Pass 1000 as SIGNPOS argument so that btst will ! 4105: not think we are testing the sign bit for an `and' ! 4106: and assume that nonzero implies a negative result. */ ! 4107: } ! 4108: if (INTVAL (operands[1]) != 32) ! 4109: cc_status.flags = CC_NOT_NEGATIVE; ! 4110: return \"bftst %0{%b2:%b1}\"; ! 4111: }") ! 4112: ! 4113: ! 4114: ;;; now handle the register cases ! 4115: (define_insn "" ! 4116: [(set (cc0) ! 4117: (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "d") ! 4118: (match_operand:SI 1 "general_operand" "di") ! 4119: (match_operand:SI 2 "general_operand" "di")))] ! 4120: "TARGET_68020 && TARGET_BITFIELD ! 4121: && GET_CODE (operands[1]) == CONST_INT" ! 4122: "* ! 4123: { ! 4124: if (operands[1] == const1_rtx ! 4125: && GET_CODE (operands[2]) == CONST_INT) ! 4126: { ! 4127: int width = GET_CODE (operands[0]) == REG ? 31 : 7; ! 4128: return output_btst (operands, ! 4129: gen_rtx (CONST_INT, VOIDmode, ! 4130: width - INTVAL (operands[2])), ! 4131: operands[0], ! 4132: insn, 1000); ! 4133: /* Pass 1000 as SIGNPOS argument so that btst will ! 4134: not think we are testing the sign bit for an `and' ! 4135: and assume that nonzero implies a negative result. */ ! 4136: } ! 4137: if (INTVAL (operands[1]) != 32) ! 4138: cc_status.flags = CC_NOT_NEGATIVE; ! 4139: return \"bftst %0{%b2:%b1}\"; ! 4140: }") ! 4141: ! 4142: (define_insn "seq" ! 4143: [(set (match_operand:QI 0 "general_operand" "=d") ! 4144: (eq:QI (cc0) (const_int 0)))] ! 4145: "" ! 4146: "* ! 4147: cc_status = cc_prev_status; ! 4148: OUTPUT_JUMP (\"seq %0\", \"fseq %0\", \"seq %0\"); ! 4149: ") ! 4150: ! 4151: (define_insn "sne" ! 4152: [(set (match_operand:QI 0 "general_operand" "=d") ! 4153: (ne:QI (cc0) (const_int 0)))] ! 4154: "" ! 4155: "* ! 4156: cc_status = cc_prev_status; ! 4157: OUTPUT_JUMP (\"sne %0\", \"fsne %0\", \"sne %0\"); ! 4158: ") ! 4159: ! 4160: (define_insn "sgt" ! 4161: [(set (match_operand:QI 0 "general_operand" "=d") ! 4162: (gt:QI (cc0) (const_int 0)))] ! 4163: "" ! 4164: "* ! 4165: cc_status = cc_prev_status; ! 4166: OUTPUT_JUMP (\"sgt %0\", \"fsgt %0\", 0); ! 4167: ") ! 4168: ! 4169: (define_insn "sgtu" ! 4170: [(set (match_operand:QI 0 "general_operand" "=d") ! 4171: (gtu:QI (cc0) (const_int 0)))] ! 4172: "" ! 4173: "* cc_status = cc_prev_status; ! 4174: return \"shi %0\"; ") ! 4175: ! 4176: (define_insn "slt" ! 4177: [(set (match_operand:QI 0 "general_operand" "=d") ! 4178: (lt:QI (cc0) (const_int 0)))] ! 4179: "" ! 4180: "* cc_status = cc_prev_status; ! 4181: OUTPUT_JUMP (\"slt %0\", \"fslt %0\", \"smi %0\"); ") ! 4182: ! 4183: (define_insn "sltu" ! 4184: [(set (match_operand:QI 0 "general_operand" "=d") ! 4185: (ltu:QI (cc0) (const_int 0)))] ! 4186: "" ! 4187: "* cc_status = cc_prev_status; ! 4188: return \"scs %0\"; ") ! 4189: ! 4190: (define_insn "sge" ! 4191: [(set (match_operand:QI 0 "general_operand" "=d") ! 4192: (ge:QI (cc0) (const_int 0)))] ! 4193: "" ! 4194: "* cc_status = cc_prev_status; ! 4195: OUTPUT_JUMP (\"sge %0\", \"fsge %0\", \"spl %0\"); ") ! 4196: ! 4197: (define_insn "sgeu" ! 4198: [(set (match_operand:QI 0 "general_operand" "=d") ! 4199: (geu:QI (cc0) (const_int 0)))] ! 4200: "" ! 4201: "* cc_status = cc_prev_status; ! 4202: return \"scc %0\"; ") ! 4203: ! 4204: (define_insn "sle" ! 4205: [(set (match_operand:QI 0 "general_operand" "=d") ! 4206: (le:QI (cc0) (const_int 0)))] ! 4207: "" ! 4208: "* ! 4209: cc_status = cc_prev_status; ! 4210: OUTPUT_JUMP (\"sle %0\", \"fsle %0\", 0); ! 4211: ") ! 4212: ! 4213: (define_insn "sleu" ! 4214: [(set (match_operand:QI 0 "general_operand" "=d") ! 4215: (leu:QI (cc0) (const_int 0)))] ! 4216: "" ! 4217: "* cc_status = cc_prev_status; ! 4218: return \"sls %0\"; ") ! 4219: ! 4220: ;; Basic conditional jump instructions. ! 4221: ! 4222: (define_insn "beq" ! 4223: [(set (pc) ! 4224: (if_then_else (eq (cc0) ! 4225: (const_int 0)) ! 4226: (label_ref (match_operand 0 "" "")) ! 4227: (pc)))] ! 4228: "" ! 4229: "* ! 4230: { ! 4231: #ifdef MOTOROLA ! 4232: OUTPUT_JUMP (\"jbeq %l0\", \"fbeq %l0\", \"jbeq %l0\"); ! 4233: #else ! 4234: OUTPUT_JUMP (\"jeq %l0\", \"fjeq %l0\", \"jeq %l0\"); ! 4235: #endif ! 4236: }") ! 4237: ! 4238: (define_insn "bne" ! 4239: [(set (pc) ! 4240: (if_then_else (ne (cc0) ! 4241: (const_int 0)) ! 4242: (label_ref (match_operand 0 "" "")) ! 4243: (pc)))] ! 4244: "" ! 4245: "* ! 4246: { ! 4247: #ifdef MOTOROLA ! 4248: OUTPUT_JUMP (\"jbne %l0\", \"fbne %l0\", \"jbne %l0\"); ! 4249: #else ! 4250: OUTPUT_JUMP (\"jne %l0\", \"fjne %l0\", \"jne %l0\"); ! 4251: #endif ! 4252: }") ! 4253: ! 4254: (define_insn "bgt" ! 4255: [(set (pc) ! 4256: (if_then_else (gt (cc0) ! 4257: (const_int 0)) ! 4258: (label_ref (match_operand 0 "" "")) ! 4259: (pc)))] ! 4260: "" ! 4261: "* ! 4262: #ifdef MOTOROLA ! 4263: OUTPUT_JUMP (\"jbgt %l0\", \"fbgt %l0\", 0); ! 4264: #else ! 4265: OUTPUT_JUMP (\"jgt %l0\", \"fjgt %l0\", 0); ! 4266: #endif ! 4267: ") ! 4268: ! 4269: (define_insn "bgtu" ! 4270: [(set (pc) ! 4271: (if_then_else (gtu (cc0) ! 4272: (const_int 0)) ! 4273: (label_ref (match_operand 0 "" "")) ! 4274: (pc)))] ! 4275: "" ! 4276: "* ! 4277: #ifdef MOTOROLA ! 4278: return \"jbhi %l0\"; ! 4279: #else ! 4280: return \"jhi %l0\"; ! 4281: #endif ! 4282: ") ! 4283: ! 4284: (define_insn "blt" ! 4285: [(set (pc) ! 4286: (if_then_else (lt (cc0) ! 4287: (const_int 0)) ! 4288: (label_ref (match_operand 0 "" "")) ! 4289: (pc)))] ! 4290: "" ! 4291: "* ! 4292: #ifdef MOTOROLA ! 4293: OUTPUT_JUMP (\"jblt %l0\", \"fblt %l0\", \"jbmi %l0\"); ! 4294: #else ! 4295: OUTPUT_JUMP (\"jlt %l0\", \"fjlt %l0\", \"jmi %l0\"); ! 4296: #endif ! 4297: ") ! 4298: ! 4299: (define_insn "bltu" ! 4300: [(set (pc) ! 4301: (if_then_else (ltu (cc0) ! 4302: (const_int 0)) ! 4303: (label_ref (match_operand 0 "" "")) ! 4304: (pc)))] ! 4305: "" ! 4306: "* ! 4307: #ifdef MOTOROLA ! 4308: return \"jbcs %l0\"; ! 4309: #else ! 4310: return \"jcs %l0\"; ! 4311: #endif ! 4312: ") ! 4313: ! 4314: (define_insn "bge" ! 4315: [(set (pc) ! 4316: (if_then_else (ge (cc0) ! 4317: (const_int 0)) ! 4318: (label_ref (match_operand 0 "" "")) ! 4319: (pc)))] ! 4320: "" ! 4321: "* ! 4322: #ifdef MOTOROLA ! 4323: OUTPUT_JUMP (\"jbge %l0\", \"fbge %l0\", \"jbpl %l0\"); ! 4324: #else ! 4325: OUTPUT_JUMP (\"jge %l0\", \"fjge %l0\", \"jpl %l0\"); ! 4326: #endif ! 4327: ") ! 4328: ! 4329: (define_insn "bgeu" ! 4330: [(set (pc) ! 4331: (if_then_else (geu (cc0) ! 4332: (const_int 0)) ! 4333: (label_ref (match_operand 0 "" "")) ! 4334: (pc)))] ! 4335: "" ! 4336: "* ! 4337: #ifdef MOTOROLA ! 4338: return \"jbcc %l0\"; ! 4339: #else ! 4340: return \"jcc %l0\"; ! 4341: #endif ! 4342: ") ! 4343: ! 4344: (define_insn "ble" ! 4345: [(set (pc) ! 4346: (if_then_else (le (cc0) ! 4347: (const_int 0)) ! 4348: (label_ref (match_operand 0 "" "")) ! 4349: (pc)))] ! 4350: "" ! 4351: "* ! 4352: #ifdef MOTOROLA ! 4353: OUTPUT_JUMP (\"jble %l0\", \"fble %l0\", 0); ! 4354: #else ! 4355: OUTPUT_JUMP (\"jle %l0\", \"fjle %l0\", 0); ! 4356: #endif ! 4357: ") ! 4358: ! 4359: (define_insn "bleu" ! 4360: [(set (pc) ! 4361: (if_then_else (leu (cc0) ! 4362: (const_int 0)) ! 4363: (label_ref (match_operand 0 "" "")) ! 4364: (pc)))] ! 4365: "" ! 4366: "* ! 4367: #ifdef MOTOROLA ! 4368: return \"jbls %l0\"; ! 4369: #else ! 4370: return \"jls %l0\"; ! 4371: #endif ! 4372: ") ! 4373: ! 4374: ;; Negated conditional jump instructions. ! 4375: ! 4376: (define_insn "" ! 4377: [(set (pc) ! 4378: (if_then_else (eq (cc0) ! 4379: (const_int 0)) ! 4380: (pc) ! 4381: (label_ref (match_operand 0 "" ""))))] ! 4382: "" ! 4383: "* ! 4384: { ! 4385: #ifdef MOTOROLA ! 4386: OUTPUT_JUMP (\"jbne %l0\", \"fbne %l0\", \"jbne %l0\"); ! 4387: #else ! 4388: OUTPUT_JUMP (\"jne %l0\", \"fjne %l0\", \"jne %l0\"); ! 4389: #endif ! 4390: }") ! 4391: ! 4392: (define_insn "" ! 4393: [(set (pc) ! 4394: (if_then_else (ne (cc0) ! 4395: (const_int 0)) ! 4396: (pc) ! 4397: (label_ref (match_operand 0 "" ""))))] ! 4398: "" ! 4399: "* ! 4400: { ! 4401: #ifdef MOTOROLA ! 4402: OUTPUT_JUMP (\"jbeq %l0\", \"fbeq %l0\", \"jbeq %l0\"); ! 4403: #else ! 4404: OUTPUT_JUMP (\"jeq %l0\", \"fjeq %l0\", \"jeq %l0\"); ! 4405: #endif ! 4406: }") ! 4407: ! 4408: (define_insn "" ! 4409: [(set (pc) ! 4410: (if_then_else (gt (cc0) ! 4411: (const_int 0)) ! 4412: (pc) ! 4413: (label_ref (match_operand 0 "" ""))))] ! 4414: "" ! 4415: "* ! 4416: #ifdef MOTOROLA ! 4417: OUTPUT_JUMP (\"jble %l0\", \"fbngt %l0\", 0); ! 4418: #else ! 4419: OUTPUT_JUMP (\"jle %l0\", \"fjngt %l0\", 0); ! 4420: #endif ! 4421: ") ! 4422: ! 4423: (define_insn "" ! 4424: [(set (pc) ! 4425: (if_then_else (gtu (cc0) ! 4426: (const_int 0)) ! 4427: (pc) ! 4428: (label_ref (match_operand 0 "" ""))))] ! 4429: "" ! 4430: "* ! 4431: #ifdef MOTOROLA ! 4432: return \"jbls %l0\"; ! 4433: #else ! 4434: return \"jls %l0\"; ! 4435: #endif ! 4436: ") ! 4437: ! 4438: (define_insn "" ! 4439: [(set (pc) ! 4440: (if_then_else (lt (cc0) ! 4441: (const_int 0)) ! 4442: (pc) ! 4443: (label_ref (match_operand 0 "" ""))))] ! 4444: "" ! 4445: "* ! 4446: #ifdef MOTOROLA ! 4447: OUTPUT_JUMP (\"jbge %l0\", \"fbnlt %l0\", \"jbpl %l0\"); ! 4448: #else ! 4449: OUTPUT_JUMP (\"jge %l0\", \"fjnlt %l0\", \"jpl %l0\"); ! 4450: #endif ! 4451: ") ! 4452: ! 4453: (define_insn "" ! 4454: [(set (pc) ! 4455: (if_then_else (ltu (cc0) ! 4456: (const_int 0)) ! 4457: (pc) ! 4458: (label_ref (match_operand 0 "" ""))))] ! 4459: "" ! 4460: "* ! 4461: #ifdef MOTOROLA ! 4462: return \"jbcc %l0\"; ! 4463: #else ! 4464: return \"jcc %l0\"; ! 4465: #endif ! 4466: ") ! 4467: ! 4468: (define_insn "" ! 4469: [(set (pc) ! 4470: (if_then_else (ge (cc0) ! 4471: (const_int 0)) ! 4472: (pc) ! 4473: (label_ref (match_operand 0 "" ""))))] ! 4474: "" ! 4475: "* ! 4476: #ifdef MOTOROLA ! 4477: OUTPUT_JUMP (\"jblt %l0\", \"fbnge %l0\", \"jbmi %l0\"); ! 4478: #else ! 4479: OUTPUT_JUMP (\"jlt %l0\", \"fjnge %l0\", \"jmi %l0\"); ! 4480: #endif ! 4481: ") ! 4482: ! 4483: (define_insn "" ! 4484: [(set (pc) ! 4485: (if_then_else (geu (cc0) ! 4486: (const_int 0)) ! 4487: (pc) ! 4488: (label_ref (match_operand 0 "" ""))))] ! 4489: "" ! 4490: "* ! 4491: #ifdef MOTOROLA ! 4492: return \"jbcs %l0\"; ! 4493: #else ! 4494: return \"jcs %l0\"; ! 4495: #endif ! 4496: ") ! 4497: ! 4498: (define_insn "" ! 4499: [(set (pc) ! 4500: (if_then_else (le (cc0) ! 4501: (const_int 0)) ! 4502: (pc) ! 4503: (label_ref (match_operand 0 "" ""))))] ! 4504: "" ! 4505: "* ! 4506: #ifdef MOTOROLA ! 4507: OUTPUT_JUMP (\"jbgt %l0\", \"fbnle %l0\", 0); ! 4508: #else ! 4509: OUTPUT_JUMP (\"jgt %l0\", \"fjnle %l0\", 0); ! 4510: #endif ! 4511: ") ! 4512: ! 4513: (define_insn "" ! 4514: [(set (pc) ! 4515: (if_then_else (leu (cc0) ! 4516: (const_int 0)) ! 4517: (pc) ! 4518: (label_ref (match_operand 0 "" ""))))] ! 4519: "" ! 4520: "* ! 4521: #ifdef MOTOROLA ! 4522: return \"jbhi %l0\"; ! 4523: #else ! 4524: return \"jhi %l0\"; ! 4525: #endif ! 4526: ") ! 4527: ! 4528: ;; Unconditional and other jump instructions ! 4529: (define_insn "jump" ! 4530: [(set (pc) ! 4531: (label_ref (match_operand 0 "" "")))] ! 4532: "" ! 4533: "* ! 4534: #ifdef MOTOROLA ! 4535: return \"jbra %l0\"; ! 4536: #else ! 4537: return \"jra %l0\"; ! 4538: #endif ! 4539: ") ! 4540: ! 4541: ;; We support two different ways of handling dispatch tables. ! 4542: ;; The NeXT uses absolute tables, and other machines use relative. ! 4543: ;; This define_expand can generate either kind. ! 4544: (define_expand "tablejump" ! 4545: [(parallel [(set (pc) (match_operand 0 "" "")) ! 4546: (use (label_ref (match_operand 1 "" "")))])] ! 4547: "" ! 4548: " ! 4549: { ! 4550: #ifdef CASE_VECTOR_PC_RELATIVE ! 4551: operands[0] = gen_rtx (PLUS, SImode, pc_rtx, operands[0]); ! 4552: #endif ! 4553: }") ! 4554: ! 4555: ;; Jump to variable address from dispatch table of absolute addresses. ! 4556: (define_insn "" ! 4557: [(set (pc) (match_operand:SI 0 "register_operand" "a")) ! 4558: (use (label_ref (match_operand 1 "" "")))] ! 4559: "" ! 4560: "* ! 4561: #ifdef MOTOROLA ! 4562: return \"jmp (%0)\"; ! 4563: #else ! 4564: return \"jmp %0@\"; ! 4565: #endif ! 4566: ") ! 4567: ! 4568: ;; Jump to variable address from dispatch table of relative addresses. ! 4569: (define_insn "" ! 4570: [(set (pc) ! 4571: (plus:SI (pc) (match_operand:HI 0 "register_operand" "r"))) ! 4572: (use (label_ref (match_operand 1 "" "")))] ! 4573: "" ! 4574: "* ! 4575: #ifdef ASM_RETURN_CASE_JUMP ! 4576: ASM_RETURN_CASE_JUMP; ! 4577: #else ! 4578: #ifdef SGS ! 4579: #ifdef ASM_OUTPUT_CASE_LABEL ! 4580: return \"jmp 6(%%pc,%0.w)\"; ! 4581: #else ! 4582: #ifdef CRDS ! 4583: return \"jmp 2(pc,%0.w)\"; ! 4584: #else ! 4585: return \"jmp 2(%%pc,%0.w)\"; ! 4586: #endif /* end !CRDS */ ! 4587: #endif ! 4588: #else /* not SGS */ ! 4589: #ifdef MOTOROLA ! 4590: return \"jmp (2,pc,%0.w)\"; ! 4591: #else ! 4592: return \"jmp pc@(2,%0:w)\"; ! 4593: #endif ! 4594: #endif ! 4595: #endif ! 4596: ") ! 4597: ! 4598: ;; Decrement-and-branch insns. ! 4599: (define_insn "" ! 4600: [(set (pc) ! 4601: (if_then_else ! 4602: (ne (match_operand:HI 0 "general_operand" "+g") ! 4603: (const_int 0)) ! 4604: (label_ref (match_operand 1 "" "")) ! 4605: (pc))) ! 4606: (set (match_dup 0) ! 4607: (plus:HI (match_dup 0) ! 4608: (const_int -1)))] ! 4609: "" ! 4610: "* ! 4611: { ! 4612: CC_STATUS_INIT; ! 4613: if (DATA_REG_P (operands[0])) ! 4614: return \"dbra %0,%l1\"; ! 4615: if (GET_CODE (operands[0]) == MEM) ! 4616: { ! 4617: #ifdef MOTOROLA ! 4618: #ifdef NO_ADDSUB_Q ! 4619: return \"sub%.w %#1,%0\;jbcc %l1\"; ! 4620: #else ! 4621: return \"subq%.w %#1,%0\;jbcc %l1\"; ! 4622: #endif ! 4623: #else /* not MOTOROLA */ ! 4624: return \"subqw %#1,%0\;jcc %l1\"; ! 4625: #endif ! 4626: } ! 4627: #ifdef MOTOROLA ! 4628: #ifdef SGS_CMP_ORDER ! 4629: #ifdef NO_ADDSUB_Q ! 4630: return \"sub%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\"; ! 4631: #else ! 4632: return \"subq%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\"; ! 4633: #endif ! 4634: #else /* not SGS_CMP_ORDER */ ! 4635: return \"subq%.w %#1,%0\;cmp%.w %#-1,%0\;jbne %l1\"; ! 4636: #endif ! 4637: #else /* not MOTOROLA */ ! 4638: return \"subqw %#1,%0\;cmpw %#-1,%0\;jne %l1\"; ! 4639: #endif ! 4640: }") ! 4641: ! 4642: (define_insn "" ! 4643: [(set (pc) ! 4644: (if_then_else ! 4645: (ne (match_operand:SI 0 "general_operand" "+g") ! 4646: (const_int 0)) ! 4647: (label_ref (match_operand 1 "" "")) ! 4648: (pc))) ! 4649: (set (match_dup 0) ! 4650: (plus:SI (match_dup 0) ! 4651: (const_int -1)))] ! 4652: "" ! 4653: "* ! 4654: { ! 4655: CC_STATUS_INIT; ! 4656: #ifdef MOTOROLA ! 4657: #ifdef NO_ADDSUB_Q ! 4658: if (DATA_REG_P (operands[0])) ! 4659: return \"dbra %0,%l1\;clr%.w %0\;sub%.l %#1,%0\;jbcc %l1\"; ! 4660: if (GET_CODE (operands[0]) == MEM) ! 4661: return \"sub%.l %#1,%0\;jbcc %l1\"; ! 4662: #else ! 4663: if (DATA_REG_P (operands[0])) ! 4664: return \"dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jbcc %l1\"; ! 4665: if (GET_CODE (operands[0]) == MEM) ! 4666: return \"subq%.l %#1,%0\;jbcc %l1\"; ! 4667: #endif /* NO_ADDSUB_Q */ ! 4668: #ifdef SGS_CMP_ORDER ! 4669: #ifdef NO_ADDSUB_Q ! 4670: return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; ! 4671: #else ! 4672: return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; ! 4673: #endif ! 4674: #else /* not SGS_CMP_ORDER */ ! 4675: return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\"; ! 4676: #endif /* not SGS_CMP_ORDER */ ! 4677: #else /* not MOTOROLA */ ! 4678: if (DATA_REG_P (operands[0])) ! 4679: return \"dbra %0,%l1\;clr%.w %0\;subql %#1,%0\;jcc %l1\"; ! 4680: if (GET_CODE (operands[0]) == MEM) ! 4681: return \"subql %#1,%0\;jcc %l1\"; ! 4682: return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\"; ! 4683: #endif /* not MOTOROLA */ ! 4684: }") ! 4685: ! 4686: ;; Two dbra patterns that use REG_NOTES info generated by strength_reduce. ! 4687: ! 4688: (define_insn "" ! 4689: [(set (pc) ! 4690: (if_then_else ! 4691: (ge (plus:HI (match_operand:HI 0 "general_operand" "+g") ! 4692: (const_int -1)) ! 4693: (const_int 0)) ! 4694: (label_ref (match_operand 1 "" "")) ! 4695: (pc))) ! 4696: (set (match_dup 0) ! 4697: (plus:HI (match_dup 0) ! 4698: (const_int -1)))] ! 4699: "find_reg_note (insn, REG_NONNEG, 0)" ! 4700: "* ! 4701: { ! 4702: CC_STATUS_INIT; ! 4703: #ifdef MOTOROLA ! 4704: #ifdef NO_ADDSUB_Q ! 4705: if (DATA_REG_P (operands[0])) ! 4706: return \"dbra %0,%l1\"; ! 4707: if (GET_CODE (operands[0]) == MEM) ! 4708: return \"sub%.w %#1,%0\;jbcc %l1\"; ! 4709: #else ! 4710: if (DATA_REG_P (operands[0])) ! 4711: return \"dbra %0,%l1\"; ! 4712: if (GET_CODE (operands[0]) == MEM) ! 4713: return \"subq%.w %#1,%0\;jbcc %l1\"; ! 4714: #endif ! 4715: #ifdef SGS_CMP_ORDER ! 4716: #ifdef NO_ADDSUB_Q ! 4717: return \"sub.w %#1,%0\;cmp.w %0,%#-1\;jbne %l1\"; ! 4718: #else ! 4719: return \"subq.w %#1,%0\;cmp.w %0,%#-1\;jbne %l1\"; ! 4720: #endif ! 4721: #else /* not SGS_CMP_ORDER */ ! 4722: return \"subq.w %#1,%0\;cmp.w %#-1,%0\;jbne %l1\"; ! 4723: #endif /* not SGS_CMP_ORDER */ ! 4724: #else /* not MOTOROLA */ ! 4725: if (DATA_REG_P (operands[0])) ! 4726: return \"dbra %0,%l1\"; ! 4727: if (GET_CODE (operands[0]) == MEM) ! 4728: return \"subqw %#1,%0\;jcc %l1\"; ! 4729: return \"subqw %#1,%0\;cmpw %#-1,%0\;jne %l1\"; ! 4730: #endif /* not MOTOROLA */ ! 4731: }") ! 4732: ! 4733: (define_insn "decrement_and_branch_until_zero" ! 4734: [(set (pc) ! 4735: (if_then_else ! 4736: (ge (plus:SI (match_operand:SI 0 "general_operand" "+g") ! 4737: (const_int -1)) ! 4738: (const_int 0)) ! 4739: (label_ref (match_operand 1 "" "")) ! 4740: (pc))) ! 4741: (set (match_dup 0) ! 4742: (plus:SI (match_dup 0) ! 4743: (const_int -1)))] ! 4744: "find_reg_note (insn, REG_NONNEG, 0)" ! 4745: "* ! 4746: { ! 4747: CC_STATUS_INIT; ! 4748: #ifdef MOTOROLA ! 4749: #ifdef NO_ADDSUB_Q ! 4750: if (DATA_REG_P (operands[0])) ! 4751: return \"dbra %0,%l1\;clr%.w %0\;sub%.l %#1,%0\;jbcc %l1\"; ! 4752: if (GET_CODE (operands[0]) == MEM) ! 4753: return \"sub%.l %#1,%0\;jbcc %l1\"; ! 4754: #else ! 4755: if (DATA_REG_P (operands[0])) ! 4756: return \"dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jbcc %l1\"; ! 4757: if (GET_CODE (operands[0]) == MEM) ! 4758: return \"subq%.l %#1,%0\;jbcc %l1\"; ! 4759: #endif ! 4760: #ifdef SGS_CMP_ORDER ! 4761: #ifdef NO_ADDSUB_Q ! 4762: return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; ! 4763: #else ! 4764: return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; ! 4765: #endif ! 4766: #else /* not SGS_CMP_ORDER */ ! 4767: return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\"; ! 4768: #endif /* not SGS_CMP_ORDER */ ! 4769: #else /* not MOTOROLA */ ! 4770: if (DATA_REG_P (operands[0])) ! 4771: return \"dbra %0,%l1\;clr%.w %0\;subql %#1,%0\;jcc %l1\"; ! 4772: if (GET_CODE (operands[0]) == MEM) ! 4773: return \"subql %#1,%0\;jcc %l1\"; ! 4774: return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\"; ! 4775: #endif /* not MOTOROLA */ ! 4776: }") ! 4777: ! 4778: ! 4779: ;; PIC calls are handled by loading the address of the function into a ! 4780: ;; register (via movsi), then emitting a register indirect call using ! 4781: ;; the "jsr" function call syntax. ! 4782: ;; ! 4783: ;; It is important to note that the "jsr" syntax is always used for ! 4784: ;; PIC calls, even on machines in which GCC normally uses the "jbsr" ! 4785: ;; syntax for non-PIC calls. This keeps at least 1 assembler (Sun) ! 4786: ;; from emitting incorrect code for a PIC call. ! 4787: ;; ! 4788: ;; We have different patterns for PIC calls and non-PIC calls. The ! 4789: ;; different patterns are only used to choose the right syntax ! 4790: ;; ("jsr" vs "jbsr"). ! 4791: ;; ! 4792: ;; On svr4 m68k, PIC stuff is done differently. To be able to support ! 4793: ;; dynamic linker LAZY BINDING, all the procedure calls need to go ! 4794: ;; through the PLT (Procedure Linkage Table) section in PIC mode. The ! 4795: ;; svr4 m68k assembler recognizes this syntax: `bsr FUNC@PLTPC' and it ! 4796: ;; will create the correct relocation entry (R_68K_PLT32) for `FUNC', ! 4797: ;; that tells the linker editor to create an entry for `FUNC' in PLT ! 4798: ;; section at link time. However, all global objects reference are still ! 4799: ;; done by using `OBJ@GOT'. So, the goal here is to output the function ! 4800: ;; call operand as `FUNC@PLTPC', but output object operand as `OBJ@GOT'. ! 4801: ;; We need to have a way to differentiate these two different operands. ! 4802: ;; ! 4803: ;; The strategy I use here is to use SYMBOL_REF_FLAG to differentiate ! 4804: ;; these two different operands. The macro LEGITIMATE_PIC_OPERAND_P needs ! 4805: ;; to be changed to recognize function calls symbol_ref operand as a legal ! 4806: ;; PIC operand (by checking whether SYMBOL_REF_FLAG is set). This will ! 4807: ;; avoid the compiler to load this symbol_ref operand into a register. ! 4808: ;; Remember, the operand "foo@PLTPC" cannot be called via jsr directly ! 4809: ;; since the value is a PC relative offset, not a real address. ! 4810: ;; ! 4811: ;; All global objects are treated in the similar way as in SUN3. The only ! 4812: ;; difference is: on m68k svr4, the reference of such global object needs ! 4813: ;; to end with a suffix "@GOT" so the assembler and linker know to create ! 4814: ;; an entry for it in GOT (Global Offset Table) section. This is done in ! 4815: ;; m68k.c. ! 4816: ! 4817: ;; Call subroutine with no return value. ! 4818: (define_expand "call" ! 4819: [(call (match_operand:QI 0 "memory_operand" "") ! 4820: (match_operand:SI 1 "general_operand" ""))] ! 4821: ;; Operand 1 not really used on the m68000. ! 4822: ! 4823: "" ! 4824: " ! 4825: { ! 4826: if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) ! 4827: #ifdef MOTOROLA ! 4828: SYMBOL_REF_FLAG (XEXP (operands[0], 0)) = 1; ! 4829: #else ! 4830: operands[0] = gen_rtx (MEM, GET_MODE (operands[0]), ! 4831: force_reg (Pmode, XEXP (operands[0], 0))); ! 4832: #endif ! 4833: }") ! 4834: ! 4835: ;; This is a normal call sequence. ! 4836: (define_insn "" ! 4837: [(call (match_operand:QI 0 "memory_operand" "o") ! 4838: (match_operand:SI 1 "general_operand" "g"))] ! 4839: ;; Operand 1 not really used on the m68000. ! 4840: ! 4841: "! flag_pic" ! 4842: "* ! 4843: #ifdef MOTOROLA ! 4844: return \"jsr %0\"; ! 4845: #else ! 4846: return \"jbsr %0\"; ! 4847: #endif ! 4848: ") ! 4849: ! 4850: ;; This is a PIC call sequence. ! 4851: (define_insn "" ! 4852: [(call (match_operand:QI 0 "memory_operand" "o") ! 4853: (match_operand:SI 1 "general_operand" "g"))] ! 4854: ;; Operand 1 not really used on the m68000. ! 4855: ! 4856: "flag_pic" ! 4857: "* ! 4858: #ifdef MOTOROLA ! 4859: if (GET_CODE (operands[0]) == MEM ! 4860: && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) ! 4861: return \"bsr %0@PLTPC\"; ! 4862: #endif ! 4863: return \"jsr %0\"; ! 4864: ") ! 4865: ! 4866: ;; Call subroutine, returning value in operand 0 ! 4867: ;; (which must be a hard register). ! 4868: ;; See comments before "call" regarding PIC calls. ! 4869: (define_expand "call_value" ! 4870: [(set (match_operand 0 "" "") ! 4871: (call (match_operand:QI 1 "memory_operand" "") ! 4872: (match_operand:SI 2 "general_operand" "")))] ! 4873: ;; Operand 2 not really used on the m68000. ! 4874: "" ! 4875: " ! 4876: { ! 4877: if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) ! 4878: #ifdef MOTOROLA ! 4879: SYMBOL_REF_FLAG (XEXP (operands[1], 0)) = 1; ! 4880: #else ! 4881: operands[1] = gen_rtx (MEM, GET_MODE (operands[1]), ! 4882: force_reg (Pmode, XEXP (operands[1], 0))); ! 4883: #endif ! 4884: }") ! 4885: ! 4886: ;; This is a normal call_value ! 4887: (define_insn "" ! 4888: [(set (match_operand 0 "" "=rf") ! 4889: (call (match_operand:QI 1 "memory_operand" "o") ! 4890: (match_operand:SI 2 "general_operand" "g")))] ! 4891: ;; Operand 2 not really used on the m68000. ! 4892: "! flag_pic" ! 4893: "* ! 4894: #ifdef MOTOROLA ! 4895: return \"jsr %1\"; ! 4896: #else ! 4897: return \"jbsr %1\"; ! 4898: #endif ! 4899: ") ! 4900: ! 4901: ;; This is a PIC call_value ! 4902: (define_insn "" ! 4903: [(set (match_operand 0 "" "=rf") ! 4904: (call (match_operand:QI 1 "memory_operand" "o") ! 4905: (match_operand:SI 2 "general_operand" "g")))] ! 4906: ;; Operand 2 not really used on the m68000. ! 4907: "flag_pic" ! 4908: "* ! 4909: #ifdef MOTOROLA ! 4910: if (GET_CODE (operands[1]) == MEM ! 4911: && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) ! 4912: return \"bsr %1@PLTPC\"; ! 4913: #endif ! 4914: return \"jsr %1\"; ! 4915: ") ! 4916: ! 4917: ;; Call subroutine returning any type. ! 4918: ! 4919: (define_expand "untyped_call" ! 4920: [(parallel [(call (match_operand 0 "" "") ! 4921: (const_int 0)) ! 4922: (match_operand 1 "" "") ! 4923: (match_operand 2 "" "")])] ! 4924: "NEEDS_UNTYPED_CALL" ! 4925: " ! 4926: { ! 4927: int i; ! 4928: ! 4929: emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); ! 4930: ! 4931: for (i = 0; i < XVECLEN (operands[2], 0); i++) ! 4932: { ! 4933: rtx set = XVECEXP (operands[2], 0, i); ! 4934: emit_move_insn (SET_DEST (set), SET_SRC (set)); ! 4935: } ! 4936: ! 4937: /* The optimizer does not know that the call sets the function value ! 4938: registers we stored in the result block. We avoid problems by ! 4939: claiming that all hard registers are used and clobbered at this ! 4940: point. */ ! 4941: emit_insn (gen_blockage ()); ! 4942: ! 4943: DONE; ! 4944: }") ! 4945: ! 4946: ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and ! 4947: ;; all of memory. This blocks insns from being moved across this point. ! 4948: ! 4949: (define_insn "blockage" ! 4950: [(unspec_volatile [(const_int 0)] 0)] ! 4951: "" ! 4952: "") ! 4953: ! 4954: (define_insn "nop" ! 4955: [(const_int 0)] ! 4956: "" ! 4957: "nop") ! 4958: ! 4959: (define_insn "probe" ! 4960: [(reg:SI 15)] ! 4961: "NEED_PROBE" ! 4962: "* ! 4963: { ! 4964: operands[0] = gen_rtx (PLUS, SImode, stack_pointer_rtx, ! 4965: gen_rtx (CONST_INT, VOIDmode, NEED_PROBE)); ! 4966: return \"tstl %a0\"; ! 4967: }") ! 4968: ! 4969: ;; Used for frameless functions which save no regs and allocate no locals. ! 4970: (define_insn "return" ! 4971: [(return)] ! 4972: "USE_RETURN_INSN" ! 4973: "* ! 4974: { ! 4975: if (current_function_pops_args == 0) ! 4976: return \"rts\"; ! 4977: operands[0] = gen_rtx (CONST_INT, VOIDmode, current_function_pops_args); ! 4978: return \"rtd %0\"; ! 4979: }") ! 4980: ! 4981: (define_insn "indirect_jump" ! 4982: [(set (pc) (match_operand:SI 0 "address_operand" "p"))] ! 4983: "" ! 4984: "jmp %a0") ! 4985: ! 4986: ;; This should not be used unless the add/sub insns can't be. ! 4987: ! 4988: (define_insn "" ! 4989: [(set (match_operand:SI 0 "general_operand" "=a") ! 4990: (match_operand:QI 1 "address_operand" "p"))] ! 4991: "" ! 4992: "lea %a1,%0") ! 4993: ! 4994: ;; This is the first machine-dependent peephole optimization. ! 4995: ;; It is useful when a floating value is returned from a function call ! 4996: ;; and then is moved into an FP register. ! 4997: ;; But it is mainly intended to test the support for these optimizations. ! 4998: ! 4999: (define_peephole ! 5000: [(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int 4))) ! 5001: (set (match_operand:DF 0 "register_operand" "=f") ! 5002: (match_operand:DF 1 "register_operand" "ad"))] ! 5003: "FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])" ! 5004: "* ! 5005: { ! 5006: rtx xoperands[2]; ! 5007: xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); ! 5008: output_asm_insn (\"move%.l %1,%@\", xoperands); ! 5009: output_asm_insn (\"move%.l %1,%-\", operands); ! 5010: return \"fmove%.d %+,%0\"; ! 5011: } ! 5012: ") ! 5013: ! 5014: ;; Optimize a stack-adjust followed by a push of an argument. ! 5015: ;; This is said to happen frequently with -msoft-float ! 5016: ;; when there are consecutive library calls. ! 5017: ! 5018: (define_peephole ! 5019: [(set (reg:SI 15) (plus:SI (reg:SI 15) ! 5020: (match_operand:SI 0 "immediate_operand" "n"))) ! 5021: (set (match_operand:SF 1 "push_operand" "=m") ! 5022: (match_operand:SF 2 "general_operand" "rmfF"))] ! 5023: "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) >= 4 ! 5024: && ! reg_mentioned_p (stack_pointer_rtx, operands[2])" ! 5025: "* ! 5026: { ! 5027: if (INTVAL (operands[0]) > 4) ! 5028: { ! 5029: rtx xoperands[2]; ! 5030: xoperands[0] = stack_pointer_rtx; ! 5031: xoperands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[0]) - 4); ! 5032: #ifndef NO_ADDSUB_Q ! 5033: if (INTVAL (xoperands[1]) <= 8) ! 5034: output_asm_insn (\"addq%.w %1,%0\", xoperands); ! 5035: else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020) ! 5036: { ! 5037: xoperands[1] = gen_rtx (CONST_INT, VOIDmode, ! 5038: INTVAL (xoperands[1]) - 8); ! 5039: output_asm_insn (\"addq%.w %#8,%0\;addq%.w %1,%0\", xoperands); ! 5040: } ! 5041: else ! 5042: #endif ! 5043: if (INTVAL (xoperands[1]) <= 0x7FFF) ! 5044: output_asm_insn (\"add%.w %1,%0\", xoperands); ! 5045: else ! 5046: output_asm_insn (\"add%.l %1,%0\", xoperands); ! 5047: } ! 5048: if (FP_REG_P (operands[2])) ! 5049: return \"fmove%.s %2,%@\"; ! 5050: return \"move%.l %2,%@\"; ! 5051: }") ! 5052: ! 5053: ;; Speed up stack adjust followed by a fullword fixedpoint push. ! 5054: ! 5055: (define_peephole ! 5056: [(set (reg:SI 15) (plus:SI (reg:SI 15) ! 5057: (match_operand:SI 0 "immediate_operand" "n"))) ! 5058: (set (match_operand:SI 1 "push_operand" "=m") ! 5059: (match_operand:SI 2 "general_operand" "g"))] ! 5060: "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) >= 4 ! 5061: && ! reg_mentioned_p (stack_pointer_rtx, operands[2])" ! 5062: "* ! 5063: { ! 5064: if (INTVAL (operands[0]) > 4) ! 5065: { ! 5066: rtx xoperands[2]; ! 5067: xoperands[0] = stack_pointer_rtx; ! 5068: xoperands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[0]) - 4); ! 5069: #ifndef NO_ADDSUB_Q ! 5070: if (INTVAL (xoperands[1]) <= 8) ! 5071: output_asm_insn (\"addq%.w %1,%0\", xoperands); ! 5072: else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020) ! 5073: { ! 5074: xoperands[1] = gen_rtx (CONST_INT, VOIDmode, ! 5075: INTVAL (xoperands[1]) - 8); ! 5076: output_asm_insn (\"addq%.w %#8,%0\;addq%.w %1,%0\", xoperands); ! 5077: } ! 5078: else ! 5079: #endif ! 5080: if (INTVAL (xoperands[1]) <= 0x7FFF) ! 5081: output_asm_insn (\"add%.w %1,%0\", xoperands); ! 5082: else ! 5083: output_asm_insn (\"add%.l %1,%0\", xoperands); ! 5084: } ! 5085: if (operands[2] == const0_rtx) ! 5086: return \"clr%.l %@\"; ! 5087: return \"move%.l %2,%@\"; ! 5088: }") ! 5089: ! 5090: ;; Speed up pushing a single byte but leaving four bytes of space. ! 5091: ! 5092: (define_peephole ! 5093: [(set (mem:QI (pre_dec:SI (reg:SI 15))) ! 5094: (match_operand:QI 1 "general_operand" "dami")) ! 5095: (set (reg:SI 15) (minus:SI (reg:SI 15) (const_int 2)))] ! 5096: "! reg_mentioned_p (stack_pointer_rtx, operands[1])" ! 5097: "* ! 5098: { ! 5099: rtx xoperands[4]; ! 5100: ! 5101: if (GET_CODE (operands[1]) == REG) ! 5102: return \"move%.l %1,%-\"; ! 5103: ! 5104: xoperands[1] = operands[1]; ! 5105: xoperands[2] ! 5106: = gen_rtx (MEM, QImode, ! 5107: gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, ! 5108: gen_rtx (CONST_INT, VOIDmode, 3))); ! 5109: xoperands[3] = stack_pointer_rtx; ! 5110: output_asm_insn (\"subq%.w %#4,%3\;move%.b %1,%2\", xoperands); ! 5111: return \"\"; ! 5112: }") ! 5113: ! 5114: (define_peephole ! 5115: [(set (match_operand:SI 0 "register_operand" "=d") ! 5116: (const_int 0)) ! 5117: (set (strict_low_part (subreg:HI (match_dup 0) 0)) ! 5118: (match_operand:HI 1 "general_operand" "rmn"))] ! 5119: "strict_low_part_peephole_ok (HImode, prev_nonnote_insn (insn), operands[0])" ! 5120: "* ! 5121: { ! 5122: if (GET_CODE (operands[1]) == CONST_INT) ! 5123: { ! 5124: if (operands[1] == const0_rtx ! 5125: && (DATA_REG_P (operands[0]) ! 5126: || GET_CODE (operands[0]) == MEM) ! 5127: /* clr insns on 68000 read before writing. ! 5128: This isn't so on the 68010, but we have no alternative for it. */ ! 5129: && (TARGET_68020 ! 5130: || !(GET_CODE (operands[0]) == MEM ! 5131: && MEM_VOLATILE_P (operands[0])))) ! 5132: return \"clr%.w %0\"; ! 5133: } ! 5134: return \"move%.w %1,%0\"; ! 5135: }") ! 5136: ! 5137: ;; dbCC peepholes ! 5138: ;; ! 5139: ;; Turns ! 5140: ;; loop: ! 5141: ;; [ ... ] ! 5142: ;; jCC label ; abnormal loop termination ! 5143: ;; dbra dN, loop ; normal loop termination ! 5144: ;; ! 5145: ;; Into ! 5146: ;; loop: ! 5147: ;; [ ... ] ! 5148: ;; dbCC dN, loop ! 5149: ;; jCC label ! 5150: ;; ! 5151: ;; Which moves the jCC condition outside the inner loop for free. ! 5152: ;; ! 5153: (define_peephole ! 5154: [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p" ! 5155: [(cc0) (const_int 0)]) ! 5156: (label_ref (match_operand 2 "" "")) ! 5157: (pc))) ! 5158: (parallel ! 5159: [(set (pc) ! 5160: (if_then_else ! 5161: (ge (plus:HI (match_operand:HI 0 "register_operand" "+d") ! 5162: (const_int -1)) ! 5163: (const_int 0)) ! 5164: (label_ref (match_operand 1 "" "")) ! 5165: (pc))) ! 5166: (set (match_dup 0) ! 5167: (plus:HI (match_dup 0) ! 5168: (const_int -1)))])] ! 5169: "DATA_REG_P (operands[0])" ! 5170: "* ! 5171: { ! 5172: CC_STATUS_INIT; ! 5173: output_dbcc_and_branch (operands); ! 5174: return \"\"; ! 5175: }") ! 5176: ! 5177: (define_peephole ! 5178: [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p" ! 5179: [(cc0) (const_int 0)]) ! 5180: (label_ref (match_operand 2 "" "")) ! 5181: (pc))) ! 5182: (parallel ! 5183: [(set (pc) ! 5184: (if_then_else ! 5185: (ge (plus:SI (match_operand:SI 0 "register_operand" "+d") ! 5186: (const_int -1)) ! 5187: (const_int 0)) ! 5188: (label_ref (match_operand 1 "" "")) ! 5189: (pc))) ! 5190: (set (match_dup 0) ! 5191: (plus:SI (match_dup 0) ! 5192: (const_int -1)))])] ! 5193: "DATA_REG_P (operands[0])" ! 5194: "* ! 5195: { ! 5196: CC_STATUS_INIT; ! 5197: output_dbcc_and_branch (operands); ! 5198: return \"\"; ! 5199: }") ! 5200: ! 5201: ! 5202: ;; FPA multiply and add. ! 5203: (define_insn "" ! 5204: [(set (match_operand:DF 0 "register_operand" "=x,y,y") ! 5205: (plus:DF (mult:DF (match_operand:DF 1 "general_operand" "%x,dmF,y") ! 5206: (match_operand:DF 2 "general_operand" "xH,y,y")) ! 5207: (match_operand:DF 3 "general_operand" "xH,y,dmF")))] ! 5208: "TARGET_FPA" ! 5209: "@ ! 5210: fpma%.d %1,%w2,%w3,%0 ! 5211: fpma%.d %x1,%x2,%x3,%0 ! 5212: fpma%.d %x1,%x2,%x3,%0") ! 5213: ! 5214: (define_insn "" ! 5215: [(set (match_operand:SF 0 "register_operand" "=x,y,y") ! 5216: (plus:SF (mult:SF (match_operand:SF 1 "general_operand" "%x,ydmF,y") ! 5217: (match_operand:SF 2 "general_operand" "xH,y,ydmF")) ! 5218: (match_operand:SF 3 "general_operand" "xH,ydmF,ydmF")))] ! 5219: "TARGET_FPA" ! 5220: "@ ! 5221: fpma%.s %1,%w2,%w3,%0 ! 5222: fpma%.s %1,%2,%3,%0 ! 5223: fpma%.s %1,%2,%3,%0") ! 5224: ! 5225: ;; FPA Multiply and subtract ! 5226: (define_insn "" ! 5227: [(set (match_operand:DF 0 "register_operand" "=x,y,y") ! 5228: (minus:DF (match_operand:DF 1 "general_operand" "xH,rmF,y") ! 5229: (mult:DF (match_operand:DF 2 "general_operand" "%xH,y,y") ! 5230: (match_operand:DF 3 "general_operand" "x,y,rmF"))))] ! 5231: "TARGET_FPA" ! 5232: "@ ! 5233: fpms%.d %3,%w2,%w1,%0 ! 5234: fpms%.d %x3,%2,%x1,%0 ! 5235: fpms%.d %x3,%2,%x1,%0") ! 5236: ! 5237: (define_insn "" ! 5238: [(set (match_operand:SF 0 "register_operand" "=x,y,y") ! 5239: (minus:SF (match_operand:SF 1 "general_operand" "xH,rmF,yrmF") ! 5240: (mult:SF (match_operand:SF 2 "general_operand" "%xH,rmF,y") ! 5241: (match_operand:SF 3 "general_operand" "x,y,yrmF"))))] ! 5242: "TARGET_FPA" ! 5243: "@ ! 5244: fpms%.s %3,%w2,%w1,%0 ! 5245: fpms%.s %3,%2,%1,%0 ! 5246: fpms%.s %3,%2,%1,%0") ! 5247: ! 5248: (define_insn "" ! 5249: [(set (match_operand:DF 0 "register_operand" "=x,y,y") ! 5250: (minus:DF (mult:DF (match_operand:DF 1 "general_operand" "%xH,y,y") ! 5251: (match_operand:DF 2 "general_operand" "x,y,rmF")) ! 5252: (match_operand:DF 3 "general_operand" "xH,rmF,y")))] ! 5253: "TARGET_FPA" ! 5254: "@ ! 5255: fpmr%.d %2,%w1,%w3,%0 ! 5256: fpmr%.d %x2,%1,%x3,%0 ! 5257: fpmr%.d %x2,%1,%x3,%0") ! 5258: ! 5259: (define_insn "" ! 5260: [(set (match_operand:SF 0 "register_operand" "=x,y,y") ! 5261: (minus:SF (mult:SF (match_operand:SF 1 "general_operand" "%xH,rmF,y") ! 5262: (match_operand:SF 2 "general_operand" "x,y,yrmF")) ! 5263: (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))] ! 5264: "TARGET_FPA" ! 5265: "@ ! 5266: fpmr%.s %2,%w1,%w3,%0 ! 5267: fpmr%.s %x2,%1,%x3,%0 ! 5268: fpmr%.s %x2,%1,%x3,%0") ! 5269: ! 5270: ;; FPA Add and multiply ! 5271: (define_insn "" ! 5272: [(set (match_operand:DF 0 "register_operand" "=x,y,y") ! 5273: (mult:DF (plus:DF (match_operand:DF 1 "general_operand" "%xH,y,y") ! 5274: (match_operand:DF 2 "general_operand" "x,y,rmF")) ! 5275: (match_operand:DF 3 "general_operand" "xH,rmF,y")))] ! 5276: "TARGET_FPA" ! 5277: "@ ! 5278: fpam%.d %2,%w1,%w3,%0 ! 5279: fpam%.d %x2,%1,%x3,%0 ! 5280: fpam%.d %x2,%1,%x3,%0") ! 5281: ! 5282: (define_insn "" ! 5283: [(set (match_operand:SF 0 "register_operand" "=x,y,y") ! 5284: (mult:SF (plus:SF (match_operand:SF 1 "general_operand" "%xH,rmF,y") ! 5285: (match_operand:SF 2 "general_operand" "x,y,yrmF")) ! 5286: (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))] ! 5287: "TARGET_FPA" ! 5288: "@ ! 5289: fpam%.s %2,%w1,%w3,%0 ! 5290: fpam%.s %x2,%1,%x3,%0 ! 5291: fpam%.s %x2,%1,%x3,%0") ! 5292: ! 5293: ;;FPA Subtract and multiply ! 5294: (define_insn "" ! 5295: [(set (match_operand:DF 0 "register_operand" "=x,y,y") ! 5296: (mult:DF (minus:DF (match_operand:DF 1 "general_operand" "xH,y,y") ! 5297: (match_operand:DF 2 "general_operand" "x,y,rmF")) ! 5298: (match_operand:DF 3 "general_operand" "xH,rmF,y")))] ! 5299: "TARGET_FPA" ! 5300: "@ ! 5301: fpsm%.d %2,%w1,%w3,%0 ! 5302: fpsm%.d %x2,%1,%x3,%0 ! 5303: fpsm%.d %x2,%1,%x3,%0") ! 5304: ! 5305: (define_insn "" ! 5306: [(set (match_operand:DF 0 "register_operand" "=x,y,y") ! 5307: (mult:DF (match_operand:DF 1 "general_operand" "xH,rmF,y") ! 5308: (minus:DF (match_operand:DF 2 "general_operand" "xH,y,y") ! 5309: (match_operand:DF 3 "general_operand" "x,y,rmF"))))] ! 5310: "TARGET_FPA" ! 5311: "@ ! 5312: fpsm%.d %3,%w2,%w1,%0 ! 5313: fpsm%.d %x3,%2,%x1,%0 ! 5314: fpsm%.d %x3,%2,%x1,%0") ! 5315: ! 5316: (define_insn "" ! 5317: [(set (match_operand:SF 0 "register_operand" "=x,y,y") ! 5318: (mult:SF (minus:SF (match_operand:SF 1 "general_operand" "xH,rmF,y") ! 5319: (match_operand:SF 2 "general_operand" "x,y,yrmF")) ! 5320: (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))] ! 5321: "TARGET_FPA" ! 5322: "@ ! 5323: fpsm%.s %2,%w1,%w3,%0 ! 5324: fpsm%.s %x2,%1,%x3,%0 ! 5325: fpsm%.s %x2,%1,%x3,%0") ! 5326: ! 5327: (define_insn "" ! 5328: [(set (match_operand:SF 0 "register_operand" "=x,y,y") ! 5329: (mult:SF (match_operand:SF 1 "general_operand" "xH,rmF,yrmF") ! 5330: (minus:SF (match_operand:SF 2 "general_operand" "xH,rmF,y") ! 5331: (match_operand:SF 3 "general_operand" "x,y,yrmF"))))] ! 5332: "TARGET_FPA" ! 5333: "@ ! 5334: fpsm%.s %3,%w2,%w1,%0 ! 5335: fpsm%.s %x3,%2,%x1,%0 ! 5336: fpsm%.s %x3,%2,%x1,%0") ! 5337: ! 5338: (define_insn "tstxf" ! 5339: [(set (cc0) ! 5340: (match_operand:XF 0 "nonimmediate_operand" "fm"))] ! 5341: "TARGET_68881" ! 5342: "* ! 5343: { ! 5344: cc_status.flags = CC_IN_68881; ! 5345: return \"ftst%.x %0\"; ! 5346: }") ! 5347: ! 5348: ! 5349: (define_expand "cmpxf" ! 5350: [(set (cc0) ! 5351: (compare (match_operand:XF 0 "general_operand" "f,mG") ! 5352: (match_operand:XF 1 "general_operand" "fmG,f")))] ! 5353: "TARGET_68881" ! 5354: " ! 5355: { ! 5356: if (CONSTANT_P (operands[0])) ! 5357: operands[0] = force_const_mem (XFmode, operands[0]); ! 5358: if (CONSTANT_P (operands[1])) ! 5359: operands[1] = force_const_mem (XFmode, operands[1]); ! 5360: }") ! 5361: ! 5362: (define_insn "" ! 5363: [(set (cc0) ! 5364: (compare (match_operand:XF 0 "nonimmediate_operand" "f,mG") ! 5365: (match_operand:XF 1 "nonimmediate_operand" "fmG,f")))] ! 5366: "TARGET_68881" ! 5367: "* ! 5368: { ! 5369: cc_status.flags = CC_IN_68881; ! 5370: #ifdef SGS_CMP_ORDER ! 5371: if (REG_P (operands[0])) ! 5372: { ! 5373: if (REG_P (operands[1])) ! 5374: return \"fcmp%.x %0,%1\"; ! 5375: else ! 5376: return \"fcmp%.x %0,%f1\"; ! 5377: } ! 5378: cc_status.flags |= CC_REVERSED; ! 5379: return \"fcmp%.x %1,%f0\"; ! 5380: #else ! 5381: if (REG_P (operands[0])) ! 5382: { ! 5383: if (REG_P (operands[1])) ! 5384: return \"fcmp%.x %1,%0\"; ! 5385: else ! 5386: return \"fcmp%.x %f1,%0\"; ! 5387: } ! 5388: cc_status.flags |= CC_REVERSED; ! 5389: return \"fcmp%.x %f0,%1\"; ! 5390: #endif ! 5391: }") ! 5392: ! 5393: (define_insn "extendsfxf2" ! 5394: [(set (match_operand:XF 0 "general_operand" "=fm,f") ! 5395: (float_extend:XF (match_operand:SF 1 "general_operand" "f,m")))] ! 5396: "TARGET_68881" ! 5397: "* ! 5398: { ! 5399: if (FP_REG_P (operands[0]) && FP_REG_P (operands[1])) ! 5400: { ! 5401: if (REGNO (operands[0]) == REGNO (operands[1])) ! 5402: { ! 5403: /* Extending float to double in an fp-reg is a no-op. ! 5404: NOTICE_UPDATE_CC has already assumed that the ! 5405: cc will be set. So cancel what it did. */ ! 5406: cc_status = cc_prev_status; ! 5407: return \"\"; ! 5408: } ! 5409: return \"f%$move%.x %1,%0\"; ! 5410: } ! 5411: if (FP_REG_P (operands[0])) ! 5412: return \"f%$move%.s %f1,%0\"; ! 5413: return \"fmove%.x %f1,%0\"; ! 5414: }") ! 5415: ! 5416: ! 5417: (define_insn "extenddfxf2" ! 5418: [(set (match_operand:XF 0 "general_operand" "=fm,f") ! 5419: (float_extend:XF ! 5420: (match_operand:DF 1 "general_operand" "f,m")))] ! 5421: "TARGET_68881" ! 5422: "* ! 5423: { ! 5424: if (FP_REG_P (operands[0]) && FP_REG_P (operands[1])) ! 5425: { ! 5426: if (REGNO (operands[0]) == REGNO (operands[1])) ! 5427: { ! 5428: /* Extending float to double in an fp-reg is a no-op. ! 5429: NOTICE_UPDATE_CC has already assumed that the ! 5430: cc will be set. So cancel what it did. */ ! 5431: cc_status = cc_prev_status; ! 5432: return \"\"; ! 5433: } ! 5434: return \"fmove%.x %1,%0\"; ! 5435: } ! 5436: if (FP_REG_P (operands[0])) ! 5437: return \"f%&move%.d %f1,%0\"; ! 5438: return \"fmove%.x %f1,%0\"; ! 5439: }") ! 5440: ! 5441: (define_insn "truncxfdf2" ! 5442: [(set (match_operand:DF 0 "general_operand" "=m,!r") ! 5443: (float_truncate:DF ! 5444: (match_operand:XF 1 "general_operand" "f,f")))] ! 5445: "TARGET_68881" ! 5446: "* ! 5447: { ! 5448: if (REG_P (operands[0])) ! 5449: { ! 5450: output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands); ! 5451: operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); ! 5452: return \"move%.l %+,%0\"; ! 5453: } ! 5454: return \"fmove%.d %f1,%0\"; ! 5455: }") ! 5456: ! 5457: (define_insn "truncxfsf2" ! 5458: [(set (match_operand:SF 0 "general_operand" "=dm") ! 5459: (float_truncate:SF ! 5460: (match_operand:XF 1 "general_operand" "f")))] ! 5461: "TARGET_68881" ! 5462: "fmove%.s %f1,%0") ! 5463: ! 5464: (define_insn "floatsixf2" ! 5465: [(set (match_operand:XF 0 "general_operand" "=f") ! 5466: (float:XF (match_operand:SI 1 "general_operand" "dmi")))] ! 5467: "TARGET_68881" ! 5468: "fmove%.l %1,%0") ! 5469: ! 5470: (define_insn "floathixf2" ! 5471: [(set (match_operand:XF 0 "general_operand" "=f") ! 5472: (float:XF (match_operand:HI 1 "general_operand" "dmn")))] ! 5473: "TARGET_68881" ! 5474: "fmove%.w %1,%0") ! 5475: ! 5476: (define_insn "floatqixf2" ! 5477: [(set (match_operand:XF 0 "general_operand" "=f") ! 5478: (float:XF (match_operand:QI 1 "general_operand" "dmn")))] ! 5479: "TARGET_68881" ! 5480: "fmove%.b %1,%0") ! 5481: ! 5482: (define_insn "ftruncxf2" ! 5483: [(set (match_operand:XF 0 "general_operand" "=f") ! 5484: (fix:XF (match_operand:XF 1 "general_operand" "fFm")))] ! 5485: "TARGET_68881" ! 5486: "* ! 5487: { ! 5488: if (FP_REG_P (operands[1])) ! 5489: return \"fintrz%.x %f1,%0\"; ! 5490: return \"fintrz%.x %f1,%0\"; ! 5491: }") ! 5492: ! 5493: (define_insn "fixxfqi2" ! 5494: [(set (match_operand:QI 0 "general_operand" "=dm") ! 5495: (fix:QI (match_operand:XF 1 "general_operand" "f")))] ! 5496: "TARGET_68881" ! 5497: "fmove%.b %1,%0") ! 5498: ! 5499: (define_insn "fixxfhi2" ! 5500: [(set (match_operand:HI 0 "general_operand" "=dm") ! 5501: (fix:HI (match_operand:XF 1 "general_operand" "f")))] ! 5502: "TARGET_68881" ! 5503: "fmove%.w %1,%0") ! 5504: ! 5505: (define_insn "fixxfsi2" ! 5506: [(set (match_operand:SI 0 "general_operand" "=dm") ! 5507: (fix:SI (match_operand:XF 1 "general_operand" "f")))] ! 5508: "TARGET_68881" ! 5509: "fmove%.l %1,%0") ! 5510: ! 5511: (define_expand "addxf3" ! 5512: [(set (match_operand:XF 0 "general_operand" "") ! 5513: (plus:XF (match_operand:XF 1 "general_operand" "") ! 5514: (match_operand:XF 2 "general_operand" "")))] ! 5515: "TARGET_68881" ! 5516: " ! 5517: { ! 5518: if (CONSTANT_P (operands[1])) ! 5519: operands[1] = force_const_mem (XFmode, operands[1]); ! 5520: if (CONSTANT_P (operands[2])) ! 5521: operands[2] = force_const_mem (XFmode, operands[2]); ! 5522: }") ! 5523: ! 5524: (define_insn "" ! 5525: [(set (match_operand:XF 0 "general_operand" "=f") ! 5526: (plus:XF (match_operand:XF 1 "nonimmediate_operand" "%0") ! 5527: (match_operand:XF 2 "nonimmediate_operand" "fmG")))] ! 5528: "TARGET_68881" ! 5529: "* ! 5530: { ! 5531: if (REG_P (operands[2])) ! 5532: return \"fadd%.x %2,%0\"; ! 5533: return \"fadd%.x %f2,%0\"; ! 5534: }") ! 5535: ! 5536: (define_expand "subxf3" ! 5537: [(set (match_operand:XF 0 "general_operand" "") ! 5538: (minus:XF (match_operand:XF 1 "general_operand" "") ! 5539: (match_operand:XF 2 "general_operand" "")))] ! 5540: "TARGET_68881" ! 5541: " ! 5542: { ! 5543: if (CONSTANT_P (operands[1])) ! 5544: operands[1] = force_const_mem (XFmode, operands[1]); ! 5545: if (CONSTANT_P (operands[2])) ! 5546: operands[2] = force_const_mem (XFmode, operands[2]); ! 5547: }") ! 5548: ! 5549: (define_insn "" ! 5550: [(set (match_operand:XF 0 "general_operand" "=f") ! 5551: (minus:XF (match_operand:XF 1 "nonimmediate_operand" "0") ! 5552: (match_operand:XF 2 "nonimmediate_operand" "fmG")))] ! 5553: "TARGET_68881" ! 5554: "* ! 5555: { ! 5556: if (REG_P (operands[2])) ! 5557: return \"fsub%.x %2,%0\"; ! 5558: return \"fsub%.x %f2,%0\"; ! 5559: }") ! 5560: ! 5561: (define_expand "mulxf3" ! 5562: [(set (match_operand:XF 0 "general_operand" "") ! 5563: (mult:XF (match_operand:XF 1 "general_operand" "") ! 5564: (match_operand:XF 2 "general_operand" "")))] ! 5565: "TARGET_68881" ! 5566: " ! 5567: { ! 5568: if (CONSTANT_P (operands[1])) ! 5569: operands[1] = force_const_mem (XFmode, operands[1]); ! 5570: if (CONSTANT_P (operands[2])) ! 5571: operands[2] = force_const_mem (XFmode, operands[2]); ! 5572: }") ! 5573: ! 5574: (define_insn "" ! 5575: [(set (match_operand:XF 0 "general_operand" "=f") ! 5576: (mult:XF (match_operand:XF 1 "nonimmediate_operand" "%0") ! 5577: (match_operand:XF 2 "nonimmediate_operand" "fmG")))] ! 5578: "TARGET_68881" ! 5579: "* ! 5580: { ! 5581: if (REG_P (operands[2])) ! 5582: return \"fmul%.x %2,%0\"; ! 5583: return \"fmul%.x %f2,%0\"; ! 5584: }") ! 5585: ! 5586: (define_expand "divxf3" ! 5587: [(set (match_operand:XF 0 "general_operand" "") ! 5588: (div:XF (match_operand:XF 1 "general_operand" "") ! 5589: (match_operand:XF 2 "general_operand" "")))] ! 5590: "TARGET_68881" ! 5591: " ! 5592: { ! 5593: if (CONSTANT_P (operands[1])) ! 5594: operands[1] = force_const_mem (XFmode, operands[1]); ! 5595: if (CONSTANT_P (operands[2])) ! 5596: operands[2] = force_const_mem (XFmode, operands[2]); ! 5597: }") ! 5598: ! 5599: (define_insn "" ! 5600: [(set (match_operand:XF 0 "general_operand" "=f") ! 5601: (div:XF (match_operand:XF 1 "nonimmediate_operand" "0") ! 5602: (match_operand:XF 2 "nonimmediate_operand" "fmG")))] ! 5603: "TARGET_68881" ! 5604: "* ! 5605: { ! 5606: if (REG_P (operands[2])) ! 5607: return \"fdiv%.x %2,%0\"; ! 5608: return \"fdiv%.x %f2,%0\"; ! 5609: }") ! 5610: ! 5611: (define_insn "negxf2" ! 5612: [(set (match_operand:XF 0 "general_operand" "=f") ! 5613: (neg:XF (match_operand:XF 1 "nonimmediate_operand" "fmF")))] ! 5614: "TARGET_68881" ! 5615: "* ! 5616: { ! 5617: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) ! 5618: return \"fneg%.x %1,%0\"; ! 5619: return \"fneg%.x %f1,%0\"; ! 5620: }") ! 5621: ! 5622: (define_insn "absxf2" ! 5623: [(set (match_operand:XF 0 "general_operand" "=f") ! 5624: (abs:XF (match_operand:XF 1 "nonimmediate_operand" "fmF")))] ! 5625: "TARGET_68881" ! 5626: "* ! 5627: { ! 5628: if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) ! 5629: return \"fabs%.x %1,%0\"; ! 5630: return \"fabs%.x %f1,%0\"; ! 5631: }") ! 5632: ! 5633: (define_insn "sqrtxf2" ! 5634: [(set (match_operand:XF 0 "general_operand" "=f") ! 5635: (sqrt:XF (match_operand:DF 1 "nonimmediate_operand" "fm")))] ! 5636: "TARGET_68881" ! 5637: "* ! 5638: { ! 5639: return \"fsqrt%.x %1,%0\"; ! 5640: }")
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.