OSDN Git Service

Update Copyright years for files modified in 2010.
[pf3gnuchains/gcc-fork.git] / gcc / config / v850 / v850.md
1 ;; GCC machine description for NEC V850
2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2002, 2004, 2005, 2007, 2008, 2010
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by Jeff Law (law@cygnus.com).
5
6 ;; This file is part of GCC.
7
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
12
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.
21
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
24
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
26
27 ;; The V851 manual states that the instruction address space is 16M;
28 ;; the various branch/call instructions only have a 22bit offset (4M range).
29 ;;
30 ;; One day we'll probably need to handle calls to targets more than 4M
31 ;; away.
32
33 ;; The size of instructions in bytes.
34
35 ;;---------------------------------------------------------------------------
36 ;; Constants
37
38 ;;
39 (define_constants
40   [(ZERO_REGNUM                 0)          ; constant zero
41    (SP_REGNUM                   3)          ; Stack Pointer
42    (GP_REGNUM                   4)          ; GP Pointer
43    (EP_REGNUM                   30)         ; EP pointer
44    (LP_REGNUM                   31)         ; Return address register
45    (CC_REGNUM                   32)         ; Condition code pseudo register
46    (FCC_REGNUM                  33)         ; Floating Condition code pseudo register
47   ]
48 )
49
50 (define_attr "length" ""
51   (const_int 4))
52
53 (define_attr "long_calls" "yes,no"
54   (const (if_then_else (symbol_ref "TARGET_LONG_CALLS")
55                        (const_string "yes")
56                        (const_string "no"))))
57             
58 ;; Types of instructions (for scheduling purposes).
59
60 (define_attr "type" "load,store,bit1,mult,macc,div,fpu,single,other"
61   (const_string "other"))
62
63 (define_attr "cpu" "none,v850,v850e,v850e1,v850e2,v850e2v3"
64   (cond [(ne (symbol_ref "TARGET_V850") (const_int 0))
65        (const_string "v850")
66        (ne (symbol_ref "TARGET_V850E") (const_int 0))
67        (const_string "v850e")
68        (ne (symbol_ref "TARGET_V850E1") (const_int 0))
69        (const_string "v850e1")
70        (ne (symbol_ref "TARGET_V850E2") (const_int 0))
71        (const_string "v850e2")
72        (ne (symbol_ref "TARGET_V850E2") (const_int 0))
73        (const_string "v850e2v3")]
74        (const_string "none")))
75
76 ;; Condition code settings.
77 ;; none - insn does not affect cc
78 ;; none_0hit - insn does not affect cc but it does modify operand 0
79 ;;      This attribute is used to keep track of when operand 0 changes.
80 ;;      See the description of NOTICE_UPDATE_CC for more info.
81 ;; set_znv - sets z,n,v to usable values; c is unknown.
82 ;; set_zn  - sets z,n to usable values; v,c is unknown.
83 ;; compare - compare instruction
84 ;; clobber - value of cc is unknown
85 (define_attr "cc" "none,none_0hit,set_z,set_zn,set_znv,compare,clobber"
86   (const_string "clobber"))
87 \f
88 ;; Function units for the V850.  As best as I can tell, there's
89 ;; a traditional memory load/use stall as well as a stall if
90 ;; the result of a multiply is used too early.
91
92 (define_insn_reservation "v850_other" 1
93                          (eq_attr "type" "other")
94                          "nothing")
95 (define_insn_reservation "v850_mult" 2
96                          (eq_attr "type" "mult")
97                          "nothing")
98 (define_insn_reservation "v850_memory" 2
99                          (eq_attr "type" "load")
100                          "nothing")
101
102 (include "predicates.md")
103 \f
104 ;; ----------------------------------------------------------------------
105 ;; MOVE INSTRUCTIONS
106 ;; ----------------------------------------------------------------------
107 (define_insn "sign23byte_load"
108   [(set (match_operand:SI 0 "register_operand" "=r")
109         (sign_extend:SI
110         (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
111                          (match_operand 2 "disp23_operand" "W")))))]
112   "TARGET_V850E2V3"
113   "ld.b %2[%1],%0"
114   [(set_attr "length" "4")
115    (set_attr "cc" "none_0hit")])
116   
117 (define_insn "unsign23byte_load"
118   [(set (match_operand:SI 0 "register_operand" "=r")
119         (zero_extend:SI
120         (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
121                          (match_operand 2 "disp23_operand" "W")))))]
122   "TARGET_V850E2V3"
123   "ld.bu %2[%1],%0"
124   [(set_attr "length" "4")
125    (set_attr "cc" "none_0hit")])
126
127 (define_insn "sign23hword_load"
128   [(set (match_operand:SI 0 "register_operand" "=r")
129         (sign_extend:SI
130         (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
131                          (match_operand 2 "disp23_operand" "W")))))]
132   "TARGET_V850E2V3"
133   "ld.h %2[%1],%0"
134   [(set_attr "length" "4")
135    (set_attr "cc" "none_0hit")])
136
137 (define_insn "unsign23hword_load"
138   [(set (match_operand:SI 0 "register_operand" "=r")
139         (zero_extend:SI
140         (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
141                          (match_operand 2 "disp23_operand" "W")))))]
142   "TARGET_V850E2V3"
143   "ld.hu %2[%1],%0"
144   [(set_attr "length" "4")
145    (set_attr "cc" "none_0hit")])
146
147 (define_insn "23word_load"
148   [(set (match_operand:SI 0 "register_operand" "=r")
149         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
150                          (match_operand 2 "disp23_operand" "W"))))]
151   "TARGET_V850E2V3"
152   "ld.w %2[%1],%0"
153   [(set_attr "length" "4")
154    (set_attr "cc" "none_0hit")])
155
156 (define_insn "23byte_store"
157   [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "r")
158                          (match_operand 1 "disp23_operand" "W")))
159         (match_operand:QI 2 "register_operand" "r"))]
160   "TARGET_V850E2V3"
161   "st.b %2,%1[%0]"
162   [(set_attr "length" "4")
163    (set_attr "cc" "none_0hit")])
164
165 (define_insn "23hword_store"
166   [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "r")
167                          (match_operand 1 "disp23_operand" "W")))
168         (match_operand:HI 2 "register_operand" "r"))]
169   "TARGET_V850E2V3"
170   "st.h %2,%1[%0]"
171   [(set_attr "length" "4")
172    (set_attr "cc" "none_0hit")])
173
174 (define_insn "23word_store"
175   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
176                          (match_operand 1 "disp23_operand" "W")))
177         (match_operand:SI 2 "register_operand" "r"))]
178   "TARGET_V850E2V3"
179   "st.w %2,%1[%0]"
180   [(set_attr "length" "4")
181    (set_attr "cc" "none_0hit")])
182 ;; movqi
183
184 (define_expand "movqi"
185   [(set (match_operand:QI 0 "general_operand" "")
186         (match_operand:QI 1 "general_operand" ""))]
187   ""
188   "
189 {
190   /* One of the ops has to be in a register or 0 */
191   if (!register_operand (operand0, QImode)
192       && !reg_or_0_operand (operand1, QImode))
193     operands[1] = copy_to_mode_reg (QImode, operand1);
194 }")
195
196 (define_insn "*movqi_internal"
197   [(set (match_operand:QI 0 "general_operand" "=r,r,r,Q,r,m,m")
198         (match_operand:QI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
199   "register_operand (operands[0], QImode)
200    || reg_or_0_operand (operands[1], QImode)"
201   "* return output_move_single (operands);"
202   [(set_attr "length" "2,4,2,2,4,4,4")
203    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
204    (set_attr "type" "other,other,load,other,load,store,store")])
205
206 ;; movhi
207
208 (define_expand "movhi"
209   [(set (match_operand:HI 0 "general_operand" "")
210         (match_operand:HI 1 "general_operand" ""))]
211   ""
212   "
213 {
214   /* One of the ops has to be in a register or 0 */
215   if (!register_operand (operand0, HImode)
216       && !reg_or_0_operand (operand1, HImode))
217     operands[1] = copy_to_mode_reg (HImode, operand1);
218 }")
219
220 (define_insn "*movhi_internal"
221   [(set (match_operand:HI 0 "general_operand" "=r,r,r,Q,r,m,m")
222         (match_operand:HI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
223   "register_operand (operands[0], HImode)
224    || reg_or_0_operand (operands[1], HImode)"
225   "* return output_move_single (operands);"
226   [(set_attr "length" "2,4,2,2,4,4,4")
227    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
228    (set_attr "type" "other,other,load,other,load,store,store")])
229
230 ;; movsi and helpers
231
232 (define_insn "*movsi_high"
233   [(set (match_operand:SI 0 "register_operand" "=r")
234         (high:SI (match_operand 1 "" "")))]
235   ""
236   "movhi hi(%1),%.,%0"
237   [(set_attr "length" "4")
238    (set_attr "cc" "none_0hit")
239    (set_attr "type" "other")])
240
241 (define_insn "*movsi_lo"
242   [(set (match_operand:SI 0 "register_operand" "=r")
243         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
244                    (match_operand:SI 2 "immediate_operand" "i")))]
245   ""
246   "movea lo(%2),%1,%0"
247   [(set_attr "length" "4")
248    (set_attr "cc" "none_0hit")
249    (set_attr "type" "other")])
250
251 (define_expand "movsi"
252   [(set (match_operand:SI 0 "general_operand" "")
253         (match_operand:SI 1 "general_operand" ""))]
254   ""
255   "
256 {
257   /* One of the ops has to be in a register or 0 */
258   if (!register_operand (operand0, SImode)
259       && !reg_or_0_operand (operand1, SImode))
260     operands[1] = copy_to_mode_reg (SImode, operand1);
261
262   /* Some constants, as well as symbolic operands
263      must be done with HIGH & LO_SUM patterns.  */
264   if (CONSTANT_P (operands[1])
265       && GET_CODE (operands[1]) != HIGH
266       && ! (TARGET_V850E || TARGET_V850E2_ALL)
267       && !special_symbolref_operand (operands[1], VOIDmode)
268       && !(GET_CODE (operands[1]) == CONST_INT
269            && (CONST_OK_FOR_J (INTVAL (operands[1]))
270                || CONST_OK_FOR_K (INTVAL (operands[1]))
271                || CONST_OK_FOR_L (INTVAL (operands[1])))))
272     {
273       rtx temp;
274
275       if (reload_in_progress || reload_completed)
276         temp = operands[0];
277       else
278         temp = gen_reg_rtx (SImode);
279
280       emit_insn (gen_rtx_SET (SImode, temp,
281                               gen_rtx_HIGH (SImode, operand1)));
282       emit_insn (gen_rtx_SET (SImode, operand0,
283                               gen_rtx_LO_SUM (SImode, temp, operand1)));
284       DONE;
285     }
286 }")
287
288 ;; This is the same as the following pattern, except that it includes
289 ;; support for arbitrary 32-bit immediates.
290
291 ;; ??? This always loads addresses using hilo.  If the only use of this address
292 ;; was in a load/store, then we would get smaller code if we only loaded the
293 ;; upper part with hi, and then put the lower part in the load/store insn.
294
295 (define_insn "*movsi_internal_v850e"
296   [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m,r")
297         (match_operand:SI 1 "general_operand" "Jr,K,L,Q,Ir,m,R,r,I,i"))]
298   "(TARGET_V850E || TARGET_V850E2_ALL)
299    && (register_operand (operands[0], SImode)
300        || reg_or_0_operand (operands[1], SImode))"
301   "* return output_move_single (operands);"
302   [(set_attr "length" "2,4,4,2,2,4,4,4,4,6")
303    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
304    (set_attr "type" "other,other,other,load,other,load,other,store,store,other")])
305
306 (define_insn "*movsi_internal"
307   [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m")
308         (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))]
309   "register_operand (operands[0], SImode)
310    || reg_or_0_operand (operands[1], SImode)"
311   "* return output_move_single (operands);"
312   [(set_attr "length" "2,4,4,2,2,4,4,4,4")
313    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
314    (set_attr "type" "other,other,other,load,other,load,store,store,other")])
315
316 (define_insn "*movsf_internal"
317   [(set (match_operand:SF 0 "general_operand" "=r,r,r,r,r,Q,r,m,m,r")
318         (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))]
319   "register_operand (operands[0], SFmode)
320    || reg_or_0_operand (operands[1], SFmode)"
321   "* return output_move_single (operands);"
322   [(set_attr "length" "2,4,4,8,2,2,4,4,4,8")
323    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
324    (set_attr "type" "other,other,other,other,load,other,load,store,store,other")])
325
326 ;; ----------------------------------------------------------------------
327 ;; TEST INSTRUCTIONS
328 ;; ----------------------------------------------------------------------
329
330 (define_insn "*v850_tst1"
331   [(set (cc0)
332         (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
333                                   (const_int 1)
334                                   (match_operand:QI 1 "const_int_operand" "n"))
335                  (const_int 0)))]
336   ""
337   "tst1 %1,%0"
338   [(set_attr "length" "4")
339    (set_attr "cc" "clobber")])
340
341 ;; This replaces ld.b;sar;andi with tst1;setf nz.
342
343 (define_split
344   [(set (match_operand:SI 0 "register_operand" "")
345         (compare (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
346                                   (const_int 1)
347                                   (match_operand 2 "const_int_operand" ""))
348                  (const_int 0)))]
349   ""
350   [(set (cc0) (compare (zero_extract:SI (match_dup 1)
351                                         (const_int 1)
352                                         (match_dup 2))
353                        (const_int 0)))
354    (set (match_dup 0) (ne:SI (cc0) (const_int 0)))])
355
356 (define_expand "cbranchsi4"
357   [(set (cc0)
358         (compare (match_operand:SI 1 "register_operand" "")
359                  (match_operand:SI 2 "reg_or_int5_operand" "")))
360    (set (pc)
361         (if_then_else
362               (match_operator 0 "ordered_comparison_operator" [(cc0)
363                                                                (const_int 0)])
364               (label_ref (match_operand 3 "" ""))
365               (pc)))]
366  "")
367
368 (define_expand "cstoresi4"
369   [(set (cc0)
370         (compare (match_operand:SI 2 "register_operand" "")
371                  (match_operand:SI 3 "reg_or_int5_operand" "")))
372    (set (match_operand:SI 0 "register_operand")
373         (match_operator:SI 1 "ordered_comparison_operator" [(cc0)
374                                                             (const_int 0)]))]
375   "")
376
377 (define_expand "cmpsi"
378   [(set (cc0)
379         (compare (match_operand:SI 0 "register_operand" "r,r")
380                  (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
381    ""
382   "
383 {
384   v850_compare_op0 = operands[0];
385   v850_compare_op1 = operands[1];
386   DONE;
387 }")
388
389 (define_insn "cmpsi_insn"
390   [(set (cc0)
391         (compare (match_operand:SI 0 "register_operand" "r,r")
392                  (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
393   ""
394   "@
395   cmp %1,%0
396   cmp %1,%0"
397   [(set_attr "length" "2,2")
398    (set_attr "cc" "compare")])
399
400 (define_expand "cmpsf"
401   [(set (reg:CC CC_REGNUM)
402         (compare (match_operand:SF 0 "register_operand" "r")
403                  (match_operand:SF 1 "register_operand" "r")))]
404   "TARGET_V850E2V3"
405   "
406 {
407   v850_compare_op0 = operands[0];
408   v850_compare_op1 = operands[1];
409   DONE;
410 }")
411
412 (define_expand "cmpdf"
413   [(set (reg:CC CC_REGNUM)
414         (compare (match_operand:DF 0 "even_reg_operand" "r")
415                  (match_operand:DF 1 "even_reg_operand" "r")))]
416   "TARGET_V850E2V3"
417   "
418 {
419   v850_compare_op0 = operands[0];
420   v850_compare_op1 = operands[1];
421   DONE;
422 }")
423
424 ;; ----------------------------------------------------------------------
425 ;; ADD INSTRUCTIONS
426 ;; ----------------------------------------------------------------------
427
428 (define_insn "addsi3"
429   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
430         (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
431                  (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))
432    (clobber (reg:CC CC_REGNUM))]
433
434   ""
435   "@
436    add %2,%0
437    addi %2,%1,%0
438    addi %O2(%P2),%1,%0"
439   [(set_attr "length" "2,4,4")
440    (set_attr "cc" "set_zn,set_zn,set_zn")])
441
442 ;; ----------------------------------------------------------------------
443 ;; SUBTRACT INSTRUCTIONS
444 ;; ----------------------------------------------------------------------
445
446 (define_insn "subsi3"
447   [(set (match_operand:SI 0 "register_operand" "=r,r")
448         (minus:SI (match_operand:SI 1 "register_operand" "0,r")
449                   (match_operand:SI 2 "register_operand" "r,0")))
450    (clobber (reg:CC CC_REGNUM))]
451   ""
452   "@
453   sub %2,%0
454   subr %1,%0"
455   [(set_attr "length" "2,2")
456    (set_attr "cc" "set_zn,set_zn")])
457
458 (define_insn "negsi2"
459   [(set (match_operand:SI 0 "register_operand" "=r")
460         (neg:SI (match_operand:SI 1 "register_operand" "0")))
461    (clobber (reg:CC CC_REGNUM))]
462   ""
463   "subr %.,%0"
464   [(set_attr "length" "2")
465    (set_attr "cc" "set_zn")])
466
467 ;; ----------------------------------------------------------------------
468 ;; MULTIPLY INSTRUCTIONS
469 ;; ----------------------------------------------------------------------
470
471 (define_expand "mulhisi3"
472   [(set (match_operand:SI 0 "register_operand" "")
473         (mult:SI
474           (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
475           (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
476   ""
477   "if (GET_CODE (operands[2]) == CONST_INT)
478      {
479        emit_insn (gen_mulhisi3_internal2 (operands[0], operands[1], operands[2]));
480        DONE;
481      }")
482
483 (define_insn "*mulhisi3_internal1"
484   [(set (match_operand:SI 0 "register_operand" "=r")
485         (mult:SI
486           (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
487           (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
488   ""
489   "mulh %2,%0"
490   [(set_attr "length" "2")
491    (set_attr "cc" "none_0hit")
492    (set_attr "type" "mult")])
493
494 (define_insn "mulhisi3_internal2"
495   [(set (match_operand:SI 0 "register_operand" "=r,r")
496         (mult:SI
497           (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
498           (match_operand:HI 2 "const_int_operand" "J,K")))]
499   ""
500   "@
501    mulh %2,%0
502    mulhi %2,%1,%0"
503   [(set_attr "length" "2,4")
504    (set_attr "cc" "none_0hit,none_0hit")
505    (set_attr "type" "mult")])
506
507 ;; ??? The scheduling info is probably wrong.
508
509 ;; ??? This instruction can also generate the 32-bit highpart, but using it
510 ;; may increase code size counter to the desired result.
511
512 ;; ??? This instructions can also give a DImode result.
513
514 ;; ??? There is unsigned version, but it matters only for the DImode/highpart
515 ;; results.
516
517 (define_insn "mulsi3"
518   [(set (match_operand:SI 0 "register_operand" "=r")
519         (mult:SI (match_operand:SI 1 "register_operand" "%0")
520                  (match_operand:SI 2 "reg_or_int9_operand" "rO")))]
521   "(TARGET_V850E || TARGET_V850E2_ALL)"
522   "mul %2,%1,%."
523   [(set_attr "length" "4")
524    (set_attr "cc" "none_0hit")
525    (set_attr "type" "mult")])
526
527 ;; ----------------------------------------------------------------------
528 ;; DIVIDE INSTRUCTIONS
529 ;; ----------------------------------------------------------------------
530
531 ;; ??? These insns do set the Z/N condition codes, except that they are based
532 ;; on only one of the two results, so it doesn't seem to make sense to use
533 ;; them.
534
535 ;; ??? The scheduling info is probably wrong.
536
537 (define_insn "divmodsi4"
538   [(set (match_operand:SI 0 "register_operand" "=r")
539         (div:SI (match_operand:SI 1 "register_operand" "0")
540                 (match_operand:SI 2 "register_operand" "r")))
541    (set (match_operand:SI 3 "register_operand" "=r")
542         (mod:SI (match_dup 1)
543                 (match_dup 2)))
544    (clobber (reg:CC CC_REGNUM))]
545   "TARGET_V850E"
546   "div %2,%0,%3"
547   [(set_attr "length" "4")
548    (set_attr "cc" "clobber")
549    (set_attr "type" "div")])
550         
551 (define_insn "udivmodsi4"
552   [(set (match_operand:SI 0 "register_operand" "=r")
553         (udiv:SI (match_operand:SI 1 "register_operand" "0")
554                  (match_operand:SI 2 "register_operand" "r")))
555    (set (match_operand:SI 3 "register_operand" "=r")
556         (umod:SI (match_dup 1)
557                  (match_dup 2)))
558    (clobber (reg:CC CC_REGNUM))]
559   "TARGET_V850E"
560   "divu %2,%0,%3"
561   [(set_attr "length" "4")
562    (set_attr "cc" "clobber")
563    (set_attr "type" "div")])
564         
565 ;; ??? There is a 2 byte instruction for generating only the quotient.
566 ;; However, it isn't clear how to compute the length field correctly.
567
568 (define_insn "divmodhi4"
569   [(set (match_operand:HI 0 "register_operand" "=r")
570         (div:HI (match_operand:HI 1 "register_operand" "0")
571                 (match_operand:HI 2 "register_operand" "r")))
572    (set (match_operand:HI 3 "register_operand" "=r")
573         (mod:HI (match_dup 1)
574                 (match_dup 2)))
575    (clobber (reg:CC CC_REGNUM))]
576   "TARGET_V850E"
577   "divh %2,%0,%3"
578   [(set_attr "length" "4")
579    (set_attr "cc" "clobber")
580    (set_attr "type" "div")])
581
582 ;; Half-words are sign-extended by default, so we must zero extend to a word
583 ;; here before doing the divide.
584
585 (define_insn "udivmodhi4"
586   [(set (match_operand:HI 0 "register_operand" "=r")
587         (udiv:HI (match_operand:HI 1 "register_operand" "0")
588                  (match_operand:HI 2 "register_operand" "r")))
589    (set (match_operand:HI 3 "register_operand" "=r")
590         (umod:HI (match_dup 1)
591                  (match_dup 2)))
592    (clobber (reg:CC CC_REGNUM))]
593   "TARGET_V850E"
594   "zxh %0 ; divhu %2,%0,%3"
595   [(set_attr "length" "4")
596    (set_attr "cc" "clobber")
597    (set_attr "type" "div")])
598 \f
599 ;; ----------------------------------------------------------------------
600 ;; AND INSTRUCTIONS
601 ;; ----------------------------------------------------------------------
602
603 (define_insn "*v850_clr1_1"
604   [(set (match_operand:QI 0 "memory_operand" "=m")
605         (subreg:QI
606           (and:SI (subreg:SI (match_dup 0) 0)
607                   (match_operand:QI 1 "not_power_of_two_operand" "")) 0))
608    (clobber (reg:CC CC_REGNUM))]
609   ""
610   "*
611 {
612   rtx xoperands[2];
613   xoperands[0] = operands[0];
614   xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
615   output_asm_insn (\"clr1 %M1,%0\", xoperands);
616   return \"\";
617 }"
618   [(set_attr "length" "4")
619    (set_attr "cc" "clobber")
620    (set_attr "type" "bit1")])
621
622 (define_insn "*v850_clr1_2"
623   [(set (match_operand:HI 0 "indirect_operand" "=m")
624         (subreg:HI
625           (and:SI (subreg:SI (match_dup 0) 0)
626                   (match_operand:HI 1 "not_power_of_two_operand" "")) 0))
627    (clobber (reg:CC CC_REGNUM))]
628   ""
629   "*
630 {
631   int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
632
633   rtx xoperands[2];
634   xoperands[0] = gen_rtx_MEM (QImode,
635                               plus_constant (XEXP (operands[0], 0), log2 / 8));
636   xoperands[1] = GEN_INT (log2 % 8);
637   output_asm_insn (\"clr1 %1,%0\", xoperands);
638   return \"\";
639 }"
640   [(set_attr "length" "4")
641    (set_attr "cc" "clobber")
642    (set_attr "type" "bit1")])
643
644 (define_insn "*v850_clr1_3"
645   [(set (match_operand:SI 0 "indirect_operand" "=m")
646         (and:SI (match_dup 0)
647                 (match_operand:SI 1 "not_power_of_two_operand" "")))
648    (clobber (reg:CC CC_REGNUM))]
649   ""
650   "*
651 {
652   int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
653
654   rtx xoperands[2];
655   xoperands[0] = gen_rtx_MEM (QImode,
656                               plus_constant (XEXP (operands[0], 0), log2 / 8));
657   xoperands[1] = GEN_INT (log2 % 8);
658   output_asm_insn (\"clr1 %1,%0\", xoperands);
659   return \"\";
660 }"
661   [(set_attr "length" "4")
662    (set_attr "cc" "clobber")
663    (set_attr "type" "bit1")])
664
665 (define_insn "andsi3"
666   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
667         (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
668                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
669    (clobber (reg:CC CC_REGNUM))]
670   ""
671   "@
672   and %2,%0
673   and %.,%0
674   andi %2,%1,%0"
675   [(set_attr "length" "2,2,4")
676    (set_attr "cc" "set_zn")])
677
678 ;; ----------------------------------------------------------------------
679 ;; OR INSTRUCTIONS
680 ;; ----------------------------------------------------------------------
681
682 (define_insn "*v850_set1_1"
683   [(set (match_operand:QI 0 "memory_operand" "=m")
684         (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
685                            (match_operand 1 "power_of_two_operand" "")) 0))
686    (clobber (reg:CC CC_REGNUM))]
687   ""
688   "set1 %M1,%0"
689   [(set_attr "length" "4")
690    (set_attr "cc" "clobber")
691    (set_attr "type" "bit1")])
692
693 (define_insn "*v850_set1_2"
694   [(set (match_operand:HI 0 "indirect_operand" "=m")
695         (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
696                            (match_operand 1 "power_of_two_operand" "")) 0))]
697   ""
698   "*
699 {
700   int log2 = exact_log2 (INTVAL (operands[1]));
701
702   if (log2 < 8)
703     return \"set1 %M1,%0\";
704   else
705     {
706       rtx xoperands[2];
707       xoperands[0] = gen_rtx_MEM (QImode,
708                                   plus_constant (XEXP (operands[0], 0),
709                                                  log2 / 8));
710       xoperands[1] = GEN_INT (log2 % 8);
711       output_asm_insn (\"set1 %1,%0\", xoperands);
712     }
713   return \"\";
714 }"
715   [(set_attr "length" "4")
716    (set_attr "cc" "clobber")
717    (set_attr "type" "bit1")])
718
719 (define_insn "*v850_set1_3"
720   [(set (match_operand:SI 0 "indirect_operand" "=m")
721         (ior:SI (match_dup 0)
722                 (match_operand 1 "power_of_two_operand" "")))
723    (clobber (reg:CC CC_REGNUM))]
724   ""
725   "*
726 {
727   int log2 = exact_log2 (INTVAL (operands[1]));
728
729   if (log2 < 8)
730     return \"set1 %M1,%0\";
731   else
732     {
733       rtx xoperands[2];
734       xoperands[0] = gen_rtx_MEM (QImode,
735                                   plus_constant (XEXP (operands[0], 0),
736                                                  log2 / 8));
737       xoperands[1] = GEN_INT (log2 % 8);
738       output_asm_insn (\"set1 %1,%0\", xoperands);
739     }
740   return \"\";
741 }"
742   [(set_attr "length" "4")
743    (set_attr "cc" "clobber")
744    (set_attr "type" "bit1")])
745
746 (define_insn "iorsi3"
747   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
748         (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
749                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
750    (clobber (reg:CC CC_REGNUM))]
751   ""
752   "@
753   or %2,%0
754   or %.,%0
755   ori %2,%1,%0"
756   [(set_attr "length" "2,2,4")
757    (set_attr "cc" "set_zn")])
758
759 ;; ----------------------------------------------------------------------
760 ;; XOR INSTRUCTIONS
761 ;; ----------------------------------------------------------------------
762
763 (define_insn "*v850_not1_1"
764   [(set (match_operand:QI 0 "memory_operand" "=m")
765         (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0)
766                            (match_operand 1 "power_of_two_operand" "")) 0))
767    (clobber (reg:CC CC_REGNUM))]
768   ""
769   "not1 %M1,%0"
770   [(set_attr "length" "4")
771    (set_attr "cc" "clobber")
772    (set_attr "type" "bit1")])
773
774 (define_insn "*v850_not1_2"
775   [(set (match_operand:HI 0 "indirect_operand" "=m")
776         (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
777                            (match_operand 1 "power_of_two_operand" "")) 0))]
778   ""
779   "*
780 {
781   int log2 = exact_log2 (INTVAL (operands[1]));
782
783   if (log2 < 8)
784     return \"not1 %M1,%0\";
785   else
786     {
787       rtx xoperands[2];
788       xoperands[0] = gen_rtx_MEM (QImode,
789                                   plus_constant (XEXP (operands[0], 0),
790                                                  log2 / 8));
791       xoperands[1] = GEN_INT (log2 % 8);
792       output_asm_insn (\"not1 %1,%0\", xoperands);
793     }
794   return \"\";
795 }"
796   [(set_attr "length" "4")
797    (set_attr "cc" "clobber")
798    (set_attr "type" "bit1")])
799
800 (define_insn "*v850_not1_3"
801   [(set (match_operand:SI 0 "indirect_operand" "=m")
802         (xor:SI (match_dup 0)
803                 (match_operand 1 "power_of_two_operand" "")))
804    (clobber (reg:CC CC_REGNUM))]
805   ""
806   "*
807 {
808   int log2 = exact_log2 (INTVAL (operands[1]));
809
810   if (log2 < 8)
811     return \"not1 %M1,%0\";
812   else
813     {
814       rtx xoperands[2];
815       xoperands[0] = gen_rtx_MEM (QImode,
816                                   plus_constant (XEXP (operands[0], 0),
817                                                  log2 / 8));
818       xoperands[1] = GEN_INT (log2 % 8);
819       output_asm_insn (\"not1 %1,%0\", xoperands);
820     }
821   return \"\";
822 }"
823   [(set_attr "length" "4")
824    (set_attr "cc" "clobber")
825    (set_attr "type" "bit1")])
826
827 (define_insn "xorsi3"
828   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
829         (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
830                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
831    (clobber (reg:CC CC_REGNUM))]
832   ""
833   "@
834   xor %2,%0
835   xor %.,%0
836   xori %2,%1,%0"
837   [(set_attr "length" "2,2,4")
838    (set_attr "cc" "set_zn")])
839 \f
840 ;; ----------------------------------------------------------------------
841 ;; NOT INSTRUCTIONS
842 ;; ----------------------------------------------------------------------
843
844 (define_insn "one_cmplsi2"
845   [(set (match_operand:SI 0 "register_operand" "=r")
846         (not:SI (match_operand:SI 1 "register_operand" "r")))
847    (clobber (reg:CC CC_REGNUM))]
848   ""
849   "not %1,%0"
850   [(set_attr "length" "2")
851    (set_attr "cc" "set_zn")])
852
853 ;; -----------------------------------------------------------------
854 ;; BIT FIELDS
855 ;; -----------------------------------------------------------------
856
857 ;; ??? Is it worth defining insv and extv for the V850 series?!?
858
859 ;; An insv pattern would be useful, but does not get used because
860 ;; store_bit_field never calls insv when storing a constant value into a
861 ;; single-bit bitfield.
862
863 ;; extv/extzv patterns would be useful, but do not get used because
864 ;; optimize_bitfield_compare in fold-const usually converts single
865 ;; bit extracts into an AND with a mask.
866
867 ;; -----------------------------------------------------------------
868 ;; Scc INSTRUCTIONS
869 ;; -----------------------------------------------------------------
870
871 (define_insn "*setcc"
872   [(set (match_operand:SI 0 "register_operand" "=r")
873         (match_operator:SI 1 "comparison_operator"
874          [(cc0) (const_int 0)]))]
875   ""
876   "*
877 {
878   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
879       && (GET_CODE (operands[1]) == GT
880           || GET_CODE (operands[1]) == GE
881           || GET_CODE (operands[1]) == LE
882           || GET_CODE (operands[1]) == LT))
883     return 0;
884
885   return \"setf %c1,%0\";
886 }"
887   [(set_attr "length" "4")
888    (set_attr "cc" "none_0hit")])
889
890 (define_insn "setf_insn"
891   [(set (match_operand:SI 0 "register_operand" "=r")
892         (match_operator:SI 1 "comparison_operator"
893                           [(reg:CC CC_REGNUM) (const_int 0)]))]
894   ""
895   "setf %b1,%0"
896   [(set_attr "length" "4")
897    (set_attr "cc" "none_0hit")])
898
899 (define_insn "set_z_insn"
900   [(set (match_operand:SI 0 "register_operand" "=r")
901         (match_operand 1 "v850_float_z_comparison_operator" ""))]
902   "TARGET_V850E2V3"
903   "setf z,%0"
904   [(set_attr "length" "4")
905    (set_attr "cc" "none_0hit")])
906
907 (define_insn "set_nz_insn" 
908   [(set (match_operand:SI 0 "register_operand" "=r")
909         (match_operand 1 "v850_float_nz_comparison_operator" ""))]
910   "TARGET_V850E2V3"
911   "setf nz,%0"
912   [(set_attr "length" "4")
913    (set_attr "cc" "none_0hit")])
914
915 ;; ----------------------------------------------------------------------
916 ;; CONDITIONAL MOVE INSTRUCTIONS
917 ;; ----------------------------------------------------------------------
918
919 ;; Instructions using cc0 aren't allowed to have input reloads, so we must
920 ;; hide the fact that this instruction uses cc0.  We do so by including the
921 ;; compare instruction inside it.
922
923 (define_expand "movsicc"
924   [(set (match_operand:SI 0 "register_operand" "=r")
925         (if_then_else:SI
926          (match_operand 1 "comparison_operator")
927          (match_operand:SI 2 "reg_or_const_operand" "rJ")
928          (match_operand:SI 3 "reg_or_const_operand" "rI")))]
929   "(TARGET_V850E || TARGET_V850E2_ALL)"
930   "
931 {
932   if (   (GET_CODE (operands[2]) == CONST_INT
933        && GET_CODE (operands[3]) == CONST_INT))
934     {
935       int o2 = INTVAL (operands[2]);
936       int o3 = INTVAL (operands[3]);
937
938       if (o2 == 1 && o3 == 0)
939         FAIL;   /* setf */
940       if (o3 == 1 && o2 == 0)
941         FAIL;   /* setf */
942       if (o2 == 0 && (o3 < -16 || o3 > 15) && exact_log2 (o3) >= 0)
943         FAIL;   /* setf + shift */
944       if (o3 == 0 && (o2 < -16 || o2 > 15) && exact_log2 (o2) >=0)
945         FAIL;   /* setf + shift */
946       if (o2 != 0)
947         operands[2] = copy_to_mode_reg (SImode, operands[2]);
948       if (o3 !=0 )
949         operands[3] = copy_to_mode_reg (SImode, operands[3]);
950     }
951   else
952     {
953       if (GET_CODE (operands[2]) != REG)
954         operands[2] = copy_to_mode_reg (SImode,operands[2]);
955       if (GET_CODE (operands[3]) != REG)
956         operands[3] = copy_to_mode_reg (SImode, operands[3]);
957     }
958 }")
959
960 ;; ??? Clobbering the condition codes is overkill.
961
962 ;; ??? We sometimes emit an unnecessary compare instruction because the
963 ;; condition codes may have already been set by an earlier instruction,
964 ;; but we have no code here to avoid the compare if it is unnecessary.
965
966 (define_insn "movsicc_normal_cc"
967   [(set (match_operand:SI 0 "register_operand" "=r")
968         (if_then_else:SI
969          (match_operator 1 "comparison_operator"
970                          [(reg:CC CC_REGNUM) (const_int 0)])
971          (match_operand:SI 2 "reg_or_int5_operand" "rJ")
972          (match_operand:SI 3 "reg_or_0_operand" "rI")))]
973   "(TARGET_V850E || TARGET_V850E2_ALL)"
974   "cmov %c1,%2,%z3,%0";
975   [(set_attr "length" "6")
976    (set_attr "cc" "compare")])
977
978 (define_insn "movsicc_reversed_cc"
979   [(set (match_operand:SI 0 "register_operand" "=r")
980         (if_then_else:SI
981          (match_operator 1 "comparison_operator"
982                          [(reg:CC CC_REGNUM) (const_int 0)])
983          (match_operand:SI 2 "reg_or_0_operand" "rI")
984          (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
985   "(TARGET_V850E || TARGET_V850E2_ALL)"
986   "cmov %C1,%3,%z2,%0"
987   [(set_attr "length" "6")
988    (set_attr "cc" "compare")])
989
990 (define_insn "*movsicc_normal"
991   [(set (match_operand:SI 0 "register_operand" "=r")
992         (if_then_else:SI
993          (match_operator 1 "comparison_operator"
994                          [(match_operand:SI 4 "register_operand" "r")
995                           (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
996          (match_operand:SI 2 "reg_or_int5_operand" "rJ")
997          (match_operand:SI 3 "reg_or_0_operand" "rI")))]
998   "(TARGET_V850E || TARGET_V850E2_ALL)"
999   "cmp %5,%4 ; cmov %c1,%2,%z3,%0"
1000   [(set_attr "length" "6")
1001    (set_attr "cc" "clobber")])
1002
1003 (define_insn "*movsicc_reversed"
1004   [(set (match_operand:SI 0 "register_operand" "=r")
1005         (if_then_else:SI
1006          (match_operator 1 "comparison_operator"
1007                          [(match_operand:SI 4 "register_operand" "r")
1008                           (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
1009          (match_operand:SI 2 "reg_or_0_operand" "rI")
1010          (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
1011   "(TARGET_V850E || TARGET_V850E2_ALL)"
1012   "cmp %5,%4 ; cmov %C1,%3,%z2,%0"
1013   [(set_attr "length" "6")
1014    (set_attr "cc" "clobber")])
1015
1016 (define_insn "*movsicc_tst1"
1017   [(set (match_operand:SI 0 "register_operand" "=r")
1018         (if_then_else:SI
1019          (match_operator 1 "comparison_operator"
1020                          [(zero_extract:SI
1021                            (match_operand:QI 2 "memory_operand" "m")
1022                            (const_int 1)
1023                            (match_operand 3 "const_int_operand" "n"))
1024                           (const_int 0)])
1025          (match_operand:SI 4 "reg_or_int5_operand" "rJ")
1026          (match_operand:SI 5 "reg_or_0_operand" "rI")))]
1027   "(TARGET_V850E || TARGET_V850E2_ALL)"
1028   "tst1 %3,%2 ; cmov %c1,%4,%z5,%0"
1029   [(set_attr "length" "8")
1030    (set_attr "cc" "clobber")])
1031
1032 (define_insn "*movsicc_tst1_reversed"
1033   [(set (match_operand:SI 0 "register_operand" "=r")
1034         (if_then_else:SI
1035          (match_operator 1 "comparison_operator"
1036                          [(zero_extract:SI
1037                            (match_operand:QI 2 "memory_operand" "m")
1038                            (const_int 1)
1039                            (match_operand 3 "const_int_operand" "n"))
1040                           (const_int 0)])
1041          (match_operand:SI 4 "reg_or_0_operand" "rI")
1042          (match_operand:SI 5 "reg_or_int5_operand" "rJ")))]
1043   "(TARGET_V850E || TARGET_V850E2_ALL)"
1044   "tst1 %3,%2 ; cmov %C1,%5,%z4,%0"
1045   [(set_attr "length" "8")
1046    (set_attr "cc" "clobber")])
1047
1048 ;; Matching for sasf requires combining 4 instructions, so we provide a
1049 ;; dummy pattern to match the first 3, which will always be turned into the
1050 ;; second pattern by subsequent combining.  As above, we must include the
1051 ;; comparison to avoid input reloads in an insn using cc0.
1052
1053 (define_insn "*sasf"
1054   [(set (match_operand:SI 0 "register_operand" "=r")
1055         (ior:SI
1056          (match_operator 1 "comparison_operator"
1057                          [(match_operand:SI 3 "register_operand" "r")
1058                           (match_operand:SI 4 "reg_or_int5_operand" "rJ")])
1059          (ashift:SI (match_operand:SI 2 "register_operand" "0")
1060                     (const_int 1))))
1061    (clobber (reg:CC CC_REGNUM))]
1062   "(TARGET_V850E || TARGET_V850E2_ALL)"
1063   "cmp %4,%3 ; sasf %c1,%0"
1064   [(set_attr "length" "6")
1065    (set_attr "cc" "clobber")])
1066
1067 (define_split
1068   [(set (match_operand:SI 0 "register_operand" "")
1069         (if_then_else:SI
1070          (match_operator 1 "comparison_operator"
1071                          [(match_operand:SI 4 "register_operand" "")
1072                           (match_operand:SI 5 "reg_or_int5_operand" "")])
1073          (match_operand:SI 2 "const_int_operand" "")
1074          (match_operand:SI 3 "const_int_operand" "")))
1075    (clobber (reg:CC CC_REGNUM))]
1076   "(TARGET_V850E || TARGET_V850E2_ALL)
1077    && ((INTVAL (operands[2]) ^ INTVAL (operands[3])) == 1)
1078    && ((INTVAL (operands[2]) + INTVAL (operands[3])) != 1)
1079    && (GET_CODE (operands[5]) == CONST_INT
1080       || REGNO (operands[0]) != REGNO (operands[5]))
1081    && REGNO (operands[0]) != REGNO (operands[4])"
1082   [(set (match_dup 0) (match_dup 6))
1083    (parallel [(set (match_dup 0)
1084                    (ior:SI (match_op_dup 7 [(match_dup 4) (match_dup 5)])
1085                            (ashift:SI (match_dup 0) (const_int 1))))
1086               (clobber (reg:CC CC_REGNUM))])]
1087   "
1088 {
1089   operands[6] = GEN_INT (INTVAL (operands[2]) >> 1);
1090   if (INTVAL (operands[2]) & 0x1)
1091     operands[7] = operands[1];
1092   else
1093     operands[7] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
1094                                   GET_MODE (operands[1]),
1095                                   XEXP (operands[1], 0), XEXP (operands[1], 1));
1096 }")
1097
1098 ;; ---------------------------------------------------------------------
1099 ;; BYTE SWAP INSTRUCTIONS
1100 ;; ---------------------------------------------------------------------
1101 (define_expand "rotlhi3"
1102   [(parallel [(set (match_operand:HI 0 "register_operand" "")
1103                    (rotate:HI (match_operand:HI 1 "register_operand" "")
1104                               (match_operand:HI 2 "const_int_operand" "")))
1105               (clobber (reg:CC CC_REGNUM))])]
1106   "(TARGET_V850E || TARGET_V850E2_ALL)"
1107   "
1108 {
1109   if (INTVAL (operands[2]) != 8)
1110     FAIL;
1111 }")
1112
1113 (define_insn "*rotlhi3_8"
1114   [(set (match_operand:HI 0 "register_operand" "=r")
1115         (rotate:HI (match_operand:HI 1 "register_operand" "r")
1116                    (const_int 8)))
1117    (clobber (reg:CC CC_REGNUM))]
1118   "(TARGET_V850E || TARGET_V850E2_ALL)"
1119   "bsh %1,%0"
1120   [(set_attr "length" "4")
1121    (set_attr "cc" "clobber")])
1122
1123 (define_expand "rotlsi3"
1124   [(parallel [(set (match_operand:SI 0 "register_operand" "")
1125                    (rotate:SI (match_operand:SI 1 "register_operand" "")
1126                               (match_operand:SI 2 "const_int_operand" "")))
1127               (clobber (reg:CC CC_REGNUM))])]
1128   "(TARGET_V850E || TARGET_V850E2_ALL)"
1129   "
1130 {
1131   if (INTVAL (operands[2]) != 16)
1132     FAIL;
1133 }")
1134
1135 (define_insn "*rotlsi3_16"
1136   [(set (match_operand:SI 0 "register_operand" "=r")
1137         (rotate:SI (match_operand:SI 1 "register_operand" "r")
1138                    (const_int 16)))
1139    (clobber (reg:CC CC_REGNUM))]
1140   "(TARGET_V850E || TARGET_V850E2_ALL)"
1141   "hsw %1,%0"
1142   [(set_attr "length" "4")
1143    (set_attr "cc" "clobber")])
1144
1145 ;; ----------------------------------------------------------------------
1146 ;; JUMP INSTRUCTIONS
1147 ;; ----------------------------------------------------------------------
1148
1149 ;; Conditional jump instructions
1150
1151 (define_insn "*branch_normal"
1152   [(set (pc)
1153         (if_then_else (match_operator 1 "comparison_operator"
1154                                       [(cc0) (const_int 0)])
1155                       (label_ref (match_operand 0 "" ""))
1156                       (pc)))]
1157   ""
1158   "*
1159 {
1160   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1161       && (GET_CODE (operands[1]) == GT
1162           || GET_CODE (operands[1]) == GE
1163           || GET_CODE (operands[1]) == LE
1164           || GET_CODE (operands[1]) == LT))
1165     return 0;
1166
1167   if (get_attr_length (insn) == 2)
1168     return \"b%b1 %l0\";
1169   else
1170     return \"b%B1 .+6 ; jr %l0\";
1171 }"
1172  [(set (attr "length")
1173     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1174                       (const_int 256))
1175                   (const_int 2)
1176                   (const_int 6)))
1177   (set_attr "cc" "none")])
1178
1179 (define_insn "*branch_invert"
1180   [(set (pc)
1181         (if_then_else (match_operator 1 "comparison_operator"
1182                                       [(cc0) (const_int 0)])
1183                       (pc)
1184                       (label_ref (match_operand 0 "" ""))))]
1185   ""
1186   "*
1187 {
1188   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1189       && (GET_CODE (operands[1]) == GT
1190           || GET_CODE (operands[1]) == GE
1191           || GET_CODE (operands[1]) == LE
1192           || GET_CODE (operands[1]) == LT))
1193     return 0;
1194   if (get_attr_length (insn) == 2)
1195     return \"b%B1 %l0\";
1196   else
1197     return \"b%b1 .+6 ; jr %l0\";
1198 }"
1199  [(set (attr "length")
1200     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1201                       (const_int 256))
1202                   (const_int 2)
1203                   (const_int 6)))
1204   (set_attr "cc" "none")])
1205
1206 (define_insn "branch_z_normal"  
1207   [(set (pc)
1208         (if_then_else (match_operand 1 "v850_float_z_comparison_operator" "")
1209                       (label_ref (match_operand 0 "" ""))
1210                       (pc)))]
1211   "TARGET_V850E2V3"
1212   "*
1213 {
1214   if (get_attr_length (insn) == 2)
1215     return \"bz %l0\";
1216   else
1217     return \"bnz 1f ; jr %l0 ; 1:\";
1218 }"
1219  [(set (attr "length")
1220     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1221                       (const_int 256))
1222                   (const_int 2)
1223                   (const_int 6)))
1224   (set_attr "cc" "none")])
1225
1226 (define_insn "*branch_z_invert"
1227   [(set (pc)
1228         (if_then_else (match_operand 1 "v850_float_z_comparison_operator" "")
1229                       (pc)
1230                       (label_ref (match_operand 0 "" ""))))]
1231   "TARGET_V850E2V3"
1232   "*
1233 {
1234   if (get_attr_length (insn) == 2)
1235     return \"bnz %l0\";
1236   else
1237     return \"bz 1f ; jr %l0 ; 1:\";
1238 }"
1239  [(set (attr "length")
1240     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1241                            (const_int 256))
1242                   (const_int 2)
1243                   (const_int 6)))
1244   (set_attr "cc" "none")])
1245
1246 (define_insn "branch_nz_normal"
1247   [(set (pc)
1248         (if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "")
1249                       (label_ref (match_operand 0 "" ""))
1250                       (pc)))]
1251   "TARGET_V850E2V3"
1252   "*
1253 {
1254   if (get_attr_length (insn) == 2)
1255     return \"bnz %l0\";
1256   else
1257     return \"bz 1f ; jr %l0 ; 1:\";
1258 }"
1259 [(set (attr "length")
1260     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1261                            (const_int 256))
1262                   (const_int 2)
1263                   (const_int 6)))
1264   (set_attr "cc" "none")])
1265
1266 (define_insn "*branch_nz_invert"
1267   [(set (pc)
1268         (if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "")
1269                       (pc)
1270                       (label_ref (match_operand 0 "" ""))))]
1271   "TARGET_V850E2V3"
1272   "*
1273 {
1274   if (get_attr_length (insn) == 2)
1275     return \"bz %l0\";
1276   else
1277     return \"bnz 1f ; jr %l0 ; 1:\";
1278 }"
1279  [(set (attr "length")
1280     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1281                       (const_int 256))
1282                   (const_int 2)
1283                   (const_int 6)))
1284   (set_attr "cc" "none")])
1285
1286 ;; Unconditional and other jump instructions.
1287
1288 (define_insn "jump"
1289   [(set (pc)
1290         (label_ref (match_operand 0 "" "")))]
1291   ""
1292   "*
1293 {
1294  if (get_attr_length (insn) == 2)
1295     return \"br %0\";
1296   else
1297     return \"jr %0\";
1298 }"
1299  [(set (attr "length")
1300     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1301                       (const_int 256))
1302                   (const_int 2)
1303                   (const_int 4)))
1304   (set_attr "cc" "none")])
1305
1306 (define_insn "indirect_jump"
1307   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1308   ""
1309   "jmp %0"
1310   [(set_attr "length" "2")
1311    (set_attr "cc" "none")])
1312
1313 (define_insn "tablejump"
1314   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1315    (use (label_ref (match_operand 1 "" "")))]
1316   ""
1317   "jmp  %0"
1318   [(set_attr "length" "2")
1319    (set_attr "cc" "none")])
1320
1321 (define_insn "switch"
1322   [(set (pc)
1323         (plus:SI
1324          (sign_extend:SI
1325          (mem:HI
1326           (plus:SI (ashift:SI (match_operand:SI 0 "register_operand" "r")
1327                               (const_int 1))
1328                    (label_ref (match_operand 1 "" "")))))
1329         (label_ref (match_dup 1))))]
1330   "(TARGET_V850E || TARGET_V850E2_ALL)"
1331   "switch %0"
1332   [(set_attr "length" "2")
1333    (set_attr "cc" "none")])
1334
1335 (define_expand "casesi"
1336   [(match_operand:SI 0 "register_operand" "")
1337    (match_operand:SI 1 "register_operand" "")
1338    (match_operand:SI 2 "register_operand" "")
1339    (match_operand 3 "" "") (match_operand 4 "" "")]
1340   ""
1341   "
1342 {
1343   rtx reg = gen_reg_rtx (SImode);
1344   rtx tableaddress = gen_reg_rtx (SImode);
1345   rtx test;
1346   rtx mem;
1347
1348   /* Subtract the lower bound from the index.  */
1349   emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
1350
1351   /* Compare the result against the number of table entries;
1352      branch to the default label if out of range of the table.  */
1353   test = gen_rtx_fmt_ee (GTU, VOIDmode, reg, operands[2]);
1354   emit_jump_insn (gen_cbranchsi4 (test, reg, operands[2], operands[4]));
1355
1356   /* Shift index for the table array access.  */
1357   emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
1358   /* Load the table address into a pseudo.  */
1359   emit_insn (gen_movsi (tableaddress,
1360                         gen_rtx_LABEL_REF (Pmode, operands[3])));
1361   /* Add the table address to the index.  */
1362   emit_insn (gen_addsi3 (reg, reg, tableaddress));
1363   /* Load the table entry.  */
1364   mem = gen_const_mem (CASE_VECTOR_MODE, reg);
1365   if (! TARGET_BIG_SWITCH)
1366     {
1367       rtx reg2 = gen_reg_rtx (HImode);
1368       emit_insn (gen_movhi (reg2, mem));
1369       emit_insn (gen_extendhisi2 (reg, reg2));
1370     }
1371   else
1372     emit_insn (gen_movsi (reg, mem));
1373   /* Add the table address.  */
1374   emit_insn (gen_addsi3 (reg, reg, tableaddress));
1375   /* Branch to the switch label.  */
1376   emit_jump_insn (gen_tablejump (reg, operands[3]));
1377   DONE;
1378 }")
1379
1380 ;; Call subroutine with no return value.
1381
1382 (define_expand "call"
1383   [(call (match_operand:QI 0 "general_operand" "")
1384          (match_operand:SI 1 "general_operand" ""))]
1385   ""
1386   "
1387 {
1388   if (! call_address_operand (XEXP (operands[0], 0), QImode)
1389       || TARGET_LONG_CALLS)
1390     XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1391   if (TARGET_LONG_CALLS)
1392     emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));
1393   else
1394     emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
1395   
1396   DONE;
1397 }")
1398
1399 (define_insn "call_internal_short"
1400   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1401          (match_operand:SI 1 "general_operand" "g,g"))
1402    (clobber (reg:SI 31))]
1403   "! TARGET_LONG_CALLS"
1404   "@
1405   jarl %0,r31
1406   jarl .+4,r31 ; add 4,r31 ; jmp %0"
1407   [(set_attr "length" "4,8")
1408    (set_attr "cc" "clobber,clobber")]
1409 )
1410
1411 (define_insn "call_internal_long"
1412   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1413          (match_operand:SI 1 "general_operand" "g,g"))
1414    (clobber (reg:SI 31))]
1415   "TARGET_LONG_CALLS"
1416   "*
1417   {
1418   if (which_alternative == 0)
1419     {
1420       if (GET_CODE (operands[0]) == REG)
1421         return \"jarl %0,r31\";
1422       else
1423         return \"movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11\";
1424     }
1425   else
1426     return \"jarl .+4,r31 ; add 4,r31 ; jmp %0\";
1427   }"
1428   [(set_attr "length" "16,8")
1429    (set_attr "cc" "clobber,clobber")]
1430 )
1431
1432 ;; Call subroutine, returning value in operand 0
1433 ;; (which must be a hard register).
1434
1435 (define_expand "call_value"
1436   [(set (match_operand 0 "" "")
1437         (call (match_operand:QI 1 "general_operand" "")
1438               (match_operand:SI 2 "general_operand" "")))]
1439   ""
1440   "
1441 {
1442   if (! call_address_operand (XEXP (operands[1], 0), QImode)
1443       || TARGET_LONG_CALLS)
1444     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1445   if (TARGET_LONG_CALLS)
1446     emit_call_insn (gen_call_value_internal_long (operands[0],
1447                                                   XEXP (operands[1], 0),
1448                                                   operands[2]));
1449   else
1450     emit_call_insn (gen_call_value_internal_short (operands[0],
1451                                                    XEXP (operands[1], 0),
1452                                                    operands[2]));
1453   DONE;
1454 }")
1455
1456 (define_insn "call_value_internal_short"
1457   [(set (match_operand 0 "" "=r,r")
1458         (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1459               (match_operand:SI 2 "general_operand" "g,g")))
1460    (clobber (reg:SI 31))]
1461   "! TARGET_LONG_CALLS"
1462   "@
1463   jarl %1,r31
1464   jarl .+4,r31 ; add 4,r31 ; jmp %1"
1465   [(set_attr "length" "4,8")
1466    (set_attr "cc" "clobber,clobber")]
1467 )
1468
1469 (define_insn "call_value_internal_long"
1470   [(set (match_operand 0 "" "=r,r")
1471         (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1472               (match_operand:SI 2 "general_operand" "g,g")))
1473    (clobber (reg:SI 31))]
1474   "TARGET_LONG_CALLS"
1475   "*
1476   {
1477   if (which_alternative == 0)
1478     {
1479       if (GET_CODE (operands[1]) == REG)
1480         return \"jarl %1, r31\";
1481       else
1482       /* Reload can generate this pattern....  */
1483         return \"movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11\";
1484     }
1485   else
1486     return \"jarl .+4, r31 ; add 4, r31 ; jmp %1\";
1487   }"
1488   [(set_attr "length" "16,8")
1489    (set_attr "cc" "clobber,clobber")]
1490 )
1491
1492 (define_insn "nop"
1493   [(const_int 0)]
1494   ""
1495   "nop"
1496   [(set_attr "length" "2")
1497    (set_attr "cc" "none")])
1498 \f
1499 ;; ----------------------------------------------------------------------
1500 ;; EXTEND INSTRUCTIONS
1501 ;; ----------------------------------------------------------------------
1502
1503 (define_insn ""
1504   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1505         (zero_extend:SI
1506         (match_operand:HI 1 "nonimmediate_operand" "0,r,T,m")))
1507    (clobber (reg:CC CC_REGNUM))]
1508   "(TARGET_V850E || TARGET_V850E2_ALL)"
1509   "@
1510    zxh %0
1511    andi 65535,%1,%0
1512    sld.hu %1,%0
1513    ld.hu %1,%0"
1514   [(set_attr "length" "2,4,2,4")
1515    (set_attr "cc" "none_0hit,set_zn,none_0hit,none_0hit")])
1516
1517 (define_insn "zero_extendhisi2"
1518   [(set (match_operand:SI 0 "register_operand" "=r")
1519         (zero_extend:SI
1520         (match_operand:HI 1 "register_operand" "r")))
1521    (clobber (reg:CC CC_REGNUM))]
1522   ""
1523   "andi 65535,%1,%0"
1524   [(set_attr "length" "4")
1525    (set_attr "cc" "set_zn")])
1526
1527 (define_insn ""
1528   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1529         (zero_extend:SI
1530         (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m")))
1531    (clobber (reg:CC CC_REGNUM))]
1532   "(TARGET_V850E || TARGET_V850E2_ALL)"
1533   "@
1534    zxb %0
1535    andi 255,%1,%0
1536    sld.bu %1,%0
1537    ld.bu %1,%0"
1538   [(set_attr "length" "2,4,2,4")
1539    (set_attr "cc" "none_0hit,set_zn,none_0hit,none_0hit")])
1540
1541 (define_insn "zero_extendqisi2"
1542   [(set (match_operand:SI 0 "register_operand" "=r")
1543         (zero_extend:SI
1544         (match_operand:QI 1 "register_operand" "r")))
1545    (clobber (reg:CC CC_REGNUM))]
1546   ""
1547   "andi 255,%1,%0"
1548   [(set_attr "length" "4")
1549    (set_attr "cc" "set_zn")])
1550
1551 ;;- sign extension instructions
1552
1553 ;; ??? The extendhisi2 pattern should not emit shifts for v850e?
1554
1555 (define_insn "*extendhisi_insn"
1556   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1557         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))
1558    (clobber (reg:CC CC_REGNUM))]
1559   "(TARGET_V850E || TARGET_V850E2_ALL)"
1560   "@
1561    sxh %0
1562    sld.h %1,%0
1563    ld.h %1,%0"
1564   [(set_attr "length" "2,2,4")
1565    (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1566
1567 ;; ??? This is missing a sign extend from memory pattern to match the ld.h
1568 ;; instruction.
1569
1570 (define_expand "extendhisi2"
1571   [(parallel [(set (match_dup 2)
1572                    (ashift:SI (match_operand:HI 1 "register_operand" "")
1573                               (const_int 16)))
1574               (clobber (reg:CC CC_REGNUM))])
1575    (parallel [(set (match_operand:SI 0 "register_operand" "")
1576                    (ashiftrt:SI (match_dup 2)
1577                                 (const_int 16)))
1578               (clobber (reg:CC CC_REGNUM))])]
1579   ""
1580   "
1581 {
1582   operands[1] = gen_lowpart (SImode, operands[1]);
1583   operands[2] = gen_reg_rtx (SImode);
1584 }")
1585
1586 ;; ??? The extendqisi2 pattern should not emit shifts for v850e?
1587
1588 (define_insn "*extendqisi_insn"
1589   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1590         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))
1591    (clobber (reg:CC CC_REGNUM))]
1592   "(TARGET_V850E || TARGET_V850E2_ALL)"
1593   "@
1594    sxb %0
1595    sld.b %1,%0
1596    ld.b %1,%0"
1597   [(set_attr "length" "2,2,4")
1598    (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1599
1600 ;; ??? This is missing a sign extend from memory pattern to match the ld.b
1601 ;; instruction.
1602
1603 (define_expand "extendqisi2"
1604   [(parallel [(set (match_dup 2)
1605                    (ashift:SI (match_operand:QI 1 "register_operand" "")
1606                               (const_int 24)))
1607               (clobber (reg:CC CC_REGNUM))])
1608    (parallel [(set (match_operand:SI 0 "register_operand" "")
1609                    (ashiftrt:SI (match_dup 2)
1610                               (const_int 24)))
1611               (clobber (reg:CC CC_REGNUM))])]
1612   ""
1613   "
1614 {
1615   operands[1] = gen_lowpart (SImode, operands[1]);
1616   operands[2] = gen_reg_rtx (SImode);
1617 }")
1618 \f
1619 ;; ----------------------------------------------------------------------
1620 ;; SHIFTS
1621 ;; ----------------------------------------------------------------------
1622
1623 (define_insn "ashlsi3"
1624   [(set (match_operand:SI 0 "register_operand" "=r,r")
1625       (ashift:SI
1626         (match_operand:SI 1 "register_operand" "0,0")
1627         (match_operand:SI 2 "nonmemory_operand" "r,N")))
1628    (clobber (reg:CC CC_REGNUM))]
1629   ""
1630   "@
1631   shl %2,%0
1632   shl %2,%0"
1633   [(set_attr "length" "4,2")
1634    (set_attr "cc" "set_zn")])
1635
1636 (define_insn "ashlsi3_v850e2"
1637   [(set (match_operand:SI 0 "register_operand" "=r")
1638       (ashift:SI
1639         (match_operand:SI 1 "register_operand" "r")
1640         (match_operand:SI 2 "nonmemory_operand" "r")))
1641    (clobber (reg:CC CC_REGNUM))]
1642   "TARGET_V850E2_ALL"
1643   "shl %2,%1,%0"
1644   [(set_attr "length" "4")
1645    (set_attr "cc" "set_znv")])
1646
1647 (define_insn "lshrsi3"
1648   [(set (match_operand:SI 0 "register_operand" "=r,r")
1649       (lshiftrt:SI
1650         (match_operand:SI 1 "register_operand" "0,0")
1651         (match_operand:SI 2 "nonmemory_operand" "r,N")))
1652    (clobber (reg:CC CC_REGNUM))]
1653   ""
1654   "@
1655   shr %2,%0
1656   shr %2,%0"
1657   [(set_attr "length" "4,2")
1658    (set_attr "cc" "set_zn")])
1659
1660 (define_insn "lshrsi3_v850e2"
1661   [(set (match_operand:SI 0 "register_operand" "=r")
1662       (lshiftrt:SI
1663         (match_operand:SI 1 "register_operand" "r")
1664         (match_operand:SI 2 "nonmemory_operand" "r")))
1665    (clobber (reg:CC CC_REGNUM))]
1666   "TARGET_V850E2_ALL"
1667   "shr %2,%1,%0"
1668   [(set_attr "length" "4")
1669    (set_attr "cc" "set_zn")])
1670
1671 (define_insn "ashrsi3"
1672   [(set (match_operand:SI 0 "register_operand" "=r,r")
1673       (ashiftrt:SI
1674         (match_operand:SI 1 "register_operand" "0,0")
1675         (match_operand:SI 2 "nonmemory_operand" "r,N")))
1676    (clobber (reg:CC CC_REGNUM))]
1677   ""
1678   "@
1679   sar %2,%0
1680   sar %2,%0"
1681   [(set_attr "length" "4,2")
1682    (set_attr "cc" "set_zn, set_zn")])
1683
1684 (define_insn "ashrsi3_v850e2"
1685   [(set (match_operand:SI 0 "register_operand" "=r")
1686       (ashiftrt:SI
1687         (match_operand:SI 1 "register_operand" "r")
1688         (match_operand:SI 2 "nonmemory_operand" "r")))
1689    (clobber (reg:CC CC_REGNUM))]
1690   "TARGET_V850E2_ALL"
1691   "sar %2,%1,%0"
1692   [(set_attr "length" "4")
1693    (set_attr "cc" "set_zn")])
1694
1695 ;; ----------------------------------------------------------------------
1696 ;; FIND FIRST BIT INSTRUCTION
1697 ;; ----------------------------------------------------------------------
1698
1699 (define_insn "ffssi2"
1700   [(set (match_operand:SI 0 "register_operand" "=r")
1701        (ffs:SI (match_operand:SI 1 "register_operand" "r")))
1702    (clobber (reg:CC CC_REGNUM))]
1703   "TARGET_V850E2_ALL"
1704   "sch1r %1,%0"
1705   [(set_attr "length" "4")
1706    (set_attr "cc" "clobber")])
1707
1708 ;; ----------------------------------------------------------------------
1709 ;; PROLOGUE/EPILOGUE
1710 ;; ----------------------------------------------------------------------
1711 (define_expand "prologue"
1712   [(const_int 0)]
1713   ""
1714   "expand_prologue (); DONE;")
1715
1716 (define_expand "epilogue"
1717   [(return)]
1718   ""
1719   "
1720 {
1721   expand_epilogue ();
1722   DONE;
1723 }")
1724
1725 (define_insn "return_simple"
1726   [(return)]
1727   "reload_completed"
1728   "jmp [r31]"
1729   [(set_attr "length" "2")
1730    (set_attr "cc" "none")])
1731
1732 (define_insn "return_internal"
1733   [(return)
1734    (use (reg:SI 31))]
1735   ""
1736   "jmp [r31]"
1737   [(set_attr "length" "2")
1738    (set_attr "cc" "none")])
1739
1740 ;; ----------------------------------------------------------------------
1741 ;; v850e2V3 floating-point hardware support
1742 ;; ----------------------------------------------------------------------
1743
1744
1745 (define_insn "addsf3"
1746   [(set (match_operand:SF 0 "register_operand" "=r")
1747         (plus:SF (match_operand:SF 1 "register_operand" "r")
1748                  (match_operand:SF 2 "register_operand" "r")))]
1749   "TARGET_V850E2V3"
1750   "addf.s %1,%2,%0"
1751   [(set_attr "length" "4")
1752    (set_attr "cc" "none_0hit")
1753    (set_attr "type" "fpu")])
1754
1755 (define_insn "adddf3"
1756   [(set (match_operand:DF 0 "even_reg_operand" "=r")
1757         (plus:DF (match_operand:DF 1 "even_reg_operand" "r")
1758         (match_operand:DF 2 "even_reg_operand" "r")))]
1759   "TARGET_V850E2V3"
1760   "addf.d %1,%2,%0"
1761   [(set_attr "length" "4")
1762    (set_attr "cc" "none_0hit")
1763    (set_attr "type" "fpu")])
1764
1765 (define_insn "subsf3"
1766   [(set (match_operand:SF 0 "register_operand" "=r")
1767         (minus:SF (match_operand:SF 1 "register_operand" "r")
1768                   (match_operand:SF 2 "register_operand" "r")))]
1769   "TARGET_V850E2V3"
1770   "subf.s %2,%1,%0"
1771   [(set_attr "length" "4")
1772    (set_attr "cc" "none_0hit")
1773    (set_attr "type" "fpu")])
1774
1775 (define_insn "subdf3"
1776   [(set (match_operand:DF 0 "even_reg_operand" "=r")
1777         (minus:DF (match_operand:DF 1 "even_reg_operand" "r")
1778                   (match_operand:DF 2 "even_reg_operand" "r")))]
1779   "TARGET_V850E2V3"
1780   "subf.d %2,%1,%0"
1781   [(set_attr "length" "4")
1782    (set_attr "cc" "none_0hit")
1783    (set_attr "type" "fpu")])
1784
1785 (define_insn "mulsf3"
1786   [(set (match_operand:SF 0 "register_operand" "=r")
1787         (mult:SF (match_operand:SF 1 "register_operand" "r")
1788                  (match_operand:SF 2 "register_operand" "r")))]
1789   "TARGET_V850E2V3"
1790   "mulf.s %1,%2,%0"
1791   [(set_attr "length" "4")
1792    (set_attr "cc" "none_0hit")
1793    (set_attr "type" "fpu")])
1794
1795 (define_insn "muldf3"
1796   [(set (match_operand:DF 0 "even_reg_operand" "=r")
1797         (mult:DF (match_operand:DF 1 "even_reg_operand" "r")
1798                  (match_operand:DF 2 "even_reg_operand" "r")))]
1799   "TARGET_V850E2V3"
1800   "mulf.d %1,%2,%0"
1801   [(set_attr "length" "4")
1802    (set_attr "cc" "none_0hit")
1803    (set_attr "type" "fpu")])
1804
1805 (define_insn "divsf3"
1806   [(set (match_operand:SF 0 "register_operand" "=r")
1807         (div:SF (match_operand:SF 1 "register_operand" "r")
1808                 (match_operand:SF 2 "register_operand" "r")))]
1809   "TARGET_V850E2V3"
1810   "divf.s %2,%1,%0"
1811   [(set_attr "length" "4")
1812    (set_attr "cc" "none_0hit")
1813    (set_attr "type" "fpu")])
1814
1815 (define_insn "divdf3"
1816   [(set (match_operand:DF 0 "register_operand" "=r")
1817         (div:DF (match_operand:DF 1 "even_reg_operand" "r")
1818                 (match_operand:DF 2 "even_reg_operand" "r")))]
1819   "TARGET_V850E2V3"
1820   "divf.d %2,%1,%0"
1821   [(set_attr "length" "4")
1822    (set_attr "cc" "none_0hit")
1823    (set_attr "type" "fpu")])
1824
1825 (define_insn "minsf3"
1826   [(set (match_operand:SF 0 "register_operand" "=r")
1827         (smin:SF (match_operand:SF 1 "reg_or_0_operand" "r")
1828                  (match_operand:SF 2 "reg_or_0_operand" "r")))]
1829   "TARGET_V850E2V3"
1830   "minf.s %z1,%z2,%0"
1831   [(set_attr "length" "4")
1832    (set_attr "cc" "none_0hit")
1833    (set_attr "type" "fpu")])
1834
1835 (define_insn "mindf3"
1836   [(set (match_operand:DF 0 "even_reg_operand" "=r")
1837         (smin:DF (match_operand:DF 1 "even_reg_operand" "r")
1838                  (match_operand:DF 2 "even_reg_operand" "r")))]
1839   "TARGET_V850E2V3"
1840   "minf.d %1,%2,%0"
1841   [(set_attr "length" "4")
1842    (set_attr "cc" "none_0hit")
1843    (set_attr "type" "fpu")])
1844
1845 (define_insn "maxsf3"
1846   [(set (match_operand:SF 0 "register_operand" "=r")
1847         (smax:SF (match_operand:SF 1 "reg_or_0_operand" "r")
1848                  (match_operand:SF 2 "reg_or_0_operand" "r")))]
1849   "TARGET_V850E2V3"
1850   "maxf.s %z1,%z2,%0"
1851   [(set_attr "length" "4")
1852    (set_attr "cc" "none_0hit")
1853    (set_attr "type" "fpu")])
1854
1855 (define_insn "maxdf3"
1856   [(set (match_operand:DF 0 "even_reg_operand" "=r")
1857         (smax:DF (match_operand:DF 1 "even_reg_operand" "r")
1858                  (match_operand:DF 2 "even_reg_operand" "r")))]
1859   "TARGET_V850E2V3"
1860   "maxf.d %1,%2,%0"
1861   [(set_attr "length" "4")
1862    (set_attr "cc" "none_0hit")
1863    (set_attr "type" "fpu")])
1864
1865 (define_insn "abssf2"
1866   [(set (match_operand:SF 0 "register_operand" "=r")
1867         (abs:SF (match_operand:SF 1 "register_operand" "r")))]
1868   "TARGET_V850E2V3"
1869   "absf.s %1,%0"
1870   [(set_attr "length" "4")
1871    (set_attr "cc" "none_0hit")
1872    (set_attr "type" "fpu")])
1873
1874 (define_insn "absdf2"
1875   [(set (match_operand:DF 0 "even_reg_operand" "=r")
1876         (abs:DF (match_operand:DF 1 "even_reg_operand" "r")))]
1877   "TARGET_V850E2V3"
1878   "absf.d %1,%0"
1879   [(set_attr "length" "4")
1880    (set_attr "cc" "none_0hit")
1881    (set_attr "type" "fpu")])
1882
1883 (define_insn "negsf2"
1884   [(set (match_operand:SF 0 "register_operand" "=r")
1885         (neg:SF (match_operand:SF 1 "register_operand" "r")))]
1886   "TARGET_V850E2V3"
1887   "negf.s %1,%0"
1888   [(set_attr "length" "4")
1889    (set_attr "cc" "none_0hit")
1890    (set_attr "type" "fpu")])
1891
1892 (define_insn "negdf2"
1893   [(set (match_operand:DF 0 "even_reg_operand" "=r")
1894         (neg:DF (match_operand:DF 1 "even_reg_operand" "r")))]
1895   "TARGET_V850E2V3"
1896   "negf.d %1,%0"
1897   [(set_attr "length" "4")
1898    (set_attr "cc" "none_0hit")
1899    (set_attr "type" "fpu")])
1900
1901 ;; square-root
1902 (define_insn "sqrtsf2"
1903   [(set (match_operand:SF 0 "register_operand" "=r")
1904         (sqrt:SF (match_operand:SF 1 "register_operand" "r")))]
1905   "TARGET_V850E2V3"
1906   "sqrtf.s %1,%0"
1907   [(set_attr "length" "4")
1908    (set_attr "cc" "none_0hit")
1909    (set_attr "type" "fpu")])
1910
1911 (define_insn "sqrtdf2"
1912   [(set (match_operand:DF 0 "even_reg_operand" "=r")
1913         (sqrt:DF (match_operand:DF 1 "even_reg_operand" "r")))]
1914   "TARGET_V850E2V3"
1915   "sqrtf.d %1,%0"
1916   [(set_attr "length" "4")
1917    (set_attr "cc" "none_0hit")
1918    (set_attr "type" "fpu")])
1919
1920 ;; float -> int
1921 (define_insn "fix_truncsfsi2"
1922   [(set (match_operand:SI 0 "register_operand" "=r")
1923         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "r"))))]
1924   "TARGET_V850E2V3"
1925   "trncf.sw %1,%0"
1926   [(set_attr "length" "4")
1927    (set_attr "cc" "none_0hit")
1928    (set_attr "type" "fpu")])
1929
1930 (define_insn "fix_truncdfsi2"
1931   [(set (match_operand:SI 0 "register_operand" "=r")
1932         (fix:SI (fix:DF (match_operand:DF 1 "even_reg_operand" "r"))))]
1933   "TARGET_V850E2V3"
1934   "trncf.dw %1,%0"
1935   [(set_attr "length" "4")
1936    (set_attr "cc" "none_0hit")
1937    (set_attr "type" "fpu")])
1938
1939 ;; int -> float
1940 (define_insn "floatsisf2"
1941   [(set (match_operand:SF 0 "register_operand" "=r")
1942         (float:SF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
1943   "TARGET_V850E2V3"
1944   "cvtf.ws %z1, %0"
1945   [(set_attr "length" "4")
1946    (set_attr "cc" "none_0hit")
1947    (set_attr "type" "fpu")])
1948
1949 (define_insn "floatsidf2"
1950   [(set (match_operand:DF 0 "even_reg_operand" "=r")
1951         (float:DF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
1952   "TARGET_V850E2V3"
1953   "cvtf.wd %z1,%0"
1954   [(set_attr "length" "4")
1955    (set_attr "cc" "none_0hit")
1956    (set_attr "type" "fpu")])
1957
1958 ;; single-float -> double-float
1959 (define_insn "extendsfdf2"
1960   [(set (match_operand:DF 0 "even_reg_operand" "=r")
1961         (float_extend:DF
1962          (match_operand:SF 1 "reg_or_0_operand" "rI")))]
1963   "TARGET_V850E2V3"
1964   "cvtf.sd %z1,%0"
1965   [(set_attr "length" "4")
1966    (set_attr "cc" "none_0hit")
1967    (set_attr "type" "fpu")])
1968
1969 ;; double-float -> single-float
1970 (define_insn "truncdfsf2"
1971   [(set (match_operand:SF 0 "register_operand" "=r")
1972         (float_truncate:SF
1973          (match_operand:DF 1 "even_reg_operand" "r")))]
1974   "TARGET_V850E2V3"
1975   "cvtf.ds %1,%0"
1976   [(set_attr "length" "4")
1977    (set_attr "cc" "none_0hit")
1978    (set_attr "type" "fpu")])
1979
1980 ;;
1981 ;; ---------------- special insns
1982 ;;
1983
1984 ;;; reciprocal
1985 (define_insn "recipsf2"
1986   [(set (match_operand:SF 0 "register_operand" "=r")
1987         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
1988                 (match_operand:SF 2 "register_operand" "r")))]
1989   "TARGET_V850E2V3"
1990   "recipf.s %2,%0"
1991   [(set_attr "length" "4")
1992    (set_attr "cc" "none_0hit")
1993    (set_attr "type" "fpu")])
1994
1995 (define_insn "recipdf2"
1996   [(set (match_operand:DF 0 "even_reg_operand" "=r")
1997         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
1998                 (match_operand:DF 2 "even_reg_operand" "r")))]
1999   "TARGET_V850E2V3"
2000   "recipf.d %2,%0"
2001   [(set_attr "length" "4")
2002    (set_attr "cc" "none_0hit")
2003    (set_attr "type" "fpu")])
2004
2005 ;;; reciprocal of square-root
2006 (define_insn "rsqrtsf2"
2007   [(set (match_operand:SF 0 "register_operand" "=r")
2008         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2009                 (sqrt:SF (match_operand:SF 2 "register_operand" "r"))))]
2010   "TARGET_V850E2V3"
2011   "rsqrtf.s %2,%0"
2012   [(set_attr "length" "4")
2013    (set_attr "cc" "none_0hit")
2014    (set_attr "type" "fpu")])
2015
2016 (define_insn "rsqrtdf2"
2017   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2018         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2019                 (sqrt:DF (match_operand:DF 2 "even_reg_operand" "r"))))]
2020   "TARGET_V850E2V3"
2021   "rsqrtf.d %2,%0"
2022   [(set_attr "length" "4")
2023    (set_attr "cc" "none_0hit")
2024    (set_attr "type" "fpu")])
2025
2026 ;;; multiply-add
2027 (define_insn "fmasf4"
2028   [(set (match_operand:SF         0 "register_operand" "=r")
2029         (fma:SF (match_operand:SF 1 "register_operand" "r")
2030                 (match_operand:SF 2 "register_operand" "r")
2031                 (match_operand:SF 3 "register_operand" "r")))]
2032   "TARGET_V850E2V3"
2033   "maddf.s %2,%1,%3,%0"
2034   [(set_attr "length" "4")
2035    (set_attr "cc" "none_0hit")
2036    (set_attr "type" "fpu")])
2037
2038 ;;; multiply-subtract
2039 (define_insn "fmssf4"
2040   [(set (match_operand:SF                 0 "register_operand" "=r")
2041         (fma:SF (match_operand:SF         1 "register_operand" "r")
2042                 (match_operand:SF         2 "register_operand" "r")
2043                 (neg:SF (match_operand:SF 3 "register_operand" "r"))))]
2044   "TARGET_V850E2V3"
2045   "msubf.s %2,%1,%3,%0"
2046   [(set_attr "length" "4")
2047    (set_attr "cc" "none_0hit")
2048    (set_attr "type" "fpu")])
2049
2050 ;;; negative-multiply-add
2051 (define_insn "fnmasf4"
2052   [(set (match_operand:SF                 0 "register_operand" "=r")
2053         (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "r"))
2054                 (match_operand:SF         2 "register_operand" "r")
2055                 (match_operand:SF         3 "register_operand" "r")))]
2056   "TARGET_V850E2V3"
2057   "nmaddf.s %2,%1,%3,%0"
2058   [(set_attr "length" "4")
2059    (set_attr "cc" "none_0hit")
2060    (set_attr "type" "fpu")])
2061
2062 ;; negative-multiply-subtract
2063 (define_insn "fnmssf4"
2064   [(set (match_operand:SF                 0 "register_operand" "=r")
2065         (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "r"))
2066                 (match_operand:SF         2 "register_operand" "r")
2067                 (neg:SF (match_operand:SF 3 "register_operand" "r"))))]
2068   "TARGET_V850E2V3"
2069   "nmsubf.s %2,%1,%3,%0"
2070   [(set_attr "length" "4")
2071    (set_attr "cc" "none_0hit")
2072    (set_attr "type" "fpu")])
2073 ;
2074 ; ---------------- comparison/conditionals
2075 ;
2076 ; SF
2077
2078 (define_insn "cmpsf_le_insn"
2079   [(set (reg:CC_FPU_LE FCC_REGNUM)
2080         (compare:CC_FPU_LE (match_operand:SF 0 "register_operand" "r")
2081                            (match_operand:SF 1 "register_operand" "r")))]
2082   "TARGET_V850E2V3"
2083   "cmpf.s le,%z0,%z1"
2084   [(set_attr "length" "4")
2085    (set_attr "cc" "none_0hit")
2086    (set_attr "type" "fpu")])
2087
2088 (define_insn "cmpsf_lt_insn"
2089   [(set (reg:CC_FPU_LT FCC_REGNUM)
2090         (compare:CC_FPU_LT (match_operand:SF 0 "register_operand" "r")
2091                            (match_operand:SF 1 "register_operand" "r")))]
2092   "TARGET_V850E2V3"
2093   "cmpf.s lt,%z0,%z1"
2094   [(set_attr "length" "4")
2095    (set_attr "cc" "none_0hit")
2096    (set_attr "type" "fpu")])
2097
2098 (define_insn "cmpsf_ge_insn"
2099   [(set (reg:CC_FPU_GE FCC_REGNUM)
2100         (compare:CC_FPU_GE (match_operand:SF 0 "register_operand" "r")
2101                            (match_operand:SF 1 "register_operand" "r")))]
2102   "TARGET_V850E2V3"
2103   "cmpf.s ge,%z0,%z1"
2104   [(set_attr "length" "4")
2105    (set_attr "cc" "none_0hit")
2106    (set_attr "type" "fpu")])
2107
2108 (define_insn "cmpsf_gt_insn"
2109   [(set (reg:CC_FPU_GT FCC_REGNUM)
2110         (compare:CC_FPU_GT (match_operand:SF 0 "register_operand" "r")
2111                            (match_operand:SF 1 "register_operand" "r")))]
2112   "TARGET_V850E2V3"
2113   "cmpf.s gt,%z0,%z1"
2114   [(set_attr "length" "4")
2115    (set_attr "cc" "none_0hit")
2116    (set_attr "type" "fpu")])
2117
2118 (define_insn "cmpsf_eq_insn"
2119   [(set (reg:CC_FPU_EQ FCC_REGNUM)
2120         (compare:CC_FPU_EQ (match_operand:SF 0 "register_operand" "r")
2121                            (match_operand:SF 1 "register_operand" "r")))]
2122   "TARGET_V850E2V3"
2123   "cmpf.s eq,%z0,%z1"
2124   [(set_attr "length" "4")
2125    (set_attr "cc" "none_0hit")
2126    (set_attr "type" "fpu")])
2127
2128 (define_insn "cmpsf_ne_insn"
2129   [(set (reg:CC_FPU_NE FCC_REGNUM)
2130         (compare:CC_FPU_NE (match_operand:SF 0 "register_operand" "r")
2131                            (match_operand:SF 1 "register_operand" "r")))]
2132   "TARGET_V850E2V3"
2133   "cmpf.s neq,%z0,%z1"
2134   [(set_attr "length" "4")
2135    (set_attr "cc" "none_0hit")
2136    (set_attr "type" "fpu")])
2137
2138 ; DF
2139
2140 (define_insn "cmpdf_le_insn"
2141   [(set (reg:CC_FPU_LE FCC_REGNUM)
2142         (compare:CC_FPU_LE (match_operand:DF 0 "even_reg_operand" "r")
2143                            (match_operand:DF 1 "even_reg_operand" "r")))]
2144   "TARGET_V850E2V3"
2145   "cmpf.d le,%z0,%z1"
2146   [(set_attr "length" "4")
2147    (set_attr "cc" "none_0hit")
2148    (set_attr "type" "fpu")])
2149
2150 (define_insn "cmpdf_lt_insn"
2151   [(set (reg:CC_FPU_LT FCC_REGNUM)
2152         (compare:CC_FPU_LT (match_operand:DF 0 "even_reg_operand" "r")
2153                            (match_operand:DF 1 "even_reg_operand" "r")))]
2154   "TARGET_V850E2V3"
2155   "cmpf.d lt,%z0,%z1"
2156   [(set_attr "length" "4")
2157    (set_attr "cc" "none_0hit")
2158    (set_attr "type" "fpu")])
2159
2160 (define_insn "cmpdf_ge_insn"
2161   [(set (reg:CC_FPU_GE FCC_REGNUM)
2162         (compare:CC_FPU_GE (match_operand:DF 0 "even_reg_operand" "r")
2163                            (match_operand:DF 1 "even_reg_operand" "r")))]
2164   "TARGET_V850E2V3"
2165   "cmpf.d ge,%z0,%z1"
2166   [(set_attr "length" "4")
2167    (set_attr "cc" "none_0hit")
2168    (set_attr "type" "fpu")])
2169
2170 (define_insn "cmpdf_gt_insn"
2171   [(set (reg:CC_FPU_GT FCC_REGNUM)
2172         (compare:CC_FPU_GT (match_operand:DF 0 "even_reg_operand" "r")
2173                       (match_operand:DF 1 "even_reg_operand" "r")))]
2174   "TARGET_V850E2V3"
2175   "cmpf.d gt,%z0,%z1"
2176   [(set_attr "length" "4")
2177    (set_attr "cc" "none_0hit")
2178    (set_attr "type" "fpu")])
2179
2180 (define_insn "cmpdf_eq_insn"
2181   [(set (reg:CC_FPU_EQ FCC_REGNUM)
2182         (compare:CC_FPU_EQ (match_operand:DF 0 "even_reg_operand" "r")
2183                            (match_operand:DF 1 "even_reg_operand" "r")))]
2184   "TARGET_V850E2V3"
2185   "cmpf.d eq,%z0,%z1"
2186   [(set_attr "length" "4")
2187    (set_attr "cc" "none_0hit")
2188    (set_attr "type" "fpu")])
2189
2190 (define_insn "cmpdf_ne_insn"
2191   [(set (reg:CC_FPU_NE FCC_REGNUM)
2192         (compare:CC_FPU_NE (match_operand:DF 0 "even_reg_operand" "r")
2193                            (match_operand:DF 1 "even_reg_operand" "r")))]
2194   "TARGET_V850E2V3"
2195   "cmpf.d neq,%z0,%z1"
2196   [(set_attr "length" "4")
2197    (set_attr "cc" "none_0hit")
2198    (set_attr "type" "fpu")])
2199
2200
2201 ;;
2202 ;; Transfer a v850e2v3 fcc to the Z bit of CC0 (this is necessary to do a
2203 ;; conditional branch based on a floating-point compare)
2204 ;;
2205
2206 (define_insn "trfsr"
2207   [(set (match_operand 0 "" "") (match_operand 1 "" ""))]
2208   "TARGET_V850E2V3
2209    && GET_MODE(operands[0]) == GET_MODE(operands[1])
2210    && GET_CODE(operands[0]) == REG && REGNO (operands[0]) == CC_REGNUM
2211    && GET_CODE(operands[1]) == REG && REGNO (operands[1]) == FCC_REGNUM
2212    && (GET_MODE(operands[0]) == CC_FPU_LEmode
2213        || GET_MODE(operands[0]) == CC_FPU_GEmode
2214        || GET_MODE(operands[0]) == CC_FPU_LTmode
2215        || GET_MODE(operands[0]) == CC_FPU_GTmode
2216        || GET_MODE(operands[0]) == CC_FPU_EQmode
2217        || GET_MODE(operands[0]) == CC_FPU_NEmode)"
2218   "trfsr"
2219   [(set_attr "length" "4")
2220    (set_attr "cc" "set_z")
2221    (set_attr "type" "fpu")])
2222
2223 ;;
2224 ;; Floating-point conditional moves for the v850e2v3.
2225 ;;
2226
2227 ;; The actual v850e2v3 conditional move instructions
2228 ;;
2229 (define_insn "movsfcc_z_insn"
2230   [(set (match_operand:SF 0 "register_operand" "=r")
2231         (if_then_else:SF
2232          (match_operand 3 "v850_float_z_comparison_operator" "")
2233          (match_operand:SF 1 "reg_or_0_operand" "rIG")
2234          (match_operand:SF 2 "reg_or_0_operand" "rIG")))]
2235   "TARGET_V850E2V3"
2236   "cmovf.s 0,%z1,%z2,%0"
2237   [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2238
2239 (define_insn "movsfcc_nz_insn"
2240   [(set (match_operand:SF 0 "register_operand" "=r")
2241         (if_then_else:SF
2242          (match_operand 3 "v850_float_nz_comparison_operator" "")
2243          (match_operand:SF 1 "reg_or_0_operand" "rIG")
2244          (match_operand:SF 2 "reg_or_0_operand" "rIG")))]
2245   "TARGET_V850E2V3"
2246   "cmovf.s 0,%z2,%z1,%0"
2247   [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2248
2249 (define_insn "movdfcc_z_insn"
2250   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2251         (if_then_else:DF
2252          (match_operand 3 "v850_float_z_comparison_operator" "")
2253          (match_operand:DF 1 "even_reg_operand" "r")
2254          (match_operand:DF 2 "even_reg_operand" "r")))]
2255   "TARGET_V850E2V3"
2256   "cmovf.d 0,%z1,%z2,%0"
2257   [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2258
2259 (define_insn "movdfcc_nz_insn"
2260   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2261         (if_then_else:DF
2262          (match_operand 3 "v850_float_nz_comparison_operator" "")
2263          (match_operand:DF 1 "even_reg_operand" "r")
2264          (match_operand:DF 2 "even_reg_operand" "r")))]
2265   "TARGET_V850E2V3"
2266   "cmovf.d 0,%z2,%z1,%0"
2267   [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2268
2269 (define_insn "movedfcc_z_zero"
2270   [(set (match_operand:DF 0 "register_operand" "=r")
2271         (if_then_else:DF
2272          (match_operand 3 "v850_float_z_comparison_operator" "")
2273          (match_operand:DF 1 "reg_or_0_operand" "rIG")
2274          (match_operand:DF 2 "reg_or_0_operand" "rIG")))]
2275   "TARGET_V850E2V3"
2276   "cmovf.s 0,%z1,%z2,%0 ; cmovf.s 0,%Z1,%Z2,%R0"
2277   [(set_attr "length" "8")
2278    (set_attr "cc" "clobber")]) ;; ??? or none_0hit
2279
2280 (define_insn "movedfcc_nz_zero"
2281   [(set (match_operand:DF 0 "register_operand" "=r")
2282         (if_then_else:DF
2283          (match_operand 3 "v850_float_nz_comparison_operator" "")
2284          (match_operand:DF 1 "reg_or_0_operand" "rIG")
2285          (match_operand:DF 2 "reg_or_0_operand" "rIG")))]
2286   "TARGET_V850E2V3"
2287   "cmovf.s 0,%z2,%z1,%0 ; cmovf.s 0,%Z2,%Z1,%R0"
2288   [(set_attr "length" "8")
2289    (set_attr "cc" "clobber")]) ;; ??? or none_0hit
2290
2291
2292 ;; ----------------------------------------------------------------------
2293 ;; HELPER INSTRUCTIONS for saving the prologue and epilogue registers
2294 ;; ----------------------------------------------------------------------
2295
2296 ;; This pattern will match a stack adjust RTX followed by any number of push
2297 ;; RTXs.  These RTXs will then be turned into a suitable call to a worker
2298 ;; function.
2299
2300 ;;
2301 ;; Actually, convert the RTXs into a PREPARE instruction.
2302 ;;
2303
2304 (define_insn ""
2305  [(match_parallel 0 "pattern_is_ok_for_prepare"
2306    [(set (reg:SI 3)
2307          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2308     (set (mem:SI (plus:SI (reg:SI 3)
2309                           (match_operand:SI 2 "immediate_operand" "i")))
2310          (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
2311  "TARGET_PROLOG_FUNCTION && (TARGET_V850E || TARGET_V850E2_ALL)"
2312  "* return construct_prepare_instruction (operands[0]);
2313  "
2314  [(set_attr "length" "4")
2315   (set_attr "cc"     "clobber")])
2316
2317 (define_insn ""
2318  [(match_parallel 0 "pattern_is_ok_for_prologue"
2319    [(set (reg:SI 3)
2320          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2321     (set (mem:SI (plus:SI (reg:SI 3)
2322                            (match_operand:SI 2 "immediate_operand" "i")))
2323          (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
2324  "TARGET_PROLOG_FUNCTION"
2325  "* return construct_save_jarl (operands[0]);
2326  "
2327  [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
2328                                      (const_string "16")
2329                                      (const_string "4")))
2330   (set_attr "cc"     "clobber")])
2331
2332 ;;
2333 ;; Actually, turn the RTXs into a DISPOSE instruction.
2334 ;;
2335 (define_insn ""
2336  [(match_parallel 0 "pattern_is_ok_for_dispose"
2337    [(return)
2338     (set (reg:SI 3)
2339          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2340     (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
2341          (mem:SI (plus:SI (reg:SI 3)
2342                           (match_operand:SI 3 "immediate_operand" "i"))))])]
2343  "TARGET_PROLOG_FUNCTION && (TARGET_V850E || TARGET_V850E2_ALL)"
2344  "* return construct_dispose_instruction (operands[0]);
2345  "
2346  [(set_attr "length" "4")
2347   (set_attr "cc"     "clobber")])
2348
2349 ;; This pattern will match a return RTX followed by any number of pop RTXs
2350 ;; and possible a stack adjustment as well.  These RTXs will be turned into
2351 ;; a suitable call to a worker function.
2352
2353 (define_insn ""
2354 [(match_parallel 0 "pattern_is_ok_for_epilogue"
2355    [(return)
2356     (set (reg:SI 3)
2357          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2358     (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
2359          (mem:SI (plus:SI (reg:SI 3)
2360                           (match_operand:SI 3 "immediate_operand" "i"))))])]
2361  "TARGET_PROLOG_FUNCTION"
2362  "* return construct_restore_jr (operands[0]);
2363  "
2364  [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
2365                                      (const_string "12")
2366                                      (const_string "4")))
2367   (set_attr "cc"     "clobber")])
2368
2369 ;; Initialize an interrupt function.  Do not depend on TARGET_PROLOG_FUNCTION.
2370 (define_insn "callt_save_interrupt"
2371   [(unspec_volatile [(const_int 0)] 2)]
2372     "(TARGET_V850E || TARGET_V850E2_ALL) && !TARGET_DISABLE_CALLT"
2373     ;; The CALLT instruction stores the next address of CALLT to CTPC register
2374     ;; without saving its previous value.  So if the interrupt handler
2375     ;; or its caller could possibly execute the CALLT insn, save_interrupt 
2376     ;; MUST NOT be called via CALLT.
2377     "*
2378 {
2379   output_asm_insn (\"addi -28,   sp, sp\", operands);
2380   output_asm_insn (\"st.w r1,    24[sp]\", operands);
2381   output_asm_insn (\"st.w r10,   12[sp]\", operands);
2382   output_asm_insn (\"st.w r11,   16[sp]\", operands);
2383   output_asm_insn (\"stsr ctpc,  r10\",    operands);
2384   output_asm_insn (\"st.w r10,   20[sp]\", operands);
2385   output_asm_insn (\"stsr ctpsw, r10\",    operands);
2386   output_asm_insn (\"st.w r10,   24[sp]\", operands);
2387   output_asm_insn (\"callt ctoff(__callt_save_interrupt)\", operands);
2388   return \"\";
2389 }"
2390    [(set_attr "length" "26")
2391     (set_attr "cc" "clobber")])
2392
2393 (define_insn "callt_return_interrupt"
2394   [(unspec_volatile [(const_int 0)] 3)]
2395   "(TARGET_V850E || TARGET_V850E2_ALL) && !TARGET_DISABLE_CALLT"
2396   "callt ctoff(__callt_return_interrupt)"
2397   [(set_attr "length" "2")
2398    (set_attr "cc" "clobber")])
2399
2400 (define_insn "save_interrupt"
2401   [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -20)))
2402    (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 30))
2403    (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 4))
2404    (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))
2405    (set (mem:SI (plus:SI (reg:SI 3) (const_int  -8))) (reg:SI 10))
2406    (set (mem:SI (plus:SI (reg:SI 3) (const_int  -4))) (reg:SI 11))]
2407   ""
2408   "*
2409 {
2410   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2411     return \"addi -20,sp,sp \; st.w r11,16[sp] \; st.w r10,12[sp] \; jarl __save_interrupt,r10\";
2412   else
2413     {
2414       output_asm_insn (\"addi  -20, sp, sp\", operands);
2415       output_asm_insn (\"st.w  r11, 16[sp]\", operands);
2416       output_asm_insn (\"st.w  r10, 12[sp]\", operands);
2417       output_asm_insn (\"st.w  ep, 0[sp]\", operands);
2418       output_asm_insn (\"st.w  gp, 4[sp]\", operands);
2419       output_asm_insn (\"st.w  r1, 8[sp]\", operands);
2420       output_asm_insn (\"movhi hi(__ep), r0, ep\", operands);
2421       output_asm_insn (\"movea lo(__ep), ep, ep\", operands);
2422       output_asm_insn (\"movhi hi(__gp), r0, gp\", operands);
2423       output_asm_insn (\"movea lo(__gp), gp, gp\", operands);
2424       return \"\";
2425     }
2426 }"
2427   [(set (attr "length")
2428         (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
2429                        (const_int 10)
2430                        (const_int 34)))
2431    (set_attr "cc" "clobber")])
2432   
2433 ;; Restore r1, r4, r10, and return from the interrupt
2434 (define_insn "return_interrupt"
2435   [(return)
2436    (set (reg:SI 3)  (plus:SI (reg:SI 3) (const_int 20)))
2437    (set (reg:SI 11) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))
2438    (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
2439    (set (reg:SI 1)  (mem:SI (plus:SI (reg:SI 3) (const_int  8))))
2440    (set (reg:SI 4)  (mem:SI (plus:SI (reg:SI 3) (const_int  4))))
2441    (set (reg:SI 30) (mem:SI (reg:SI 3)))]
2442   ""
2443   "*
2444 {
2445   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2446     return \"jr __return_interrupt\";
2447   else 
2448     {
2449       output_asm_insn (\"ld.w 0[sp],  ep\",   operands);
2450       output_asm_insn (\"ld.w 4[sp],  gp\",   operands);
2451       output_asm_insn (\"ld.w 8[sp],  r1\",   operands);
2452       output_asm_insn (\"ld.w 12[sp], r10\", operands);
2453       output_asm_insn (\"ld.w 16[sp], r11\", operands);
2454       output_asm_insn (\"addi 20, sp, sp\",   operands);
2455       output_asm_insn (\"reti\",            operands);
2456       return \"\";
2457     }
2458 }"
2459   [(set (attr "length")
2460         (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
2461                        (const_int 4)
2462                        (const_int 24)))
2463    (set_attr "cc" "clobber")])
2464
2465 ;; Save all registers except for the registers saved in save_interrupt when
2466 ;; an interrupt function makes a call.
2467 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2468 ;; all of memory.  This blocks insns from being moved across this point.
2469 ;; This is needed because the rest of the compiler is not ready to handle
2470 ;; insns this complicated.
2471
2472 (define_insn "callt_save_all_interrupt"
2473   [(unspec_volatile [(const_int 0)] 0)]
2474   "(TARGET_V850E || TARGET_V850E2_ALL) && !TARGET_DISABLE_CALLT"
2475   "callt ctoff(__callt_save_all_interrupt)"
2476   [(set_attr "length" "2")
2477    (set_attr "cc" "none")])
2478
2479 (define_insn "save_all_interrupt"
2480   [(unspec_volatile [(const_int 0)] 0)]
2481   ""
2482   "*
2483 {
2484   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2485     return \"jarl __save_all_interrupt,r10\";
2486
2487   output_asm_insn (\"addi -120, sp, sp\", operands);
2488
2489   if (TARGET_EP)
2490     {
2491       output_asm_insn (\"mov ep, r1\", operands);
2492       output_asm_insn (\"mov sp, ep\", operands);
2493       output_asm_insn (\"sst.w r31, 116[ep]\", operands);
2494       output_asm_insn (\"sst.w r2,  112[ep]\", operands);
2495       output_asm_insn (\"sst.w gp,  108[ep]\", operands);
2496       output_asm_insn (\"sst.w r6,  104[ep]\", operands);
2497       output_asm_insn (\"sst.w r7,  100[ep]\", operands);
2498       output_asm_insn (\"sst.w r8,   96[ep]\", operands);
2499       output_asm_insn (\"sst.w r9,   92[ep]\", operands);
2500       output_asm_insn (\"sst.w r11,  88[ep]\", operands);
2501       output_asm_insn (\"sst.w r12,  84[ep]\", operands);
2502       output_asm_insn (\"sst.w r13,  80[ep]\", operands);
2503       output_asm_insn (\"sst.w r14,  76[ep]\", operands);
2504       output_asm_insn (\"sst.w r15,  72[ep]\", operands);
2505       output_asm_insn (\"sst.w r16,  68[ep]\", operands);
2506       output_asm_insn (\"sst.w r17,  64[ep]\", operands);
2507       output_asm_insn (\"sst.w r18,  60[ep]\", operands);
2508       output_asm_insn (\"sst.w r19,  56[ep]\", operands);
2509       output_asm_insn (\"sst.w r20,  52[ep]\", operands);
2510       output_asm_insn (\"sst.w r21,  48[ep]\", operands);
2511       output_asm_insn (\"sst.w r22,  44[ep]\", operands);
2512       output_asm_insn (\"sst.w r23,  40[ep]\", operands);
2513       output_asm_insn (\"sst.w r24,  36[ep]\", operands);
2514       output_asm_insn (\"sst.w r25,  32[ep]\", operands);
2515       output_asm_insn (\"sst.w r26,  28[ep]\", operands);
2516       output_asm_insn (\"sst.w r27,  24[ep]\", operands);
2517       output_asm_insn (\"sst.w r28,  20[ep]\", operands);
2518       output_asm_insn (\"sst.w r29,  16[ep]\", operands);
2519       output_asm_insn (\"mov   r1,   ep\", operands);
2520     }
2521   else
2522     {
2523       output_asm_insn (\"st.w r31, 116[sp]\", operands);
2524       output_asm_insn (\"st.w r2,  112[sp]\", operands);
2525       output_asm_insn (\"st.w gp,  108[sp]\", operands);
2526       output_asm_insn (\"st.w r6,  104[sp]\", operands);
2527       output_asm_insn (\"st.w r7,  100[sp]\", operands);
2528       output_asm_insn (\"st.w r8,   96[sp]\", operands);
2529       output_asm_insn (\"st.w r9,   92[sp]\", operands);
2530       output_asm_insn (\"st.w r11,  88[sp]\", operands);
2531       output_asm_insn (\"st.w r12,  84[sp]\", operands);
2532       output_asm_insn (\"st.w r13,  80[sp]\", operands);
2533       output_asm_insn (\"st.w r14,  76[sp]\", operands);
2534       output_asm_insn (\"st.w r15,  72[sp]\", operands);
2535       output_asm_insn (\"st.w r16,  68[sp]\", operands);
2536       output_asm_insn (\"st.w r17,  64[sp]\", operands);
2537       output_asm_insn (\"st.w r18,  60[sp]\", operands);
2538       output_asm_insn (\"st.w r19,  56[sp]\", operands);
2539       output_asm_insn (\"st.w r20,  52[sp]\", operands);
2540       output_asm_insn (\"st.w r21,  48[sp]\", operands);
2541       output_asm_insn (\"st.w r22,  44[sp]\", operands);
2542       output_asm_insn (\"st.w r23,  40[sp]\", operands);
2543       output_asm_insn (\"st.w r24,  36[sp]\", operands);
2544       output_asm_insn (\"st.w r25,  32[sp]\", operands);
2545       output_asm_insn (\"st.w r26,  28[sp]\", operands);
2546       output_asm_insn (\"st.w r27,  24[sp]\", operands);
2547       output_asm_insn (\"st.w r28,  20[sp]\", operands);
2548       output_asm_insn (\"st.w r29,  16[sp]\", operands);
2549     }
2550     
2551   return \"\";
2552 }"
2553   [(set (attr "length")
2554         (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
2555                        (const_int 4)
2556                        (const_int 62)
2557         ))
2558    (set_attr "cc" "clobber")])
2559
2560 (define_insn "_save_all_interrupt"
2561   [(unspec_volatile [(const_int 0)] 0)]
2562   "TARGET_V850 && ! TARGET_LONG_CALLS"
2563   "jarl __save_all_interrupt,r10"
2564   [(set_attr "length" "4")
2565    (set_attr "cc" "clobber")])
2566
2567 ;; Restore all registers saved when an interrupt function makes a call.
2568 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2569 ;; all of memory.  This blocks insns from being moved across this point.
2570 ;; This is needed because the rest of the compiler is not ready to handle
2571 ;; insns this complicated.
2572
2573 (define_insn "callt_restore_all_interrupt"
2574   [(unspec_volatile [(const_int 0)] 1)]
2575   "(TARGET_V850E || TARGET_V850E2_ALL) && !TARGET_DISABLE_CALLT"
2576   "callt ctoff(__callt_restore_all_interrupt)"
2577   [(set_attr "length" "2")
2578    (set_attr "cc" "none")])
2579
2580 (define_insn "restore_all_interrupt"
2581   [(unspec_volatile [(const_int 0)] 1)]
2582   ""
2583   "*
2584 {
2585   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2586     return \"jarl __restore_all_interrupt,r10\";
2587
2588   if (TARGET_EP)
2589     {
2590       output_asm_insn (\"mov   ep,      r1\", operands);
2591       output_asm_insn (\"mov   sp,      ep\", operands);
2592       output_asm_insn (\"sld.w 116[ep], r31\", operands);
2593       output_asm_insn (\"sld.w 112[ep], r2\", operands);
2594       output_asm_insn (\"sld.w 108[ep], gp\", operands);
2595       output_asm_insn (\"sld.w 104[ep], r6\", operands);
2596       output_asm_insn (\"sld.w 100[ep], r7\", operands);
2597       output_asm_insn (\"sld.w 96[ep],  r8\", operands);
2598       output_asm_insn (\"sld.w 92[ep],  r9\", operands);
2599       output_asm_insn (\"sld.w 88[ep],  r11\", operands);
2600       output_asm_insn (\"sld.w 84[ep],  r12\", operands);
2601       output_asm_insn (\"sld.w 80[ep],  r13\", operands);
2602       output_asm_insn (\"sld.w 76[ep],  r14\", operands);
2603       output_asm_insn (\"sld.w 72[ep],  r15\", operands);
2604       output_asm_insn (\"sld.w 68[ep],  r16\", operands);
2605       output_asm_insn (\"sld.w 64[ep],  r17\", operands);
2606       output_asm_insn (\"sld.w 60[ep],  r18\", operands);
2607       output_asm_insn (\"sld.w 56[ep],  r19\", operands);
2608       output_asm_insn (\"sld.w 52[ep],  r20\", operands);
2609       output_asm_insn (\"sld.w 48[ep],  r21\", operands);
2610       output_asm_insn (\"sld.w 44[ep],  r22\", operands);
2611       output_asm_insn (\"sld.w 40[ep],  r23\", operands);
2612       output_asm_insn (\"sld.w 36[ep],  r24\", operands);
2613       output_asm_insn (\"sld.w 32[ep],  r25\", operands);
2614       output_asm_insn (\"sld.w 28[ep],  r26\", operands);
2615       output_asm_insn (\"sld.w 24[ep],  r27\", operands);
2616       output_asm_insn (\"sld.w 20[ep],  r28\", operands);
2617       output_asm_insn (\"sld.w 16[ep],  r29\", operands);
2618       output_asm_insn (\"mov   r1,      ep\", operands);
2619     }
2620   else
2621     {
2622       output_asm_insn (\"ld.w 116[sp], r31\", operands);
2623       output_asm_insn (\"ld.w 112[sp], r2\", operands);
2624       output_asm_insn (\"ld.w 108[sp], gp\", operands);
2625       output_asm_insn (\"ld.w 104[sp], r6\", operands);
2626       output_asm_insn (\"ld.w 100[sp], r7\", operands);
2627       output_asm_insn (\"ld.w 96[sp],  r8\", operands);
2628       output_asm_insn (\"ld.w 92[sp],  r9\", operands);
2629       output_asm_insn (\"ld.w 88[sp],  r11\", operands);
2630       output_asm_insn (\"ld.w 84[sp],  r12\", operands);
2631       output_asm_insn (\"ld.w 80[sp],  r13\", operands);
2632       output_asm_insn (\"ld.w 76[sp],  r14\", operands);
2633       output_asm_insn (\"ld.w 72[sp],  r15\", operands);
2634       output_asm_insn (\"ld.w 68[sp],  r16\", operands);
2635       output_asm_insn (\"ld.w 64[sp],  r17\", operands);
2636       output_asm_insn (\"ld.w 60[sp],  r18\", operands);
2637       output_asm_insn (\"ld.w 56[sp],  r19\", operands);
2638       output_asm_insn (\"ld.w 52[sp],  r20\", operands);
2639       output_asm_insn (\"ld.w 48[sp],  r21\", operands);
2640       output_asm_insn (\"ld.w 44[sp],  r22\", operands);
2641       output_asm_insn (\"ld.w 40[sp],  r23\", operands);
2642       output_asm_insn (\"ld.w 36[sp],  r24\", operands);
2643       output_asm_insn (\"ld.w 32[sp],  r25\", operands);
2644       output_asm_insn (\"ld.w 28[sp],  r26\", operands);
2645       output_asm_insn (\"ld.w 24[sp],  r27\", operands);
2646       output_asm_insn (\"ld.w 20[sp],  r28\", operands);
2647       output_asm_insn (\"ld.w 16[sp],  r29\", operands);
2648     }
2649   output_asm_insn (\"addi  120, sp, sp\", operands);
2650   return \"\";
2651 }"
2652   [(set (attr "length")
2653         (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
2654                        (const_int 4)
2655                        (const_int 62)
2656         ))
2657    (set_attr "cc" "clobber")])
2658
2659 (define_insn "_restore_all_interrupt"
2660   [(unspec_volatile [(const_int 0)] 1)]
2661   "TARGET_V850 && ! TARGET_LONG_CALLS"
2662   "jarl __restore_all_interrupt,r10"
2663   [(set_attr "length" "4")
2664    (set_attr "cc" "clobber")])
2665
2666