159693Selan;;- Machine description for GNU compiler 259693Selan;;- Motorola 68000 Version 359693Selan;; Copyright (C) 1987, 1988 Free Software Foundation, Inc. 459693Selan 559693Selan;; This file is part of GNU CC. 659693Selan 759693Selan;; GNU CC is free software; you can redistribute it and/or modify 859693Selan;; it under the terms of the GNU General Public License as published by 959693Selan;; the Free Software Foundation; either version 2, or (at your option) 1059693Selan;; any later version. 1159693Selan 1259693Selan;; GNU CC is distributed in the hope that it will be useful, 1359693Selan;; but WITHOUT ANY WARRANTY; without even the implied warranty of 1459693Selan;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1559693Selan;; GNU General Public License for more details. 1659693Selan 1759693Selan;; You should have received a copy of the GNU General Public License 1859693Selan;; along with GNU CC; see the file COPYING. If not, write to 1959693Selan;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 2059693Selan 2159693Selan 2259693Selan;;- instruction definitions 2359693Selan 2459693Selan;;- @@The original PO technology requires these to be ordered by speed, 2559693Selan;;- @@ so that assigner will pick the fastest. 2659693Selan 2759693Selan;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. 2859693Selan 2959693Selan;;- When naming insn's (operand 0 of define_insn) be careful about using 3059693Selan;;- names from other targets machine descriptions. 3159693Selan 3259693Selan;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code 3359693Selan;;- updates for most instructions. 3459693Selan 3559693Selan;;- Operand classes for the register allocator: 3659693Selan;;- 'a' one of the address registers can be used. 3759693Selan;;- 'd' one of the data registers can be used. 3859693Selan;;- 'f' one of the m68881 registers can be used 3959693Selan;;- 'r' either a data or an address register can be used. 4059693Selan;;- 'x' if one of the Sun FPA registers 4159693Selan;;- 'y' if one of the Low Sun FPA registers (fpa0-fpa15). 4259693Selan 4359693Selan;;- Immediate Floating point operator constraints 4459693Selan;;- 'G' a floating point constant that is *NOT* one of the standard 4559693Selan;; 68881 constant values (to force calling output_move_const_double 4659693Selan;; to get it from rom if it is a 68881 constant). 4759693Selan;;- 'H' one of the standard FPA constant values 4859693Selan;; 4959693Selan;; See the functions standard_XXX_constant_p in output-m68k.c for more 5059693Selan;; info. 5159693Selan 5259693Selan;;- Immediate integer operand constraints: 5359693Selan;;- 'I' 1 .. 8 5459693Selan;;- 'J' -32768 .. 32767 5559693Selan;;- 'K' all integers EXCEPT -128 .. 127 5659693Selan;;- 'L' -8 .. -1 5759693Selan 5859693Selan;;- Assembler specs: 5959693Selan;;- "%." size separator ("." or "") move%.l d0,d1 6059693Selan;;- "%#" immediate separator ("#" or "") move%.l %#0,d0 6159693Selan;;- "%-" push operand "sp@-" move%.l d0,%- 6259693Selan;;- "%+" pop operand "sp@+" move%.l d0,%+ 6359693Selan;;- "%@" top of stack "sp@" move%.l d0,%@ 6459693Selan;;- "%!" fpcr register 6559693Selan;;- "%$" single-precision fp specifier ("s" or "") f%$add.x fp0,fp1 6659693Selan;;- "%&" double-precision fp specifier ("d" or "") f%&add.x fp0,fp1 6759693Selan 6859693Selan;;- Information about 68040 port. 6959693Selan 7059693Selan;;- The 68040 executes all 68030 and 68881/2 instructions, but some must 7159693Selan;;- be emulated in software by the OS. It is faster to avoid these 7259693Selan;;- instructions and issue a library call rather than trapping into 7359693Selan;;- the kernel. The affected instructions are fintrz and fscale. The 7459693Selan;;- TARGET_68040 flag turns the use of the opcodes off. 7559693Selan 7659693Selan;;- The '040 also implements a set of new floating-point instructions 7759693Selan;;- which specify the rounding precision in the opcode. This finally 7859693Selan;;- permit the 68k series to be truly IEEE compliant, and solves all 7959693Selan;;- issues of excess precision accumulating in the extended registers. 8059693Selan;;- By default, GCC does not use these instructions, since such code will 8159693Selan;;- not run on an '030. To use these instructions, use the -m68040-only 8259693Selan;;- switch. By changing TARGET_DEFAULT to include TARGET_68040_ONLY, 8359693Selan;;- you can make these instructions the default. 8459693Selan 8559693Selan;;- These new instructions aren't directly in the md. They are brought 8659693Selan;;- into play by defining "%$" and "%&" to expand to "s" and "d" rather 8759693Selan;;- than "". 8859693Selan 8959693Selan 9059693Selan;;- FPA port explanation: 9159693Selan 9259693Selan;;- Usage of the Sun FPA and the 68881 together 9359693Selan 9459693Selan;;- The current port of gcc to the sun fpa disallows use of the m68881 9559693Selan;;- instructions completely if code is targeted for the fpa. This is 9659693Selan;;- for the following reasons: 9759693Selan 9859693Selan;;- 1) Expressing the preference hierarchy (ie. use the fpa if you 9959693Selan;;- can, the 68881 otherwise, and data registers only if you are 10059693Selan;;- forced to it) is a bitch with the current constraint scheme, 10159693Selan;;- especially since it would have to work for any combination of 10259693Selan;;- -mfpa, -m68881. 10359693Selan 10459693Selan;;- 2) There are no instructions to move between the two types of 10559693Selan;;- registers; the stack must be used as an intermediary. 10659693Selan 10759693Selan;;- It could indeed be done; I think the best way would be to have 10859693Selan;;- separate patterns for TARGET_FPA (which implies a 68881), 10959693Selan;;- TARGET_68881, and no floating point co-processor. Use 11059693Selan;;- define_expands for all of the named instruction patterns, and 11159693Selan;;- include code in the FPA instruction to deal with the 68881 with 11259693Selan;;- preferences specifically set to favor the fpa. Some of this has 11359693Selan;;- already been done: 11459693Selan;;- 11559693Selan;;- 1) Separation of most of the patterns out into a TARGET_FPA 11659693Selan;;- case and a TARGET_68881 case (the exceptions are the patterns 11759693Selan;;- which would need one define_expand and three define_insn's under 11859693Selan;;- it (with a lot of duplicate code between them) to replace the 11959693Selan;;- current single define_insn. These are mov{[ds]f,[ds]i} and the 12059693Selan;;- first two patterns in the md. 12159693Selan;;- 12259693Selan;;- Some would still have to be done: 12359693Selan;;- 12459693Selan;;- 1) Add code to the fpa patterns which correspond to 68881 12559693Selan;;- patterns to deal with the 68881 case (including preferences!). 12659693Selan;;- What you might actually do here is combine the fpa and 68881 code 12759693Selan;;- back together into one pattern for those instructions where it's 12859693Selan;;- absolutely necessary and save yourself some duplicate code. I'm 12959693Selan;;- not completely sure as to whether you could get away with doing 13059693Selan;;- this only for the mov* insns, or if you'd have to do it for all 13159693Selan;;- named insns. 13259693Selan;;- 2) Add code to the mov{[ds]f,[ds]i} instructions to handle 13359693Selan;;- moving between fpa regs and 68881 regs. 13459693Selan 13559693Selan;;- Since the fpa is more powerful than the 68881 and also has more 13659693Selan;;- registers, and since I think the resultant md would be medium ugly 13759693Selan;;- (lot's of duplicate code, ugly constraint strings), I elected not 13859693Selan;;- to do this change. 13959693Selan 14059693Selan;;- Another reason why someone *might* want to do the change is to 14159693Selan;;- control which register classes are accessed in a slightly cleaner 14259693Selan;;- way than I have. See the blurb on CONDITIONAL_REGISTER_USAGE in 14359693Selan;;- the internals manual. 14459693Selan 14559693Selan;;- Yet another reason why someone might want to do this change is to 14659693Selan;;- allow use of some of the 68881 insns which have no equivalent on 14759693Selan;;- the fpa. The sqrt instruction comes fairly quickly to mind. 14859693Selan 14959693Selan;;- If this is ever done, don't forget to change sun3.h so that 15059693Selan;;- it *will* define __HAVE_68881__ when the FPA is in use. 15159693Selan 15259693Selan;;- Condition code hack 15359693Selan 15459693Selan;;- When a floating point compare is done in the fpa, the resulting 15559693Selan;;- condition codes are left in the fpastatus register. The values in 15659693Selan;;- this register must be moved into the 68000 cc register before any 15759693Selan;;- jump is executed. Once this has been done, regular jump 15859693Selan;;- instructions are fine (ie. floating point jumps are not necessary. 15959693Selan;;- They are only done if the cc is in the 68881). 16059693Selan 16159693Selan;;- The instructions that move the fpastatus register to the 68000 16259693Selan;;- register clobber a data register (the move cannot be done direct). 16359693Selan;;- These instructions might be bundled either with the compare 16459693Selan;;- instruction, or the branch instruction. If we were using both the 16559693Selan;;- fpa and the 68881 together, we would wish to only mark the 16659693Selan;;- register clobbered if we were doing the compare in the fpa, but I 16759693Selan;;- think that that decision (whether to clobber the register or not) 16859693Selan;;- must be done before register allocation (makes sense) and hence we 16959693Selan;;- can't know if the floating point compare will be done in the fpa 17059693Selan;;- or the fp. So whenever we are asked for code that uses the fpa, 17159693Selan;;- we will mark a data register as clobbered. This is reasonable, as 17259693Selan;;- almost all floating point compare operations done with fpa code 17359693Selan;;- enabled will be done in the fpa. It's even more reasonable since 17459693Selan;;- we decided to make the 68881 and the fpa mutually exclusive. 17559693Selan 17659693Selan;;- We place to code to move the fpastatus register inside of a 17759693Selan;;- define_expand so that we can do it conditionally based on whether 17859693Selan;;- we are targeting an fpa or not. 17959693Selan 18059693Selan;;- This still leaves us with the question of where we wish to put the 18159693Selan;;- code to move the fpastatus reg. If we put it in the compare 18259693Selan;;- instruction, we can restrict the clobbering of the register to 18359693Selan;;- floating point compares, but we can't take advantage of floating 18459693Selan;;- point subtracts & etc. that alter the fpastatus register. If we 18559693Selan;;- put it in the branch instruction, all branches compiled with fpa 18659693Selan;;- code enabled will clobber a data register, but we will be able to 18759693Selan;;- take advantage of fpa subtracts. This balance favors putting the 18859693Selan;;- code in with the compare instruction. 18959693Selan 19059693Selan;;- Note that if some enterprising hacker should decide to switch 19159693Selan;;- this, he'll need to modify the code in NOTICE_UPDATE_CC. 19259693Selan 19359693Selan;;- Usage of the top 16 fpa registers 19459693Selan 19559693Selan;;- The only locations which we may transfer fpa registers 16-31 from 19659693Selan;;- or to are the fpa registers 0-15. (68000 registers and memory 19759693Selan;;- locations are impossible). This causes problems in gcc, which 19859693Selan;;- assumes that mov?? instructions require no additional registers 19959693Selan;;- (see section 11.7) and since floating point moves *must* be 20059693Selan;;- supported into general registers (see section 12.3 under 20159693Selan;;- HARD_REGNO_OK_FOR_MODE_P) from anywhere. 20259693Selan 20359693Selan;;- My solution was to reserve fpa0 for moves into or out of these top 20459693Selan;;- 16 registers and to disparage the choice to reload into or out of 20559693Selan;;- these registers as much as I could. That alternative is always 20659693Selan;;- last in the list, so it will not be used unless all else fails. I 20759693Selan;;- will note that according to my current information, sun's compiler 20859693Selan;;- doesn't use these top 16 registers at all. 20959693Selan 21059693Selan;;- There is another possible way to do it. I *believe* that if you 21159693Selan;;- make absolutely sure that the code will not be executed in the 21259693Selan;;- reload pass, you can support the mov?? names with define_expands 21359693Selan;;- which require new registers. This may be possible by the 21459693Selan;;- appropriate juggling of constraints. I may come back to this later. 21559693Selan 21659693Selan;;- Usage of constant RAM 21759693Selan 21859693Selan;;- This has been handled correctly (I believe) but the way I've done 21959693Selan;;- it could use a little explanation. The constant RAM can only be 22059693Selan;;- accessed when the instruction is in "command register" mode. 22159693Selan;;- "command register" mode means that no accessing of memory or the 22259693Selan;;- 68000 registers is being done. This can be expressed easily in 22359693Selan;;- constraints, so generally the mode of the instruction is 22459693Selan;;- determined by a branch off of which_alternative. In outputting 22559693Selan;;- instructions, a 'w' means to output an access to the constant ram 22659693Selan;;- (if the arg is CONST_DOUBLE and is one of the available 22759693Selan;;- constants), and 'x' means to output a register pair (if the arg is 22859693Selan;;- a 68000 register) and a 'y' is the combination of the above two 22959693Selan;;- processes. You use a 'y' in two operand DF instructions where you 23059693Selan;;- *know* the other operand is an fpa register, you use an 'x' in DF 23159693Selan;;- instructions where the arg might be a 68000 register and the 23259693Selan;;- instruction is *not* in "command register" mode, and you use a 'w' 23359693Selan;;- in two situations: 1) The instruction *is* in command register 23459693Selan;;- mode (and hence won't be accessing 68000 registers), or 2) The 23559693Selan;;- instruction is a two operand SF instruction where you know the 23659693Selan;;- other operand is an fpa register. 23759693Selan 23859693Selan;;- Optimization issues 23959693Selan 24059693Selan;;- I actually think that I've included all of the fpa instructions 24159693Selan;;- that should be included. Note that if someone is interested in 24259693Selan;;- doing serious floating point work on the sun fpa, I would advise 24359693Selan;;- the use of the "asm" instruction in gcc to allow you to use the 24459693Selan;;- sin, cos, and exponential functions on the fpa board. 24559693Selan 24659693Selan;;- END FPA Explanation Section. 24759693Selan 24859693Selan 24959693Selan;;- Some of these insn's are composites of several m68000 op codes. 25059693Selan;;- The assembler (or final @@??) insures that the appropriate one is 25159693Selan;;- selected. 25259693Selan 25359693Selan(define_insn "" 25459693Selan [(set (match_operand:DF 0 "push_operand" "=m") 25559693Selan (match_operand:DF 1 "general_operand" "ro<>fyE"))] 25659693Selan "" 25759693Selan "* 25859693Selan{ 25959693Selan if (FP_REG_P (operands[1])) 26059693Selan return \"fmove%.d %f1,%0\"; 26159693Selan if (FPA_REG_P (operands[1])) 26259693Selan return \"fpmove%.d %1, %x0\"; 26359693Selan return output_move_double (operands); 26459693Selan}") 26559693Selan 26659693Selan(define_insn "" 26759693Selan [(set (match_operand:DI 0 "push_operand" "=m") 26859693Selan (match_operand:DI 1 "general_operand" "ro<>Fy"))] 26959693Selan "" 27059693Selan "* 27159693Selan{ 27259693Selan return output_move_double (operands); 27359693Selan}") 27459693Selan 27559693Selan;; We don't want to allow a constant operand for test insns because 27659693Selan;; (set (cc0) (const_int foo)) has no mode information. Such insns will 27759693Selan;; be folded while optimizing anyway. 27859693Selan(define_insn "tstsi" 27959693Selan [(set (cc0) 28059693Selan (match_operand:SI 0 "nonimmediate_operand" "rm"))] 28159693Selan "" 28259693Selan "* 28359693Selan{ 28459693Selan#ifdef ISI_OV 28559693Selan /* ISI's assembler fails to handle tstl a0. */ 28659693Selan if (! ADDRESS_REG_P (operands[0])) 28759693Selan#else 28859693Selan if (TARGET_68020 || ! ADDRESS_REG_P (operands[0])) 28959693Selan#endif 29059693Selan return \"tst%.l %0\"; 29159693Selan /* If you think that the 68020 does not support tstl a0, 29259693Selan reread page B-167 of the 68020 manual more carefully. */ 29359693Selan /* On an address reg, cmpw may replace cmpl. */ 29459693Selan#ifdef SGS_CMP_ORDER 29559693Selan return \"cmp%.w %0,%#0\"; 29659693Selan#else 29759693Selan return \"cmp%.w %#0,%0\"; 29859693Selan#endif 29959693Selan}") 30059693Selan 30159693Selan;; This can't use an address register, because comparisons 30259693Selan;; with address registers as second operand always test the whole word. 30359693Selan(define_insn "tsthi" 30459693Selan [(set (cc0) 30559693Selan (match_operand:HI 0 "nonimmediate_operand" "dm"))] 30659693Selan "" 30759693Selan "tst%.w %0") 30859693Selan 30959693Selan(define_insn "tstqi" 31059693Selan [(set (cc0) 31159693Selan (match_operand:QI 0 "nonimmediate_operand" "dm"))] 31259693Selan "" 31359693Selan "tst%.b %0") 31459693Selan 31559693Selan(define_expand "tstsf" 31659693Selan [(set (cc0) 31759693Selan (match_operand:SF 0 "general_operand" ""))] 31859693Selan "TARGET_68881 || TARGET_FPA" 31959693Selan " 32059693Selan{ 32159693Selan if (TARGET_FPA) 32259693Selan { 32359693Selan emit_insn (gen_tstsf_fpa (operands[0])); 32459693Selan DONE; 32559693Selan } 32659693Selan}") 32759693Selan 32859693Selan(define_insn "tstsf_fpa" 32959693Selan [(set (cc0) 33059693Selan (match_operand:SF 0 "general_operand" "xmdF")) 33159693Selan (clobber (match_scratch:SI 1 "=d"))] 33259693Selan "TARGET_FPA" 33359693Selan "fptst%.s %x0\;fpmove fpastatus,%1\;movw %1,cc") 33459693Selan 33559693Selan(define_insn "" 33659693Selan [(set (cc0) 33759693Selan (match_operand:SF 0 "general_operand" "fdm"))] 33859693Selan "TARGET_68881" 33959693Selan "* 34059693Selan{ 34159693Selan cc_status.flags = CC_IN_68881; 34259693Selan if (FP_REG_P (operands[0])) 34359693Selan return \"ftst%.x %0\"; 34459693Selan return \"ftst%.s %0\"; 34559693Selan}") 34659693Selan 34759693Selan(define_expand "tstdf" 34859693Selan [(set (cc0) 34959693Selan (match_operand:DF 0 "general_operand" ""))] 35059693Selan "TARGET_68881 || TARGET_FPA" 35159693Selan " 35259693Selan{ 35359693Selan if (TARGET_FPA) 35459693Selan { 35559693Selan emit_insn (gen_tstsf_fpa (operands[0])); 35659693Selan DONE; 35759693Selan } 35859693Selan}") 35959693Selan 36059693Selan(define_insn "tstdf_fpa" 36159693Selan [(set (cc0) 36259693Selan (match_operand:DF 0 "general_operand" "xrmF")) 36359693Selan (clobber (match_scratch:SI 1 "=d"))] 36459693Selan "TARGET_FPA" 36559693Selan "fptst%.d %x0\;fpmove fpastatus,%1\;movw %1,cc") 36659693Selan 36759693Selan(define_insn "" 36859693Selan [(set (cc0) 36959693Selan (match_operand:DF 0 "general_operand" "fm"))] 37059693Selan "TARGET_68881" 37159693Selan "* 37259693Selan{ 37359693Selan cc_status.flags = CC_IN_68881; 37459693Selan if (FP_REG_P (operands[0])) 37559693Selan return \"ftst%.x %0\"; 37659693Selan return \"ftst%.d %0\"; 37759693Selan}") 37859693Selan 37959693Selan;; compare instructions. 38059693Selan 38159693Selan;; A composite of the cmp, cmpa, & cmpi m68000 op codes. 38259693Selan(define_insn "cmpsi" 38359693Selan [(set (cc0) 38459693Selan (compare (match_operand:SI 0 "nonimmediate_operand" "rKs,mr,>") 38559693Selan (match_operand:SI 1 "general_operand" "mr,Ksr,>")))] 38659693Selan "" 38759693Selan "* 38859693Selan{ 38959693Selan if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 39059693Selan return \"cmpm%.l %1,%0\"; 39159693Selan if (REG_P (operands[1]) 39259693Selan || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) 39359693Selan { cc_status.flags |= CC_REVERSED; 39459693Selan#ifdef SGS_CMP_ORDER 39559693Selan return \"cmp%.l %d1,%d0\"; 39659693Selan#else 39759693Selan return \"cmp%.l %d0,%d1\"; 39859693Selan#endif 39959693Selan } 40059693Selan#ifdef SGS_CMP_ORDER 40159693Selan return \"cmp%.l %d0,%d1\"; 40259693Selan#else 40359693Selan return \"cmp%.l %d1,%d0\"; 40459693Selan#endif 40559693Selan}") 40659693Selan 40759693Selan(define_insn "cmphi" 40859693Selan [(set (cc0) 40959693Selan (compare (match_operand:HI 0 "nonimmediate_operand" "rnm,d,n,m") 41059693Selan (match_operand:HI 1 "general_operand" "d,rnm,m,n")))] 41159693Selan "" 41259693Selan "* 41359693Selan{ 41459693Selan if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 41559693Selan return \"cmpm%.w %1,%0\"; 41659693Selan if ((REG_P (operands[1]) && !ADDRESS_REG_P (operands[1])) 41759693Selan || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) 41859693Selan { cc_status.flags |= CC_REVERSED; 41959693Selan#ifdef SGS_CMP_ORDER 42059693Selan return \"cmp%.w %d1,%d0\"; 42159693Selan#else 42259693Selan return \"cmp%.w %d0,%d1\"; 42359693Selan#endif 42459693Selan } 42559693Selan#ifdef SGS_CMP_ORDER 42659693Selan return \"cmp%.w %d0,%d1\"; 42759693Selan#else 42859693Selan return \"cmp%.w %d1,%d0\"; 42959693Selan#endif 43059693Selan}") 43159693Selan 43259693Selan(define_insn "cmpqi" 43359693Selan [(set (cc0) 43459693Selan (compare (match_operand:QI 0 "nonimmediate_operand" "dn,md,>") 43559693Selan (match_operand:QI 1 "general_operand" "dm,nd,>")))] 43659693Selan "" 43759693Selan "* 43859693Selan{ 43959693Selan if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 44059693Selan return \"cmpm%.b %1,%0\"; 44159693Selan if (REG_P (operands[1]) 44259693Selan || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM)) 44359693Selan { cc_status.flags |= CC_REVERSED; 44459693Selan#ifdef SGS_CMP_ORDER 44559693Selan return \"cmp%.b %d1,%d0\"; 44659693Selan#else 44759693Selan return \"cmp%.b %d0,%d1\"; 44859693Selan#endif 44959693Selan } 45059693Selan#ifdef SGS_CMP_ORDER 45159693Selan return \"cmp%.b %d0,%d1\"; 45259693Selan#else 45359693Selan return \"cmp%.b %d1,%d0\"; 45459693Selan#endif 45559693Selan}") 45659693Selan 45759693Selan(define_expand "cmpdf" 45859693Selan [(set (cc0) 45959693Selan (compare (match_operand:DF 0 "general_operand" "") 46059693Selan (match_operand:DF 1 "general_operand" "")))] 46159693Selan "TARGET_68881 || TARGET_FPA" 46259693Selan " 46359693Selan{ 46459693Selan if (TARGET_FPA) 46559693Selan { 46659693Selan emit_insn (gen_cmpdf_fpa (operands[0], operands[1])); 46759693Selan DONE; 46859693Selan } 46959693Selan}") 47059693Selan 47159693Selan(define_insn "cmpdf_fpa" 47259693Selan [(set (cc0) 47359693Selan (compare (match_operand:DF 0 "general_operand" "x,y") 47459693Selan (match_operand:DF 1 "general_operand" "xH,rmF"))) 47559693Selan (clobber (match_scratch:SI 2 "=d,d"))] 47659693Selan "TARGET_FPA" 47759693Selan "fpcmp%.d %y1,%0\;fpmove fpastatus,%2\;movw %2,cc") 47859693Selan 47959693Selan(define_insn "" 48059693Selan [(set (cc0) 48159693Selan (compare (match_operand:DF 0 "general_operand" "f,mG") 48259693Selan (match_operand:DF 1 "general_operand" "fmG,f")))] 48359693Selan "TARGET_68881" 48459693Selan "* 48559693Selan{ 48659693Selan cc_status.flags = CC_IN_68881; 48759693Selan#ifdef SGS_CMP_ORDER 48859693Selan if (REG_P (operands[0])) 48959693Selan { 49059693Selan if (REG_P (operands[1])) 49159693Selan return \"fcmp%.x %0,%1\"; 49259693Selan else 49359693Selan return \"fcmp%.d %0,%f1\"; 49459693Selan } 49559693Selan cc_status.flags |= CC_REVERSED; 49659693Selan return \"fcmp%.d %1,%f0\"; 49759693Selan#else 49859693Selan if (REG_P (operands[0])) 49959693Selan { 50059693Selan if (REG_P (operands[1])) 50159693Selan return \"fcmp%.x %1,%0\"; 50259693Selan else 50359693Selan return \"fcmp%.d %f1,%0\"; 50459693Selan } 50559693Selan cc_status.flags |= CC_REVERSED; 50659693Selan return \"fcmp%.d %f0,%1\"; 50759693Selan#endif 50859693Selan}") 50959693Selan 51059693Selan(define_expand "cmpsf" 51159693Selan [(set (cc0) 51259693Selan (compare (match_operand:SF 0 "general_operand" "") 51359693Selan (match_operand:SF 1 "general_operand" "")))] 51459693Selan "TARGET_68881 || TARGET_FPA" 51559693Selan " 51659693Selan{ 51759693Selan if (TARGET_FPA) 51859693Selan { 51959693Selan emit_insn (gen_cmpsf_fpa (operands[0], operands[1])); 52059693Selan DONE; 52159693Selan } 52259693Selan}") 52359693Selan 52459693Selan(define_insn "cmpsf_fpa" 52559693Selan [(set (cc0) 52659693Selan (compare (match_operand:SF 0 "general_operand" "x,y") 52759693Selan (match_operand:SF 1 "general_operand" "xH,rmF"))) 52859693Selan (clobber (match_scratch:SI 2 "=d,d"))] 52959693Selan "TARGET_FPA" 53059693Selan "fpcmp%.s %w1,%x0\;fpmove fpastatus,%2\;movw %2,cc") 53159693Selan 53259693Selan(define_insn "" 53359693Selan [(set (cc0) 53459693Selan (compare (match_operand:SF 0 "general_operand" "f,mdG") 53559693Selan (match_operand:SF 1 "general_operand" "fmdG,f")))] 53659693Selan "TARGET_68881" 53759693Selan "* 53859693Selan{ 53959693Selan cc_status.flags = CC_IN_68881; 54059693Selan#ifdef SGS_CMP_ORDER 54159693Selan if (FP_REG_P (operands[0])) 54259693Selan { 54359693Selan if (FP_REG_P (operands[1])) 54459693Selan return \"fcmp%.x %0,%1\"; 54559693Selan else 54659693Selan return \"fcmp%.s %0,%f1\"; 54759693Selan } 54859693Selan cc_status.flags |= CC_REVERSED; 54959693Selan return \"fcmp%.s %1,%f0\"; 55059693Selan#else 55159693Selan if (FP_REG_P (operands[0])) 55259693Selan { 55359693Selan if (FP_REG_P (operands[1])) 55459693Selan return \"fcmp%.x %1,%0\"; 55559693Selan else 55659693Selan return \"fcmp%.s %f1,%0\"; 55759693Selan } 55859693Selan cc_status.flags |= CC_REVERSED; 55959693Selan return \"fcmp%.s %f0,%1\"; 56059693Selan#endif 56159693Selan}") 56259693Selan 56359693Selan;; Recognizers for btst instructions. 56459693Selan 56559693Selan(define_insn "" 56659693Selan [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "do") 56759693Selan (const_int 1) 56859693Selan (minus:SI (const_int 7) 56959693Selan (match_operand:SI 1 "general_operand" "di"))))] 57059693Selan "" 57159693Selan "* { return output_btst (operands, operands[1], operands[0], insn, 7); }") 57259693Selan 57359693Selan(define_insn "" 57459693Selan [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "d") 57559693Selan (const_int 1) 57659693Selan (minus:SI (const_int 31) 57759693Selan (match_operand:SI 1 "general_operand" "di"))))] 57859693Selan "" 57959693Selan "* { return output_btst (operands, operands[1], operands[0], insn, 31); }") 58059693Selan 58159693Selan;; The following two patterns are like the previous two 58259693Selan;; except that they use the fact that bit-number operands 58359693Selan;; are automatically masked to 3 or 5 bits. 58459693Selan 58559693Selan(define_insn "" 58659693Selan [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "do") 58759693Selan (const_int 1) 58859693Selan (minus:SI (const_int 7) 58959693Selan (and:SI 59059693Selan (match_operand:SI 1 "general_operand" "d") 59159693Selan (const_int 7)))))] 59259693Selan "" 59359693Selan "* { return output_btst (operands, operands[1], operands[0], insn, 7); }") 59459693Selan 59559693Selan(define_insn "" 59659693Selan [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "d") 59759693Selan (const_int 1) 59859693Selan (minus:SI (const_int 31) 59959693Selan (and:SI 60059693Selan (match_operand:SI 1 "general_operand" "d") 60159693Selan (const_int 31)))))] 60259693Selan "" 60359693Selan "* { return output_btst (operands, operands[1], operands[0], insn, 31); }") 60459693Selan 60559693Selan;; Nonoffsettable mem refs are ok in this one pattern 60659693Selan;; since we don't try to adjust them. 60759693Selan(define_insn "" 60859693Selan [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "md") 60959693Selan (const_int 1) 61059693Selan (match_operand:SI 1 "general_operand" "i")))] 61159693Selan "GET_CODE (operands[1]) == CONST_INT 61259693Selan && (unsigned) INTVAL (operands[1]) < 8" 61359693Selan "* 61459693Selan{ 61559693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, 7 - INTVAL (operands[1])); 61659693Selan return output_btst (operands, operands[1], operands[0], insn, 7); 61759693Selan}") 61859693Selan 61959693Selan(define_insn "" 62059693Selan [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "do") 62159693Selan (const_int 1) 62259693Selan (match_operand:SI 1 "general_operand" "i")))] 62359693Selan "GET_CODE (operands[1]) == CONST_INT" 62459693Selan "* 62559693Selan{ 62659693Selan if (GET_CODE (operands[0]) == MEM) 62759693Selan { 62859693Selan operands[0] = adj_offsettable_operand (operands[0], 62959693Selan INTVAL (operands[1]) / 8); 63059693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, 63159693Selan 7 - INTVAL (operands[1]) % 8); 63259693Selan return output_btst (operands, operands[1], operands[0], insn, 7); 63359693Selan } 63459693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, 63559693Selan 31 - INTVAL (operands[1])); 63659693Selan return output_btst (operands, operands[1], operands[0], insn, 31); 63759693Selan}") 63859693Selan 63959693Selan 64059693Selan;; move instructions 64159693Selan 64259693Selan;; A special case in which it is not desirable 64359693Selan;; to reload the constant into a data register. 64459693Selan(define_insn "" 64559693Selan [(set (match_operand:SI 0 "push_operand" "=m") 64659693Selan (match_operand:SI 1 "general_operand" "J"))] 64759693Selan "GET_CODE (operands[1]) == CONST_INT 64859693Selan && INTVAL (operands[1]) >= -0x8000 64959693Selan && INTVAL (operands[1]) < 0x8000" 65059693Selan "* 65159693Selan{ 65259693Selan if (operands[1] == const0_rtx) 65359693Selan return \"clr%.l %0\"; 65459693Selan return \"pea %a1\"; 65559693Selan}") 65659693Selan 65759693Selan;This is never used. 65859693Selan;(define_insn "swapsi" 65959693Selan; [(set (match_operand:SI 0 "general_operand" "+r") 66059693Selan; (match_operand:SI 1 "general_operand" "+r")) 66159693Selan; (set (match_dup 1) (match_dup 0))] 66259693Selan; "" 66359693Selan; "exg %1,%0") 66459693Selan 66559693Selan;; Special case of fullword move when source is zero. 66659693Selan;; The reason this is special is to avoid loading a zero 66759693Selan;; into a data reg with moveq in order to store it elsewhere. 66859693Selan 66959693Selan(define_insn "" 67059693Selan [(set (match_operand:SI 0 "general_operand" "=g") 67159693Selan (const_int 0))] 67259693Selan ;; clr insns on 68000 read before writing. 67359693Selan ;; This isn't so on the 68010, but we have no alternative for it. 67459693Selan "(TARGET_68020 67559693Selan || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))" 67659693Selan "* 67759693Selan{ 67859693Selan if (ADDRESS_REG_P (operands[0])) 67959693Selan return \"sub%.l %0,%0\"; 68059693Selan /* moveq is faster on the 68000. */ 68159693Selan if (DATA_REG_P (operands[0]) && !TARGET_68020) 68259693Selan#if defined(MOTOROLA) && !defined(CRDS) 68359693Selan return \"moveq%.l %#0,%0\"; 68459693Selan#else 68559693Selan return \"moveq %#0,%0\"; 68659693Selan#endif 68759693Selan return \"clr%.l %0\"; 68859693Selan}") 68959693Selan 69059693Selan;; General case of fullword move. 69159693Selan;; 69259693Selan;; This is the main "hook" for PIC code. When generating 69359693Selan;; PIC, movsi is responsible for determining when the source address 69459693Selan;; needs PIC relocation and appropriately calling legitimize_pic_address 69559693Selan;; to perform the actual relocation. 69659693Selan;; 69759693Selan;; In both the PIC and non-PIC cases the patterns generated will 69859693Selan;; matched by the next define_insn. 69959693Selan(define_expand "movsi" 70059693Selan [(set (match_operand:SI 0 "general_operand" "") 70159693Selan (match_operand:SI 1 "general_operand" ""))] 70259693Selan "" 70359693Selan " 70459693Selan{ 70559693Selan if (flag_pic && symbolic_operand (operands[1], SImode)) 70659693Selan { 70759693Selan /* The source is an address which requires PIC relocation. 70859693Selan Call legitimize_pic_address with the source, mode, and a relocation 70959693Selan register (a new pseudo, or the final destination if reload_in_progress 71059693Selan is set). Then fall through normally */ 71159693Selan extern rtx legitimize_pic_address(); 71259693Selan rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode); 71359693Selan operands[1] = legitimize_pic_address (operands[1], SImode, temp); 71459693Selan } 71559693Selan}") 71659693Selan 71759693Selan;; General case of fullword move. The register constraints 71859693Selan;; force integer constants in range for a moveq to be reloaded 71959693Selan;; if they are headed for memory. 72059693Selan(define_insn "" 72159693Selan ;; Notes: make sure no alternative allows g vs g. 72259693Selan ;; We don't allow f-regs since fixed point cannot go in them. 72359693Selan ;; We do allow y and x regs since fixed point is allowed in them. 72459693Selan [(set (match_operand:SI 0 "general_operand" "=g,da,y,!*x*r*m") 72559693Selan (match_operand:SI 1 "general_operand" "daymKs,i,g,*x*r*m"))] 72659693Selan "" 72759693Selan "* 72859693Selan{ 72959693Selan if (which_alternative == 3) 73059693Selan return \"fpmove%.l %x1,fpa0\;fpmove%.l fpa0,%x0\"; 73159693Selan if (FPA_REG_P (operands[1]) || FPA_REG_P (operands[0])) 73259693Selan return \"fpmove%.l %x1,%x0\"; 73359693Selan if (GET_CODE (operands[1]) == CONST_INT) 73459693Selan { 73559693Selan if (operands[1] == const0_rtx 73659693Selan && (DATA_REG_P (operands[0]) 73759693Selan || GET_CODE (operands[0]) == MEM) 73859693Selan /* clr insns on 68000 read before writing. 73959693Selan This isn't so on the 68010, but we have no alternative for it. */ 74059693Selan && (TARGET_68020 74159693Selan || !(GET_CODE (operands[0]) == MEM 74259693Selan && MEM_VOLATILE_P (operands[0])))) 74359693Selan return \"clr%.l %0\"; 74459693Selan else if (DATA_REG_P (operands[0]) 74559693Selan && INTVAL (operands[1]) < 128 74659693Selan && INTVAL (operands[1]) >= -128) 74759693Selan { 74859693Selan#if defined(MOTOROLA) && !defined(CRDS) 74959693Selan return \"moveq%.l %1,%0\"; 75059693Selan#else 75159693Selan return \"moveq %1,%0\"; 75259693Selan#endif 75359693Selan } 75459693Selan#ifndef NO_ADDSUB_Q 75559693Selan else if (DATA_REG_P (operands[0]) 75659693Selan /* Do this with a moveq #N-8, dreg; addq #8,dreg */ 75759693Selan && INTVAL (operands[1]) < 136 75859693Selan && INTVAL (operands[1]) >= 128) 75959693Selan { 76059693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8); 76159693Selan#if defined(MOTOROLA) && !defined(CRDS) 76259693Selan return \"moveq%.l %1,%0\;addq%.w %#8,%0\"; 76359693Selan#else 76459693Selan return \"moveq %1,%0\;addq%.w %#8,%0\"; 76559693Selan#endif 76659693Selan } 76759693Selan else if (DATA_REG_P (operands[0]) 76859693Selan /* Do this with a moveq #N+8, dreg; subq #8,dreg */ 76959693Selan && INTVAL (operands[1]) < -128 77059693Selan && INTVAL (operands[1]) >= -136) 77159693Selan { 77259693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) + 8); 77359693Selan#if defined(MOTOROLA) && !defined(CRDS) 77459693Selan return \"moveq%.l %1,%0;subq%.w %#8,%0\"; 77559693Selan#else 77659693Selan return \"moveq %1,%0;subq%.w %#8,%0\"; 77759693Selan#endif 77859693Selan } 77959693Selan#endif 78059693Selan else if (DATA_REG_P (operands[0]) 78159693Selan /* If N is in the right range and is even, then use 78259693Selan moveq #N/2, dreg; addl dreg,dreg */ 78359693Selan && INTVAL (operands[1]) > 127 78459693Selan && INTVAL (operands[1]) <= 254 78559693Selan && INTVAL (operands[1]) % 2 == 0) 78659693Selan { 78759693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) / 2); 78859693Selan#if defined(MOTOROLA) && !defined(CRDS) 78959693Selan return \"moveq%.l %1,%0\;add%.w %0,%0\"; 79059693Selan#else 79159693Selan return \"moveq %1,%0\;add%.w %0,%0\"; 79259693Selan#endif 79359693Selan } 79459693Selan else if (ADDRESS_REG_P (operands[0]) 79559693Selan && INTVAL (operands[1]) < 0x8000 79659693Selan && INTVAL (operands[1]) >= -0x8000) 79759693Selan return \"move%.w %1,%0\"; 79859693Selan else if (push_operand (operands[0], SImode) 79959693Selan && INTVAL (operands[1]) < 0x8000 80059693Selan && INTVAL (operands[1]) >= -0x8000) 80159693Selan return \"pea %a1\"; 80259693Selan } 80359693Selan else if ((GET_CODE (operands[1]) == SYMBOL_REF 80459693Selan || GET_CODE (operands[1]) == CONST) 80559693Selan && push_operand (operands[0], SImode)) 80659693Selan return \"pea %a1\"; 80759693Selan else if ((GET_CODE (operands[1]) == SYMBOL_REF 80859693Selan || GET_CODE (operands[1]) == CONST) 80959693Selan && ADDRESS_REG_P (operands[0])) 81059693Selan return \"lea %a1,%0\"; 81159693Selan return \"move%.l %1,%0\"; 81259693Selan}") 81359693Selan 81459693Selan(define_insn "movhi" 81559693Selan [(set (match_operand:HI 0 "general_operand" "=g") 81659693Selan (match_operand:HI 1 "general_operand" "g"))] 81759693Selan "" 81859693Selan "* 81959693Selan{ 82059693Selan if (GET_CODE (operands[1]) == CONST_INT) 82159693Selan { 82259693Selan if (operands[1] == const0_rtx 82359693Selan && (DATA_REG_P (operands[0]) 82459693Selan || GET_CODE (operands[0]) == MEM) 82559693Selan /* clr insns on 68000 read before writing. 82659693Selan This isn't so on the 68010, but we have no alternative for it. */ 82759693Selan && (TARGET_68020 82859693Selan || !(GET_CODE (operands[0]) == MEM 82959693Selan && MEM_VOLATILE_P (operands[0])))) 83059693Selan return \"clr%.w %0\"; 83159693Selan else if (DATA_REG_P (operands[0]) 83259693Selan && INTVAL (operands[1]) < 128 83359693Selan && INTVAL (operands[1]) >= -128) 83459693Selan { 83559693Selan#if defined(MOTOROLA) && !defined(CRDS) 83659693Selan return \"moveq%.l %1,%0\"; 83759693Selan#else 83859693Selan return \"moveq %1,%0\"; 83959693Selan#endif 84059693Selan } 84159693Selan else if (INTVAL (operands[1]) < 0x8000 84259693Selan && INTVAL (operands[1]) >= -0x8000) 84359693Selan return \"move%.w %1,%0\"; 84459693Selan } 84559693Selan else if (CONSTANT_P (operands[1])) 84659693Selan return \"move%.l %1,%0\"; 84759693Selan#ifndef SGS_NO_LI 84859693Selan /* Recognize the insn before a tablejump, one that refers 84959693Selan to a table of offsets. Such an insn will need to refer 85059693Selan to a label on the insn. So output one. Use the label-number 85159693Selan of the table of offsets to generate this label. */ 85259693Selan if (GET_CODE (operands[1]) == MEM 85359693Selan && GET_CODE (XEXP (operands[1], 0)) == PLUS 85459693Selan && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF 85559693Selan || GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF) 85659693Selan && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS 85759693Selan && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) != PLUS) 85859693Selan { 85959693Selan rtx labelref; 86059693Selan if (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF) 86159693Selan labelref = XEXP (XEXP (operands[1], 0), 0); 86259693Selan else 86359693Selan labelref = XEXP (XEXP (operands[1], 0), 1); 86459693Selan#if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES) 86559693Selan#ifdef SGS 86659693Selan asm_fprintf (asm_out_file, \"\\tset %LLI%d,.+2\\n\", 86759693Selan CODE_LABEL_NUMBER (XEXP (labelref, 0))); 86859693Selan#else /* not SGS */ 86959693Selan asm_fprintf (asm_out_file, \"\\t.set %LLI%d,.+2\\n\", 87059693Selan CODE_LABEL_NUMBER (XEXP (labelref, 0))); 87159693Selan#endif /* not SGS */ 87259693Selan#else /* SGS_SWITCH_TABLES or not MOTOROLA */ 87359693Selan ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LI\", 87459693Selan CODE_LABEL_NUMBER (XEXP (labelref, 0))); 87559693Selan#ifdef SGS_SWITCH_TABLES 87659693Selan /* Set flag saying we need to define the symbol 87759693Selan LD%n (with value L%n-LI%n) at the end of the switch table. */ 87859693Selan switch_table_difference_label_flag = 1; 87959693Selan#endif /* SGS_SWITCH_TABLES */ 88059693Selan#endif /* SGS_SWITCH_TABLES or not MOTOROLA */ 88159693Selan } 88259693Selan#endif /* SGS_NO_LI */ 88359693Selan return \"move%.w %1,%0\"; 88459693Selan}") 88559693Selan 88659693Selan(define_insn "movstricthi" 88759693Selan [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm")) 88859693Selan (match_operand:HI 1 "general_operand" "rmn"))] 88959693Selan "" 89059693Selan "* 89159693Selan{ 89259693Selan if (GET_CODE (operands[1]) == CONST_INT) 89359693Selan { 89459693Selan if (operands[1] == const0_rtx 89559693Selan && (DATA_REG_P (operands[0]) 89659693Selan || GET_CODE (operands[0]) == MEM) 89759693Selan /* clr insns on 68000 read before writing. 89859693Selan This isn't so on the 68010, but we have no alternative for it. */ 89959693Selan && (TARGET_68020 90059693Selan || !(GET_CODE (operands[0]) == MEM 90159693Selan && MEM_VOLATILE_P (operands[0])))) 90259693Selan return \"clr%.w %0\"; 90359693Selan } 90459693Selan return \"move%.w %1,%0\"; 90559693Selan}") 90659693Selan 90759693Selan(define_insn "movqi" 90859693Selan [(set (match_operand:QI 0 "general_operand" "=d,*a,m,m,?*a") 90959693Selan (match_operand:QI 1 "general_operand" "dmi*a,d*a,dmi,?*a,m"))] 91059693Selan "" 91159693Selan "* 91259693Selan{ 91359693Selan rtx xoperands[4]; 91459693Selan 91559693Selan /* This is probably useless, since it loses for pushing a struct 91659693Selan of several bytes a byte at a time. */ 91759693Selan if (GET_CODE (operands[0]) == MEM 91859693Selan && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC 91959693Selan && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx) 92059693Selan { 92159693Selan xoperands[1] = operands[1]; 92259693Selan xoperands[2] 92359693Selan = gen_rtx (MEM, QImode, 92459693Selan gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx)); 92559693Selan /* Just pushing a byte puts it in the high byte of the halfword. */ 92659693Selan /* We must put it in the low-order, high-numbered byte. */ 927*60382Selan output_asm_insn (\"move%.b %1,%-\;move%.b %@,%2\", xoperands); 92859693Selan return \"\"; 92959693Selan } 93059693Selan 931*60382Selan /* HACK Alert. This is a quick fix while RMS makes up his 932*60382Selan mind about what he wants to do about this case. */ 933*60382Selan 934*60382Selan /* if d0 is used in the address calculation, use d1 */ 935*60382Selan if (refers_to_regno_p (0, 1, PATTERN (insn), NULL_PTR)) 93659693Selan { 937*60382Selan /* Moving a byte into an address register is not possible. */ 938*60382Selan /* Use d1 as an intermediate, but don't clobber its contents. */ 939*60382Selan if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM) 940*60382Selan return \"exg %/d1,%0\;move%.b %1,%/d1\;exg %/d1,%0\"; 941*60382Selan /* Likewise for moving from an address reg. */ 942*60382Selan if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM) 943*60382Selan return \"exg %/d1,%1\;move%.b %/d1,%0\;exg %/d1,%1\"; 94459693Selan } 945*60382Selan else 94659693Selan { 947*60382Selan /* Moving a byte into an address register is not possible. */ 948*60382Selan /* Use d0 as an intermediate, but don't clobber its contents. */ 949*60382Selan if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM) 950*60382Selan return \"exg %/d0,%0\;move%.b %1,%/d0\;exg %/d0,%0\"; 951*60382Selan /* Likewise for moving from an address reg. */ 952*60382Selan if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM) 953*60382Selan return \"exg %/d0,%1\;move%.b %/d0,%0\;exg %/d0,%1\"; 95459693Selan } 955*60382Selan 95659693Selan /* clr and st insns on 68000 read before writing. 95759693Selan This isn't so on the 68010, but we have no alternative for it. */ 95859693Selan if (TARGET_68020 95959693Selan || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) 96059693Selan { 96159693Selan if (operands[1] == const0_rtx) 96259693Selan return \"clr%.b %0\"; 96359693Selan if (GET_CODE (operands[1]) == CONST_INT 96459693Selan && INTVAL (operands[1]) == -1) 96559693Selan { 96659693Selan CC_STATUS_INIT; 96759693Selan return \"st %0\"; 96859693Selan } 96959693Selan } 97059693Selan if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1])) 97159693Selan return \"move%.l %1,%0\"; 97259693Selan if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1])) 97359693Selan return \"move%.w %1,%0\"; 97459693Selan return \"move%.b %1,%0\"; 97559693Selan}") 97659693Selan 97759693Selan(define_insn "movstrictqi" 97859693Selan [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm")) 97959693Selan (match_operand:QI 1 "general_operand" "dmn"))] 98059693Selan "" 98159693Selan "* 98259693Selan{ 98359693Selan if (operands[1] == const0_rtx 98459693Selan /* clr insns on 68000 read before writing. 98559693Selan This isn't so on the 68010, but we have no alternative for it. */ 98659693Selan && (TARGET_68020 98759693Selan || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))) 98859693Selan return \"clr%.b %0\"; 98959693Selan return \"move%.b %1,%0\"; 99059693Selan}") 99159693Selan 99259693Selan(define_insn "movsf" 99359693Selan [(set (match_operand:SF 0 "general_operand" "=rmf,x,y,rm,!x,!rm") 99459693Selan (match_operand:SF 1 "general_operand" "rmfF,xH,rmF,y,rm,x"))] 99559693Selan; [(set (match_operand:SF 0 "general_operand" "=rmf") 99659693Selan; (match_operand:SF 1 "general_operand" "rmfF"))] 99759693Selan "" 99859693Selan "* 99959693Selan{ 100059693Selan if (which_alternative >= 4) 100159693Selan return \"fpmove%.s %1,fpa0\;fpmove%.s fpa0,%0\"; 100259693Selan if (FPA_REG_P (operands[0])) 100359693Selan { 100459693Selan if (FPA_REG_P (operands[1])) 100559693Selan return \"fpmove%.s %x1,%x0\"; 100659693Selan else if (GET_CODE (operands[1]) == CONST_DOUBLE) 100759693Selan return output_move_const_single (operands); 100859693Selan else if (FP_REG_P (operands[1])) 100959693Selan return \"fmove%.s %1,sp@-\;fpmove%.d sp@+, %0\"; 101059693Selan return \"fpmove%.s %x1,%x0\"; 101159693Selan } 101259693Selan if (FPA_REG_P (operands[1])) 101359693Selan { 101459693Selan if (FP_REG_P (operands[0])) 101559693Selan return \"fpmove%.s %x1,sp@-\;fmove%.s sp@+,%0\"; 101659693Selan else 101759693Selan return \"fpmove%.s %x1,%x0\"; 101859693Selan } 101959693Selan if (FP_REG_P (operands[0])) 102059693Selan { 102159693Selan if (FP_REG_P (operands[1])) 102259693Selan return \"f%$move%.x %1,%0\"; 102359693Selan else if (ADDRESS_REG_P (operands[1])) 102459693Selan return \"move%.l %1,%-\;f%$move%.s %+,%0\"; 102559693Selan else if (GET_CODE (operands[1]) == CONST_DOUBLE) 102659693Selan return output_move_const_single (operands); 102759693Selan return \"f%$move%.s %f1,%0\"; 102859693Selan } 102959693Selan if (FP_REG_P (operands[1])) 103059693Selan { 103159693Selan if (ADDRESS_REG_P (operands[0])) 103259693Selan return \"fmove%.s %1,%-\;move%.l %+,%0\"; 103359693Selan return \"fmove%.s %f1,%0\"; 103459693Selan } 103559693Selan return \"move%.l %1,%0\"; 103659693Selan}") 103759693Selan 103859693Selan(define_insn "movdf" 103959693Selan [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>,y,rm,x,!x,!rm") 104059693Selan (match_operand:DF 1 "general_operand" "rf,m,rofE<>,rmE,y,xH,rm,x"))] 104159693Selan; [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>") 104259693Selan; (match_operand:DF 1 "general_operand" "rf,m,rofF<>"))] 104359693Selan "" 104459693Selan "* 104559693Selan{ 104659693Selan if (which_alternative == 6) 104759693Selan return \"fpmove%.d %x1,fpa0\;fpmove%.d fpa0,%x0\"; 104859693Selan if (FPA_REG_P (operands[0])) 104959693Selan { 105059693Selan if (GET_CODE (operands[1]) == CONST_DOUBLE) 105159693Selan return output_move_const_double (operands); 105259693Selan if (FP_REG_P (operands[1])) 105359693Selan return \"fmove%.d %1,sp@-\;fpmove%.d sp@+,%x0\"; 105459693Selan return \"fpmove%.d %x1,%x0\"; 105559693Selan } 105659693Selan else if (FPA_REG_P (operands[1])) 105759693Selan { 105859693Selan if (FP_REG_P(operands[0])) 105959693Selan return \"fpmove%.d %x1,sp@-\;fmoved sp@+,%0\"; 106059693Selan else 106159693Selan return \"fpmove%.d %x1,%x0\"; 106259693Selan } 106359693Selan if (FP_REG_P (operands[0])) 106459693Selan { 106559693Selan if (FP_REG_P (operands[1])) 106659693Selan return \"f%&move%.x %1,%0\"; 106759693Selan if (REG_P (operands[1])) 106859693Selan { 106959693Selan rtx xoperands[2]; 107059693Selan xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); 107159693Selan output_asm_insn (\"move%.l %1,%-\", xoperands); 107259693Selan output_asm_insn (\"move%.l %1,%-\", operands); 107359693Selan return \"f%&move%.d %+,%0\"; 107459693Selan } 107559693Selan if (GET_CODE (operands[1]) == CONST_DOUBLE) 107659693Selan return output_move_const_double (operands); 107759693Selan return \"f%&move%.d %f1,%0\"; 107859693Selan } 107959693Selan else if (FP_REG_P (operands[1])) 108059693Selan { 108159693Selan if (REG_P (operands[0])) 108259693Selan { 108359693Selan output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands); 108459693Selan operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); 108559693Selan return \"move%.l %+,%0\"; 108659693Selan } 108759693Selan else 108859693Selan return \"fmove%.d %f1,%0\"; 108959693Selan } 109059693Selan return output_move_double (operands); 109159693Selan} 109259693Selan") 109359693Selan 109459693Selan;; movdi can apply to fp regs in some cases 109559693Selan(define_insn "movdi" 109659693Selan ;; Let's see if it really still needs to handle fp regs, and, if so, why. 109759693Selan [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>,y,rm,!*x,!rm") 109859693Selan (match_operand:DI 1 "general_operand" "rF,m,roi<>F,rmiF,y,rmF,*x"))] 109959693Selan; [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>,!&rm,!&f,y,rm,x,!x,!rm") 110059693Selan; (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfmF,rmi,y,rm,x"))] 110159693Selan; [(set (match_operand:DI 0 "general_operand" "=rm,&rf,&ro<>,!&rm,!&f") 110259693Selan; (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfF"))] 110359693Selan "" 110459693Selan "* 110559693Selan{ 110659693Selan if (which_alternative == 8) 110759693Selan return \"fpmove%.d %x1,fpa0\;fpmove%.d fpa0,%x0\"; 110859693Selan if (FPA_REG_P (operands[0]) || FPA_REG_P (operands[1])) 110959693Selan return \"fpmove%.d %x1,%x0\"; 111059693Selan if (FP_REG_P (operands[0])) 111159693Selan { 111259693Selan if (FP_REG_P (operands[1])) 111359693Selan return \"fmove%.x %1,%0\"; 111459693Selan if (REG_P (operands[1])) 111559693Selan { 111659693Selan rtx xoperands[2]; 111759693Selan xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); 111859693Selan output_asm_insn (\"move%.l %1,%-\", xoperands); 111959693Selan output_asm_insn (\"move%.l %1,%-\", operands); 112059693Selan return \"fmove%.d %+,%0\"; 112159693Selan } 112259693Selan if (GET_CODE (operands[1]) == CONST_DOUBLE) 112359693Selan return output_move_const_double (operands); 112459693Selan return \"fmove%.d %f1,%0\"; 112559693Selan } 112659693Selan else if (FP_REG_P (operands[1])) 112759693Selan { 112859693Selan if (REG_P (operands[0])) 112959693Selan { 113059693Selan output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands); 113159693Selan operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); 113259693Selan return \"move%.l %+,%0\"; 113359693Selan } 113459693Selan else 113559693Selan return \"fmove%.d %f1,%0\"; 113659693Selan } 113759693Selan return output_move_double (operands); 113859693Selan} 113959693Selan") 114059693Selan 114159693Selan;; Thus goes after the move instructions 114259693Selan;; because the move instructions are better (require no spilling) 114359693Selan;; when they can apply. It goes before the add/sub insns 114459693Selan;; so we will prefer it to them. 114559693Selan 114659693Selan(define_insn "pushasi" 114759693Selan [(set (match_operand:SI 0 "push_operand" "=m") 114859693Selan (match_operand:SI 1 "address_operand" "p"))] 114959693Selan "" 115059693Selan "pea %a1") 115159693Selan 115259693Selan;; truncation instructions 115359693Selan(define_insn "truncsiqi2" 115459693Selan [(set (match_operand:QI 0 "general_operand" "=dm,d") 115559693Selan (truncate:QI 115659693Selan (match_operand:SI 1 "general_operand" "doJ,i")))] 115759693Selan "" 115859693Selan "* 115959693Selan{ 116059693Selan if (GET_CODE (operands[0]) == REG) 116159693Selan { 116259693Selan /* Must clear condition codes, since the move.l bases them on 116359693Selan the entire 32 bits, not just the desired 8 bits. */ 116459693Selan CC_STATUS_INIT; 116559693Selan return \"move%.l %1,%0\"; 116659693Selan } 116759693Selan if (GET_CODE (operands[1]) == MEM) 116859693Selan operands[1] = adj_offsettable_operand (operands[1], 3); 116959693Selan return \"move%.b %1,%0\"; 117059693Selan}") 117159693Selan 117259693Selan(define_insn "trunchiqi2" 117359693Selan [(set (match_operand:QI 0 "general_operand" "=dm,d") 117459693Selan (truncate:QI 117559693Selan (match_operand:HI 1 "general_operand" "doJ,i")))] 117659693Selan "" 117759693Selan "* 117859693Selan{ 117959693Selan if (GET_CODE (operands[0]) == REG 118059693Selan && (GET_CODE (operands[1]) == MEM 118159693Selan || GET_CODE (operands[1]) == CONST_INT)) 118259693Selan { 118359693Selan /* Must clear condition codes, since the move.w bases them on 118459693Selan the entire 16 bits, not just the desired 8 bits. */ 118559693Selan CC_STATUS_INIT; 118659693Selan return \"move%.w %1,%0\"; 118759693Selan } 118859693Selan if (GET_CODE (operands[0]) == REG) 118959693Selan { 119059693Selan /* Must clear condition codes, since the move.l bases them on 119159693Selan the entire 32 bits, not just the desired 8 bits. */ 119259693Selan CC_STATUS_INIT; 119359693Selan return \"move%.l %1,%0\"; 119459693Selan } 119559693Selan if (GET_CODE (operands[1]) == MEM) 119659693Selan operands[1] = adj_offsettable_operand (operands[1], 1); 119759693Selan return \"move%.b %1,%0\"; 119859693Selan}") 119959693Selan 120059693Selan(define_insn "truncsihi2" 120159693Selan [(set (match_operand:HI 0 "general_operand" "=dm,d") 120259693Selan (truncate:HI 120359693Selan (match_operand:SI 1 "general_operand" "roJ,i")))] 120459693Selan "" 120559693Selan "* 120659693Selan{ 120759693Selan if (GET_CODE (operands[0]) == REG) 120859693Selan { 120959693Selan /* Must clear condition codes, since the move.l bases them on 121059693Selan the entire 32 bits, not just the desired 8 bits. */ 121159693Selan CC_STATUS_INIT; 121259693Selan return \"move%.l %1,%0\"; 121359693Selan } 121459693Selan if (GET_CODE (operands[1]) == MEM) 121559693Selan operands[1] = adj_offsettable_operand (operands[1], 2); 121659693Selan return \"move%.w %1,%0\"; 121759693Selan}") 121859693Selan 121959693Selan;; zero extension instructions 122059693Selan 122159693Selan(define_expand "zero_extendhisi2" 122259693Selan [(set (match_operand:SI 0 "register_operand" "") 122359693Selan (const_int 0)) 122459693Selan (set (strict_low_part (match_dup 2)) 122559693Selan (match_operand:HI 1 "general_operand" ""))] 122659693Selan "" 122759693Selan " 122859693Selan{ 122959693Selan operands[1] = make_safe_from (operands[1], operands[0]); 123059693Selan if (GET_CODE (operands[0]) == SUBREG) 123159693Selan operands[2] = gen_rtx (SUBREG, HImode, SUBREG_REG (operands[0]), 123259693Selan SUBREG_WORD (operands[0])); 123359693Selan else 123459693Selan operands[2] = gen_rtx (SUBREG, HImode, operands[0], 0); 123559693Selan}") 123659693Selan 123759693Selan(define_expand "zero_extendqihi2" 123859693Selan [(set (match_operand:HI 0 "register_operand" "") 123959693Selan (const_int 0)) 124059693Selan (set (strict_low_part (match_dup 2)) 124159693Selan (match_operand:QI 1 "general_operand" ""))] 124259693Selan "" 124359693Selan " 124459693Selan{ 124559693Selan operands[1] = make_safe_from (operands[1], operands[0]); 124659693Selan if (GET_CODE (operands[0]) == SUBREG) 124759693Selan operands[2] = gen_rtx (SUBREG, QImode, SUBREG_REG (operands[0]), 124859693Selan SUBREG_WORD (operands[0])); 124959693Selan else 125059693Selan operands[2] = gen_rtx (SUBREG, QImode, operands[0], 0); 125159693Selan}") 125259693Selan 125359693Selan(define_expand "zero_extendqisi2" 125459693Selan [(set (match_operand:SI 0 "register_operand" "") 125559693Selan (const_int 0)) 125659693Selan (set (strict_low_part (match_dup 2)) 125759693Selan (match_operand:QI 1 "general_operand" ""))] 125859693Selan "" 125959693Selan " 126059693Selan{ 126159693Selan operands[1] = make_safe_from (operands[1], operands[0]); 126259693Selan if (GET_CODE (operands[0]) == SUBREG) 126359693Selan operands[2] = gen_rtx (SUBREG, QImode, SUBREG_REG (operands[0]), 126459693Selan SUBREG_WORD (operands[0])); 126559693Selan else 126659693Selan operands[2] = gen_rtx (SUBREG, QImode, operands[0], 0); 126759693Selan}") 126859693Selan 126959693Selan;; Patterns to recognize zero-extend insns produced by the combiner. 127059693Selan;; We don't allow both operands in memory, because of aliasing problems. 127159693Selan;; Explicitly disallow two memory operands via the condition since reloading 127259693Selan;; of this case will result in worse code than the uncombined patterns. 127359693Selan 127459693Selan(define_insn "" 127559693Selan [(set (match_operand:SI 0 "general_operand" "=do<>,d<") 127659693Selan (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))] 127759693Selan "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 127859693Selan "* 127959693Selan{ 128059693Selan if (DATA_REG_P (operands[0])) 128159693Selan { 128259693Selan if (GET_CODE (operands[1]) == REG 128359693Selan && REGNO (operands[0]) == REGNO (operands[1])) 128459693Selan return \"and%.l %#0xFFFF,%0\"; 128559693Selan if (reg_mentioned_p (operands[0], operands[1])) 128659693Selan return \"move%.w %1,%0\;and%.l %#0xFFFF,%0\"; 128759693Selan return \"clr%.l %0\;move%.w %1,%0\"; 128859693Selan } 128959693Selan else if (GET_CODE (operands[0]) == MEM 129059693Selan && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) 129159693Selan return \"move%.w %1,%0\;clr%.w %0\"; 129259693Selan else if (GET_CODE (operands[0]) == MEM 129359693Selan && GET_CODE (XEXP (operands[0], 0)) == POST_INC) 129459693Selan return \"clr%.w %0\;move%.w %1,%0\"; 129559693Selan else 129659693Selan { 129759693Selan output_asm_insn (\"clr%.w %0\", operands); 129859693Selan operands[0] = adj_offsettable_operand (operands[0], 2); 129959693Selan return \"move%.w %1,%0\"; 130059693Selan } 130159693Selan}") 130259693Selan 130359693Selan(define_insn "" 130459693Selan [(set (match_operand:HI 0 "general_operand" "=do<>,d") 130559693Selan (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))] 130659693Selan "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 130759693Selan "* 130859693Selan{ 130959693Selan if (DATA_REG_P (operands[0])) 131059693Selan { 131159693Selan if (GET_CODE (operands[1]) == REG 131259693Selan && REGNO (operands[0]) == REGNO (operands[1])) 131359693Selan return \"and%.w %#0xFF,%0\"; 131459693Selan if (reg_mentioned_p (operands[0], operands[1])) 131559693Selan return \"move%.b %1,%0\;and%.w %#0xFF,%0\"; 131659693Selan return \"clr%.w %0\;move%.b %1,%0\"; 131759693Selan } 131859693Selan else if (GET_CODE (operands[0]) == MEM 131959693Selan && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) 132059693Selan { 132159693Selan if (REGNO (XEXP (XEXP (operands[0], 0), 0)) 132259693Selan == STACK_POINTER_REGNUM) 132359693Selan { 132459693Selan output_asm_insn (\"clr%.w %-\", operands); 132559693Selan operands[0] = gen_rtx (MEM, GET_MODE (operands[0]), 132659693Selan plus_constant (stack_pointer_rtx, 1)); 132759693Selan return \"move%.b %1,%0\"; 132859693Selan } 132959693Selan else 133059693Selan return \"move%.b %1,%0\;clr%.b %0\"; 133159693Selan } 133259693Selan else if (GET_CODE (operands[0]) == MEM 133359693Selan && GET_CODE (XEXP (operands[0], 0)) == POST_INC) 133459693Selan return \"clr%.b %0\;move%.b %1,%0\"; 133559693Selan else 133659693Selan { 133759693Selan output_asm_insn (\"clr%.b %0\", operands); 133859693Selan operands[0] = adj_offsettable_operand (operands[0], 1); 133959693Selan return \"move%.b %1,%0\"; 134059693Selan } 134159693Selan}") 134259693Selan 134359693Selan(define_insn "" 134459693Selan [(set (match_operand:SI 0 "general_operand" "=do<>,d") 134559693Selan (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))] 134659693Selan "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 134759693Selan "* 134859693Selan{ 134959693Selan if (DATA_REG_P (operands[0])) 135059693Selan { 135159693Selan if (GET_CODE (operands[1]) == REG 135259693Selan && REGNO (operands[0]) == REGNO (operands[1])) 135359693Selan return \"and%.l %#0xFF,%0\"; 135459693Selan if (reg_mentioned_p (operands[0], operands[1])) 135559693Selan return \"move%.b %1,%0\;and%.l %#0xFF,%0\"; 135659693Selan return \"clr%.l %0\;move%.b %1,%0\"; 135759693Selan } 135859693Selan else if (GET_CODE (operands[0]) == MEM 135959693Selan && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) 136059693Selan { 136159693Selan operands[0] = XEXP (XEXP (operands[0], 0), 0); 136259693Selan#ifdef MOTOROLA 136359693Selan#ifdef SGS 136459693Selan return \"clr%.l -(%0)\;move%.b %1,3(%0)\"; 136559693Selan#else 136659693Selan return \"clr%.l -(%0)\;move%.b %1,(3,%0)\"; 136759693Selan#endif 136859693Selan#else 136959693Selan return \"clrl %0@-\;moveb %1,%0@(3)\"; 137059693Selan#endif 137159693Selan } 137259693Selan else if (GET_CODE (operands[0]) == MEM 137359693Selan && GET_CODE (XEXP (operands[0], 0)) == POST_INC) 137459693Selan { 137559693Selan operands[0] = XEXP (XEXP (operands[0], 0), 0); 137659693Selan#ifdef MOTOROLA 137759693Selan#ifdef SGS 137859693Selan return \"clr%.l (%0)+\;move%.b %1,-1(%0)\"; 137959693Selan#else 138059693Selan return \"clr%.l (%0)+\;move%.b %1,(-1,%0)\"; 138159693Selan#endif 138259693Selan#else 138359693Selan return \"clrl %0@+\;moveb %1,%0@(-1)\"; 138459693Selan#endif 138559693Selan } 138659693Selan else 138759693Selan { 138859693Selan output_asm_insn (\"clr%.l %0\", operands); 138959693Selan operands[0] = adj_offsettable_operand (operands[0], 3); 139059693Selan return \"move%.b %1,%0\"; 139159693Selan } 139259693Selan}") 139359693Selan 139459693Selan;; sign extension instructions 139559693Selan 139659693Selan(define_insn "extendhisi2" 139759693Selan [(set (match_operand:SI 0 "general_operand" "=*d,a") 139859693Selan (sign_extend:SI 139959693Selan (match_operand:HI 1 "nonimmediate_operand" "0,rm")))] 140059693Selan "" 140159693Selan "* 140259693Selan{ 140359693Selan if (ADDRESS_REG_P (operands[0])) 140459693Selan return \"move%.w %1,%0\"; 140559693Selan return \"ext%.l %0\"; 140659693Selan}") 140759693Selan 140859693Selan(define_insn "extendqihi2" 140959693Selan [(set (match_operand:HI 0 "general_operand" "=d") 141059693Selan (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))] 141159693Selan "" 141259693Selan "ext%.w %0") 141359693Selan 141459693Selan(define_insn "extendqisi2" 141559693Selan [(set (match_operand:SI 0 "general_operand" "=d") 141659693Selan (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))] 141759693Selan "TARGET_68020" 141859693Selan "extb%.l %0") 141959693Selan 142059693Selan;; Conversions between float and double. 142159693Selan 142259693Selan(define_expand "extendsfdf2" 142359693Selan [(set (match_operand:DF 0 "general_operand" "") 142459693Selan (float_extend:DF 142559693Selan (match_operand:SF 1 "general_operand" "")))] 142659693Selan "TARGET_68881 || TARGET_FPA" 142759693Selan "") 142859693Selan 142959693Selan(define_insn "" 143059693Selan [(set (match_operand:DF 0 "general_operand" "=x,y") 143159693Selan (float_extend:DF 143259693Selan (match_operand:SF 1 "general_operand" "xH,rmF")))] 143359693Selan "TARGET_FPA" 143459693Selan "fpstod %w1,%0") 143559693Selan 143659693Selan(define_insn "" 143759693Selan [(set (match_operand:DF 0 "general_operand" "=*fdm,f") 143859693Selan (float_extend:DF 143959693Selan (match_operand:SF 1 "general_operand" "f,dmF")))] 144059693Selan "TARGET_68881" 144159693Selan "* 144259693Selan{ 144359693Selan if (FP_REG_P (operands[0]) && FP_REG_P (operands[1])) 144459693Selan { 144559693Selan if (REGNO (operands[0]) == REGNO (operands[1])) 144659693Selan { 144759693Selan /* Extending float to double in an fp-reg is a no-op. 144859693Selan NOTICE_UPDATE_CC has already assumed that the 144959693Selan cc will be set. So cancel what it did. */ 145059693Selan cc_status = cc_prev_status; 145159693Selan return \"\"; 145259693Selan } 145359693Selan return \"f%&move%.x %1,%0\"; 145459693Selan } 145559693Selan if (FP_REG_P (operands[0])) 145659693Selan return \"f%&move%.s %f1,%0\"; 145759693Selan if (DATA_REG_P (operands[0]) && FP_REG_P (operands[1])) 145859693Selan { 145959693Selan output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands); 146059693Selan operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); 146159693Selan return \"move%.l %+,%0\"; 146259693Selan } 146359693Selan return \"fmove%.d %f1,%0\"; 146459693Selan}") 146559693Selan 146659693Selan;; This cannot output into an f-reg because there is no way to be 146759693Selan;; sure of truncating in that case. 146859693Selan;; But on the Sun FPA, we can be sure. 146959693Selan(define_expand "truncdfsf2" 147059693Selan [(set (match_operand:SF 0 "general_operand" "") 147159693Selan (float_truncate:SF 147259693Selan (match_operand:DF 1 "general_operand" "")))] 147359693Selan "TARGET_68881 || TARGET_FPA" 147459693Selan "") 147559693Selan 147659693Selan(define_insn "" 147759693Selan [(set (match_operand:SF 0 "general_operand" "=x,y") 147859693Selan (float_truncate:SF 147959693Selan (match_operand:DF 1 "general_operand" "xH,rmF")))] 148059693Selan "TARGET_FPA" 148159693Selan "fpdtos %y1,%0") 148259693Selan 148359693Selan;; On the '040 we can truncate in a register accurately and easily. 148459693Selan(define_insn "" 148559693Selan [(set (match_operand:SF 0 "general_operand" "=f") 148659693Selan (float_truncate:SF 148759693Selan (match_operand:DF 1 "general_operand" "fmG")))] 148859693Selan "TARGET_68040_ONLY" 148959693Selan "* 149059693Selan{ 149159693Selan if (FP_REG_P (operands[1])) 149259693Selan return \"fsmove%.x %1,%0\"; 149359693Selan return \"fsmove%.d %f1,%0\"; 149459693Selan}") 149559693Selan 149659693Selan(define_insn "" 149759693Selan [(set (match_operand:SF 0 "general_operand" "=dm") 149859693Selan (float_truncate:SF 149959693Selan (match_operand:DF 1 "general_operand" "f")))] 150059693Selan "TARGET_68881" 150159693Selan "fmove%.s %f1,%0") 150259693Selan 150359693Selan;; Conversion between fixed point and floating point. 150459693Selan;; Note that among the fix-to-float insns 150559693Selan;; the ones that start with SImode come first. 150659693Selan;; That is so that an operand that is a CONST_INT 150759693Selan;; (and therefore lacks a specific machine mode). 150859693Selan;; will be recognized as SImode (which is always valid) 150959693Selan;; rather than as QImode or HImode. 151059693Selan 151159693Selan(define_expand "floatsisf2" 151259693Selan [(set (match_operand:SF 0 "general_operand" "") 151359693Selan (float:SF (match_operand:SI 1 "general_operand" "")))] 151459693Selan "TARGET_68881 || TARGET_FPA" 151559693Selan "") 151659693Selan 151759693Selan(define_insn "" 151859693Selan [(set (match_operand:SF 0 "general_operand" "=y,x") 151959693Selan (float:SF (match_operand:SI 1 "general_operand" "rmi,x")))] 152059693Selan "TARGET_FPA" 152159693Selan "fpltos %1,%0") 152259693Selan 152359693Selan(define_insn "" 152459693Selan [(set (match_operand:SF 0 "general_operand" "=f") 152559693Selan (float:SF (match_operand:SI 1 "general_operand" "dmi")))] 152659693Selan "TARGET_68881" 152759693Selan "f%$move%.l %1,%0") 152859693Selan 152959693Selan(define_expand "floatsidf2" 153059693Selan [(set (match_operand:DF 0 "general_operand" "") 153159693Selan (float:DF (match_operand:SI 1 "general_operand" "")))] 153259693Selan "TARGET_68881 || TARGET_FPA" 153359693Selan "") 153459693Selan 153559693Selan(define_insn "" 153659693Selan [(set (match_operand:DF 0 "general_operand" "=y,x") 153759693Selan (float:DF (match_operand:SI 1 "general_operand" "rmi,x")))] 153859693Selan "TARGET_FPA" 153959693Selan "fpltod %1,%0") 154059693Selan 154159693Selan(define_insn "" 154259693Selan [(set (match_operand:DF 0 "general_operand" "=f") 154359693Selan (float:DF (match_operand:SI 1 "general_operand" "dmi")))] 154459693Selan "TARGET_68881" 154559693Selan "f%&move%.l %1,%0") 154659693Selan 154759693Selan(define_insn "floathisf2" 154859693Selan [(set (match_operand:SF 0 "general_operand" "=f") 154959693Selan (float:SF (match_operand:HI 1 "general_operand" "dmn")))] 155059693Selan "TARGET_68881" 155159693Selan "f%$move%.w %1,%0") 155259693Selan 155359693Selan(define_insn "floathidf2" 155459693Selan [(set (match_operand:DF 0 "general_operand" "=f") 155559693Selan (float:DF (match_operand:HI 1 "general_operand" "dmn")))] 155659693Selan "TARGET_68881" 155759693Selan "fmove%.w %1,%0") 155859693Selan 155959693Selan(define_insn "floatqisf2" 156059693Selan [(set (match_operand:SF 0 "general_operand" "=f") 156159693Selan (float:SF (match_operand:QI 1 "general_operand" "dmn")))] 156259693Selan "TARGET_68881" 156359693Selan "fmove%.b %1,%0") 156459693Selan 156559693Selan(define_insn "floatqidf2" 156659693Selan [(set (match_operand:DF 0 "general_operand" "=f") 156759693Selan (float:DF (match_operand:QI 1 "general_operand" "dmn")))] 156859693Selan "TARGET_68881" 156959693Selan "f%&move%.b %1,%0") 157059693Selan 157159693Selan;; New routines to convert floating-point values to integers 157259693Selan;; to be used on the '040. These should be faster than trapping 157359693Selan;; into the kernel to emulate fintrz. They should also be faster 157459693Selan;; than calling the subroutines fixsfsi() or fixdfsi(). 157559693Selan 157659693Selan(define_insn "fix_truncdfsi2" 157759693Selan [(set (match_operand:SI 0 "general_operand" "=dm") 157859693Selan (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f")))) 157959693Selan (clobber (match_scratch:SI 2 "=d")) 158059693Selan (clobber (match_scratch:SI 3 "=d"))] 158159693Selan "TARGET_68040" 158259693Selan "* 158359693Selan{ 158459693Selan CC_STATUS_INIT; 158559693Selan 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,%!\"; 158659693Selan}") 158759693Selan 158859693Selan(define_insn "fix_truncdfhi2" 158959693Selan [(set (match_operand:HI 0 "general_operand" "=dm") 159059693Selan (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "f")))) 159159693Selan (clobber (match_scratch:SI 2 "=d")) 159259693Selan (clobber (match_scratch:SI 3 "=d"))] 159359693Selan "TARGET_68040" 159459693Selan "* 159559693Selan{ 159659693Selan CC_STATUS_INIT; 159759693Selan 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,%!\"; 159859693Selan}") 159959693Selan 160059693Selan(define_insn "fix_truncdfqi2" 160159693Selan [(set (match_operand:QI 0 "general_operand" "=dm") 160259693Selan (fix:QI (fix:DF (match_operand:DF 1 "register_operand" "f")))) 160359693Selan (clobber (match_scratch:SI 2 "=d")) 160459693Selan (clobber (match_scratch:SI 3 "=d"))] 160559693Selan "TARGET_68040" 160659693Selan "* 160759693Selan{ 160859693Selan CC_STATUS_INIT; 160959693Selan 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,%!\"; 161059693Selan}") 161159693Selan 161259693Selan;; Convert a float to a float whose value is an integer. 161359693Selan;; This is the first stage of converting it to an integer type. 161459693Selan 161559693Selan(define_insn "ftruncdf2" 161659693Selan [(set (match_operand:DF 0 "general_operand" "=f") 161759693Selan (fix:DF (match_operand:DF 1 "general_operand" "fFm")))] 161859693Selan "TARGET_68881 && !TARGET_68040" 161959693Selan "* 162059693Selan{ 162159693Selan if (FP_REG_P (operands[1])) 162259693Selan return \"fintrz%.x %f1,%0\"; 162359693Selan return \"fintrz%.d %f1,%0\"; 162459693Selan}") 162559693Selan 162659693Selan(define_insn "ftruncsf2" 162759693Selan [(set (match_operand:SF 0 "general_operand" "=f") 162859693Selan (fix:SF (match_operand:SF 1 "general_operand" "dfFm")))] 162959693Selan "TARGET_68881 && !TARGET_68040" 163059693Selan "* 163159693Selan{ 163259693Selan if (FP_REG_P (operands[1])) 163359693Selan return \"fintrz%.x %f1,%0\"; 163459693Selan return \"fintrz%.s %f1,%0\"; 163559693Selan}") 163659693Selan 163759693Selan;; Convert a float whose value is an integer 163859693Selan;; to an actual integer. Second stage of converting float to integer type. 163959693Selan(define_insn "fixsfqi2" 164059693Selan [(set (match_operand:QI 0 "general_operand" "=dm") 164159693Selan (fix:QI (match_operand:SF 1 "general_operand" "f")))] 164259693Selan "TARGET_68881" 164359693Selan "fmove%.b %1,%0") 164459693Selan 164559693Selan(define_insn "fixsfhi2" 164659693Selan [(set (match_operand:HI 0 "general_operand" "=dm") 164759693Selan (fix:HI (match_operand:SF 1 "general_operand" "f")))] 164859693Selan "TARGET_68881" 164959693Selan "fmove%.w %1,%0") 165059693Selan 165159693Selan(define_insn "fixsfsi2" 165259693Selan [(set (match_operand:SI 0 "general_operand" "=dm") 165359693Selan (fix:SI (match_operand:SF 1 "general_operand" "f")))] 165459693Selan "TARGET_68881" 165559693Selan "fmove%.l %1,%0") 165659693Selan 165759693Selan(define_insn "fixdfqi2" 165859693Selan [(set (match_operand:QI 0 "general_operand" "=dm") 165959693Selan (fix:QI (match_operand:DF 1 "general_operand" "f")))] 166059693Selan "TARGET_68881" 166159693Selan "fmove%.b %1,%0") 166259693Selan 166359693Selan(define_insn "fixdfhi2" 166459693Selan [(set (match_operand:HI 0 "general_operand" "=dm") 166559693Selan (fix:HI (match_operand:DF 1 "general_operand" "f")))] 166659693Selan "TARGET_68881" 166759693Selan "fmove%.w %1,%0") 166859693Selan 166959693Selan(define_insn "fixdfsi2" 167059693Selan [(set (match_operand:SI 0 "general_operand" "=dm") 167159693Selan (fix:SI (match_operand:DF 1 "general_operand" "f")))] 167259693Selan "TARGET_68881" 167359693Selan "fmove%.l %1,%0") 167459693Selan 167559693Selan;; Convert a float to an integer. 167659693Selan;; On the Sun FPA, this is done in one step. 167759693Selan 167859693Selan(define_insn "" 167959693Selan [(set (match_operand:SI 0 "general_operand" "=x,y") 168059693Selan (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "xH,rmF"))))] 168159693Selan "TARGET_FPA" 168259693Selan "fpstol %w1,%0") 168359693Selan 168459693Selan(define_insn "" 168559693Selan [(set (match_operand:SI 0 "general_operand" "=x,y") 168659693Selan (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "xH,rmF"))))] 168759693Selan "TARGET_FPA" 168859693Selan "fpdtol %y1,%0") 168959693Selan 169059693Selan;; add instructions 169159693Selan 169259693Selan;; Note that the middle two alternatives are near-duplicates 169359693Selan;; in order to handle insns generated by reload. 169459693Selan;; This is needed since they are not themselves reloaded, 169559693Selan;; so commutativity won't apply to them. 169659693Selan(define_insn "addsi3" 169759693Selan [(set (match_operand:SI 0 "general_operand" "=m,?a,?a,r") 169859693Selan (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0") 169959693Selan (match_operand:SI 2 "general_operand" "dIKLs,rJK,a,mrIKLs")))] 170059693Selan "" 170159693Selan "* 170259693Selan{ 170359693Selan if (! operands_match_p (operands[0], operands[1])) 170459693Selan { 170559693Selan if (!ADDRESS_REG_P (operands[1])) 170659693Selan { 170759693Selan rtx tmp = operands[1]; 170859693Selan 170959693Selan operands[1] = operands[2]; 171059693Selan operands[2] = tmp; 171159693Selan } 171259693Selan 171359693Selan /* These insns can result from reloads to access 171459693Selan stack slots over 64k from the frame pointer. */ 171559693Selan if (GET_CODE (operands[2]) == CONST_INT 171659693Selan && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000) 171759693Selan return \"move%.l %2,%0\;add%.l %1,%0\"; 171859693Selan#ifdef SGS 171959693Selan if (GET_CODE (operands[2]) == REG) 172059693Selan return \"lea 0(%1,%2.l),%0\"; 172159693Selan else 172259693Selan return \"lea %c2(%1),%0\"; 172359693Selan#else /* not SGS */ 172459693Selan#ifdef MOTOROLA 172559693Selan if (GET_CODE (operands[2]) == REG) 172659693Selan return \"lea (%1,%2.l),%0\"; 172759693Selan else 172859693Selan return \"lea (%c2,%1),%0\"; 172959693Selan#else /* not MOTOROLA (MIT syntax) */ 173059693Selan if (GET_CODE (operands[2]) == REG) 173159693Selan return \"lea %1@(0,%2:l),%0\"; 173259693Selan else 173359693Selan return \"lea %1@(%c2),%0\"; 173459693Selan#endif /* not MOTOROLA */ 173559693Selan#endif /* not SGS */ 173659693Selan } 173759693Selan if (GET_CODE (operands[2]) == CONST_INT) 173859693Selan { 173959693Selan#ifndef NO_ADDSUB_Q 174059693Selan if (INTVAL (operands[2]) > 0 174159693Selan && INTVAL (operands[2]) <= 8) 174259693Selan return (ADDRESS_REG_P (operands[0]) 174359693Selan ? \"addq%.w %2,%0\" 174459693Selan : \"addq%.l %2,%0\"); 174559693Selan if (INTVAL (operands[2]) < 0 174659693Selan && INTVAL (operands[2]) >= -8) 174759693Selan { 174859693Selan operands[2] = gen_rtx (CONST_INT, VOIDmode, 174959693Selan - INTVAL (operands[2])); 175059693Selan return (ADDRESS_REG_P (operands[0]) 175159693Selan ? \"subq%.w %2,%0\" 175259693Selan : \"subq%.l %2,%0\"); 175359693Selan } 175459693Selan /* On everything except the 68000 it is faster to use two 175559693Selan addqw instructions to add a small integer (8 < N <= 16) 175659693Selan to an address register. Likewise for subqw.*/ 175759693Selan if (INTVAL (operands[2]) > 8 175859693Selan && INTVAL (operands[2]) <= 16 175959693Selan && ADDRESS_REG_P (operands[0]) 176059693Selan && TARGET_68020) 176159693Selan { 176259693Selan operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8); 176359693Selan return \"addq%.w %#8,%0\;addq%.w %2,%0\"; 176459693Selan } 176559693Selan if (INTVAL (operands[2]) < -8 176659693Selan && INTVAL (operands[2]) >= -16 176759693Selan && ADDRESS_REG_P (operands[0]) 176859693Selan && TARGET_68020) 176959693Selan { 177059693Selan operands[2] = gen_rtx (CONST_INT, VOIDmode, 177159693Selan - INTVAL (operands[2]) - 8); 177259693Selan return \"subq%.w %#8,%0\;subq%.w %2,%0\"; 177359693Selan } 177459693Selan#endif 177559693Selan if (ADDRESS_REG_P (operands[0]) 177659693Selan && INTVAL (operands[2]) >= -0x8000 177759693Selan && INTVAL (operands[2]) < 0x8000) 177859693Selan return \"add%.w %2,%0\"; 177959693Selan } 178059693Selan return \"add%.l %2,%0\"; 178159693Selan}") 178259693Selan 178359693Selan(define_insn "" 178459693Selan [(set (match_operand:SI 0 "general_operand" "=a") 178559693Selan (plus:SI (match_operand:SI 1 "general_operand" "0") 178659693Selan (sign_extend:SI 178759693Selan (match_operand:HI 2 "nonimmediate_operand" "rm"))))] 178859693Selan "" 178959693Selan "add%.w %2,%0") 179059693Selan 179159693Selan(define_insn "addhi3" 179259693Selan [(set (match_operand:HI 0 "general_operand" "=m,r") 179359693Selan (plus:HI (match_operand:HI 1 "general_operand" "%0,0") 179459693Selan (match_operand:HI 2 "general_operand" "dn,rmn")))] 179559693Selan "" 179659693Selan "* 179759693Selan{ 179859693Selan#ifndef NO_ADDSUB_Q 179959693Selan if (GET_CODE (operands[2]) == CONST_INT) 180059693Selan { 180159693Selan /* If the constant would be a negative number when interpreted as 180259693Selan HImode, make it negative. This is usually, but not always, done 180359693Selan elsewhere in the compiler. First check for constants out of range, 180459693Selan which could confuse us. */ 180559693Selan 180659693Selan if (INTVAL (operands[2]) >= 32768) 180759693Selan operands[2] = gen_rtx (CONST_INT, VOIDmode, 180859693Selan INTVAL (operands[2]) - 65536); 180959693Selan 181059693Selan if (INTVAL (operands[2]) > 0 181159693Selan && INTVAL (operands[2]) <= 8) 181259693Selan return \"addq%.w %2,%0\"; 181359693Selan if (INTVAL (operands[2]) < 0 181459693Selan && INTVAL (operands[2]) >= -8) 181559693Selan { 181659693Selan operands[2] = gen_rtx (CONST_INT, VOIDmode, 181759693Selan - INTVAL (operands[2])); 181859693Selan return \"subq%.w %2,%0\"; 181959693Selan } 182059693Selan /* On everything except the 68000 it is faster to use two 182159693Selan addqw instructions to add a small integer (8 < N <= 16) 182259693Selan to an address register. Likewise for subqw. */ 182359693Selan if (INTVAL (operands[2]) > 8 182459693Selan && INTVAL (operands[2]) <= 16 182559693Selan && ADDRESS_REG_P (operands[0]) 182659693Selan && TARGET_68020) 182759693Selan { 182859693Selan operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8); 182959693Selan return \"addq%.w %#8,%0\;addq%.w %2,%0\"; 183059693Selan } 183159693Selan if (INTVAL (operands[2]) < -8 183259693Selan && INTVAL (operands[2]) >= -16 183359693Selan && ADDRESS_REG_P (operands[0]) 183459693Selan && TARGET_68020) 183559693Selan { 183659693Selan operands[2] = gen_rtx (CONST_INT, VOIDmode, 183759693Selan - INTVAL (operands[2]) - 8); 183859693Selan return \"subq%.w %#8,%0\;subq%.w %2,%0\"; 183959693Selan } 184059693Selan } 184159693Selan#endif 184259693Selan return \"add%.w %2,%0\"; 184359693Selan}") 184459693Selan 184559693Selan;; These insns must use MATCH_DUP instead of the more expected 184659693Selan;; use of a matching constraint because the "output" here is also 184759693Selan;; an input, so you can't use the matching constraint. That also means 184859693Selan;; that you can't use the "%", so you need patterns with the matched 184959693Selan;; operand in both positions. 185059693Selan 185159693Selan(define_insn "" 185259693Selan [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) 185359693Selan (plus:HI (match_dup 0) 185459693Selan (match_operand:HI 1 "general_operand" "dn,rmn")))] 185559693Selan "" 185659693Selan "* 185759693Selan{ 185859693Selan#ifndef NO_ADDSUB_Q 185959693Selan if (GET_CODE (operands[1]) == CONST_INT) 186059693Selan { 186159693Selan /* If the constant would be a negative number when interpreted as 186259693Selan HImode, make it negative. This is usually, but not always, done 186359693Selan elsewhere in the compiler. First check for constants out of range, 186459693Selan which could confuse us. */ 186559693Selan 186659693Selan if (INTVAL (operands[1]) >= 32768) 186759693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, 186859693Selan INTVAL (operands[1]) - 65536); 186959693Selan 187059693Selan if (INTVAL (operands[1]) > 0 187159693Selan && INTVAL (operands[1]) <= 8) 187259693Selan return \"addq%.w %1,%0\"; 187359693Selan if (INTVAL (operands[1]) < 0 187459693Selan && INTVAL (operands[1]) >= -8) 187559693Selan { 187659693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, 187759693Selan - INTVAL (operands[1])); 187859693Selan return \"subq%.w %1,%0\"; 187959693Selan } 188059693Selan /* On everything except the 68000 it is faster to use two 188159693Selan addqw instructions to add a small integer (8 < N <= 16) 188259693Selan to an address register. Likewise for subqw. */ 188359693Selan if (INTVAL (operands[1]) > 8 188459693Selan && INTVAL (operands[1]) <= 16 188559693Selan && ADDRESS_REG_P (operands[0]) 188659693Selan && TARGET_68020) 188759693Selan { 188859693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8); 188959693Selan return \"addq%.w %#8,%0\;addq%.w %1,%0\"; 189059693Selan } 189159693Selan if (INTVAL (operands[1]) < -8 189259693Selan && INTVAL (operands[1]) >= -16 189359693Selan && ADDRESS_REG_P (operands[0]) 189459693Selan && TARGET_68020) 189559693Selan { 189659693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, 189759693Selan - INTVAL (operands[1]) - 8); 189859693Selan return \"subq%.w %#8,%0\;subq%.w %1,%0\"; 189959693Selan } 190059693Selan } 190159693Selan#endif 190259693Selan return \"add%.w %1,%0\"; 190359693Selan}") 190459693Selan 190559693Selan(define_insn "" 190659693Selan [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) 190759693Selan (plus:HI (match_operand:HI 1 "general_operand" "dn,rmn") 190859693Selan (match_dup 0)))] 190959693Selan "" 191059693Selan "* 191159693Selan{ 191259693Selan#ifndef NO_ADDSUB_Q 191359693Selan if (GET_CODE (operands[1]) == CONST_INT) 191459693Selan { 191559693Selan /* If the constant would be a negative number when interpreted as 191659693Selan HImode, make it negative. This is usually, but not always, done 191759693Selan elsewhere in the compiler. First check for constants out of range, 191859693Selan which could confuse us. */ 191959693Selan 192059693Selan if (INTVAL (operands[1]) >= 32768) 192159693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, 192259693Selan INTVAL (operands[1]) - 65536); 192359693Selan 192459693Selan if (INTVAL (operands[1]) > 0 192559693Selan && INTVAL (operands[1]) <= 8) 192659693Selan return \"addq%.w %1,%0\"; 192759693Selan if (INTVAL (operands[1]) < 0 192859693Selan && INTVAL (operands[1]) >= -8) 192959693Selan { 193059693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, 193159693Selan - INTVAL (operands[1])); 193259693Selan return \"subq%.w %1,%0\"; 193359693Selan } 193459693Selan /* On everything except the 68000 it is faster to use two 193559693Selan addqw instructions to add a small integer (8 < N <= 16) 193659693Selan to an address register. Likewise for subqw. */ 193759693Selan if (INTVAL (operands[1]) > 8 193859693Selan && INTVAL (operands[1]) <= 16 193959693Selan && ADDRESS_REG_P (operands[0]) 194059693Selan && TARGET_68020) 194159693Selan { 194259693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8); 194359693Selan return \"addq%.w %#8,%0\;addq%.w %1,%0\"; 194459693Selan } 194559693Selan if (INTVAL (operands[1]) < -8 194659693Selan && INTVAL (operands[1]) >= -16 194759693Selan && ADDRESS_REG_P (operands[0]) 194859693Selan && TARGET_68020) 194959693Selan { 195059693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, 195159693Selan - INTVAL (operands[1]) - 8); 195259693Selan return \"subq%.w %#8,%0\;subq%.w %1,%0\"; 195359693Selan } 195459693Selan } 195559693Selan#endif 195659693Selan return \"add%.w %1,%0\"; 195759693Selan}") 195859693Selan 195959693Selan(define_insn "addqi3" 196059693Selan [(set (match_operand:QI 0 "general_operand" "=m,d") 196159693Selan (plus:QI (match_operand:QI 1 "general_operand" "%0,0") 196259693Selan (match_operand:QI 2 "general_operand" "dn,dmn")))] 196359693Selan "" 196459693Selan "* 196559693Selan{ 196659693Selan#ifndef NO_ADDSUB_Q 196759693Selan if (GET_CODE (operands[2]) == CONST_INT) 196859693Selan { 196959693Selan if (INTVAL (operands[2]) >= 128) 197059693Selan operands[2] = gen_rtx (CONST_INT, VOIDmode, 197159693Selan INTVAL (operands[2]) - 256); 197259693Selan 197359693Selan if (INTVAL (operands[2]) > 0 197459693Selan && INTVAL (operands[2]) <= 8) 197559693Selan return \"addq%.b %2,%0\"; 197659693Selan if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) >= -8) 197759693Selan { 197859693Selan operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2])); 197959693Selan return \"subq%.b %2,%0\"; 198059693Selan } 198159693Selan } 198259693Selan#endif 198359693Selan return \"add%.b %2,%0\"; 198459693Selan}") 198559693Selan 198659693Selan(define_insn "" 198759693Selan [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) 198859693Selan (plus:QI (match_dup 0) 198959693Selan (match_operand:QI 1 "general_operand" "dn,dmn")))] 199059693Selan "" 199159693Selan "* 199259693Selan{ 199359693Selan#ifndef NO_ADDSUB_Q 199459693Selan if (GET_CODE (operands[1]) == CONST_INT) 199559693Selan { 199659693Selan if (INTVAL (operands[1]) >= 128) 199759693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, 199859693Selan INTVAL (operands[1]) - 256); 199959693Selan 200059693Selan if (INTVAL (operands[1]) > 0 200159693Selan && INTVAL (operands[1]) <= 8) 200259693Selan return \"addq%.b %1,%0\"; 200359693Selan if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8) 200459693Selan { 200559693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1])); 200659693Selan return \"subq%.b %1,%0\"; 200759693Selan } 200859693Selan } 200959693Selan#endif 201059693Selan return \"add%.b %1,%0\"; 201159693Selan}") 201259693Selan 201359693Selan(define_insn "" 201459693Selan [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) 201559693Selan (plus:QI (match_operand:QI 1 "general_operand" "dn,dmn") 201659693Selan (match_dup 0)))] 201759693Selan "" 201859693Selan "* 201959693Selan{ 202059693Selan#ifndef NO_ADDSUB_Q 202159693Selan if (GET_CODE (operands[1]) == CONST_INT) 202259693Selan { 202359693Selan if (INTVAL (operands[1]) >= 128) 202459693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, 202559693Selan INTVAL (operands[1]) - 256); 202659693Selan 202759693Selan if (INTVAL (operands[1]) > 0 202859693Selan && INTVAL (operands[1]) <= 8) 202959693Selan return \"addq%.b %1,%0\"; 203059693Selan if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8) 203159693Selan { 203259693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1])); 203359693Selan return \"subq%.b %1,%0\"; 203459693Selan } 203559693Selan } 203659693Selan#endif 203759693Selan return \"add%.b %1,%0\"; 203859693Selan}") 203959693Selan 204059693Selan(define_expand "adddf3" 204159693Selan [(set (match_operand:DF 0 "general_operand" "") 204259693Selan (plus:DF (match_operand:DF 1 "general_operand" "") 204359693Selan (match_operand:DF 2 "general_operand" "")))] 204459693Selan "TARGET_68881 || TARGET_FPA" 204559693Selan "") 204659693Selan 204759693Selan(define_insn "" 204859693Selan [(set (match_operand:DF 0 "general_operand" "=x,y") 204959693Selan (plus:DF (match_operand:DF 1 "general_operand" "%xH,y") 205059693Selan (match_operand:DF 2 "general_operand" "xH,dmF")))] 205159693Selan "TARGET_FPA" 205259693Selan "* 205359693Selan{ 205459693Selan if (rtx_equal_p (operands[0], operands[1])) 205559693Selan return \"fpadd%.d %y2,%0\"; 205659693Selan if (rtx_equal_p (operands[0], operands[2])) 205759693Selan return \"fpadd%.d %y1,%0\"; 205859693Selan if (which_alternative == 0) 205959693Selan return \"fpadd3%.d %w2,%w1,%0\"; 206059693Selan return \"fpadd3%.d %x2,%x1,%0\"; 206159693Selan}") 206259693Selan 206359693Selan(define_insn "" 206459693Selan [(set (match_operand:DF 0 "general_operand" "=f") 206559693Selan (plus:DF (match_operand:DF 1 "general_operand" "%0") 206659693Selan (match_operand:DF 2 "general_operand" "fmG")))] 206759693Selan "TARGET_68881" 206859693Selan "* 206959693Selan{ 207059693Selan if (REG_P (operands[2])) 207159693Selan return \"f%&add%.x %2,%0\"; 207259693Selan return \"f%&add%.d %f2,%0\"; 207359693Selan}") 207459693Selan 207559693Selan(define_expand "addsf3" 207659693Selan [(set (match_operand:SF 0 "general_operand" "") 207759693Selan (plus:SF (match_operand:SF 1 "general_operand" "") 207859693Selan (match_operand:SF 2 "general_operand" "")))] 207959693Selan "TARGET_68881 || TARGET_FPA" 208059693Selan "") 208159693Selan 208259693Selan(define_insn "" 208359693Selan [(set (match_operand:SF 0 "general_operand" "=x,y") 208459693Selan (plus:SF (match_operand:SF 1 "general_operand" "%xH,y") 208559693Selan (match_operand:SF 2 "general_operand" "xH,rmF")))] 208659693Selan "TARGET_FPA" 208759693Selan "* 208859693Selan{ 208959693Selan if (rtx_equal_p (operands[0], operands[1])) 209059693Selan return \"fpadd%.s %w2,%0\"; 209159693Selan if (rtx_equal_p (operands[0], operands[2])) 209259693Selan return \"fpadd%.s %w1,%0\"; 209359693Selan if (which_alternative == 0) 209459693Selan return \"fpadd3%.s %w2,%w1,%0\"; 209559693Selan return \"fpadd3%.s %2,%1,%0\"; 209659693Selan}") 209759693Selan 209859693Selan(define_insn "" 209959693Selan [(set (match_operand:SF 0 "general_operand" "=f") 210059693Selan (plus:SF (match_operand:SF 1 "general_operand" "%0") 210159693Selan (match_operand:SF 2 "general_operand" "fdmF")))] 210259693Selan "TARGET_68881" 210359693Selan "* 210459693Selan{ 210559693Selan if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) 210659693Selan return \"f%$add%.x %2,%0\"; 210759693Selan return \"f%$add%.s %f2,%0\"; 210859693Selan}") 210959693Selan 211059693Selan;; subtract instructions 211159693Selan 211259693Selan(define_insn "subsi3" 211359693Selan [(set (match_operand:SI 0 "general_operand" "=m,r,!a,?d") 211459693Selan (minus:SI (match_operand:SI 1 "general_operand" "0,0,a,mrIKs") 211559693Selan (match_operand:SI 2 "general_operand" "dIKs,mrIKs,J,0")))] 211659693Selan "" 211759693Selan "* 211859693Selan{ 211959693Selan if (! operands_match_p (operands[0], operands[1])) 212059693Selan { 212159693Selan if (operands_match_p (operands[0], operands[2])) 212259693Selan { 212359693Selan#ifndef NO_ADDSUB_Q 212459693Selan if (GET_CODE (operands[1]) == CONST_INT) 212559693Selan { 212659693Selan if (INTVAL (operands[1]) > 0 212759693Selan && INTVAL (operands[1]) <= 8) 212859693Selan return \"subq%.l %1,%0\;neg%.l %0\"; 212959693Selan } 213059693Selan#endif 213159693Selan return \"sub%.l %1,%0\;neg%.l %0\"; 213259693Selan } 213359693Selan /* This case is matched by J, but negating -0x8000 213459693Selan in an lea would give an invalid displacement. 213559693Selan So do this specially. */ 213659693Selan if (INTVAL (operands[2]) == -0x8000) 213759693Selan return \"move%.l %1,%0\;sub%.l %2,%0\"; 213859693Selan#ifdef SGS 213959693Selan return \"lea %n2(%1),%0\"; 214059693Selan#else 214159693Selan#ifdef MOTOROLA 214259693Selan return \"lea (%n2,%1),%0\"; 214359693Selan#else /* not MOTOROLA (MIT syntax) */ 214459693Selan return \"lea %1@(%n2),%0\"; 214559693Selan#endif /* not MOTOROLA */ 214659693Selan#endif /* not SGS */ 214759693Selan } 214859693Selan if (GET_CODE (operands[2]) == CONST_INT) 214959693Selan { 215059693Selan#ifndef NO_ADDSUB_Q 215159693Selan if (INTVAL (operands[2]) > 0 215259693Selan && INTVAL (operands[2]) <= 8) 215359693Selan return \"subq%.l %2,%0\"; 215459693Selan /* Using two subqw for 8 < N <= 16 being subtracted from an 215559693Selan address register is faster on all but 68000 */ 215659693Selan if (INTVAL (operands[2]) > 8 215759693Selan && INTVAL (operands[2]) <= 16 215859693Selan && ADDRESS_REG_P (operands[0]) 215959693Selan && TARGET_68020) 216059693Selan { 216159693Selan operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8); 216259693Selan return \"subq%.w %#8,%0\;subq%.w %2,%0\"; 216359693Selan } 216459693Selan#endif 216559693Selan if (ADDRESS_REG_P (operands[0]) 216659693Selan && INTVAL (operands[2]) >= -0x8000 216759693Selan && INTVAL (operands[2]) < 0x8000) 216859693Selan return \"sub%.w %2,%0\"; 216959693Selan } 217059693Selan return \"sub%.l %2,%0\"; 217159693Selan}") 217259693Selan 217359693Selan(define_insn "" 217459693Selan [(set (match_operand:SI 0 "general_operand" "=a") 217559693Selan (minus:SI (match_operand:SI 1 "general_operand" "0") 217659693Selan (sign_extend:SI 217759693Selan (match_operand:HI 2 "nonimmediate_operand" "rm"))))] 217859693Selan "" 217959693Selan "sub%.w %2,%0") 218059693Selan 218159693Selan(define_insn "subhi3" 218259693Selan [(set (match_operand:HI 0 "general_operand" "=m,r") 218359693Selan (minus:HI (match_operand:HI 1 "general_operand" "0,0") 218459693Selan (match_operand:HI 2 "general_operand" "dn,rmn")))] 218559693Selan "" 218659693Selan "sub%.w %2,%0") 218759693Selan 218859693Selan(define_insn "" 218959693Selan [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) 219059693Selan (minus:HI (match_dup 0) 219159693Selan (match_operand:HI 1 "general_operand" "dn,rmn")))] 219259693Selan "" 219359693Selan "sub%.w %1,%0") 219459693Selan 219559693Selan(define_insn "subqi3" 219659693Selan [(set (match_operand:QI 0 "general_operand" "=m,d") 219759693Selan (minus:QI (match_operand:QI 1 "general_operand" "0,0") 219859693Selan (match_operand:QI 2 "general_operand" "dn,dmn")))] 219959693Selan "" 220059693Selan "sub%.b %2,%0") 220159693Selan 220259693Selan(define_insn "" 220359693Selan [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) 220459693Selan (minus:QI (match_dup 0) 220559693Selan (match_operand:QI 1 "general_operand" "dn,dmn")))] 220659693Selan "" 220759693Selan "sub%.b %1,%0") 220859693Selan 220959693Selan(define_expand "subdf3" 221059693Selan [(set (match_operand:DF 0 "general_operand" "") 221159693Selan (minus:DF (match_operand:DF 1 "general_operand" "") 221259693Selan (match_operand:DF 2 "general_operand" "")))] 221359693Selan "TARGET_68881 || TARGET_FPA" 221459693Selan "") 221559693Selan 221659693Selan(define_insn "" 221759693Selan [(set (match_operand:DF 0 "general_operand" "=x,y,y") 221859693Selan (minus:DF (match_operand:DF 1 "general_operand" "xH,y,dmF") 221959693Selan (match_operand:DF 2 "general_operand" "xH,dmF,0")))] 222059693Selan "TARGET_FPA" 222159693Selan "* 222259693Selan{ 222359693Selan if (rtx_equal_p (operands[0], operands[2])) 222459693Selan return \"fprsub%.d %y1,%0\"; 222559693Selan if (rtx_equal_p (operands[0], operands[1])) 222659693Selan return \"fpsub%.d %y2,%0\"; 222759693Selan if (which_alternative == 0) 222859693Selan return \"fpsub3%.d %w2,%w1,%0\"; 222959693Selan return \"fpsub3%.d %x2,%x1,%0\"; 223059693Selan}") 223159693Selan 223259693Selan(define_insn "" 223359693Selan [(set (match_operand:DF 0 "general_operand" "=f") 223459693Selan (minus:DF (match_operand:DF 1 "general_operand" "0") 223559693Selan (match_operand:DF 2 "general_operand" "fmG")))] 223659693Selan "TARGET_68881" 223759693Selan "* 223859693Selan{ 223959693Selan if (REG_P (operands[2])) 224059693Selan return \"f%&sub%.x %2,%0\"; 224159693Selan return \"f%&sub%.d %f2,%0\"; 224259693Selan}") 224359693Selan 224459693Selan(define_expand "subsf3" 224559693Selan [(set (match_operand:SF 0 "general_operand" "") 224659693Selan (minus:SF (match_operand:SF 1 "general_operand" "") 224759693Selan (match_operand:SF 2 "general_operand" "")))] 224859693Selan "TARGET_68881 || TARGET_FPA" 224959693Selan "") 225059693Selan 225159693Selan(define_insn "" 225259693Selan [(set (match_operand:SF 0 "general_operand" "=x,y,y") 225359693Selan (minus:SF (match_operand:SF 1 "general_operand" "xH,y,rmF") 225459693Selan (match_operand:SF 2 "general_operand" "xH,rmF,0")))] 225559693Selan "TARGET_FPA" 225659693Selan "* 225759693Selan{ 225859693Selan if (rtx_equal_p (operands[0], operands[2])) 225959693Selan return \"fprsub%.s %w1,%0\"; 226059693Selan if (rtx_equal_p (operands[0], operands[1])) 226159693Selan return \"fpsub%.s %w2,%0\"; 226259693Selan if (which_alternative == 0) 226359693Selan return \"fpsub3%.s %w2,%w1,%0\"; 226459693Selan return \"fpsub3%.s %2,%1,%0\"; 226559693Selan}") 226659693Selan 226759693Selan(define_insn "" 226859693Selan [(set (match_operand:SF 0 "general_operand" "=f") 226959693Selan (minus:SF (match_operand:SF 1 "general_operand" "0") 227059693Selan (match_operand:SF 2 "general_operand" "fdmF")))] 227159693Selan "TARGET_68881" 227259693Selan "* 227359693Selan{ 227459693Selan if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) 227559693Selan return \"f%$sub%.x %2,%0\"; 227659693Selan return \"f%$sub%.s %f2,%0\"; 227759693Selan}") 227859693Selan 227959693Selan;; multiply instructions 228059693Selan 228159693Selan(define_insn "mulhi3" 228259693Selan [(set (match_operand:HI 0 "general_operand" "=d") 228359693Selan (mult:HI (match_operand:HI 1 "general_operand" "%0") 228459693Selan (match_operand:HI 2 "general_operand" "dmn")))] 228559693Selan "" 228659693Selan "* 228759693Selan{ 228859693Selan#if defined(MOTOROLA) && !defined(CRDS) 228959693Selan return \"muls%.w %2,%0\"; 229059693Selan#else 229159693Selan return \"muls %2,%0\"; 229259693Selan#endif 229359693Selan}") 229459693Selan 229559693Selan(define_insn "mulhisi3" 229659693Selan [(set (match_operand:SI 0 "general_operand" "=d") 229759693Selan (mult:SI (sign_extend:SI 229859693Selan (match_operand:HI 1 "nonimmediate_operand" "%0")) 229959693Selan (sign_extend:SI 230059693Selan (match_operand:HI 2 "nonimmediate_operand" "dm"))))] 230159693Selan "" 230259693Selan "* 230359693Selan{ 230459693Selan#if defined(MOTOROLA) && !defined(CRDS) 230559693Selan return \"muls%.w %2,%0\"; 230659693Selan#else 230759693Selan return \"muls %2,%0\"; 230859693Selan#endif 230959693Selan}") 231059693Selan 231159693Selan(define_insn "" 231259693Selan [(set (match_operand:SI 0 "general_operand" "=d") 231359693Selan (mult:SI (sign_extend:SI 231459693Selan (match_operand:HI 1 "nonimmediate_operand" "%0")) 231559693Selan (match_operand:SI 2 "const_int_operand" "n")))] 231659693Selan "" 231759693Selan "* 231859693Selan{ 231959693Selan#if defined(MOTOROLA) && !defined(CRDS) 232059693Selan return \"muls%.w %2,%0\"; 232159693Selan#else 232259693Selan return \"muls %2,%0\"; 232359693Selan#endif 232459693Selan}") 232559693Selan 232659693Selan(define_insn "mulsi3" 232759693Selan [(set (match_operand:SI 0 "general_operand" "=d") 232859693Selan (mult:SI (match_operand:SI 1 "general_operand" "%0") 232959693Selan (match_operand:SI 2 "general_operand" "dmsK")))] 233059693Selan "TARGET_68020" 233159693Selan "muls%.l %2,%0") 233259693Selan 233359693Selan(define_insn "umulhisi3" 233459693Selan [(set (match_operand:SI 0 "general_operand" "=d") 233559693Selan (mult:SI (zero_extend:SI 233659693Selan (match_operand:HI 1 "nonimmediate_operand" "%0")) 233759693Selan (zero_extend:SI 233859693Selan (match_operand:HI 2 "nonimmediate_operand" "dm"))))] 233959693Selan "" 234059693Selan "* 234159693Selan{ 234259693Selan#if defined(MOTOROLA) && !defined(CRDS) 234359693Selan return \"mulu%.w %2,%0\"; 234459693Selan#else 234559693Selan return \"mulu %2,%0\"; 234659693Selan#endif 234759693Selan}") 234859693Selan 234959693Selan(define_insn "" 235059693Selan [(set (match_operand:SI 0 "general_operand" "=d") 235159693Selan (mult:SI (zero_extend:SI 235259693Selan (match_operand:HI 1 "nonimmediate_operand" "%0")) 235359693Selan (match_operand:SI 2 "const_int_operand" "n")))] 235459693Selan "" 235559693Selan "* 235659693Selan{ 235759693Selan#if defined(MOTOROLA) && !defined(CRDS) 235859693Selan return \"mulu%.w %2,%0\"; 235959693Selan#else 236059693Selan return \"mulu %2,%0\"; 236159693Selan#endif 236259693Selan}") 236359693Selan 236459693Selan;; We need a separate DEFINE_EXPAND for u?mulsidi3 to be able to use the 236559693Selan;; proper matching constraint. This is because the matching is between 236659693Selan;; the high-numbered word of the DImode operand[0] and operand[1]. 236759693Selan(define_expand "umulsidi3" 236859693Selan [(parallel 236959693Selan [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 1) 237059693Selan (subreg:SI 237159693Selan (mult:DI (zero_extend:DI 237259693Selan (match_operand:SI 1 "register_operand" "")) 237359693Selan (zero_extend:DI 237459693Selan (match_operand:SI 2 "nonimmediate_operand" ""))) 1)) 237559693Selan (set (subreg:SI (match_dup 0) 0) 237659693Selan (subreg:SI 237759693Selan (mult:DI (zero_extend:DI 237859693Selan (match_dup 1)) 237959693Selan (zero_extend:DI 238059693Selan (match_dup 2))) 0))])] 238159693Selan "TARGET_68020" 238259693Selan "") 238359693Selan 238459693Selan(define_insn "" 238559693Selan [(set (match_operand:SI 0 "register_operand" "=d") 238659693Selan (subreg:SI 238759693Selan (mult:DI (zero_extend:DI 238859693Selan (match_operand:SI 1 "register_operand" "%0")) 238959693Selan (zero_extend:DI 239059693Selan (match_operand:SI 2 "nonimmediate_operand" "dm"))) 1)) 239159693Selan (set (match_operand:SI 3 "register_operand" "=d") 239259693Selan (subreg:SI 239359693Selan (mult:DI (zero_extend:DI 239459693Selan (match_dup 1)) 239559693Selan (zero_extend:DI 239659693Selan (match_dup 2))) 0))] 239759693Selan "TARGET_68020" 239859693Selan "mulu%.l %2,%3:%0") 239959693Selan 240059693Selan(define_insn "" 240159693Selan [(set (match_operand:SI 0 "register_operand" "=d") 240259693Selan (subreg:SI 240359693Selan (mult:DI (zero_extend:DI 240459693Selan (match_operand:SI 1 "register_operand" "%0")) 240559693Selan (match_operand:SI 2 "immediate_operand" "sK")) 1)) 240659693Selan (set (match_operand:SI 3 "register_operand" "=d") 240759693Selan (subreg:SI 240859693Selan (mult:DI (zero_extend:DI 240959693Selan (match_dup 1)) 241059693Selan (match_dup 2)) 0))] 241159693Selan "TARGET_68020 241259693Selan && (GET_CODE (operands[2]) != CONST_INT 241359693Selan || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))" 241459693Selan "mulu%.l %2,%3:%0") 241559693Selan 241659693Selan(define_expand "mulsidi3" 241759693Selan [(parallel 241859693Selan [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 1) 241959693Selan (subreg:SI 242059693Selan (mult:DI (sign_extend:DI 242159693Selan (match_operand:SI 1 "register_operand" "")) 242259693Selan (sign_extend:DI 242359693Selan (match_operand:SI 2 "nonimmediate_operand" ""))) 1)) 242459693Selan (set (subreg:SI (match_dup 0) 0) 242559693Selan (subreg:SI 242659693Selan (mult:DI (sign_extend:DI 242759693Selan (match_dup 1)) 242859693Selan (sign_extend:DI 242959693Selan (match_dup 2))) 0))])] 243059693Selan "TARGET_68020" 243159693Selan "") 243259693Selan 243359693Selan(define_insn "" 243459693Selan [(set (match_operand:SI 0 "register_operand" "=d") 243559693Selan (subreg:SI 243659693Selan (mult:DI (sign_extend:DI 243759693Selan (match_operand:SI 1 "register_operand" "%0")) 243859693Selan (sign_extend:DI 243959693Selan (match_operand:SI 2 "nonimmediate_operand" "dm"))) 1)) 244059693Selan (set (match_operand:SI 3 "register_operand" "=d") 244159693Selan (subreg:SI 244259693Selan (mult:DI (sign_extend:DI 244359693Selan (match_dup 1)) 244459693Selan (sign_extend:DI 244559693Selan (match_dup 2))) 0))] 244659693Selan "TARGET_68020" 244759693Selan "muls%.l %2,%3:%0") 244859693Selan 244959693Selan(define_insn "" 245059693Selan [(set (match_operand:SI 0 "register_operand" "=d") 245159693Selan (subreg:SI 245259693Selan (mult:DI (sign_extend:DI 245359693Selan (match_operand:SI 1 "register_operand" "%0")) 245459693Selan (match_operand:SI 2 "immediate_operand" "sK")) 1)) 245559693Selan (set (match_operand:SI 3 "register_operand" "=d") 245659693Selan (subreg:SI 245759693Selan (mult:DI (sign_extend:DI 245859693Selan (match_dup 1)) 245959693Selan (match_dup 2)) 0))] 246059693Selan "TARGET_68020 246159693Selan && (GET_CODE (operands[2]) != CONST_INT 246259693Selan || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))" 246359693Selan "muls%.l %2,%3:%0") 246459693Selan 246559693Selan(define_expand "muldf3" 246659693Selan [(set (match_operand:DF 0 "general_operand" "") 246759693Selan (mult:DF (match_operand:DF 1 "general_operand" "") 246859693Selan (match_operand:DF 2 "general_operand" "")))] 246959693Selan "TARGET_68881 || TARGET_FPA" 247059693Selan "") 247159693Selan 247259693Selan(define_insn "" 247359693Selan [(set (match_operand:DF 0 "general_operand" "=x,y") 247459693Selan (mult:DF (match_operand:DF 1 "general_operand" "%xH,y") 247559693Selan (match_operand:DF 2 "general_operand" "xH,rmF")))] 247659693Selan "TARGET_FPA" 247759693Selan "* 247859693Selan{ 247959693Selan if (rtx_equal_p (operands[1], operands[2])) 248059693Selan return \"fpsqr%.d %y1,%0\"; 248159693Selan if (rtx_equal_p (operands[0], operands[1])) 248259693Selan return \"fpmul%.d %y2,%0\"; 248359693Selan if (rtx_equal_p (operands[0], operands[2])) 248459693Selan return \"fpmul%.d %y1,%0\"; 248559693Selan if (which_alternative == 0) 248659693Selan return \"fpmul3%.d %w2,%w1,%0\"; 248759693Selan return \"fpmul3%.d %x2,%x1,%0\"; 248859693Selan}") 248959693Selan 249059693Selan(define_insn "" 249159693Selan [(set (match_operand:DF 0 "general_operand" "=f") 249259693Selan (mult:DF (match_operand:DF 1 "general_operand" "%0") 249359693Selan (match_operand:DF 2 "general_operand" "fmG")))] 249459693Selan "TARGET_68881" 249559693Selan "* 249659693Selan{ 249759693Selan if (GET_CODE (operands[2]) == CONST_DOUBLE 249859693Selan && floating_exact_log2 (operands[2]) && !TARGET_68040) 249959693Selan { 250059693Selan int i = floating_exact_log2 (operands[2]); 250159693Selan operands[2] = gen_rtx (CONST_INT, VOIDmode, i); 250259693Selan return \"fscale%.l %2,%0\"; 250359693Selan } 250459693Selan if (REG_P (operands[2])) 250559693Selan return \"f%&mul%.x %2,%0\"; 250659693Selan return \"f%&mul%.d %f2,%0\"; 250759693Selan}") 250859693Selan 250959693Selan(define_expand "mulsf3" 251059693Selan [(set (match_operand:SF 0 "general_operand" "") 251159693Selan (mult:SF (match_operand:SF 1 "general_operand" "") 251259693Selan (match_operand:SF 2 "general_operand" "")))] 251359693Selan "TARGET_68881 || TARGET_FPA" 251459693Selan "") 251559693Selan 251659693Selan(define_insn "" 251759693Selan [(set (match_operand:SF 0 "general_operand" "=x,y") 251859693Selan (mult:SF (match_operand:SF 1 "general_operand" "%xH,y") 251959693Selan (match_operand:SF 2 "general_operand" "xH,rmF")))] 252059693Selan "TARGET_FPA" 252159693Selan "* 252259693Selan{ 252359693Selan if (rtx_equal_p (operands[1], operands[2])) 252459693Selan return \"fpsqr%.s %w1,%0\"; 252559693Selan if (rtx_equal_p (operands[0], operands[1])) 252659693Selan return \"fpmul%.s %w2,%0\"; 252759693Selan if (rtx_equal_p (operands[0], operands[2])) 252859693Selan return \"fpmul%.s %w1,%0\"; 252959693Selan if (which_alternative == 0) 253059693Selan return \"fpmul3%.s %w2,%w1,%0\"; 253159693Selan return \"fpmul3%.s %2,%1,%0\"; 253259693Selan}") 253359693Selan 253459693Selan(define_insn "" 253559693Selan [(set (match_operand:SF 0 "general_operand" "=f") 253659693Selan (mult:SF (match_operand:SF 1 "general_operand" "%0") 253759693Selan (match_operand:SF 2 "general_operand" "fdmF")))] 253859693Selan "TARGET_68881" 253959693Selan "* 254059693Selan{ 254159693Selan#ifdef FSGLMUL_USE_S 254259693Selan if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) 254359693Selan return (TARGET_68040_ONLY 254459693Selan ? \"fsmul%.s %2,%0\" 254559693Selan : \"fsglmul%.s %2,%0\"); 254659693Selan#else 254759693Selan if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) 254859693Selan return (TARGET_68040_ONLY 254959693Selan ? \"fsmul%.x %2,%0\" 255059693Selan : \"fsglmul%.x %2,%0\"); 255159693Selan#endif 255259693Selan return (TARGET_68040_ONLY 255359693Selan ? \"fsmul%.s %f2,%0\" 255459693Selan : \"fsglmul%.s %f2,%0\"); 255559693Selan}") 255659693Selan 255759693Selan;; divide instructions 255859693Selan 255959693Selan(define_insn "divhi3" 256059693Selan [(set (match_operand:HI 0 "general_operand" "=d") 256159693Selan (div:HI (match_operand:HI 1 "general_operand" "0") 256259693Selan (match_operand:HI 2 "general_operand" "dmn")))] 256359693Selan "" 256459693Selan "* 256559693Selan{ 256659693Selan#ifdef MOTOROLA 256759693Selan return \"ext%.l %0\;divs%.w %2,%0\"; 256859693Selan#else 256959693Selan return \"extl %0\;divs %2,%0\"; 257059693Selan#endif 257159693Selan}") 257259693Selan 257359693Selan(define_insn "divhisi3" 257459693Selan [(set (match_operand:HI 0 "general_operand" "=d") 257559693Selan (truncate:HI 257659693Selan (div:SI 257759693Selan (match_operand:SI 1 "general_operand" "0") 257859693Selan (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))] 257959693Selan "" 258059693Selan "* 258159693Selan{ 258259693Selan#ifdef MOTOROLA 258359693Selan return \"divs%.w %2,%0\"; 258459693Selan#else 258559693Selan return \"divs %2,%0\"; 258659693Selan#endif 258759693Selan}") 258859693Selan 258959693Selan(define_insn "" 259059693Selan [(set (match_operand:HI 0 "general_operand" "=d") 259159693Selan (truncate:HI (div:SI (match_operand:SI 1 "general_operand" "0") 259259693Selan (match_operand:SI 2 "const_int_operand" "n"))))] 259359693Selan "" 259459693Selan "* 259559693Selan{ 259659693Selan#ifdef MOTOROLA 259759693Selan return \"divs%.w %2,%0\"; 259859693Selan#else 259959693Selan return \"divs %2,%0\"; 260059693Selan#endif 260159693Selan}") 260259693Selan 260359693Selan(define_insn "udivhi3" 260459693Selan [(set (match_operand:HI 0 "general_operand" "=d") 260559693Selan (udiv:HI (match_operand:HI 1 "general_operand" "0") 260659693Selan (match_operand:HI 2 "general_operand" "dmn")))] 260759693Selan "" 260859693Selan "* 260959693Selan{ 261059693Selan#ifdef MOTOROLA 261159693Selan return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\"; 261259693Selan#else 261359693Selan return \"andl %#0xFFFF,%0\;divu %2,%0\"; 261459693Selan#endif 261559693Selan}") 261659693Selan 261759693Selan(define_insn "udivhisi3" 261859693Selan [(set (match_operand:HI 0 "general_operand" "=d") 261959693Selan (truncate:HI 262059693Selan (udiv:SI 262159693Selan (match_operand:SI 1 "general_operand" "0") 262259693Selan (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))] 262359693Selan "" 262459693Selan "* 262559693Selan{ 262659693Selan#ifdef MOTOROLA 262759693Selan return \"divu%.w %2,%0\"; 262859693Selan#else 262959693Selan return \"divu %2,%0\"; 263059693Selan#endif 263159693Selan}") 263259693Selan 263359693Selan(define_insn "" 263459693Selan [(set (match_operand:HI 0 "general_operand" "=d") 263559693Selan (truncate:HI (udiv:SI (match_operand:SI 1 "general_operand" "0") 263659693Selan (match_operand:SI 2 "const_int_operand" "n"))))] 263759693Selan "" 263859693Selan "* 263959693Selan{ 264059693Selan#ifdef MOTOROLA 264159693Selan return \"divu%.w %2,%0\"; 264259693Selan#else 264359693Selan return \"divu %2,%0\"; 264459693Selan#endif 264559693Selan}") 264659693Selan 264759693Selan(define_expand "divdf3" 264859693Selan [(set (match_operand:DF 0 "general_operand" "") 264959693Selan (div:DF (match_operand:DF 1 "general_operand" "") 265059693Selan (match_operand:DF 2 "general_operand" "")))] 265159693Selan "TARGET_68881 || TARGET_FPA" 265259693Selan "") 265359693Selan 265459693Selan(define_insn "" 265559693Selan [(set (match_operand:DF 0 "general_operand" "=x,y,y") 265659693Selan (div:DF (match_operand:DF 1 "general_operand" "xH,y,rmF") 265759693Selan (match_operand:DF 2 "general_operand" "xH,rmF,0")))] 265859693Selan "TARGET_FPA" 265959693Selan "* 266059693Selan{ 266159693Selan if (rtx_equal_p (operands[0], operands[2])) 266259693Selan return \"fprdiv%.d %y1,%0\"; 266359693Selan if (rtx_equal_p (operands[0], operands[1])) 266459693Selan return \"fpdiv%.d %y2,%0\"; 266559693Selan if (which_alternative == 0) 266659693Selan return \"fpdiv3%.d %w2,%w1,%0\"; 266759693Selan return \"fpdiv3%.d %x2,%x1,%x0\"; 266859693Selan}") 266959693Selan 267059693Selan(define_insn "" 267159693Selan [(set (match_operand:DF 0 "general_operand" "=f") 267259693Selan (div:DF (match_operand:DF 1 "general_operand" "0") 267359693Selan (match_operand:DF 2 "general_operand" "fmG")))] 267459693Selan "TARGET_68881" 267559693Selan "* 267659693Selan{ 267759693Selan if (REG_P (operands[2])) 267859693Selan return \"f%&div%.x %2,%0\"; 267959693Selan return \"f%&div%.d %f2,%0\"; 268059693Selan}") 268159693Selan 268259693Selan(define_expand "divsf3" 268359693Selan [(set (match_operand:SF 0 "general_operand" "") 268459693Selan (div:SF (match_operand:SF 1 "general_operand" "") 268559693Selan (match_operand:SF 2 "general_operand" "")))] 268659693Selan "TARGET_68881 || TARGET_FPA" 268759693Selan "") 268859693Selan 268959693Selan(define_insn "" 269059693Selan [(set (match_operand:SF 0 "general_operand" "=x,y,y") 269159693Selan (div:SF (match_operand:SF 1 "general_operand" "xH,y,rmF") 269259693Selan (match_operand:SF 2 "general_operand" "xH,rmF,0")))] 269359693Selan "TARGET_FPA" 269459693Selan "* 269559693Selan{ 269659693Selan if (rtx_equal_p (operands[0], operands[1])) 269759693Selan return \"fpdiv%.s %w2,%0\"; 269859693Selan if (rtx_equal_p (operands[0], operands[2])) 269959693Selan return \"fprdiv%.s %w1,%0\"; 270059693Selan if (which_alternative == 0) 270159693Selan return \"fpdiv3%.s %w2,%w1,%0\"; 270259693Selan return \"fpdiv3%.s %2,%1,%0\"; 270359693Selan}") 270459693Selan 270559693Selan(define_insn "" 270659693Selan [(set (match_operand:SF 0 "general_operand" "=f") 270759693Selan (div:SF (match_operand:SF 1 "general_operand" "0") 270859693Selan (match_operand:SF 2 "general_operand" "fdmF")))] 270959693Selan "TARGET_68881" 271059693Selan "* 271159693Selan{ 271259693Selan#ifdef FSGLDIV_USE_S 271359693Selan if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) 271459693Selan return (TARGET_68040_ONLY 271559693Selan ? \"fsdiv%.s %2,%0\" 271659693Selan : \"fsgldiv%.s %2,%0\"); 271759693Selan#else 271859693Selan if (REG_P (operands[2]) && ! DATA_REG_P (operands[2])) 271959693Selan return (TARGET_68040_ONLY 272059693Selan ? \"fsdiv%.x %2,%0\" 272159693Selan : \"fsgldiv%.x %2,%0\"); 272259693Selan#endif 272359693Selan return (TARGET_68040_ONLY 272459693Selan ? \"fsdiv%.s %f2,%0\" 272559693Selan : \"fsgldiv%.s %f2,%0\"); 272659693Selan}") 272759693Selan 272859693Selan;; Remainder instructions. 272959693Selan 273059693Selan(define_insn "modhi3" 273159693Selan [(set (match_operand:HI 0 "general_operand" "=d") 273259693Selan (mod:HI (match_operand:HI 1 "general_operand" "0") 273359693Selan (match_operand:HI 2 "general_operand" "dmn")))] 273459693Selan "" 273559693Selan "* 273659693Selan{ 273759693Selan /* The swap insn produces cc's that don't correspond to the result. */ 273859693Selan CC_STATUS_INIT; 273959693Selan#ifdef MOTOROLA 274059693Selan return \"ext%.l %0\;divs%.w %2,%0\;swap %0\"; 274159693Selan#else 274259693Selan return \"extl %0\;divs %2,%0\;swap %0\"; 274359693Selan#endif 274459693Selan}") 274559693Selan 274659693Selan(define_insn "modhisi3" 274759693Selan [(set (match_operand:HI 0 "general_operand" "=d") 274859693Selan (truncate:HI 274959693Selan (mod:SI 275059693Selan (match_operand:SI 1 "general_operand" "0") 275159693Selan (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))] 275259693Selan "" 275359693Selan "* 275459693Selan{ 275559693Selan /* The swap insn produces cc's that don't correspond to the result. */ 275659693Selan CC_STATUS_INIT; 275759693Selan#ifdef MOTOROLA 275859693Selan return \"divs%.w %2,%0\;swap %0\"; 275959693Selan#else 276059693Selan return \"divs %2,%0\;swap %0\"; 276159693Selan#endif 276259693Selan}") 276359693Selan 276459693Selan(define_insn "" 276559693Selan [(set (match_operand:HI 0 "general_operand" "=d") 276659693Selan (truncate:HI (mod:SI (match_operand:SI 1 "general_operand" "0") 276759693Selan (match_operand:SI 2 "const_int_operand" "n"))))] 276859693Selan "" 276959693Selan "* 277059693Selan{ 277159693Selan /* The swap insn produces cc's that don't correspond to the result. */ 277259693Selan CC_STATUS_INIT; 277359693Selan#ifdef MOTOROLA 277459693Selan return \"divs%.w %2,%0\;swap %0\"; 277559693Selan#else 277659693Selan return \"divs %2,%0\;swap %0\"; 277759693Selan#endif 277859693Selan}") 277959693Selan 278059693Selan(define_insn "umodhi3" 278159693Selan [(set (match_operand:HI 0 "general_operand" "=d") 278259693Selan (umod:HI (match_operand:HI 1 "general_operand" "0") 278359693Selan (match_operand:HI 2 "general_operand" "dmn")))] 278459693Selan "" 278559693Selan "* 278659693Selan{ 278759693Selan /* The swap insn produces cc's that don't correspond to the result. */ 278859693Selan CC_STATUS_INIT; 278959693Selan#ifdef MOTOROLA 279059693Selan return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\;swap %0\"; 279159693Selan#else 279259693Selan return \"andl %#0xFFFF,%0\;divu %2,%0\;swap %0\"; 279359693Selan#endif 279459693Selan}") 279559693Selan 279659693Selan(define_insn "umodhisi3" 279759693Selan [(set (match_operand:HI 0 "general_operand" "=d") 279859693Selan (truncate:HI 279959693Selan (umod:SI 280059693Selan (match_operand:SI 1 "general_operand" "0") 280159693Selan (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "dm")))))] 280259693Selan "" 280359693Selan "* 280459693Selan{ 280559693Selan /* The swap insn produces cc's that don't correspond to the result. */ 280659693Selan CC_STATUS_INIT; 280759693Selan#ifdef MOTOROLA 280859693Selan return \"divu%.w %2,%0\;swap %0\"; 280959693Selan#else 281059693Selan return \"divu %2,%0\;swap %0\"; 281159693Selan#endif 281259693Selan}") 281359693Selan 281459693Selan(define_insn "" 281559693Selan [(set (match_operand:HI 0 "general_operand" "=d") 281659693Selan (truncate:HI (umod:SI (match_operand:SI 1 "general_operand" "0") 281759693Selan (match_operand:SI 2 "const_int_operand" "n"))))] 281859693Selan "" 281959693Selan "* 282059693Selan{ 282159693Selan /* The swap insn produces cc's that don't correspond to the result. */ 282259693Selan CC_STATUS_INIT; 282359693Selan#ifdef MOTOROLA 282459693Selan return \"divu%.w %2,%0\;swap %0\"; 282559693Selan#else 282659693Selan return \"divu %2,%0\;swap %0\"; 282759693Selan#endif 282859693Selan}") 282959693Selan 283059693Selan(define_insn "divmodsi4" 283159693Selan [(set (match_operand:SI 0 "general_operand" "=d") 283259693Selan (div:SI (match_operand:SI 1 "general_operand" "0") 283359693Selan (match_operand:SI 2 "general_operand" "dmsK"))) 283459693Selan (set (match_operand:SI 3 "general_operand" "=d") 283559693Selan (mod:SI (match_dup 1) (match_dup 2)))] 283659693Selan "TARGET_68020" 283759693Selan "* 283859693Selan{ 283959693Selan if (find_reg_note (insn, REG_UNUSED, operands[3])) 284059693Selan return \"divs%.l %2,%0\"; 284159693Selan else 284259693Selan return \"divsl%.l %2,%3:%0\"; 284359693Selan}") 284459693Selan 284559693Selan(define_insn "udivmodsi4" 284659693Selan [(set (match_operand:SI 0 "general_operand" "=d") 284759693Selan (udiv:SI (match_operand:SI 1 "general_operand" "0") 284859693Selan (match_operand:SI 2 "general_operand" "dmsK"))) 284959693Selan (set (match_operand:SI 3 "general_operand" "=d") 285059693Selan (umod:SI (match_dup 1) (match_dup 2)))] 285159693Selan "TARGET_68020" 285259693Selan "* 285359693Selan{ 285459693Selan if (find_reg_note (insn, REG_UNUSED, operands[3])) 285559693Selan return \"divu%.l %2,%0\"; 285659693Selan else 285759693Selan return \"divul%.l %2,%3:%0\"; 285859693Selan}") 285959693Selan 286059693Selan;; logical-and instructions 286159693Selan 286259693Selan;; Prevent AND from being made with sp. This doesn't exist in the machine 286359693Selan;; and reload will cause inefficient code. Since sp is a FIXED_REG, we 286459693Selan;; can't allocate pseudos into it. 286559693Selan(define_insn "andsi3" 286659693Selan [(set (match_operand:SI 0 "not_sp_operand" "=m,d") 286759693Selan (and:SI (match_operand:SI 1 "general_operand" "%0,0") 286859693Selan (match_operand:SI 2 "general_operand" "dKs,dmKs")))] 286959693Selan "" 287059693Selan "* 287159693Selan{ 287259693Selan int logval; 287359693Selan if (GET_CODE (operands[2]) == CONST_INT 287459693Selan && (INTVAL (operands[2]) | 0xffff) == 0xffffffff 287559693Selan && (DATA_REG_P (operands[0]) 287659693Selan || offsettable_memref_p (operands[0]))) 287759693Selan { 287859693Selan if (GET_CODE (operands[0]) != REG) 287959693Selan operands[0] = adj_offsettable_operand (operands[0], 2); 288059693Selan operands[2] = gen_rtx (CONST_INT, VOIDmode, 288159693Selan INTVAL (operands[2]) & 0xffff); 288259693Selan /* Do not delete a following tstl %0 insn; that would be incorrect. */ 288359693Selan CC_STATUS_INIT; 288459693Selan if (operands[2] == const0_rtx) 288559693Selan return \"clr%.w %0\"; 288659693Selan return \"and%.w %2,%0\"; 288759693Selan } 288859693Selan if (GET_CODE (operands[2]) == CONST_INT 288959693Selan && (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0 289059693Selan && (DATA_REG_P (operands[0]) 289159693Selan || offsettable_memref_p (operands[0]))) 289259693Selan { 289359693Selan if (DATA_REG_P (operands[0])) 289459693Selan { 289559693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, logval); 289659693Selan } 289759693Selan else 289859693Selan { 289959693Selan operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8)); operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8); 290059693Selan } 290159693Selan /* This does not set condition codes in a standard way. */ 290259693Selan CC_STATUS_INIT; 290359693Selan return \"bclr %1,%0\"; 290459693Selan } 290559693Selan return \"and%.l %2,%0\"; 290659693Selan}") 290759693Selan 290859693Selan(define_insn "andhi3" 290959693Selan [(set (match_operand:HI 0 "general_operand" "=m,d") 291059693Selan (and:HI (match_operand:HI 1 "general_operand" "%0,0") 291159693Selan (match_operand:HI 2 "general_operand" "dn,dmn")))] 291259693Selan "" 291359693Selan "and%.w %2,%0") 291459693Selan 291559693Selan(define_insn "" 291659693Selan [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) 291759693Selan (and:HI (match_dup 0) 291859693Selan (match_operand:HI 1 "general_operand" "dn,dmn")))] 291959693Selan "" 292059693Selan "and%.w %1,%0") 292159693Selan 292259693Selan(define_insn "" 292359693Selan [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) 292459693Selan (and:HI (match_operand:HI 1 "general_operand" "dn,dmn") 292559693Selan (match_dup 0)))] 292659693Selan "" 292759693Selan "and%.w %1,%0") 292859693Selan 292959693Selan(define_insn "andqi3" 293059693Selan [(set (match_operand:QI 0 "general_operand" "=m,d") 293159693Selan (and:QI (match_operand:QI 1 "general_operand" "%0,0") 293259693Selan (match_operand:QI 2 "general_operand" "dn,dmn")))] 293359693Selan "" 293459693Selan "and%.b %2,%0") 293559693Selan 293659693Selan(define_insn "" 293759693Selan [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) 293859693Selan (and:QI (match_dup 0) 293959693Selan (match_operand:QI 1 "general_operand" "dn,dmn")))] 294059693Selan "" 294159693Selan "and%.b %1,%0") 294259693Selan 294359693Selan(define_insn "" 294459693Selan [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) 294559693Selan (and:QI (match_operand:QI 1 "general_operand" "dn,dmn") 294659693Selan (match_dup 0)))] 294759693Selan "" 294859693Selan "and%.b %1,%0") 294959693Selan 295059693Selan;; inclusive-or instructions 295159693Selan 295259693Selan(define_insn "iorsi3" 295359693Selan [(set (match_operand:SI 0 "general_operand" "=m,d") 295459693Selan (ior:SI (match_operand:SI 1 "general_operand" "%0,0") 295559693Selan (match_operand:SI 2 "general_operand" "dKs,dmKs")))] 295659693Selan "" 295759693Selan "* 295859693Selan{ 295959693Selan register int logval; 296059693Selan if (GET_CODE (operands[2]) == CONST_INT 296159693Selan && INTVAL (operands[2]) >> 16 == 0 296259693Selan && (DATA_REG_P (operands[0]) 296359693Selan || offsettable_memref_p (operands[0]))) 296459693Selan { 296559693Selan if (GET_CODE (operands[0]) != REG) 296659693Selan operands[0] = adj_offsettable_operand (operands[0], 2); 296759693Selan /* Do not delete a following tstl %0 insn; that would be incorrect. */ 296859693Selan CC_STATUS_INIT; 296959693Selan return \"or%.w %2,%0\"; 297059693Selan } 297159693Selan if (GET_CODE (operands[2]) == CONST_INT 297259693Selan && (logval = exact_log2 (INTVAL (operands[2]))) >= 0 297359693Selan && (DATA_REG_P (operands[0]) 297459693Selan || offsettable_memref_p (operands[0]))) 297559693Selan { 297659693Selan if (DATA_REG_P (operands[0])) 297759693Selan { 297859693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, logval); 297959693Selan } 298059693Selan else 298159693Selan { 298259693Selan operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8)); 298359693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8); 298459693Selan } 298559693Selan return \"bset %1,%0\"; 298659693Selan } 298759693Selan return \"or%.l %2,%0\"; 298859693Selan}") 298959693Selan 299059693Selan(define_insn "iorhi3" 299159693Selan [(set (match_operand:HI 0 "general_operand" "=m,d") 299259693Selan (ior:HI (match_operand:HI 1 "general_operand" "%0,0") 299359693Selan (match_operand:HI 2 "general_operand" "dn,dmn")))] 299459693Selan "" 299559693Selan "or%.w %2,%0") 299659693Selan 299759693Selan(define_insn "" 299859693Selan [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) 299959693Selan (ior:HI (match_dup 0) 300059693Selan (match_operand:HI 1 "general_operand" "dn,dmn")))] 300159693Selan "" 300259693Selan "or%.w %1,%0") 300359693Selan 300459693Selan(define_insn "" 300559693Selan [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) 300659693Selan (ior:HI (match_operand:HI 1 "general_operand" "dn,dmn") 300759693Selan (match_dup 0)))] 300859693Selan "" 300959693Selan "or%.w %1,%0") 301059693Selan 301159693Selan(define_insn "iorqi3" 301259693Selan [(set (match_operand:QI 0 "general_operand" "=m,d") 301359693Selan (ior:QI (match_operand:QI 1 "general_operand" "%0,0") 301459693Selan (match_operand:QI 2 "general_operand" "dn,dmn")))] 301559693Selan "" 301659693Selan "or%.b %2,%0") 301759693Selan 301859693Selan(define_insn "" 301959693Selan [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) 302059693Selan (ior:QI (match_dup 0) 302159693Selan (match_operand:QI 1 "general_operand" "dn,dmn")))] 302259693Selan "" 302359693Selan "or%.b %1,%0") 302459693Selan 302559693Selan(define_insn "" 302659693Selan [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) 302759693Selan (ior:QI (match_operand:QI 1 "general_operand" "dn,dmn") 302859693Selan (match_dup 0)))] 302959693Selan "" 303059693Selan "or%.b %1,%0") 303159693Selan 303259693Selan;; xor instructions 303359693Selan 303459693Selan(define_insn "xorsi3" 303559693Selan [(set (match_operand:SI 0 "general_operand" "=do,m") 303659693Selan (xor:SI (match_operand:SI 1 "general_operand" "%0,0") 303759693Selan (match_operand:SI 2 "general_operand" "di,dKs")))] 303859693Selan "" 303959693Selan "* 304059693Selan{ 304159693Selan if (GET_CODE (operands[2]) == CONST_INT 304259693Selan && INTVAL (operands[2]) >> 16 == 0 304359693Selan && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0]))) 304459693Selan { 304559693Selan if (! DATA_REG_P (operands[0])) 304659693Selan operands[0] = adj_offsettable_operand (operands[0], 2); 304759693Selan /* Do not delete a following tstl %0 insn; that would be incorrect. */ 304859693Selan CC_STATUS_INIT; 304959693Selan return \"eor%.w %2,%0\"; 305059693Selan } 305159693Selan return \"eor%.l %2,%0\"; 305259693Selan}") 305359693Selan 305459693Selan(define_insn "xorhi3" 305559693Selan [(set (match_operand:HI 0 "general_operand" "=dm") 305659693Selan (xor:HI (match_operand:HI 1 "general_operand" "%0") 305759693Selan (match_operand:HI 2 "general_operand" "dn")))] 305859693Selan "" 305959693Selan "eor%.w %2,%0") 306059693Selan 306159693Selan(define_insn "" 306259693Selan [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm")) 306359693Selan (xor:HI (match_dup 0) 306459693Selan (match_operand:HI 1 "general_operand" "dn")))] 306559693Selan "" 306659693Selan "eor%.w %1,%0") 306759693Selan 306859693Selan 306959693Selan(define_insn "" 307059693Selan [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm")) 307159693Selan (xor:HI (match_operand:HI 1 "general_operand" "dn") 307259693Selan (match_dup 0)))] 307359693Selan "" 307459693Selan "eor%.w %1,%0") 307559693Selan 307659693Selan(define_insn "xorqi3" 307759693Selan [(set (match_operand:QI 0 "general_operand" "=dm") 307859693Selan (xor:QI (match_operand:QI 1 "general_operand" "%0") 307959693Selan (match_operand:QI 2 "general_operand" "dn")))] 308059693Selan "" 308159693Selan "eor%.b %2,%0") 308259693Selan 308359693Selan(define_insn "" 308459693Selan [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm")) 308559693Selan (xor:QI (match_dup 0) 308659693Selan (match_operand:QI 1 "general_operand" "dn")))] 308759693Selan "" 308859693Selan "eor%.b %1,%0") 308959693Selan 309059693Selan(define_insn "" 309159693Selan [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm")) 309259693Selan (xor:QI (match_operand:QI 1 "general_operand" "dn") 309359693Selan (match_dup 0)))] 309459693Selan "" 309559693Selan "eor%.b %1,%0") 309659693Selan 309759693Selan;; negation instructions 309859693Selan 309959693Selan(define_insn "negsi2" 310059693Selan [(set (match_operand:SI 0 "general_operand" "=dm") 310159693Selan (neg:SI (match_operand:SI 1 "general_operand" "0")))] 310259693Selan "" 310359693Selan "neg%.l %0") 310459693Selan 310559693Selan(define_insn "neghi2" 310659693Selan [(set (match_operand:HI 0 "general_operand" "=dm") 310759693Selan (neg:HI (match_operand:HI 1 "general_operand" "0")))] 310859693Selan "" 310959693Selan "neg%.w %0") 311059693Selan 311159693Selan(define_insn "" 311259693Selan [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm")) 311359693Selan (neg:HI (match_dup 0)))] 311459693Selan "" 311559693Selan "neg%.w %0") 311659693Selan 311759693Selan(define_insn "negqi2" 311859693Selan [(set (match_operand:QI 0 "general_operand" "=dm") 311959693Selan (neg:QI (match_operand:QI 1 "general_operand" "0")))] 312059693Selan "" 312159693Selan "neg%.b %0") 312259693Selan 312359693Selan(define_insn "" 312459693Selan [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm")) 312559693Selan (neg:QI (match_dup 0)))] 312659693Selan "" 312759693Selan "neg%.b %0") 312859693Selan 312959693Selan(define_expand "negsf2" 313059693Selan [(set (match_operand:SF 0 "general_operand" "") 313159693Selan (neg:SF (match_operand:SF 1 "general_operand" "")))] 313259693Selan "TARGET_68881 || TARGET_FPA" 313359693Selan "") 313459693Selan 313559693Selan(define_insn "" 313659693Selan [(set (match_operand:SF 0 "general_operand" "=x,y") 313759693Selan (neg:SF (match_operand:SF 1 "general_operand" "xH,rmF")))] 313859693Selan "TARGET_FPA" 313959693Selan "fpneg%.s %w1,%0") 314059693Selan 314159693Selan(define_insn "" 314259693Selan [(set (match_operand:SF 0 "general_operand" "=f,d") 314359693Selan (neg:SF (match_operand:SF 1 "general_operand" "fdmF,0")))] 314459693Selan "TARGET_68881" 314559693Selan "* 314659693Selan{ 314759693Selan if (DATA_REG_P (operands[0])) 314859693Selan { 314959693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, 31); 315059693Selan return \"bchg %1,%0\"; 315159693Selan } 315259693Selan if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) 315359693Selan return \"f%$neg%.x %1,%0\"; 315459693Selan return \"f%$neg%.s %f1,%0\"; 315559693Selan}") 315659693Selan 315759693Selan(define_expand "negdf2" 315859693Selan [(set (match_operand:DF 0 "general_operand" "") 315959693Selan (neg:DF (match_operand:DF 1 "general_operand" "")))] 316059693Selan "TARGET_68881 || TARGET_FPA" 316159693Selan "") 316259693Selan 316359693Selan(define_insn "" 316459693Selan [(set (match_operand:DF 0 "general_operand" "=x,y") 316559693Selan (neg:DF (match_operand:DF 1 "general_operand" "xH,rmF")))] 316659693Selan "TARGET_FPA" 316759693Selan "fpneg%.d %y1, %0") 316859693Selan 316959693Selan(define_insn "" 317059693Selan [(set (match_operand:DF 0 "general_operand" "=f,d") 317159693Selan (neg:DF (match_operand:DF 1 "general_operand" "fmF,0")))] 317259693Selan "TARGET_68881" 317359693Selan "* 317459693Selan{ 317559693Selan if (DATA_REG_P (operands[0])) 317659693Selan { 317759693Selan operands[1] = gen_rtx (CONST_INT, VOIDmode, 31); 317859693Selan return \"bchg %1,%0\"; 317959693Selan } 318059693Selan if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) 318159693Selan return \"f%&neg%.x %1,%0\"; 318259693Selan return \"f%&neg%.d %f1,%0\"; 318359693Selan}") 318459693Selan 318559693Selan;; Sqrt instruction for the 68881 318659693Selan 318759693Selan(define_insn "sqrtdf2" 318859693Selan [(set (match_operand:DF 0 "general_operand" "=f") 318959693Selan (sqrt:DF (match_operand:DF 1 "general_operand" "fm")))] 319059693Selan "TARGET_68881" 319159693Selan "* 319259693Selan{ 319359693Selan if (FP_REG_P (operands[1])) 319459693Selan return \"fsqrt%.x %1,%0\"; 319559693Selan else 319659693Selan return \"fsqrt%.d %1,%0\"; 319759693Selan}") 319859693Selan 319959693Selan;; Absolute value instructions 320059693Selan 320159693Selan(define_expand "abssf2" 320259693Selan [(set (match_operand:SF 0 "general_operand" "") 320359693Selan (abs:SF (match_operand:SF 1 "general_operand" "")))] 320459693Selan "TARGET_68881 || TARGET_FPA" 320559693Selan "") 320659693Selan 320759693Selan(define_insn "" 320859693Selan [(set (match_operand:SF 0 "general_operand" "=x,y") 320959693Selan (abs:SF (match_operand:SF 1 "general_operand" "xH,rmF")))] 321059693Selan "TARGET_FPA" 321159693Selan "fpabs%.s %y1,%0") 321259693Selan 321359693Selan(define_insn "" 321459693Selan [(set (match_operand:SF 0 "general_operand" "=f") 321559693Selan (abs:SF (match_operand:SF 1 "general_operand" "fdmF")))] 321659693Selan "TARGET_68881" 321759693Selan "* 321859693Selan{ 321959693Selan if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) 322059693Selan return \"f%$abs%.x %1,%0\"; 322159693Selan return \"f%$abs%.s %f1,%0\"; 322259693Selan}") 322359693Selan 322459693Selan(define_expand "absdf2" 322559693Selan [(set (match_operand:DF 0 "general_operand" "") 322659693Selan (abs:DF (match_operand:DF 1 "general_operand" "")))] 322759693Selan "TARGET_68881 || TARGET_FPA" 322859693Selan "") 322959693Selan 323059693Selan(define_insn "" 323159693Selan [(set (match_operand:DF 0 "general_operand" "=x,y") 323259693Selan (abs:DF (match_operand:DF 1 "general_operand" "xH,rmF")))] 323359693Selan "TARGET_FPA" 323459693Selan "fpabs%.d %y1,%0") 323559693Selan 323659693Selan(define_insn "" 323759693Selan [(set (match_operand:DF 0 "general_operand" "=f") 323859693Selan (abs:DF (match_operand:DF 1 "general_operand" "fmF")))] 323959693Selan "TARGET_68881" 324059693Selan "* 324159693Selan{ 324259693Selan if (REG_P (operands[1]) && ! DATA_REG_P (operands[1])) 324359693Selan return \"f%&abs%.x %1,%0\"; 324459693Selan return \"f%&abs%.d %f1,%0\"; 324559693Selan}") 324659693Selan 324759693Selan;; one complement instructions 324859693Selan 324959693Selan(define_insn "one_cmplsi2" 325059693Selan [(set (match_operand:SI 0 "general_operand" "=dm") 325159693Selan (not:SI (match_operand:SI 1 "general_operand" "0")))] 325259693Selan "" 325359693Selan "not%.l %0") 325459693Selan 325559693Selan(define_insn "one_cmplhi2" 325659693Selan [(set (match_operand:HI 0 "general_operand" "=dm") 325759693Selan (not:HI (match_operand:HI 1 "general_operand" "0")))] 325859693Selan "" 325959693Selan "not%.w %0") 326059693Selan 326159693Selan(define_insn "" 326259693Selan [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm")) 326359693Selan (not:HI (match_dup 0)))] 326459693Selan "" 326559693Selan "not%.w %0") 326659693Selan 326759693Selan(define_insn "one_cmplqi2" 326859693Selan [(set (match_operand:QI 0 "general_operand" "=dm") 326959693Selan (not:QI (match_operand:QI 1 "general_operand" "0")))] 327059693Selan "" 327159693Selan "not%.b %0") 327259693Selan 327359693Selan(define_insn "" 327459693Selan [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm")) 327559693Selan (not:QI (match_dup 0)))] 327659693Selan "" 327759693Selan "not%.b %0") 327859693Selan 327959693Selan;; arithmetic shift instructions 328059693Selan;; We don't need the shift memory by 1 bit instruction 328159693Selan 328259693Selan;; On all 68k models, this makes faster code in a special case. 328359693Selan 328459693Selan(define_insn "" 328559693Selan [(set (match_operand:SI 0 "register_operand" "=d") 328659693Selan (ashift:SI (match_operand:SI 1 "register_operand" "0") 328759693Selan (match_operand:SI 2 "immediate_operand" "i")))] 328859693Selan "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)" 328959693Selan "* 329059693Selan{ 329159693Selan CC_STATUS_INIT; 329259693Selan return \"swap %0\;clr%.w %0\"; 329359693Selan}") 329459693Selan 329559693Selan;; On the 68000, this makes faster code in a special case. 329659693Selan 329759693Selan(define_insn "" 329859693Selan [(set (match_operand:SI 0 "register_operand" "=d") 329959693Selan (ashift:SI (match_operand:SI 1 "register_operand" "0") 330059693Selan (match_operand:SI 2 "immediate_operand" "i")))] 330159693Selan "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT 330259693Selan && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)" 330359693Selan "* 330459693Selan{ 330559693Selan CC_STATUS_INIT; 330659693Selan 330759693Selan operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); 330859693Selan return \"asl%.w %2,%0\;swap %0\;clr%.w %0\"; 330959693Selan}") 331059693Selan 331159693Selan(define_insn "ashlsi3" 331259693Selan [(set (match_operand:SI 0 "register_operand" "=d") 331359693Selan (ashift:SI (match_operand:SI 1 "register_operand" "0") 331459693Selan (match_operand:SI 2 "general_operand" "dI")))] 331559693Selan "" 331659693Selan "* 331759693Selan{ 331859693Selan if (operands[2] == const1_rtx) 331959693Selan return \"add%.l %0,%0\"; 332059693Selan return \"asl%.l %2,%0\"; 332159693Selan}") 332259693Selan 332359693Selan(define_insn "ashlhi3" 332459693Selan [(set (match_operand:HI 0 "register_operand" "=d") 332559693Selan (ashift:HI (match_operand:HI 1 "register_operand" "0") 332659693Selan (match_operand:HI 2 "general_operand" "dI")))] 332759693Selan "" 332859693Selan "asl%.w %2,%0") 332959693Selan 333059693Selan(define_insn "" 333159693Selan [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) 333259693Selan (ashift:HI (match_dup 0) 333359693Selan (match_operand:HI 1 "general_operand" "dI")))] 333459693Selan "" 333559693Selan "asl%.w %1,%0") 333659693Selan 333759693Selan(define_insn "ashlqi3" 333859693Selan [(set (match_operand:QI 0 "register_operand" "=d") 333959693Selan (ashift:QI (match_operand:QI 1 "register_operand" "0") 334059693Selan (match_operand:QI 2 "general_operand" "dI")))] 334159693Selan "" 334259693Selan "asl%.b %2,%0") 334359693Selan 334459693Selan(define_insn "" 334559693Selan [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) 334659693Selan (ashift:QI (match_dup 0) 334759693Selan (match_operand:QI 1 "general_operand" "dI")))] 334859693Selan "" 334959693Selan "asl%.b %1,%0") 335059693Selan 335159693Selan;; On all 68k models, this makes faster code in a special case. 335259693Selan 335359693Selan(define_insn "" 335459693Selan [(set (match_operand:SI 0 "register_operand" "=d") 335559693Selan (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 335659693Selan (match_operand:SI 2 "immediate_operand" "i")))] 335759693Selan "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)" 335859693Selan "swap %0\;ext%.l %0") 335959693Selan 336059693Selan;; On the 68000, this makes faster code in a special case. 336159693Selan 336259693Selan(define_insn "" 336359693Selan [(set (match_operand:SI 0 "register_operand" "=d") 336459693Selan (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 336559693Selan (match_operand:SI 2 "immediate_operand" "i")))] 336659693Selan "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT 336759693Selan && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)" 336859693Selan "* 336959693Selan{ 337059693Selan operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); 337159693Selan return \"swap %0\;asr%.w %2,%0\;ext%.l %0\"; 337259693Selan}") 337359693Selan 337459693Selan(define_insn "ashrsi3" 337559693Selan [(set (match_operand:SI 0 "register_operand" "=d") 337659693Selan (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 337759693Selan (match_operand:SI 2 "general_operand" "dI")))] 337859693Selan "" 337959693Selan "* 338059693Selan{ 338159693Selan return \"asr%.l %2,%0\"; 338259693Selan}") 338359693Selan 338459693Selan(define_insn "ashrhi3" 338559693Selan [(set (match_operand:HI 0 "register_operand" "=d") 338659693Selan (ashiftrt:HI (match_operand:HI 1 "register_operand" "0") 338759693Selan (match_operand:HI 2 "general_operand" "dI")))] 338859693Selan "" 338959693Selan "asr%.w %2,%0") 339059693Selan 339159693Selan(define_insn "" 339259693Selan [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) 339359693Selan (ashiftrt:HI (match_dup 0) 339459693Selan (match_operand:HI 1 "general_operand" "dI")))] 339559693Selan "" 339659693Selan "asr%.w %1,%0") 339759693Selan 339859693Selan(define_insn "ashrqi3" 339959693Selan [(set (match_operand:QI 0 "register_operand" "=d") 340059693Selan (ashiftrt:QI (match_operand:QI 1 "register_operand" "0") 340159693Selan (match_operand:QI 2 "general_operand" "dI")))] 340259693Selan "" 340359693Selan "asr%.b %2,%0") 340459693Selan 340559693Selan(define_insn "" 340659693Selan [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) 340759693Selan (ashiftrt:QI (match_dup 0) 340859693Selan (match_operand:QI 1 "general_operand" "dI")))] 340959693Selan "" 341059693Selan "asr%.b %1,%0") 341159693Selan 341259693Selan;; logical shift instructions 341359693Selan 341459693Selan;; On all 68k models, this makes faster code in a special case. 341559693Selan 341659693Selan(define_insn "" 341759693Selan [(set (match_operand:SI 0 "register_operand" "=d") 341859693Selan (lshift:SI (match_operand:SI 1 "register_operand" "0") 341959693Selan (match_operand:SI 2 "immediate_operand" "i")))] 342059693Selan "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)" 342159693Selan "* 342259693Selan{ 342359693Selan CC_STATUS_INIT; 342459693Selan return \"swap %0\;clr%.w %0\"; 342559693Selan}") 342659693Selan 342759693Selan;; On the 68000, this makes faster code in a special case. 342859693Selan 342959693Selan(define_insn "" 343059693Selan [(set (match_operand:SI 0 "register_operand" "=d") 343159693Selan (lshift:SI (match_operand:SI 1 "register_operand" "0") 343259693Selan (match_operand:SI 2 "immediate_operand" "i")))] 343359693Selan "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT 343459693Selan && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)" 343559693Selan "* 343659693Selan{ 343759693Selan CC_STATUS_INIT; 343859693Selan 343959693Selan operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); 344059693Selan return \"lsl%.w %2,%0\;swap %0\;clr%.w %0\"; 344159693Selan}") 344259693Selan 344359693Selan(define_insn "lshlsi3" 344459693Selan [(set (match_operand:SI 0 "register_operand" "=d") 344559693Selan (lshift:SI (match_operand:SI 1 "register_operand" "0") 344659693Selan (match_operand:SI 2 "general_operand" "dI")))] 344759693Selan "" 344859693Selan "* 344959693Selan{ 345059693Selan if (operands[2] == const1_rtx) 345159693Selan return \"add%.l %0,%0\"; 345259693Selan return \"lsl%.l %2,%0\"; 345359693Selan}") 345459693Selan 345559693Selan(define_insn "lshlhi3" 345659693Selan [(set (match_operand:HI 0 "register_operand" "=d") 345759693Selan (lshift:HI (match_operand:HI 1 "register_operand" "0") 345859693Selan (match_operand:HI 2 "general_operand" "dI")))] 345959693Selan "" 346059693Selan "lsl%.w %2,%0") 346159693Selan 346259693Selan(define_insn "" 346359693Selan [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) 346459693Selan (lshift:HI (match_dup 0) 346559693Selan (match_operand:HI 1 "general_operand" "dI")))] 346659693Selan "" 346759693Selan "lsl%.w %1,%0") 346859693Selan 346959693Selan(define_insn "lshlqi3" 347059693Selan [(set (match_operand:QI 0 "register_operand" "=d") 347159693Selan (lshift:QI (match_operand:QI 1 "register_operand" "0") 347259693Selan (match_operand:QI 2 "general_operand" "dI")))] 347359693Selan "" 347459693Selan "lsl%.b %2,%0") 347559693Selan 347659693Selan(define_insn "" 347759693Selan [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) 347859693Selan (lshift:QI (match_dup 0) 347959693Selan (match_operand:QI 1 "general_operand" "dI")))] 348059693Selan "" 348159693Selan "lsl%.b %1,%0") 348259693Selan 348359693Selan;; On all 68k models, this makes faster code in a special case. 348459693Selan 348559693Selan(define_insn "" 348659693Selan [(set (match_operand:SI 0 "register_operand" "=d") 348759693Selan (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") 348859693Selan (match_operand:SI 2 "immediate_operand" "i")))] 348959693Selan "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)" 349059693Selan "* 349159693Selan{ 349259693Selan CC_STATUS_INIT; 349359693Selan return \"clr%.w %0\;swap %0\"; 349459693Selan}") 349559693Selan 349659693Selan;; On the 68000, this makes faster code in a special case. 349759693Selan 349859693Selan(define_insn "" 349959693Selan [(set (match_operand:SI 0 "register_operand" "=d") 350059693Selan (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") 350159693Selan (match_operand:SI 2 "immediate_operand" "i")))] 350259693Selan "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT 350359693Selan && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)" 350459693Selan "* 350559693Selan{ 350659693Selan /* I think lsr%.w sets the CC properly. */ 350759693Selan operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); 350859693Selan return \"clr%.w %0\;swap %0\;lsr%.w %2,%0\"; 350959693Selan}") 351059693Selan 351159693Selan(define_insn "lshrsi3" 351259693Selan [(set (match_operand:SI 0 "register_operand" "=d") 351359693Selan (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") 351459693Selan (match_operand:SI 2 "general_operand" "dI")))] 351559693Selan "" 351659693Selan "* 351759693Selan{ 351859693Selan return \"lsr%.l %2,%0\"; 351959693Selan}") 352059693Selan 352159693Selan(define_insn "lshrhi3" 352259693Selan [(set (match_operand:HI 0 "register_operand" "=d") 352359693Selan (lshiftrt:HI (match_operand:HI 1 "register_operand" "0") 352459693Selan (match_operand:HI 2 "general_operand" "dI")))] 352559693Selan "" 352659693Selan "lsr%.w %2,%0") 352759693Selan 352859693Selan(define_insn "" 352959693Selan [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) 353059693Selan (lshiftrt:HI (match_dup 0) 353159693Selan (match_operand:HI 1 "general_operand" "dI")))] 353259693Selan "" 353359693Selan "lsr%.w %1,%0") 353459693Selan 353559693Selan(define_insn "lshrqi3" 353659693Selan [(set (match_operand:QI 0 "register_operand" "=d") 353759693Selan (lshiftrt:QI (match_operand:QI 1 "register_operand" "0") 353859693Selan (match_operand:QI 2 "general_operand" "dI")))] 353959693Selan "" 354059693Selan "lsr%.b %2,%0") 354159693Selan 354259693Selan(define_insn "" 354359693Selan [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) 354459693Selan (lshiftrt:QI (match_dup 0) 354559693Selan (match_operand:QI 1 "general_operand" "dI")))] 354659693Selan "" 354759693Selan "lsr%.b %1,%0") 354859693Selan 354959693Selan;; rotate instructions 355059693Selan 355159693Selan(define_insn "rotlsi3" 355259693Selan [(set (match_operand:SI 0 "register_operand" "=d") 355359693Selan (rotate:SI (match_operand:SI 1 "register_operand" "0") 355459693Selan (match_operand:SI 2 "general_operand" "dI")))] 355559693Selan "" 355659693Selan "rol%.l %2,%0") 355759693Selan 355859693Selan(define_insn "rotlhi3" 355959693Selan [(set (match_operand:HI 0 "register_operand" "=d") 356059693Selan (rotate:HI (match_operand:HI 1 "register_operand" "0") 356159693Selan (match_operand:HI 2 "general_operand" "dI")))] 356259693Selan "" 356359693Selan "rol%.w %2,%0") 356459693Selan 356559693Selan 356659693Selan(define_insn "" 356759693Selan [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) 356859693Selan (rotate:HI (match_dup 0) 356959693Selan (match_operand:HI 1 "general_operand" "dI")))] 357059693Selan "" 357159693Selan "rol%.w %1,%0") 357259693Selan 357359693Selan(define_insn "rotlqi3" 357459693Selan [(set (match_operand:QI 0 "register_operand" "=d") 357559693Selan (rotate:QI (match_operand:QI 1 "register_operand" "0") 357659693Selan (match_operand:QI 2 "general_operand" "dI")))] 357759693Selan "" 357859693Selan "rol%.b %2,%0") 357959693Selan 358059693Selan(define_insn "" 358159693Selan [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) 358259693Selan (rotate:QI (match_dup 0) 358359693Selan (match_operand:QI 1 "general_operand" "dI")))] 358459693Selan "" 358559693Selan "rol%.b %1,%0") 358659693Selan 358759693Selan(define_insn "rotrsi3" 358859693Selan [(set (match_operand:SI 0 "register_operand" "=d") 358959693Selan (rotatert:SI (match_operand:SI 1 "register_operand" "0") 359059693Selan (match_operand:SI 2 "general_operand" "dI")))] 359159693Selan "" 359259693Selan "ror%.l %2,%0") 359359693Selan 359459693Selan(define_insn "rotrhi3" 359559693Selan [(set (match_operand:HI 0 "register_operand" "=d") 359659693Selan (rotatert:HI (match_operand:HI 1 "register_operand" "0") 359759693Selan (match_operand:HI 2 "general_operand" "dI")))] 359859693Selan "" 359959693Selan "ror%.w %2,%0") 360059693Selan 360159693Selan(define_insn "" 360259693Selan [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) 360359693Selan (rotatert:HI (match_dup 0) 360459693Selan (match_operand:HI 1 "general_operand" "dI")))] 360559693Selan "" 360659693Selan "ror%.w %1,%0") 360759693Selan 360859693Selan(define_insn "rotrqi3" 360959693Selan [(set (match_operand:QI 0 "register_operand" "=d") 361059693Selan (rotatert:QI (match_operand:QI 1 "register_operand" "0") 361159693Selan (match_operand:QI 2 "general_operand" "dI")))] 361259693Selan "" 361359693Selan "ror%.b %2,%0") 361459693Selan 361559693Selan(define_insn "" 361659693Selan [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) 361759693Selan (rotatert:QI (match_dup 0) 361859693Selan (match_operand:QI 1 "general_operand" "dI")))] 361959693Selan "" 362059693Selan "ror%.b %1,%0") 362159693Selan 362259693Selan;; Special cases of bit-field insns which we should 362359693Selan;; recognize in preference to the general case. 362459693Selan;; These handle aligned 8-bit and 16-bit fields, 362559693Selan;; which can usually be done with move instructions. 362659693Selan 362759693Selan; 362859693Selan; Special case for 32-bit field in memory. This only occurs when 32-bit 362959693Selan; alignment of structure members is specified. 363059693Selan; 363159693Selan; The move is allowed to be odd byte aligned, because that's still faster 363259693Selan; than an odd byte aligned bit field instruction. 363359693Selan; 363459693Selan(define_insn "" 363559693Selan [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o") 363659693Selan (match_operand:SI 1 "immediate_operand" "i") 363759693Selan (match_operand:SI 2 "immediate_operand" "i")) 363859693Selan (match_operand:SI 3 "general_operand" "rmi"))] 363959693Selan "TARGET_68020 && TARGET_BITFIELD 364059693Selan && GET_CODE (operands[1]) == CONST_INT 364159693Selan && (INTVAL (operands[1]) == 32) 364259693Selan && GET_CODE (operands[2]) == CONST_INT 364359693Selan && (INTVAL (operands[2]) % 8) == 0 364459693Selan && ! mode_dependent_address_p (XEXP (operands[0], 0))" 364559693Selan "* 364659693Selan{ 364759693Selan operands[0] 364859693Selan = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8); 364959693Selan 365059693Selan return \"move%.l %3,%0\"; 365159693Selan}") 365259693Selan 365359693Selan(define_insn "" 365459693Selan [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+do") 365559693Selan (match_operand:SI 1 "immediate_operand" "i") 365659693Selan (match_operand:SI 2 "immediate_operand" "i")) 365759693Selan (match_operand:SI 3 "general_operand" "d"))] 365859693Selan "TARGET_68020 && TARGET_BITFIELD 365959693Selan && GET_CODE (operands[1]) == CONST_INT 366059693Selan && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) 366159693Selan && GET_CODE (operands[2]) == CONST_INT 366259693Selan && INTVAL (operands[2]) % INTVAL (operands[1]) == 0 366359693Selan && (GET_CODE (operands[0]) == REG 366459693Selan || ! mode_dependent_address_p (XEXP (operands[0], 0)))" 366559693Selan "* 366659693Selan{ 366759693Selan if (REG_P (operands[0])) 366859693Selan { 366959693Selan if (INTVAL (operands[1]) + INTVAL (operands[2]) != 32) 367059693Selan return \"bfins %3,%0{%b2:%b1}\"; 367159693Selan } 367259693Selan else 367359693Selan operands[0] 367459693Selan = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8); 367559693Selan 367659693Selan if (GET_CODE (operands[3]) == MEM) 367759693Selan operands[3] = adj_offsettable_operand (operands[3], 367859693Selan (32 - INTVAL (operands[1])) / 8); 367959693Selan if (INTVAL (operands[1]) == 8) 368059693Selan return \"move%.b %3,%0\"; 368159693Selan return \"move%.w %3,%0\"; 368259693Selan}") 368359693Selan 368459693Selan 368559693Selan; 368659693Selan; Special case for 32-bit field in memory. This only occurs when 32-bit 368759693Selan; alignment of structure members is specified. 368859693Selan; 368959693Selan; The move is allowed to be odd byte aligned, because that's still faster 369059693Selan; than an odd byte aligned bit field instruction. 369159693Selan; 369259693Selan(define_insn "" 369359693Selan [(set (match_operand:SI 0 "general_operand" "=rm") 369459693Selan (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o") 369559693Selan (match_operand:SI 2 "immediate_operand" "i") 369659693Selan (match_operand:SI 3 "immediate_operand" "i")))] 369759693Selan "TARGET_68020 && TARGET_BITFIELD 369859693Selan && GET_CODE (operands[2]) == CONST_INT 369959693Selan && (INTVAL (operands[2]) == 32) 370059693Selan && GET_CODE (operands[3]) == CONST_INT 370159693Selan && (INTVAL (operands[3]) % 8) == 0 370259693Selan && ! mode_dependent_address_p (XEXP (operands[1], 0))" 370359693Selan "* 370459693Selan{ 370559693Selan operands[1] 370659693Selan = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); 370759693Selan 370859693Selan return \"move%.l %1,%0\"; 370959693Selan}") 371059693Selan 371159693Selan(define_insn "" 371259693Selan [(set (match_operand:SI 0 "general_operand" "=&d") 371359693Selan (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do") 371459693Selan (match_operand:SI 2 "immediate_operand" "i") 371559693Selan (match_operand:SI 3 "immediate_operand" "i")))] 371659693Selan "TARGET_68020 && TARGET_BITFIELD 371759693Selan && GET_CODE (operands[2]) == CONST_INT 371859693Selan && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) 371959693Selan && GET_CODE (operands[3]) == CONST_INT 372059693Selan && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 372159693Selan && (GET_CODE (operands[1]) == REG 372259693Selan || ! mode_dependent_address_p (XEXP (operands[1], 0)))" 372359693Selan "* 372459693Selan{ 372559693Selan cc_status.flags |= CC_NOT_NEGATIVE; 372659693Selan if (REG_P (operands[1])) 372759693Selan { 372859693Selan if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32) 372959693Selan return \"bfextu %1{%b3:%b2},%0\"; 373059693Selan } 373159693Selan else 373259693Selan operands[1] 373359693Selan = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); 373459693Selan 373559693Selan output_asm_insn (\"clr%.l %0\", operands); 373659693Selan if (GET_CODE (operands[0]) == MEM) 373759693Selan operands[0] = adj_offsettable_operand (operands[0], 373859693Selan (32 - INTVAL (operands[1])) / 8); 373959693Selan if (INTVAL (operands[2]) == 8) 374059693Selan return \"move%.b %1,%0\"; 374159693Selan return \"move%.w %1,%0\"; 374259693Selan}") 374359693Selan 374459693Selan; 374559693Selan; Special case for 32-bit field in memory. This only occurs when 32-bit 374659693Selan; alignment of structure members is specified. 374759693Selan; 374859693Selan; The move is allowed to be odd byte aligned, because that's still faster 374959693Selan; than an odd byte aligned bit field instruction. 375059693Selan; 375159693Selan(define_insn "" 375259693Selan [(set (match_operand:SI 0 "general_operand" "=rm") 375359693Selan (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o") 375459693Selan (match_operand:SI 2 "immediate_operand" "i") 375559693Selan (match_operand:SI 3 "immediate_operand" "i")))] 375659693Selan "TARGET_68020 && TARGET_BITFIELD 375759693Selan && GET_CODE (operands[2]) == CONST_INT 375859693Selan && (INTVAL (operands[2]) == 32) 375959693Selan && GET_CODE (operands[3]) == CONST_INT 376059693Selan && (INTVAL (operands[3]) % 8) == 0 376159693Selan && ! mode_dependent_address_p (XEXP (operands[1], 0))" 376259693Selan "* 376359693Selan{ 376459693Selan operands[1] 376559693Selan = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); 376659693Selan 376759693Selan return \"move%.l %1,%0\"; 376859693Selan}") 376959693Selan 377059693Selan(define_insn "" 377159693Selan [(set (match_operand:SI 0 "general_operand" "=d") 377259693Selan (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do") 377359693Selan (match_operand:SI 2 "immediate_operand" "i") 377459693Selan (match_operand:SI 3 "immediate_operand" "i")))] 377559693Selan "TARGET_68020 && TARGET_BITFIELD 377659693Selan && GET_CODE (operands[2]) == CONST_INT 377759693Selan && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) 377859693Selan && GET_CODE (operands[3]) == CONST_INT 377959693Selan && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 378059693Selan && (GET_CODE (operands[1]) == REG 378159693Selan || ! mode_dependent_address_p (XEXP (operands[1], 0)))" 378259693Selan "* 378359693Selan{ 378459693Selan if (REG_P (operands[1])) 378559693Selan { 378659693Selan if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32) 378759693Selan return \"bfexts %1{%b3:%b2},%0\"; 378859693Selan } 378959693Selan else 379059693Selan operands[1] 379159693Selan = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); 379259693Selan 379359693Selan if (INTVAL (operands[2]) == 8) 379459693Selan return \"move%.b %1,%0\;extb%.l %0\"; 379559693Selan return \"move%.w %1,%0\;ext%.l %0\"; 379659693Selan}") 379759693Selan 379859693Selan;; Bit field instructions, general cases. 379959693Selan;; "o,d" constraint causes a nonoffsettable memref to match the "o" 380059693Selan;; so that its address is reloaded. 380159693Selan 380259693Selan(define_insn "extv" 380359693Selan [(set (match_operand:SI 0 "general_operand" "=d,d") 380459693Selan (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d") 380559693Selan (match_operand:SI 2 "general_operand" "di,di") 380659693Selan (match_operand:SI 3 "general_operand" "di,di")))] 380759693Selan "TARGET_68020 && TARGET_BITFIELD" 380859693Selan "bfexts %1{%b3:%b2},%0") 380959693Selan 381059693Selan(define_insn "extzv" 381159693Selan [(set (match_operand:SI 0 "general_operand" "=d,d") 381259693Selan (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d") 381359693Selan (match_operand:SI 2 "general_operand" "di,di") 381459693Selan (match_operand:SI 3 "general_operand" "di,di")))] 381559693Selan "TARGET_68020 && TARGET_BITFIELD" 381659693Selan "* 381759693Selan{ 381859693Selan cc_status.flags |= CC_NOT_NEGATIVE; 381959693Selan return \"bfextu %1{%b3:%b2},%0\"; 382059693Selan}") 382159693Selan 382259693Selan(define_insn "" 382359693Selan [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d") 382459693Selan (match_operand:SI 1 "general_operand" "di,di") 382559693Selan (match_operand:SI 2 "general_operand" "di,di")) 382659693Selan (xor:SI (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)) 382759693Selan (match_operand 3 "immediate_operand" "i,i")))] 382859693Selan "TARGET_68020 && TARGET_BITFIELD 382959693Selan && GET_CODE (operands[3]) == CONST_INT 383059693Selan && (INTVAL (operands[3]) == -1 383159693Selan || (GET_CODE (operands[1]) == CONST_INT 383259693Selan && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))" 383359693Selan "* 383459693Selan{ 383559693Selan CC_STATUS_INIT; 383659693Selan return \"bfchg %0{%b2:%b1}\"; 383759693Selan}") 383859693Selan 383959693Selan(define_insn "" 384059693Selan [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d") 384159693Selan (match_operand:SI 1 "general_operand" "di,di") 384259693Selan (match_operand:SI 2 "general_operand" "di,di")) 384359693Selan (const_int 0))] 384459693Selan "TARGET_68020 && TARGET_BITFIELD" 384559693Selan "* 384659693Selan{ 384759693Selan CC_STATUS_INIT; 384859693Selan return \"bfclr %0{%b2:%b1}\"; 384959693Selan}") 385059693Selan 385159693Selan(define_insn "" 385259693Selan [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d") 385359693Selan (match_operand:SI 1 "general_operand" "di,di") 385459693Selan (match_operand:SI 2 "general_operand" "di,di")) 385559693Selan (const_int -1))] 385659693Selan "TARGET_68020 && TARGET_BITFIELD" 385759693Selan "* 385859693Selan{ 385959693Selan CC_STATUS_INIT; 386059693Selan return \"bfset %0{%b2:%b1}\"; 386159693Selan}") 386259693Selan 386359693Selan(define_insn "insv" 386459693Selan [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d") 386559693Selan (match_operand:SI 1 "general_operand" "di,di") 386659693Selan (match_operand:SI 2 "general_operand" "di,di")) 386759693Selan (match_operand:SI 3 "general_operand" "d,d"))] 386859693Selan "TARGET_68020 && TARGET_BITFIELD" 386959693Selan "bfins %3,%0{%b2:%b1}") 387059693Selan 387159693Selan;; Now recognize bit field insns that operate on registers 387259693Selan;; (or at least were intended to do so). 387359693Selan 387459693Selan(define_insn "" 387559693Selan [(set (match_operand:SI 0 "general_operand" "=d") 387659693Selan (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d") 387759693Selan (match_operand:SI 2 "general_operand" "di") 387859693Selan (match_operand:SI 3 "general_operand" "di")))] 387959693Selan "TARGET_68020 && TARGET_BITFIELD" 388059693Selan "bfexts %1{%b3:%b2},%0") 388159693Selan 388259693Selan(define_insn "" 388359693Selan [(set (match_operand:SI 0 "general_operand" "=d") 388459693Selan (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d") 388559693Selan (match_operand:SI 2 "general_operand" "di") 388659693Selan (match_operand:SI 3 "general_operand" "di")))] 388759693Selan "TARGET_68020 && TARGET_BITFIELD" 388859693Selan "* 388959693Selan{ 389059693Selan cc_status.flags |= CC_NOT_NEGATIVE; 389159693Selan return \"bfextu %1{%b3:%b2},%0\"; 389259693Selan}") 389359693Selan 389459693Selan(define_insn "" 389559693Selan [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d") 389659693Selan (match_operand:SI 1 "general_operand" "di") 389759693Selan (match_operand:SI 2 "general_operand" "di")) 389859693Selan (const_int 0))] 389959693Selan "TARGET_68020 && TARGET_BITFIELD" 390059693Selan "* 390159693Selan{ 390259693Selan CC_STATUS_INIT; 390359693Selan return \"bfclr %0{%b2:%b1}\"; 390459693Selan}") 390559693Selan 390659693Selan(define_insn "" 390759693Selan [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d") 390859693Selan (match_operand:SI 1 "general_operand" "di") 390959693Selan (match_operand:SI 2 "general_operand" "di")) 391059693Selan (const_int -1))] 391159693Selan "TARGET_68020 && TARGET_BITFIELD" 391259693Selan "* 391359693Selan{ 391459693Selan CC_STATUS_INIT; 391559693Selan return \"bfset %0{%b2:%b1}\"; 391659693Selan}") 391759693Selan 391859693Selan(define_insn "" 391959693Selan [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d") 392059693Selan (match_operand:SI 1 "general_operand" "di") 392159693Selan (match_operand:SI 2 "general_operand" "di")) 392259693Selan (match_operand:SI 3 "general_operand" "d"))] 392359693Selan "TARGET_68020 && TARGET_BITFIELD" 392459693Selan "* 392559693Selan{ 392659693Selan#if 0 392759693Selan /* These special cases are now recognized by a specific pattern. */ 392859693Selan if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT 392959693Selan && INTVAL (operands[1]) == 16 && INTVAL (operands[2]) == 16) 393059693Selan return \"move%.w %3,%0\"; 393159693Selan if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT 393259693Selan && INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8) 393359693Selan return \"move%.b %3,%0\"; 393459693Selan#endif 393559693Selan return \"bfins %3,%0{%b2:%b1}\"; 393659693Selan}") 393759693Selan 393859693Selan;; Special patterns for optimizing bit-field instructions. 393959693Selan 394059693Selan(define_insn "" 394159693Selan [(set (cc0) 394259693Selan (zero_extract:SI (match_operand:QI 0 "memory_operand" "o") 394359693Selan (match_operand:SI 1 "general_operand" "di") 394459693Selan (match_operand:SI 2 "general_operand" "di")))] 394559693Selan "TARGET_68020 && TARGET_BITFIELD 394659693Selan && GET_CODE (operands[1]) == CONST_INT" 394759693Selan "* 394859693Selan{ 394959693Selan if (operands[1] == const1_rtx 395059693Selan && GET_CODE (operands[2]) == CONST_INT) 395159693Selan { 395259693Selan int width = GET_CODE (operands[0]) == REG ? 31 : 7; 395359693Selan return output_btst (operands, 395459693Selan gen_rtx (CONST_INT, VOIDmode, 395559693Selan width - INTVAL (operands[2])), 395659693Selan operands[0], 395759693Selan insn, 1000); 395859693Selan /* Pass 1000 as SIGNPOS argument so that btst will 395959693Selan not think we are testing the sign bit for an `and' 396059693Selan and assume that nonzero implies a negative result. */ 396159693Selan } 396259693Selan if (INTVAL (operands[1]) != 32) 396359693Selan cc_status.flags = CC_NOT_NEGATIVE; 396459693Selan return \"bftst %0{%b2:%b1}\"; 396559693Selan}") 396659693Selan 396759693Selan 396859693Selan;;; now handle the register cases 396959693Selan(define_insn "" 397059693Selan [(set (cc0) 397159693Selan (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "d") 397259693Selan (match_operand:SI 1 "general_operand" "di") 397359693Selan (match_operand:SI 2 "general_operand" "di")))] 397459693Selan "TARGET_68020 && TARGET_BITFIELD 397559693Selan && GET_CODE (operands[1]) == CONST_INT" 397659693Selan "* 397759693Selan{ 397859693Selan if (operands[1] == const1_rtx 397959693Selan && GET_CODE (operands[2]) == CONST_INT) 398059693Selan { 398159693Selan int width = GET_CODE (operands[0]) == REG ? 31 : 7; 398259693Selan return output_btst (operands, 398359693Selan gen_rtx (CONST_INT, VOIDmode, 398459693Selan width - INTVAL (operands[2])), 398559693Selan operands[0], 398659693Selan insn, 1000); 398759693Selan /* Pass 1000 as SIGNPOS argument so that btst will 398859693Selan not think we are testing the sign bit for an `and' 398959693Selan and assume that nonzero implies a negative result. */ 399059693Selan } 399159693Selan if (INTVAL (operands[1]) != 32) 399259693Selan cc_status.flags = CC_NOT_NEGATIVE; 399359693Selan return \"bftst %0{%b2:%b1}\"; 399459693Selan}") 399559693Selan 399659693Selan(define_insn "seq" 399759693Selan [(set (match_operand:QI 0 "general_operand" "=d") 399859693Selan (eq:QI (cc0) (const_int 0)))] 399959693Selan "" 400059693Selan "* 400159693Selan cc_status = cc_prev_status; 400259693Selan OUTPUT_JUMP (\"seq %0\", \"fseq %0\", \"seq %0\"); 400359693Selan") 400459693Selan 400559693Selan(define_insn "sne" 400659693Selan [(set (match_operand:QI 0 "general_operand" "=d") 400759693Selan (ne:QI (cc0) (const_int 0)))] 400859693Selan "" 400959693Selan "* 401059693Selan cc_status = cc_prev_status; 401159693Selan OUTPUT_JUMP (\"sne %0\", \"fsne %0\", \"sne %0\"); 401259693Selan") 401359693Selan 401459693Selan(define_insn "sgt" 401559693Selan [(set (match_operand:QI 0 "general_operand" "=d") 401659693Selan (gt:QI (cc0) (const_int 0)))] 401759693Selan "" 401859693Selan "* 401959693Selan cc_status = cc_prev_status; 402059693Selan OUTPUT_JUMP (\"sgt %0\", \"fsgt %0\", 0); 402159693Selan") 402259693Selan 402359693Selan(define_insn "sgtu" 402459693Selan [(set (match_operand:QI 0 "general_operand" "=d") 402559693Selan (gtu:QI (cc0) (const_int 0)))] 402659693Selan "" 402759693Selan "* cc_status = cc_prev_status; 402859693Selan return \"shi %0\"; ") 402959693Selan 403059693Selan(define_insn "slt" 403159693Selan [(set (match_operand:QI 0 "general_operand" "=d") 403259693Selan (lt:QI (cc0) (const_int 0)))] 403359693Selan "" 403459693Selan "* cc_status = cc_prev_status; 403559693Selan OUTPUT_JUMP (\"slt %0\", \"fslt %0\", \"smi %0\"); ") 403659693Selan 403759693Selan(define_insn "sltu" 403859693Selan [(set (match_operand:QI 0 "general_operand" "=d") 403959693Selan (ltu:QI (cc0) (const_int 0)))] 404059693Selan "" 404159693Selan "* cc_status = cc_prev_status; 404259693Selan return \"scs %0\"; ") 404359693Selan 404459693Selan(define_insn "sge" 404559693Selan [(set (match_operand:QI 0 "general_operand" "=d") 404659693Selan (ge:QI (cc0) (const_int 0)))] 404759693Selan "" 404859693Selan "* cc_status = cc_prev_status; 404959693Selan OUTPUT_JUMP (\"sge %0\", \"fsge %0\", \"spl %0\"); ") 405059693Selan 405159693Selan(define_insn "sgeu" 405259693Selan [(set (match_operand:QI 0 "general_operand" "=d") 405359693Selan (geu:QI (cc0) (const_int 0)))] 405459693Selan "" 405559693Selan "* cc_status = cc_prev_status; 405659693Selan return \"scc %0\"; ") 405759693Selan 405859693Selan(define_insn "sle" 405959693Selan [(set (match_operand:QI 0 "general_operand" "=d") 406059693Selan (le:QI (cc0) (const_int 0)))] 406159693Selan "" 406259693Selan "* 406359693Selan cc_status = cc_prev_status; 406459693Selan OUTPUT_JUMP (\"sle %0\", \"fsle %0\", 0); 406559693Selan") 406659693Selan 406759693Selan(define_insn "sleu" 406859693Selan [(set (match_operand:QI 0 "general_operand" "=d") 406959693Selan (leu:QI (cc0) (const_int 0)))] 407059693Selan "" 407159693Selan "* cc_status = cc_prev_status; 407259693Selan return \"sls %0\"; ") 407359693Selan 407459693Selan;; Basic conditional jump instructions. 407559693Selan 407659693Selan(define_insn "beq" 407759693Selan [(set (pc) 407859693Selan (if_then_else (eq (cc0) 407959693Selan (const_int 0)) 408059693Selan (label_ref (match_operand 0 "" "")) 408159693Selan (pc)))] 408259693Selan "" 408359693Selan "* 408459693Selan{ 408559693Selan#ifdef MOTOROLA 408659693Selan OUTPUT_JUMP (\"jbeq %l0\", \"fbeq %l0\", \"jbeq %l0\"); 408759693Selan#else 408859693Selan OUTPUT_JUMP (\"jeq %l0\", \"fjeq %l0\", \"jeq %l0\"); 408959693Selan#endif 409059693Selan}") 409159693Selan 409259693Selan(define_insn "bne" 409359693Selan [(set (pc) 409459693Selan (if_then_else (ne (cc0) 409559693Selan (const_int 0)) 409659693Selan (label_ref (match_operand 0 "" "")) 409759693Selan (pc)))] 409859693Selan "" 409959693Selan "* 410059693Selan{ 410159693Selan#ifdef MOTOROLA 410259693Selan OUTPUT_JUMP (\"jbne %l0\", \"fbne %l0\", \"jbne %l0\"); 410359693Selan#else 410459693Selan OUTPUT_JUMP (\"jne %l0\", \"fjne %l0\", \"jne %l0\"); 410559693Selan#endif 410659693Selan}") 410759693Selan 410859693Selan(define_insn "bgt" 410959693Selan [(set (pc) 411059693Selan (if_then_else (gt (cc0) 411159693Selan (const_int 0)) 411259693Selan (label_ref (match_operand 0 "" "")) 411359693Selan (pc)))] 411459693Selan "" 411559693Selan "* 411659693Selan#ifdef MOTOROLA 411759693Selan OUTPUT_JUMP (\"jbgt %l0\", \"fbgt %l0\", 0); 411859693Selan#else 411959693Selan OUTPUT_JUMP (\"jgt %l0\", \"fjgt %l0\", 0); 412059693Selan#endif 412159693Selan") 412259693Selan 412359693Selan(define_insn "bgtu" 412459693Selan [(set (pc) 412559693Selan (if_then_else (gtu (cc0) 412659693Selan (const_int 0)) 412759693Selan (label_ref (match_operand 0 "" "")) 412859693Selan (pc)))] 412959693Selan "" 413059693Selan "* 413159693Selan#ifdef MOTOROLA 413259693Selan return \"jbhi %l0\"; 413359693Selan#else 413459693Selan return \"jhi %l0\"; 413559693Selan#endif 413659693Selan") 413759693Selan 413859693Selan(define_insn "blt" 413959693Selan [(set (pc) 414059693Selan (if_then_else (lt (cc0) 414159693Selan (const_int 0)) 414259693Selan (label_ref (match_operand 0 "" "")) 414359693Selan (pc)))] 414459693Selan "" 414559693Selan "* 414659693Selan#ifdef MOTOROLA 414759693Selan OUTPUT_JUMP (\"jblt %l0\", \"fblt %l0\", \"jbmi %l0\"); 414859693Selan#else 414959693Selan OUTPUT_JUMP (\"jlt %l0\", \"fjlt %l0\", \"jmi %l0\"); 415059693Selan#endif 415159693Selan") 415259693Selan 415359693Selan(define_insn "bltu" 415459693Selan [(set (pc) 415559693Selan (if_then_else (ltu (cc0) 415659693Selan (const_int 0)) 415759693Selan (label_ref (match_operand 0 "" "")) 415859693Selan (pc)))] 415959693Selan "" 416059693Selan "* 416159693Selan#ifdef MOTOROLA 416259693Selan return \"jbcs %l0\"; 416359693Selan#else 416459693Selan return \"jcs %l0\"; 416559693Selan#endif 416659693Selan") 416759693Selan 416859693Selan(define_insn "bge" 416959693Selan [(set (pc) 417059693Selan (if_then_else (ge (cc0) 417159693Selan (const_int 0)) 417259693Selan (label_ref (match_operand 0 "" "")) 417359693Selan (pc)))] 417459693Selan "" 417559693Selan "* 417659693Selan#ifdef MOTOROLA 417759693Selan OUTPUT_JUMP (\"jbge %l0\", \"fbge %l0\", \"jbpl %l0\"); 417859693Selan#else 417959693Selan OUTPUT_JUMP (\"jge %l0\", \"fjge %l0\", \"jpl %l0\"); 418059693Selan#endif 418159693Selan") 418259693Selan 418359693Selan(define_insn "bgeu" 418459693Selan [(set (pc) 418559693Selan (if_then_else (geu (cc0) 418659693Selan (const_int 0)) 418759693Selan (label_ref (match_operand 0 "" "")) 418859693Selan (pc)))] 418959693Selan "" 419059693Selan "* 419159693Selan#ifdef MOTOROLA 419259693Selan return \"jbcc %l0\"; 419359693Selan#else 419459693Selan return \"jcc %l0\"; 419559693Selan#endif 419659693Selan") 419759693Selan 419859693Selan(define_insn "ble" 419959693Selan [(set (pc) 420059693Selan (if_then_else (le (cc0) 420159693Selan (const_int 0)) 420259693Selan (label_ref (match_operand 0 "" "")) 420359693Selan (pc)))] 420459693Selan "" 420559693Selan "* 420659693Selan#ifdef MOTOROLA 420759693Selan OUTPUT_JUMP (\"jble %l0\", \"fble %l0\", 0); 420859693Selan#else 420959693Selan OUTPUT_JUMP (\"jle %l0\", \"fjle %l0\", 0); 421059693Selan#endif 421159693Selan") 421259693Selan 421359693Selan(define_insn "bleu" 421459693Selan [(set (pc) 421559693Selan (if_then_else (leu (cc0) 421659693Selan (const_int 0)) 421759693Selan (label_ref (match_operand 0 "" "")) 421859693Selan (pc)))] 421959693Selan "" 422059693Selan "* 422159693Selan#ifdef MOTOROLA 422259693Selan return \"jbls %l0\"; 422359693Selan#else 422459693Selan return \"jls %l0\"; 422559693Selan#endif 422659693Selan") 422759693Selan 422859693Selan;; Negated conditional jump instructions. 422959693Selan 423059693Selan(define_insn "" 423159693Selan [(set (pc) 423259693Selan (if_then_else (eq (cc0) 423359693Selan (const_int 0)) 423459693Selan (pc) 423559693Selan (label_ref (match_operand 0 "" ""))))] 423659693Selan "" 423759693Selan "* 423859693Selan{ 423959693Selan#ifdef MOTOROLA 424059693Selan OUTPUT_JUMP (\"jbne %l0\", \"fbne %l0\", \"jbne %l0\"); 424159693Selan#else 424259693Selan OUTPUT_JUMP (\"jne %l0\", \"fjne %l0\", \"jne %l0\"); 424359693Selan#endif 424459693Selan}") 424559693Selan 424659693Selan(define_insn "" 424759693Selan [(set (pc) 424859693Selan (if_then_else (ne (cc0) 424959693Selan (const_int 0)) 425059693Selan (pc) 425159693Selan (label_ref (match_operand 0 "" ""))))] 425259693Selan "" 425359693Selan "* 425459693Selan{ 425559693Selan#ifdef MOTOROLA 425659693Selan OUTPUT_JUMP (\"jbeq %l0\", \"fbeq %l0\", \"jbeq %l0\"); 425759693Selan#else 425859693Selan OUTPUT_JUMP (\"jeq %l0\", \"fjeq %l0\", \"jeq %l0\"); 425959693Selan#endif 426059693Selan}") 426159693Selan 426259693Selan(define_insn "" 426359693Selan [(set (pc) 426459693Selan (if_then_else (gt (cc0) 426559693Selan (const_int 0)) 426659693Selan (pc) 426759693Selan (label_ref (match_operand 0 "" ""))))] 426859693Selan "" 426959693Selan "* 427059693Selan#ifdef MOTOROLA 427159693Selan OUTPUT_JUMP (\"jble %l0\", \"fbngt %l0\", 0); 427259693Selan#else 427359693Selan OUTPUT_JUMP (\"jle %l0\", \"fjngt %l0\", 0); 427459693Selan#endif 427559693Selan") 427659693Selan 427759693Selan(define_insn "" 427859693Selan [(set (pc) 427959693Selan (if_then_else (gtu (cc0) 428059693Selan (const_int 0)) 428159693Selan (pc) 428259693Selan (label_ref (match_operand 0 "" ""))))] 428359693Selan "" 428459693Selan "* 428559693Selan#ifdef MOTOROLA 428659693Selan return \"jbls %l0\"; 428759693Selan#else 428859693Selan return \"jls %l0\"; 428959693Selan#endif 429059693Selan") 429159693Selan 429259693Selan(define_insn "" 429359693Selan [(set (pc) 429459693Selan (if_then_else (lt (cc0) 429559693Selan (const_int 0)) 429659693Selan (pc) 429759693Selan (label_ref (match_operand 0 "" ""))))] 429859693Selan "" 429959693Selan "* 430059693Selan#ifdef MOTOROLA 430159693Selan OUTPUT_JUMP (\"jbge %l0\", \"fbnlt %l0\", \"jbpl %l0\"); 430259693Selan#else 430359693Selan OUTPUT_JUMP (\"jge %l0\", \"fjnlt %l0\", \"jpl %l0\"); 430459693Selan#endif 430559693Selan") 430659693Selan 430759693Selan(define_insn "" 430859693Selan [(set (pc) 430959693Selan (if_then_else (ltu (cc0) 431059693Selan (const_int 0)) 431159693Selan (pc) 431259693Selan (label_ref (match_operand 0 "" ""))))] 431359693Selan "" 431459693Selan "* 431559693Selan#ifdef MOTOROLA 431659693Selan return \"jbcc %l0\"; 431759693Selan#else 431859693Selan return \"jcc %l0\"; 431959693Selan#endif 432059693Selan") 432159693Selan 432259693Selan(define_insn "" 432359693Selan [(set (pc) 432459693Selan (if_then_else (ge (cc0) 432559693Selan (const_int 0)) 432659693Selan (pc) 432759693Selan (label_ref (match_operand 0 "" ""))))] 432859693Selan "" 432959693Selan "* 433059693Selan#ifdef MOTOROLA 433159693Selan OUTPUT_JUMP (\"jblt %l0\", \"fbnge %l0\", \"jbmi %l0\"); 433259693Selan#else 433359693Selan OUTPUT_JUMP (\"jlt %l0\", \"fjnge %l0\", \"jmi %l0\"); 433459693Selan#endif 433559693Selan") 433659693Selan 433759693Selan(define_insn "" 433859693Selan [(set (pc) 433959693Selan (if_then_else (geu (cc0) 434059693Selan (const_int 0)) 434159693Selan (pc) 434259693Selan (label_ref (match_operand 0 "" ""))))] 434359693Selan "" 434459693Selan "* 434559693Selan#ifdef MOTOROLA 434659693Selan return \"jbcs %l0\"; 434759693Selan#else 434859693Selan return \"jcs %l0\"; 434959693Selan#endif 435059693Selan") 435159693Selan 435259693Selan(define_insn "" 435359693Selan [(set (pc) 435459693Selan (if_then_else (le (cc0) 435559693Selan (const_int 0)) 435659693Selan (pc) 435759693Selan (label_ref (match_operand 0 "" ""))))] 435859693Selan "" 435959693Selan "* 436059693Selan#ifdef MOTOROLA 436159693Selan OUTPUT_JUMP (\"jbgt %l0\", \"fbnle %l0\", 0); 436259693Selan#else 436359693Selan OUTPUT_JUMP (\"jgt %l0\", \"fjnle %l0\", 0); 436459693Selan#endif 436559693Selan") 436659693Selan 436759693Selan(define_insn "" 436859693Selan [(set (pc) 436959693Selan (if_then_else (leu (cc0) 437059693Selan (const_int 0)) 437159693Selan (pc) 437259693Selan (label_ref (match_operand 0 "" ""))))] 437359693Selan "" 437459693Selan "* 437559693Selan#ifdef MOTOROLA 437659693Selan return \"jbhi %l0\"; 437759693Selan#else 437859693Selan return \"jhi %l0\"; 437959693Selan#endif 438059693Selan") 438159693Selan 438259693Selan;; Unconditional and other jump instructions 438359693Selan(define_insn "jump" 438459693Selan [(set (pc) 438559693Selan (label_ref (match_operand 0 "" "")))] 438659693Selan "" 438759693Selan "* 438859693Selan#ifdef MOTOROLA 438959693Selan return \"jbra %l0\"; 439059693Selan#else 439159693Selan return \"jra %l0\"; 439259693Selan#endif 439359693Selan") 439459693Selan 439559693Selan;; We support two different ways of handling dispatch tables. 439659693Selan;; The NeXT uses absolute tables, and other machines use relative. 439759693Selan;; This define_expand can generate either kind. 439859693Selan(define_expand "tablejump" 439959693Selan [(parallel [(set (pc) (match_operand 0 "" "")) 440059693Selan (use (label_ref (match_operand 1 "" "")))])] 440159693Selan "" 440259693Selan " 440359693Selan{ 440459693Selan#ifdef CASE_VECTOR_PC_RELATIVE 440559693Selan operands[0] = gen_rtx (PLUS, SImode, pc_rtx, operands[0]); 440659693Selan#endif 440759693Selan}") 440859693Selan 440959693Selan;; Jump to variable address from dispatch table of absolute addresses. 441059693Selan(define_insn "" 441159693Selan [(set (pc) (match_operand:SI 0 "register_operand" "a")) 441259693Selan (use (label_ref (match_operand 1 "" "")))] 441359693Selan "" 441459693Selan "* 441559693Selan#ifdef MOTOROLA 441659693Selan return \"jmp (%0)\"; 441759693Selan#else 441859693Selan return \"jmp %0@\"; 441959693Selan#endif 442059693Selan") 442159693Selan 442259693Selan;; Jump to variable address from dispatch table of relative addresses. 442359693Selan(define_insn "" 442459693Selan [(set (pc) 442559693Selan (plus:SI (pc) (match_operand:HI 0 "register_operand" "r"))) 442659693Selan (use (label_ref (match_operand 1 "" "")))] 442759693Selan "" 442859693Selan "* 442959693Selan#ifdef ASM_RETURN_CASE_JUMP 443059693Selan ASM_RETURN_CASE_JUMP; 443159693Selan#else 443259693Selan#ifdef SGS 443359693Selan#ifdef ASM_OUTPUT_CASE_LABEL 443459693Selan return \"jmp 6(%%pc,%0.w)\"; 443559693Selan#else 443659693Selan#ifdef CRDS 443759693Selan return \"jmp 2(pc,%0.w)\"; 443859693Selan#else 443959693Selan return \"jmp 2(%%pc,%0.w)\"; 444059693Selan#endif /* end !CRDS */ 444159693Selan#endif 444259693Selan#else /* not SGS */ 444359693Selan#ifdef MOTOROLA 444459693Selan return \"jmp (2,pc,%0.w)\"; 444559693Selan#else 444659693Selan return \"jmp pc@(2,%0:w)\"; 444759693Selan#endif 444859693Selan#endif 444959693Selan#endif 445059693Selan") 445159693Selan 445259693Selan;; Decrement-and-branch insns. 445359693Selan(define_insn "" 445459693Selan [(set (pc) 445559693Selan (if_then_else 445659693Selan (ne (match_operand:HI 0 "general_operand" "+g") 445759693Selan (const_int 0)) 445859693Selan (label_ref (match_operand 1 "" "")) 445959693Selan (pc))) 446059693Selan (set (match_dup 0) 446159693Selan (plus:HI (match_dup 0) 446259693Selan (const_int -1)))] 446359693Selan "" 446459693Selan "* 446559693Selan{ 446659693Selan CC_STATUS_INIT; 446759693Selan if (DATA_REG_P (operands[0])) 446859693Selan return \"dbra %0,%l1\"; 446959693Selan if (GET_CODE (operands[0]) == MEM) 447059693Selan { 447159693Selan#ifdef MOTOROLA 447259693Selan#ifdef NO_ADDSUB_Q 447359693Selan return \"sub%.w %#1,%0\;jbcc %l1\"; 447459693Selan#else 447559693Selan return \"subq%.w %#1,%0\;jbcc %l1\"; 447659693Selan#endif 447759693Selan#else /* not MOTOROLA */ 447859693Selan return \"subqw %#1,%0\;jcc %l1\"; 447959693Selan#endif 448059693Selan } 448159693Selan#ifdef MOTOROLA 448259693Selan#ifdef SGS_CMP_ORDER 448359693Selan#ifdef NO_ADDSUB_Q 448459693Selan return \"sub%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\"; 448559693Selan#else 448659693Selan return \"subq%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\"; 448759693Selan#endif 448859693Selan#else /* not SGS_CMP_ORDER */ 448959693Selan return \"subq%.w %#1,%0\;cmp%.w %#-1,%0\;jbne %l1\"; 449059693Selan#endif 449159693Selan#else /* not MOTOROLA */ 449259693Selan return \"subqw %#1,%0\;cmpw %#-1,%0\;jne %l1\"; 449359693Selan#endif 449459693Selan}") 449559693Selan 449659693Selan(define_insn "" 449759693Selan [(set (pc) 449859693Selan (if_then_else 449959693Selan (ne (match_operand:SI 0 "general_operand" "+g") 450059693Selan (const_int 0)) 450159693Selan (label_ref (match_operand 1 "" "")) 450259693Selan (pc))) 450359693Selan (set (match_dup 0) 450459693Selan (plus:SI (match_dup 0) 450559693Selan (const_int -1)))] 450659693Selan "" 450759693Selan "* 450859693Selan{ 450959693Selan CC_STATUS_INIT; 451059693Selan#ifdef MOTOROLA 451159693Selan#ifdef NO_ADDSUB_Q 451259693Selan if (DATA_REG_P (operands[0])) 451359693Selan return \"dbra %0,%l1\;clr%.w %0\;sub%.l %#1,%0\;jbcc %l1\"; 451459693Selan if (GET_CODE (operands[0]) == MEM) 451559693Selan return \"sub%.l %#1,%0\;jbcc %l1\"; 451659693Selan#else 451759693Selan if (DATA_REG_P (operands[0])) 451859693Selan return \"dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jbcc %l1\"; 451959693Selan if (GET_CODE (operands[0]) == MEM) 452059693Selan return \"subq%.l %#1,%0\;jbcc %l1\"; 452159693Selan#endif /* NO_ADDSUB_Q */ 452259693Selan#ifdef SGS_CMP_ORDER 452359693Selan#ifdef NO_ADDSUB_Q 452459693Selan return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; 452559693Selan#else 452659693Selan return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; 452759693Selan#endif 452859693Selan#else /* not SGS_CMP_ORDER */ 452959693Selan return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\"; 453059693Selan#endif /* not SGS_CMP_ORDER */ 453159693Selan#else /* not MOTOROLA */ 453259693Selan if (DATA_REG_P (operands[0])) 453359693Selan return \"dbra %0,%l1\;clr%.w %0\;subql %#1,%0\;jcc %l1\"; 453459693Selan if (GET_CODE (operands[0]) == MEM) 453559693Selan return \"subql %#1,%0\;jcc %l1\"; 453659693Selan return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\"; 453759693Selan#endif /* not MOTOROLA */ 453859693Selan}") 453959693Selan 454059693Selan;; Two dbra patterns that use REG_NOTES info generated by strength_reduce. 454159693Selan 454259693Selan(define_insn "" 454359693Selan [(set (pc) 454459693Selan (if_then_else 454559693Selan (ge (plus:HI (match_operand:HI 0 "general_operand" "+g") 454659693Selan (const_int -1)) 454759693Selan (const_int 0)) 454859693Selan (label_ref (match_operand 1 "" "")) 454959693Selan (pc))) 455059693Selan (set (match_dup 0) 455159693Selan (plus:HI (match_dup 0) 455259693Selan (const_int -1)))] 455359693Selan "find_reg_note (insn, REG_NONNEG, 0)" 455459693Selan "* 455559693Selan{ 455659693Selan CC_STATUS_INIT; 455759693Selan#ifdef MOTOROLA 455859693Selan#ifdef NO_ADDSUB_Q 455959693Selan if (DATA_REG_P (operands[0])) 456059693Selan return \"dbra %0,%l1\"; 456159693Selan if (GET_CODE (operands[0]) == MEM) 456259693Selan return \"sub%.w %#1,%0\;jbcc %l1\"; 456359693Selan#else 456459693Selan if (DATA_REG_P (operands[0])) 456559693Selan return \"dbra %0,%l1\"; 456659693Selan if (GET_CODE (operands[0]) == MEM) 456759693Selan return \"subq%.w %#1,%0\;jbcc %l1\"; 456859693Selan#endif 456959693Selan#ifdef SGS_CMP_ORDER 457059693Selan#ifdef NO_ADDSUB_Q 457159693Selan return \"sub.w %#1,%0\;cmp.w %0,%#-1\;jbne %l1\"; 457259693Selan#else 457359693Selan return \"subq.w %#1,%0\;cmp.w %0,%#-1\;jbne %l1\"; 457459693Selan#endif 457559693Selan#else /* not SGS_CMP_ORDER */ 457659693Selan return \"subq.w %#1,%0\;cmp.w %#-1,%0\;jbne %l1\"; 457759693Selan#endif /* not SGS_CMP_ORDER */ 457859693Selan#else /* not MOTOROLA */ 457959693Selan if (DATA_REG_P (operands[0])) 458059693Selan return \"dbra %0,%l1\"; 458159693Selan if (GET_CODE (operands[0]) == MEM) 458259693Selan return \"subqw %#1,%0\;jcc %l1\"; 458359693Selan return \"subqw %#1,%0\;cmpw %#-1,%0\;jne %l1\"; 458459693Selan#endif /* not MOTOROLA */ 458559693Selan}") 458659693Selan 458759693Selan(define_insn "decrement_and_branch_until_zero" 458859693Selan [(set (pc) 458959693Selan (if_then_else 459059693Selan (ge (plus:SI (match_operand:SI 0 "general_operand" "+g") 459159693Selan (const_int -1)) 459259693Selan (const_int 0)) 459359693Selan (label_ref (match_operand 1 "" "")) 459459693Selan (pc))) 459559693Selan (set (match_dup 0) 459659693Selan (plus:SI (match_dup 0) 459759693Selan (const_int -1)))] 459859693Selan "find_reg_note (insn, REG_NONNEG, 0)" 459959693Selan "* 460059693Selan{ 460159693Selan CC_STATUS_INIT; 460259693Selan#ifdef MOTOROLA 460359693Selan#ifdef NO_ADDSUB_Q 460459693Selan if (DATA_REG_P (operands[0])) 460559693Selan return \"dbra %0,%l1\;clr%.w %0\;sub%.l %#1,%0\;jbcc %l1\"; 460659693Selan if (GET_CODE (operands[0]) == MEM) 460759693Selan return \"sub%.l %#1,%0\;jbcc %l1\"; 460859693Selan#else 460959693Selan if (DATA_REG_P (operands[0])) 461059693Selan return \"dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jbcc %l1\"; 461159693Selan if (GET_CODE (operands[0]) == MEM) 461259693Selan return \"subq%.l %#1,%0\;jbcc %l1\"; 461359693Selan#endif 461459693Selan#ifdef SGS_CMP_ORDER 461559693Selan#ifdef NO_ADDSUB_Q 461659693Selan return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; 461759693Selan#else 461859693Selan return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; 461959693Selan#endif 462059693Selan#else /* not SGS_CMP_ORDER */ 462159693Selan return \"subq.l %#1,%0\;cmp.l %#-1,%0\;jbne %l1\"; 462259693Selan#endif /* not SGS_CMP_ORDER */ 462359693Selan#else /* not MOTOROLA */ 462459693Selan if (DATA_REG_P (operands[0])) 462559693Selan return \"dbra %0,%l1\;clr%.w %0\;subql %#1,%0\;jcc %l1\"; 462659693Selan if (GET_CODE (operands[0]) == MEM) 462759693Selan return \"subql %#1,%0\;jcc %l1\"; 462859693Selan return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\"; 462959693Selan#endif /* not MOTOROLA */ 463059693Selan}") 463159693Selan 463259693Selan 463359693Selan;; PIC calls are handled by loading the address of the function into a 463459693Selan;; register (via movsi), then emitting a register indirect call using 463559693Selan;; the "jsr" function call syntax. 463659693Selan;; 463759693Selan;; It is important to note that the "jsr" syntax is always used for 463859693Selan;; PIC calls, even on machines in which GCC normally uses the "jbsr" 463959693Selan;; syntax for non-PIC calls. This keeps at least 1 assembler (Sun) 464059693Selan;; from emitting incorrect code for a PIC call. 464159693Selan;; 464259693Selan;; We have different patterns for PIC calls and non-PIC calls. The 464359693Selan;; different patterns are only used to choose the right syntax 464459693Selan;; ("jsr" vs "jbsr"). 464559693Selan 464659693Selan;; Call subroutine with no return value. 464759693Selan(define_expand "call" 464859693Selan [(call (match_operand:QI 0 "memory_operand" "") 464959693Selan (match_operand:SI 1 "general_operand" ""))] 465059693Selan ;; Operand 1 not really used on the m68000. 465159693Selan 465259693Selan "" 465359693Selan " 465459693Selan{ 465559693Selan if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) 465659693Selan operands[0] = gen_rtx (MEM, GET_MODE (operands[0]), 465759693Selan force_reg (Pmode, XEXP (operands[0], 0))); 465859693Selan}") 465959693Selan 466059693Selan;; This is a normal call sequence. 466159693Selan(define_insn "" 466259693Selan [(call (match_operand:QI 0 "memory_operand" "o") 466359693Selan (match_operand:SI 1 "general_operand" "g"))] 466459693Selan ;; Operand 1 not really used on the m68000. 466559693Selan 466659693Selan "! flag_pic" 466759693Selan "* 466859693Selan#ifdef MOTOROLA 466959693Selan return \"jsr %0\"; 467059693Selan#else 467159693Selan return \"jbsr %0\"; 467259693Selan#endif 467359693Selan") 467459693Selan 467559693Selan;; This is a PIC call sequence. 467659693Selan(define_insn "" 467759693Selan [(call (match_operand:QI 0 "memory_operand" "o") 467859693Selan (match_operand:SI 1 "general_operand" "g"))] 467959693Selan ;; Operand 1 not really used on the m68000. 468059693Selan 468159693Selan "flag_pic" 468259693Selan "* 468359693Selan return \"jsr %0\"; 468459693Selan") 468559693Selan 468659693Selan;; Call subroutine, returning value in operand 0 468759693Selan;; (which must be a hard register). 468859693Selan;; See comments before "call" regarding PIC calls. 468959693Selan(define_expand "call_value" 469059693Selan [(set (match_operand 0 "" "") 469159693Selan (call (match_operand:QI 1 "memory_operand" "") 469259693Selan (match_operand:SI 2 "general_operand" "")))] 469359693Selan ;; Operand 2 not really used on the m68000. 469459693Selan "" 469559693Selan " 469659693Selan{ 469759693Selan if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) 469859693Selan operands[1] = gen_rtx (MEM, GET_MODE (operands[1]), 469959693Selan force_reg (Pmode, XEXP (operands[1], 0))); 470059693Selan}") 470159693Selan 470259693Selan;; This is a normal call_value 470359693Selan(define_insn "" 470459693Selan [(set (match_operand 0 "" "=rf") 470559693Selan (call (match_operand:QI 1 "memory_operand" "o") 470659693Selan (match_operand:SI 2 "general_operand" "g")))] 470759693Selan ;; Operand 2 not really used on the m68000. 470859693Selan "! flag_pic" 470959693Selan "* 471059693Selan#ifdef MOTOROLA 471159693Selan return \"jsr %1\"; 471259693Selan#else 471359693Selan return \"jbsr %1\"; 471459693Selan#endif 471559693Selan") 471659693Selan 471759693Selan;; This is a PIC call_value 471859693Selan(define_insn "" 471959693Selan [(set (match_operand 0 "" "=rf") 472059693Selan (call (match_operand:QI 1 "memory_operand" "o") 472159693Selan (match_operand:SI 2 "general_operand" "g")))] 472259693Selan ;; Operand 2 not really used on the m68000. 472359693Selan "flag_pic" 472459693Selan "* 472559693Selan return \"jsr %1\"; 472659693Selan") 472759693Selan 472859693Selan(define_insn "nop" 472959693Selan [(const_int 0)] 473059693Selan "" 473159693Selan "nop") 473259693Selan 473359693Selan(define_insn "probe" 473459693Selan [(reg:SI 15)] 473559693Selan "NEED_PROBE" 473659693Selan "* 473759693Selan{ 473859693Selan operands[0] = gen_rtx (PLUS, SImode, stack_pointer_rtx, 473959693Selan gen_rtx (CONST_INT, VOIDmode, NEED_PROBE)); 474059693Selan return \"tstl %a0\"; 474159693Selan}") 474259693Selan 474359693Selan;; Used for frameless functions which save no regs and allocate no locals. 474459693Selan(define_insn "return" 474559693Selan [(return)] 474659693Selan "USE_RETURN_INSN" 474759693Selan "* 474859693Selan{ 474959693Selan if (current_function_pops_args == 0) 475059693Selan return \"rts\"; 475159693Selan operands[0] = gen_rtx (CONST_INT, VOIDmode, current_function_pops_args); 475259693Selan return \"rtd %0\"; 475359693Selan}") 475459693Selan 475559693Selan(define_insn "indirect_jump" 475659693Selan [(set (pc) (match_operand:SI 0 "address_operand" "p"))] 475759693Selan "" 475859693Selan "jmp %a0") 475959693Selan 476059693Selan;; This should not be used unless the add/sub insns can't be. 476159693Selan 476259693Selan(define_insn "" 476359693Selan [(set (match_operand:SI 0 "general_operand" "=a") 476459693Selan (match_operand:QI 1 "address_operand" "p"))] 476559693Selan "" 476659693Selan "lea %a1,%0") 476759693Selan 476859693Selan;; This is the first machine-dependent peephole optimization. 476959693Selan;; It is useful when a floating value is returned from a function call 477059693Selan;; and then is moved into an FP register. 477159693Selan;; But it is mainly intended to test the support for these optimizations. 477259693Selan 477359693Selan(define_peephole 477459693Selan [(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int 4))) 477559693Selan (set (match_operand:DF 0 "register_operand" "=f") 477659693Selan (match_operand:DF 1 "register_operand" "ad"))] 477759693Selan "FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])" 477859693Selan "* 477959693Selan{ 478059693Selan rtx xoperands[2]; 478159693Selan xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); 478259693Selan output_asm_insn (\"move%.l %1,%@\", xoperands); 478359693Selan output_asm_insn (\"move%.l %1,%-\", operands); 478459693Selan return \"fmove%.d %+,%0\"; 478559693Selan} 478659693Selan") 478759693Selan 478859693Selan;; Optimize a stack-adjust followed by a push of an argument. 478959693Selan;; This is said to happen frequently with -msoft-float 479059693Selan;; when there are consecutive library calls. 479159693Selan 479259693Selan(define_peephole 479359693Selan [(set (reg:SI 15) (plus:SI (reg:SI 15) 479459693Selan (match_operand:SI 0 "immediate_operand" "n"))) 479559693Selan (set (match_operand:SF 1 "push_operand" "=m") 479659693Selan (match_operand:SF 2 "general_operand" "rmfF"))] 479759693Selan "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) >= 4 479859693Selan && ! reg_mentioned_p (stack_pointer_rtx, operands[2])" 479959693Selan "* 480059693Selan{ 480159693Selan if (INTVAL (operands[0]) > 4) 480259693Selan { 480359693Selan rtx xoperands[2]; 480459693Selan xoperands[0] = stack_pointer_rtx; 480559693Selan xoperands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[0]) - 4); 480659693Selan#ifndef NO_ADDSUB_Q 480759693Selan if (INTVAL (xoperands[1]) <= 8) 480859693Selan output_asm_insn (\"addq%.w %1,%0\", xoperands); 480959693Selan else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020) 481059693Selan { 481159693Selan xoperands[1] = gen_rtx (CONST_INT, VOIDmode, 481259693Selan INTVAL (xoperands[1]) - 8); 481359693Selan output_asm_insn (\"addq%.w %#8,%0\;addq%.w %1,%0\", xoperands); 481459693Selan } 481559693Selan else 481659693Selan#endif 481759693Selan if (INTVAL (xoperands[1]) <= 0x7FFF) 481859693Selan output_asm_insn (\"add%.w %1,%0\", xoperands); 481959693Selan else 482059693Selan output_asm_insn (\"add%.l %1,%0\", xoperands); 482159693Selan } 482259693Selan if (FP_REG_P (operands[2])) 482359693Selan return \"fmove%.s %2,%@\"; 482459693Selan return \"move%.l %2,%@\"; 482559693Selan}") 482659693Selan 482759693Selan;; Speed up stack adjust followed by a fullword fixedpoint push. 482859693Selan 482959693Selan(define_peephole 483059693Selan [(set (reg:SI 15) (plus:SI (reg:SI 15) 483159693Selan (match_operand:SI 0 "immediate_operand" "n"))) 483259693Selan (set (match_operand:SI 1 "push_operand" "=m") 483359693Selan (match_operand:SI 2 "general_operand" "g"))] 483459693Selan "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) >= 4 483559693Selan && ! reg_mentioned_p (stack_pointer_rtx, operands[2])" 483659693Selan "* 483759693Selan{ 483859693Selan if (INTVAL (operands[0]) > 4) 483959693Selan { 484059693Selan rtx xoperands[2]; 484159693Selan xoperands[0] = stack_pointer_rtx; 484259693Selan xoperands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[0]) - 4); 484359693Selan#ifndef NO_ADDSUB_Q 484459693Selan if (INTVAL (xoperands[1]) <= 8) 484559693Selan output_asm_insn (\"addq%.w %1,%0\", xoperands); 484659693Selan else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020) 484759693Selan { 484859693Selan xoperands[1] = gen_rtx (CONST_INT, VOIDmode, 484959693Selan INTVAL (xoperands[1]) - 8); 485059693Selan output_asm_insn (\"addq%.w %#8,%0\;addq%.w %1,%0\", xoperands); 485159693Selan } 485259693Selan else 485359693Selan#endif 485459693Selan if (INTVAL (xoperands[1]) <= 0x7FFF) 485559693Selan output_asm_insn (\"add%.w %1,%0\", xoperands); 485659693Selan else 485759693Selan output_asm_insn (\"add%.l %1,%0\", xoperands); 485859693Selan } 485959693Selan if (operands[2] == const0_rtx) 486059693Selan return \"clr%.l %@\"; 486159693Selan return \"move%.l %2,%@\"; 486259693Selan}") 486359693Selan 486459693Selan;; Speed up pushing a single byte but leaving four bytes of space. 486559693Selan 486659693Selan(define_peephole 486759693Selan [(set (mem:QI (pre_dec:SI (reg:SI 15))) 486859693Selan (match_operand:QI 1 "general_operand" "dami")) 486959693Selan (set (reg:SI 15) (minus:SI (reg:SI 15) (const_int 2)))] 487059693Selan "! reg_mentioned_p (stack_pointer_rtx, operands[1])" 487159693Selan "* 487259693Selan{ 487359693Selan rtx xoperands[4]; 487459693Selan 487559693Selan if (GET_CODE (operands[1]) == REG) 487659693Selan return \"move%.l %1,%-\"; 487759693Selan 487859693Selan xoperands[1] = operands[1]; 487959693Selan xoperands[2] 488059693Selan = gen_rtx (MEM, QImode, 488159693Selan gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, 488259693Selan gen_rtx (CONST_INT, VOIDmode, 3))); 488359693Selan xoperands[3] = stack_pointer_rtx; 488459693Selan output_asm_insn (\"subq%.w %#4,%3\;move%.b %1,%2\", xoperands); 488559693Selan return \"\"; 488659693Selan}") 488759693Selan 488859693Selan;; dbCC peepholes 488959693Selan;; 489059693Selan;; Turns 489159693Selan;; loop: 489259693Selan;; [ ... ] 489359693Selan;; jCC label ; abnormal loop termination 489459693Selan;; dbra dN, loop ; normal loop termination 489559693Selan;; 489659693Selan;; Into 489759693Selan;; loop: 489859693Selan;; [ ... ] 489959693Selan;; dbCC dN, loop 490059693Selan;; jCC label 490159693Selan;; 490259693Selan;; Which moves the jCC condition outside the inner loop for free. 490359693Selan;; 490459693Selan(define_peephole 490559693Selan [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p" 490659693Selan [(cc0) (const_int 0)]) 490759693Selan (label_ref (match_operand 2 "" "")) 490859693Selan (pc))) 490959693Selan (parallel 491059693Selan [(set (pc) 491159693Selan (if_then_else 491259693Selan (ge (plus:HI (match_operand:HI 0 "register_operand" "+d") 491359693Selan (const_int -1)) 491459693Selan (const_int 0)) 491559693Selan (label_ref (match_operand 1 "" "")) 491659693Selan (pc))) 491759693Selan (set (match_dup 0) 491859693Selan (plus:HI (match_dup 0) 491959693Selan (const_int -1)))])] 492059693Selan "DATA_REG_P (operands[0])" 492159693Selan "* 492259693Selan{ 492359693Selan CC_STATUS_INIT; 492459693Selan output_dbcc_and_branch (operands); 492559693Selan return \"\"; 492659693Selan}") 492759693Selan 492859693Selan(define_peephole 492959693Selan [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p" 493059693Selan [(cc0) (const_int 0)]) 493159693Selan (label_ref (match_operand 2 "" "")) 493259693Selan (pc))) 493359693Selan (parallel 493459693Selan [(set (pc) 493559693Selan (if_then_else 493659693Selan (ge (plus:SI (match_operand:SI 0 "register_operand" "+d") 493759693Selan (const_int -1)) 493859693Selan (const_int 0)) 493959693Selan (label_ref (match_operand 1 "" "")) 494059693Selan (pc))) 494159693Selan (set (match_dup 0) 494259693Selan (plus:SI (match_dup 0) 494359693Selan (const_int -1)))])] 494459693Selan "DATA_REG_P (operands[0])" 494559693Selan "* 494659693Selan{ 494759693Selan CC_STATUS_INIT; 494859693Selan output_dbcc_and_branch (operands); 494959693Selan return \"\"; 495059693Selan}") 495159693Selan 495259693Selan 495359693Selan;; FPA multiply and add. 495459693Selan(define_insn "" 495559693Selan [(set (match_operand:DF 0 "register_operand" "=x,y,y") 495659693Selan (plus:DF (mult:DF (match_operand:DF 1 "general_operand" "%x,dmF,y") 495759693Selan (match_operand:DF 2 "general_operand" "xH,y,y")) 495859693Selan (match_operand:DF 3 "general_operand" "xH,y,dmF")))] 495959693Selan "TARGET_FPA" 496059693Selan "@ 496159693Selan fpma%.d %1,%w2,%w3,%0 496259693Selan fpma%.d %x1,%x2,%x3,%0 496359693Selan fpma%.d %x1,%x2,%x3,%0") 496459693Selan 496559693Selan(define_insn "" 496659693Selan [(set (match_operand:SF 0 "register_operand" "=x,y,y") 496759693Selan (plus:SF (mult:SF (match_operand:SF 1 "general_operand" "%x,ydmF,y") 496859693Selan (match_operand:SF 2 "general_operand" "xH,y,ydmF")) 496959693Selan (match_operand:SF 3 "general_operand" "xH,ydmF,ydmF")))] 497059693Selan "TARGET_FPA" 497159693Selan "@ 497259693Selan fpma%.s %1,%w2,%w3,%0 497359693Selan fpma%.s %1,%2,%3,%0 497459693Selan fpma%.s %1,%2,%3,%0") 497559693Selan 497659693Selan;; FPA Multiply and subtract 497759693Selan(define_insn "" 497859693Selan [(set (match_operand:DF 0 "register_operand" "=x,y,y") 497959693Selan (minus:DF (match_operand:DF 1 "general_operand" "xH,rmF,y") 498059693Selan (mult:DF (match_operand:DF 2 "general_operand" "%xH,y,y") 498159693Selan (match_operand:DF 3 "general_operand" "x,y,rmF"))))] 498259693Selan "TARGET_FPA" 498359693Selan "@ 498459693Selan fpms%.d %3,%w2,%w1,%0 498559693Selan fpms%.d %x3,%2,%x1,%0 498659693Selan fpms%.d %x3,%2,%x1,%0") 498759693Selan 498859693Selan(define_insn "" 498959693Selan [(set (match_operand:SF 0 "register_operand" "=x,y,y") 499059693Selan (minus:SF (match_operand:SF 1 "general_operand" "xH,rmF,yrmF") 499159693Selan (mult:SF (match_operand:SF 2 "general_operand" "%xH,rmF,y") 499259693Selan (match_operand:SF 3 "general_operand" "x,y,yrmF"))))] 499359693Selan "TARGET_FPA" 499459693Selan "@ 499559693Selan fpms%.s %3,%w2,%w1,%0 499659693Selan fpms%.s %3,%2,%1,%0 499759693Selan fpms%.s %3,%2,%1,%0") 499859693Selan 499959693Selan(define_insn "" 500059693Selan [(set (match_operand:DF 0 "register_operand" "=x,y,y") 500159693Selan (minus:DF (mult:DF (match_operand:DF 1 "general_operand" "%xH,y,y") 500259693Selan (match_operand:DF 2 "general_operand" "x,y,rmF")) 500359693Selan (match_operand:DF 3 "general_operand" "xH,rmF,y")))] 500459693Selan "TARGET_FPA" 500559693Selan "@ 500659693Selan fpmr%.d %2,%w1,%w3,%0 500759693Selan fpmr%.d %x2,%1,%x3,%0 500859693Selan fpmr%.d %x2,%1,%x3,%0") 500959693Selan 501059693Selan(define_insn "" 501159693Selan [(set (match_operand:SF 0 "register_operand" "=x,y,y") 501259693Selan (minus:SF (mult:SF (match_operand:SF 1 "general_operand" "%xH,rmF,y") 501359693Selan (match_operand:SF 2 "general_operand" "x,y,yrmF")) 501459693Selan (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))] 501559693Selan "TARGET_FPA" 501659693Selan "@ 501759693Selan fpmr%.s %2,%w1,%w3,%0 501859693Selan fpmr%.s %x2,%1,%x3,%0 501959693Selan fpmr%.s %x2,%1,%x3,%0") 502059693Selan 502159693Selan;; FPA Add and multiply 502259693Selan(define_insn "" 502359693Selan [(set (match_operand:DF 0 "register_operand" "=x,y,y") 502459693Selan (mult:DF (plus:DF (match_operand:DF 1 "general_operand" "%xH,y,y") 502559693Selan (match_operand:DF 2 "general_operand" "x,y,rmF")) 502659693Selan (match_operand:DF 3 "general_operand" "xH,rmF,y")))] 502759693Selan "TARGET_FPA" 502859693Selan "@ 502959693Selan fpam%.d %2,%w1,%w3,%0 503059693Selan fpam%.d %x2,%1,%x3,%0 503159693Selan fpam%.d %x2,%1,%x3,%0") 503259693Selan 503359693Selan(define_insn "" 503459693Selan [(set (match_operand:SF 0 "register_operand" "=x,y,y") 503559693Selan (mult:SF (plus:SF (match_operand:SF 1 "general_operand" "%xH,rmF,y") 503659693Selan (match_operand:SF 2 "general_operand" "x,y,yrmF")) 503759693Selan (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))] 503859693Selan "TARGET_FPA" 503959693Selan "@ 504059693Selan fpam%.s %2,%w1,%w3,%0 504159693Selan fpam%.s %x2,%1,%x3,%0 504259693Selan fpam%.s %x2,%1,%x3,%0") 504359693Selan 504459693Selan;;FPA Subtract and multiply 504559693Selan(define_insn "" 504659693Selan [(set (match_operand:DF 0 "register_operand" "=x,y,y") 504759693Selan (mult:DF (minus:DF (match_operand:DF 1 "general_operand" "xH,y,y") 504859693Selan (match_operand:DF 2 "general_operand" "x,y,rmF")) 504959693Selan (match_operand:DF 3 "general_operand" "xH,rmF,y")))] 505059693Selan "TARGET_FPA" 505159693Selan "@ 505259693Selan fpsm%.d %2,%w1,%w3,%0 505359693Selan fpsm%.d %x2,%1,%x3,%0 505459693Selan fpsm%.d %x2,%1,%x3,%0") 505559693Selan 505659693Selan(define_insn "" 505759693Selan [(set (match_operand:DF 0 "register_operand" "=x,y,y") 505859693Selan (mult:DF (match_operand:DF 1 "general_operand" "xH,rmF,y") 505959693Selan (minus:DF (match_operand:DF 2 "general_operand" "xH,y,y") 506059693Selan (match_operand:DF 3 "general_operand" "x,y,rmF"))))] 506159693Selan "TARGET_FPA" 506259693Selan "@ 506359693Selan fpsm%.d %3,%w2,%w1,%0 506459693Selan fpsm%.d %x3,%2,%x1,%0 506559693Selan fpsm%.d %x3,%2,%x1,%0") 506659693Selan 506759693Selan(define_insn "" 506859693Selan [(set (match_operand:SF 0 "register_operand" "=x,y,y") 506959693Selan (mult:SF (minus:SF (match_operand:SF 1 "general_operand" "xH,rmF,y") 507059693Selan (match_operand:SF 2 "general_operand" "x,y,yrmF")) 507159693Selan (match_operand:SF 3 "general_operand" "xH,rmF,yrmF")))] 507259693Selan "TARGET_FPA" 507359693Selan "@ 507459693Selan fpsm%.s %2,%w1,%w3,%0 507559693Selan fpsm%.s %x2,%1,%x3,%0 507659693Selan fpsm%.s %x2,%1,%x3,%0") 507759693Selan 507859693Selan(define_insn "" 507959693Selan [(set (match_operand:SF 0 "register_operand" "=x,y,y") 508059693Selan (mult:SF (match_operand:SF 1 "general_operand" "xH,rmF,yrmF") 508159693Selan (minus:SF (match_operand:SF 2 "general_operand" "xH,rmF,y") 508259693Selan (match_operand:SF 3 "general_operand" "x,y,yrmF"))))] 508359693Selan "TARGET_FPA" 508459693Selan "@ 508559693Selan fpsm%.s %3,%w2,%w1,%0 508659693Selan fpsm%.s %x3,%2,%x1,%0 508759693Selan fpsm%.s %x3,%2,%x1,%0") 508859693Selan 508959693Selan;;- Local variables: 509059693Selan;;- mode:emacs-lisp 509159693Selan;;- comment-start: ";;- " 509259693Selan;;- comment-start-skip: ";+- *" 509359693Selan;;- eval: (set-syntax-table (copy-sequence (syntax-table))) 509459693Selan;;- eval: (modify-syntax-entry ?[ "(]") 509559693Selan;;- eval: (modify-syntax-entry ?] ")[") 509659693Selan;;- eval: (modify-syntax-entry ?{ "(}") 509759693Selan;;- eval: (modify-syntax-entry ?} "){") 509859693Selan;;- End: 5099