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