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