Merged revisions 195034,195219,195245,195357,195374,195428,195599,195673,195809 via...
[official-gcc.git] / main / gcc / config / v850 / v850.md
blob4ed0e40b05fb065f6a89449bf73b5df6f130bd11
1 ;; GCC machine description for NEC V850
2 ;; Copyright (C) 1996-2013 Free Software Foundation, Inc.
3 ;; Contributed by Jeff Law (law@cygnus.com).
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;; The original PO technology requires these to be ordered by speed,
22 ;; so that assigner will pick the fastest.
24 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;; The V851 manual states that the instruction address space is 16M;
27 ;; the various branch/call instructions only have a 22bit offset (4M range).
29 ;; One day we'll probably need to handle calls to targets more than 4M
30 ;; away.
32 ;; The size of instructions in bytes.
34 ;;---------------------------------------------------------------------------
35 ;; Constants
38 (define_constants
39   [(ZERO_REGNUM                 0)          ; constant zero
40    (SP_REGNUM                   3)          ; Stack Pointer
41    (GP_REGNUM                   4)          ; GP Pointer
42    (EP_REGNUM                   30)         ; EP pointer
43    (LP_REGNUM                   31)         ; Return address register
44    (CC_REGNUM                   32)         ; Condition code pseudo register
45    (FCC_REGNUM                  33)         ; Floating Condition code pseudo register
46    (UNSPEC_LOOP                200)         ; loop counter
47   ]
50 (define_attr "length" ""
51   (const_int 4))
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).
60 (define_attr "type" "load,store,bit1,mult,macc,div,fpu,single,other"
61   (const_string "other"))
63 (define_attr "cpu" "none,v850,v850e,v850e1,v850e2,v850e2v3,v850e3v5"
64   (cond [(match_test "TARGET_V850")
65          (const_string "v850")
66          (match_test "TARGET_V850E")
67          (const_string "v850e")
68          (match_test "TARGET_V850E1")
69          (const_string "v850e1")
70          (match_test "TARGET_V850E2")
71          (const_string "v850e2")
72          (match_test "TARGET_V850E2V3")
73          (const_string "v850e2v3")
74          (match_test "TARGET_V850E3V5")
75          (const_string "v850e3v5")]      
76          (const_string "none")))
78 ;; Condition code settings.
79 ;; none - insn does not affect cc
80 ;; none_0hit - insn does not affect cc but it does modify operand 0
81 ;;      This attribute is used to keep track of when operand 0 changes.
82 ;;      See the description of NOTICE_UPDATE_CC for more info.
83 ;; set_znv - sets z,n,v to usable values; c is unknown.
84 ;; set_zn  - sets z,n to usable values; v,c is unknown.
85 ;; compare - compare instruction
86 ;; clobber - value of cc is unknown
87 (define_attr "cc" "none,none_0hit,set_z,set_zn,set_znv,compare,clobber"
88   (const_string "clobber"))
90 ;; Function units for the V850.  As best as I can tell, there's
91 ;; a traditional memory load/use stall as well as a stall if
92 ;; the result of a multiply is used too early.
94 (define_insn_reservation "v850_other" 1
95                          (eq_attr "type" "other")
96                          "nothing")
97 (define_insn_reservation "v850_mult" 2
98                          (eq_attr "type" "mult")
99                          "nothing")
100 (define_insn_reservation "v850_memory" 2
101                          (eq_attr "type" "load")
102                          "nothing")
104 (include "predicates.md")
105 (include "constraints.md")
107 ;; ----------------------------------------------------------------------
108 ;; MOVE INSTRUCTIONS
109 ;; ----------------------------------------------------------------------
110 (define_insn "sign23byte_load"
111   [(set (match_operand:SI 0 "register_operand" "=r")
112         (sign_extend:SI
113         (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
114                          (match_operand 2 "disp23_operand" "W")))))]
115   "TARGET_V850E2V3_UP"
116   "ld.b %2[%1],%0"
117   [(set_attr "length" "4")
118    (set_attr "cc" "none_0hit")])
119   
120 (define_insn "unsign23byte_load"
121   [(set (match_operand:SI 0 "register_operand" "=r")
122         (zero_extend:SI
123         (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
124                          (match_operand 2 "disp23_operand" "W")))))]
125   "TARGET_V850E2V3_UP"
126   "ld.bu %2[%1],%0"
127   [(set_attr "length" "4")
128    (set_attr "cc" "none_0hit")])
130 (define_insn "sign23hword_load"
131   [(set (match_operand:SI 0 "register_operand" "=r")
132         (sign_extend:SI
133         (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
134                          (match_operand 2 "disp23_operand" "W")))))]
135   "TARGET_V850E2V3_UP"
136   "ld.h %2[%1],%0"
137   [(set_attr "length" "4")
138    (set_attr "cc" "none_0hit")])
140 (define_insn "unsign23hword_load"
141   [(set (match_operand:SI 0 "register_operand" "=r")
142         (zero_extend:SI
143         (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
144                          (match_operand 2 "disp23_operand" "W")))))]
145   "TARGET_V850E2V3_UP"
146   "ld.hu %2[%1],%0"
147   [(set_attr "length" "4")
148    (set_attr "cc" "none_0hit")])
150 (define_insn "23word_load"
151   [(set (match_operand:SI 0 "register_operand" "=r")
152         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
153                          (match_operand 2 "disp23_operand" "W"))))]
154   "TARGET_V850E2V3_UP"
155   "ld.w %2[%1],%0"
156   [(set_attr "length" "4")
157    (set_attr "cc" "none_0hit")])
159 (define_insn "23byte_store"
160   [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "r")
161                          (match_operand 1 "disp23_operand" "W")))
162         (match_operand:QI 2 "register_operand" "r"))]
163   "TARGET_V850E2V3_UP"
164   "st.b %2,%1[%0]"
165   [(set_attr "length" "4")
166    (set_attr "cc" "none_0hit")])
168 (define_insn "23hword_store"
169   [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "r")
170                          (match_operand 1 "disp23_operand" "W")))
171         (match_operand:HI 2 "register_operand" "r"))]
172   "TARGET_V850E2V3_UP"
173   "st.h %2,%1[%0]"
174   [(set_attr "length" "4")
175    (set_attr "cc" "none_0hit")])
177 (define_insn "23word_store"
178   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
179                          (match_operand 1 "disp23_operand" "W")))
180         (match_operand:SI 2 "register_operand" "r"))]
181   "TARGET_V850E2V3_UP"
182   "st.w %2,%1[%0]"
183   [(set_attr "length" "4")
184    (set_attr "cc" "none_0hit")])
186 ;; movdi
188 (define_expand "movdi"
189   [(set (match_operand:DI 0 "general_operand")
190         (match_operand:DI 1 "general_operand"))]
191   "TARGET_V850E3V5_UP"
192   {
193     /* One of the ops has to be in a register or 0.  */
194     if (!register_operand (operand0, DImode)
195         && !register_operand (operand1, DImode))
196       operands[1] = copy_to_mode_reg (DImode, operand1);
198     if (register_operand (operand0, DImode)
199         && (CONST_INT_P (operands[1]) || CONST_DOUBLE_P (operands[1])))
200       {
201         int i;
203         for (i = 0; i < UNITS_PER_WORD * 2; i += UNITS_PER_WORD)
204           emit_move_insn (simplify_gen_subreg (SImode, operands[0], DImode, i),
205                           simplify_gen_subreg (SImode, operands[1], DImode, i));
206         DONE;
207       }
208   }
211 (define_insn "*movdi_internal"
212   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,e!r,m")
213         (match_operand:DI 1 "nonimmediate_operand"  "r,m,e!r"))]
214   "TARGET_V850E3V5_UP
215    || (register_operand (operands[0], DImode) && register_operand (operands[1], DImode))"
216   { return v850_gen_movdi (operands); }
217   [(set_attr "length" "4,12,12")
218    (set_attr "cc" "none_0hit")
219    (set_attr "type" "other,load,store")]
222 ;; movqi
224 (define_expand "movqi"
225   [(set (match_operand:QI 0 "general_operand" "")
226         (match_operand:QI 1 "general_operand" ""))]
227   ""
228   {
229     /* One of the ops has to be in a register or 0 */
230     if (!register_operand (operand0, QImode)
231         && !reg_or_0_operand (operand1, QImode))
232       operands[1] = copy_to_mode_reg (QImode, operand1);
233   })
235 (define_insn "*movqi_internal"
236   [(set (match_operand:QI 0 "general_operand" "=r,r,r,Q,r,m,m")
237         (match_operand:QI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
238   "register_operand (operands[0], QImode)
239    || reg_or_0_operand (operands[1], QImode)"
241   return output_move_single (operands);
243   [(set_attr "length" "2,4,2,2,4,4,4")
244    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
245    (set_attr "type" "other,other,load,other,load,store,store")])
247 ;; movhi
249 (define_expand "movhi"
250   [(set (match_operand:HI 0 "general_operand" "")
251         (match_operand:HI 1 "general_operand" ""))]
252   ""
254   /* One of the ops has to be in a register or 0 */
255   if (!register_operand (operand0, HImode)
256       && !reg_or_0_operand (operand1, HImode))
257     operands[1] = copy_to_mode_reg (HImode, operand1);
260 (define_insn "*movhi_internal"
261   [(set (match_operand:HI 0 "general_operand" "=r,r,r,Q,r,m,m")
262         (match_operand:HI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
263   "register_operand (operands[0], HImode)
264    || reg_or_0_operand (operands[1], HImode)"
266   return output_move_single (operands);
268   [(set_attr "length" "2,4,2,2,4,4,4")
269    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
270    (set_attr "type" "other,other,load,other,load,store,store")])
272 ;; movsi and helpers
274 (define_insn "*movsi_high"
275   [(set (match_operand:SI 0 "register_operand" "=r")
276         (high:SI (match_operand 1 "immediate_operand" "i")))]
277   ""
278   "movhi hi(%1),%.,%0"
279   [(set_attr "length" "4")
280    (set_attr "cc" "none_0hit")
281    (set_attr "type" "other")])
283 (define_insn "*movsi_lo"
284   [(set (match_operand:SI 0 "register_operand" "=r")
285         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
286                    (match_operand:SI 2 "immediate_operand" "i")))]
287   ""
288   "movea lo(%2),%1,%0"
289   [(set_attr "length" "4")
290    (set_attr "cc" "none_0hit")
291    (set_attr "type" "other")])
293 (define_expand "movsi"
294   [(set (match_operand:SI 0 "general_operand" "")
295         (match_operand:SI 1 "general_operand" ""))]
296   ""
297   {
298     /* One of the ops has to be in a register or 0 */
299     if (!register_operand (operand0, SImode)
300         && !reg_or_0_operand (operand1, SImode))
301       operands[1] = copy_to_mode_reg (SImode, operand1);
303     /* Some constants, as well as symbolic operands
304        must be done with HIGH & LO_SUM patterns.  */
305     if (CONSTANT_P (operands[1])        
306         && GET_CODE (operands[1]) != HIGH
307         && ! (TARGET_V850E_UP)
308         && !special_symbolref_operand (operands[1], VOIDmode)
309         && !(GET_CODE (operands[1]) == CONST_INT
310              && (CONST_OK_FOR_J (INTVAL (operands[1]))
311                  || CONST_OK_FOR_K (INTVAL (operands[1]))
312                  || CONST_OK_FOR_L (INTVAL (operands[1])))))
313       {
314         rtx temp;
316         if (reload_in_progress || reload_completed)
317           temp = operands[0];
318         else
319           temp = gen_reg_rtx (SImode);
321         emit_insn (gen_rtx_SET (SImode, temp,
322                                 gen_rtx_HIGH (SImode, operand1)));
323         emit_insn (gen_rtx_SET (SImode, operand0,
324                                 gen_rtx_LO_SUM (SImode, temp, operand1)));
325         DONE;
326       }
327   })
329 ;; This is the same as the following pattern, except that it includes
330 ;; support for arbitrary 32-bit immediates.
332 ;; ??? This always loads addresses using hilo.  If the only use of this address
333 ;; was in a load/store, then we would get smaller code if we only loaded the
334 ;; upper part with hi, and then put the lower part in the load/store insn.
336 (define_insn "*movsi_internal_v850e"
337   [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m,r")
338         (match_operand:SI 1 "general_operand" "Jr,K,L,Q,Ir,m,R,r,I,i"))]
339   "(TARGET_V850E_UP)
340    && (register_operand (operands[0], SImode)
341        || reg_or_0_operand (operands[1], SImode))"
343   return output_move_single (operands);
345   [(set_attr "length" "2,4,4,2,2,4,4,4,4,6")
346    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
347    (set_attr "type" "other,other,other,load,other,load,other,store,store,other")])
349 (define_insn "*movsi_internal"
350   [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m")
351         (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))]
352   "register_operand (operands[0], SImode)
353    || reg_or_0_operand (operands[1], SImode)"
355   return output_move_single (operands);
357   [(set_attr "length" "2,4,4,2,2,4,4,4,4")
358    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
359    (set_attr "type" "other,other,other,load,other,load,store,store,other")])
361 (define_insn "*movsf_internal"
362   [(set (match_operand:SF 0 "general_operand" "=r,r,r,r,r,Q,r,m,m,r")
363         (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))]
364   "register_operand (operands[0], SFmode)
365    || reg_or_0_operand (operands[1], SFmode)"
367   return output_move_single (operands);
369   [(set_attr "length" "2,4,4,8,2,2,4,4,4,8")
370    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
371    (set_attr "type" "other,other,other,other,load,other,load,store,store,other")])
373 ;; ----------------------------------------------------------------------
374 ;; TEST INSTRUCTIONS
375 ;; ----------------------------------------------------------------------
377 (define_insn "*v850_tst1"
378   [(set (cc0)
379         (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
380                                   (const_int 1)
381                                   (match_operand:QI 1 "const_int_operand" "n"))
382                  (const_int 0)))]
383   ""
384   "tst1 %1,%0"
385   [(set_attr "length" "4")
386    (set_attr "cc" "clobber")])
388 ;; This replaces ld.b;sar;andi with tst1;setf nz.
390 (define_split
391   [(set (match_operand:SI 0 "register_operand" "")
392         (compare (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
393                                   (const_int 1)
394                                   (match_operand 2 "const_int_operand" ""))
395                  (const_int 0)))]
396   ""
397   [(set (cc0) (compare (zero_extract:SI (match_dup 1)
398                                         (const_int 1)
399                                         (match_dup 2))
400                        (const_int 0)))
401    (set (match_dup 0) (ne:SI (cc0) (const_int 0)))])
403 (define_expand "cbranchsi4"
404   [(set (cc0)
405         (compare (match_operand:SI 1 "register_operand" "")
406                  (match_operand:SI 2 "reg_or_int5_operand" "")))
407    (set (pc)
408         (if_then_else
409               (match_operator 0 "ordered_comparison_operator" [(cc0)
410                                                                (const_int 0)])
411               (label_ref (match_operand 3 "" ""))
412               (pc)))]
413  "")
415 (define_expand "cstoresi4"
416   [(set (cc0)
417         (compare (match_operand:SI 2 "register_operand" "")
418                  (match_operand:SI 3 "reg_or_int5_operand" "")))
419    (set (match_operand:SI 0 "register_operand")
420         (match_operator:SI 1 "ordered_comparison_operator" [(cc0)
421                                                             (const_int 0)]))]
422   "")
424 (define_expand "cmpsi"
425   [(set (cc0)
426         (compare (match_operand:SI 0 "register_operand" "r,r")
427                  (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
428    ""
429   {
430     v850_compare_op0 = operands[0];
431     v850_compare_op1 = operands[1];
432     DONE;
433   })
435 (define_insn "cmpsi_insn"
436   [(set (cc0)
437         (compare (match_operand:SI 0 "register_operand" "r,r")
438                  (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
439   ""
440   "@
441   cmp %1,%0
442   cmp %1,%0"
443   [(set_attr "length" "2,2")
444    (set_attr "cc" "compare")])
446 (define_expand "cbranchsf4"
447   [(set (pc)
448        (if_then_else (match_operator     0 "ordered_comparison_operator"
449                       [(match_operand:SF 1 "register_operand")
450                        (match_operand:SF 2 "register_operand")])
451                      (label_ref (match_operand 3 ""))
452                      (pc)))
453   (clobber (cc0))]
454   "TARGET_USE_FPU"
456   enum rtx_code cond = GET_CODE (operands[0]);
457   enum machine_mode mode;
458   rtx fcc_reg;
459   rtx cc_reg;
460   rtx tmp;
462   v850_compare_op0 = operands[1];
463   v850_compare_op1 = operands[2];
465   if (GET_MODE_CLASS (GET_MODE (v850_compare_op0)) != MODE_FLOAT)
466     FAIL;
468   mode = v850_gen_float_compare (cond, VOIDmode, v850_compare_op0, v850_compare_op1);
469   fcc_reg = gen_rtx_REG (mode, FCC_REGNUM);
470   cc_reg = gen_rtx_REG (mode, CC_REGNUM);
471   emit_insn(gen_rtx_SET (mode, cc_reg, fcc_reg));
472   tmp = gen_rtx_fmt_ee (cond, mode, cc_reg, const0_rtx);
473   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
474                               gen_rtx_LABEL_REF (VOIDmode, operands[3]), pc_rtx);
475   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
476   DONE;
479 (define_insn "cstoresf4"
480   [(set (match_operand:SI   0 "register_operand" "=r")
481         (match_operator:SI  1 "ordered_comparison_operator"
482          [(match_operand:SF 2 "register_operand" "r")
483           (match_operand:SF 3 "register_operand" "r")]))]
484   "TARGET_USE_FPU"
486   if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
487     return "cmpf.s %c1, %z2, %z3 ; trfsr ; setf nz, %0";
488   if (GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE)
489     return "cmpf.s %c1, %z2, %z3 ; trfsr ; setf z, %0";
490   if (GET_CODE (operands[1]) == EQ)
491     return "cmpf.s eq, %z2, %z3 ; trfsr ; setf z, %0";
492   if (GET_CODE (operands[1]) == NE)
493     return "cmpf.s neq, %z2, %z3 ; trfsr ; setf nz, %0";
494   gcc_unreachable ();
496   [(set_attr "length" "12")
497    (set_attr "type" "fpu")]
500 (define_expand "cbranchdf4"
501   [(set (pc)
502        (if_then_else (match_operator     0 "ordered_comparison_operator"
503                       [(match_operand:DF 1 "even_reg_operand")
504                        (match_operand:DF 2 "even_reg_operand")])
505                      (label_ref (match_operand 3 ""))
506                      (pc)))
507   (clobber (cc0))]
508   "TARGET_USE_FPU"
510   enum rtx_code cond = GET_CODE (operands[0]);
511   enum machine_mode mode;
512   rtx fcc_reg;
513   rtx cc_reg;
514   rtx tmp;
516     v850_compare_op0 = operands[1];
517     v850_compare_op1 = operands[2];
519   if (GET_MODE_CLASS (GET_MODE (v850_compare_op0)) != MODE_FLOAT)
520     FAIL;
522   mode = v850_gen_float_compare (cond, VOIDmode, v850_compare_op0, v850_compare_op1);
523   fcc_reg = gen_rtx_REG (mode, FCC_REGNUM);
524   cc_reg = gen_rtx_REG (mode, CC_REGNUM);
525   emit_insn(gen_rtx_SET (mode, cc_reg, fcc_reg));
526   tmp = gen_rtx_fmt_ee (cond, mode, cc_reg, const0_rtx);
527   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
528                               gen_rtx_LABEL_REF (VOIDmode, operands[3]), pc_rtx);
529   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
530   DONE;
533 (define_insn "cstoredf4"
534   [(set (match_operand:SI   0 "register_operand" "=r")
535         (match_operator:SI  1 "ordered_comparison_operator"
536          [(match_operand:DF 2 "even_reg_operand"  "r")
537           (match_operand:DF 3 "even_reg_operand" "r")]))]
538   "TARGET_USE_FPU"
540   if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
541     return "cmpf.d %c1, %z2, %z3 ; trfsr ; setf nz, %0";
542   if (GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE)
543     return "cmpf.d %c1, %z2, %z3 ; trfsr ; setf z, %0";
544   if (GET_CODE (operands[1]) == EQ)
545     return "cmpf.d eq, %z2, %z3 ; trfsr ; setf z ,%0";
546   if (GET_CODE (operands[1]) == NE)
547     return "cmpf.d neq, %z2, %z3 ; trfsr ; setf nz, %0";
548   gcc_unreachable ();
550   [(set_attr "length" "12")
551    (set_attr "type" "fpu")]
554 (define_expand "cmpsf"
555   [(set (reg:CC CC_REGNUM)
556         (compare (match_operand:SF 0 "register_operand" "r")
557                  (match_operand:SF 1 "register_operand" "r")))]
558   "TARGET_USE_FPU"
559   {
560     v850_compare_op0 = operands[0];
561     v850_compare_op1 = operands[1];
562     DONE;
563   })
565 (define_expand "cmpdf"
566   [(set (reg:CC CC_REGNUM)
567         (compare (match_operand:DF 0 "even_reg_operand" "r")
568                  (match_operand:DF 1 "even_reg_operand" "r")))]
569   "TARGET_USE_FPU"
570   {
571     v850_compare_op0 = operands[0];
572     v850_compare_op1 = operands[1];
573     DONE;
574   })
576 ;; ----------------------------------------------------------------------
577 ;; ADD INSTRUCTIONS
578 ;; ----------------------------------------------------------------------
580 (define_insn "addsi3"
581   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
582         (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
583                  (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))
584    (clobber (reg:CC CC_REGNUM))]
586   ""
587   "@
588    add %2,%0
589    addi %2,%1,%0
590    addi %O2(%P2),%1,%0"
591   [(set_attr "length" "2,4,4")
592    (set_attr "cc" "set_zn,set_zn,set_zn")])
594 ;; ----------------------------------------------------------------------
595 ;; SUBTRACT INSTRUCTIONS
596 ;; ----------------------------------------------------------------------
598 (define_insn "subsi3"
599   [(set (match_operand:SI 0 "register_operand" "=r,r")
600         (minus:SI (match_operand:SI 1 "register_operand" "0,r")
601                   (match_operand:SI 2 "register_operand" "r,0")))
602    (clobber (reg:CC CC_REGNUM))]
603   ""
604   "@
605   sub %2,%0
606   subr %1,%0"
607   [(set_attr "length" "2,2")
608    (set_attr "cc" "set_zn,set_zn")])
610 (define_insn "negsi2"
611   [(set (match_operand:SI 0 "register_operand" "=r")
612         (neg:SI (match_operand:SI 1 "register_operand" "0")))
613    (clobber (reg:CC CC_REGNUM))]
614   ""
615   "subr %.,%0"
616   [(set_attr "length" "2")
617    (set_attr "cc" "set_zn")])
619 ;; ----------------------------------------------------------------------
620 ;; MULTIPLY INSTRUCTIONS
621 ;; ----------------------------------------------------------------------
623 (define_expand "mulhisi3"
624   [(set (match_operand:SI 0 "register_operand" "")
625         (mult:SI
626           (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
627           (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
628   ""
629   {
630     if (GET_CODE (operands[2]) == CONST_INT)
631       {
632         emit_insn (gen_mulhisi3_internal2 (operands[0], operands[1], operands[2]));
633         DONE;
634       }
635   })
637 (define_insn "*mulhisi3_internal1"
638   [(set (match_operand:SI 0 "register_operand" "=r")
639         (mult:SI
640           (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
641           (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
642   ""
643   "mulh %2,%0"
644   [(set_attr "length" "2")
645    (set_attr "cc" "none_0hit")
646    (set_attr "type" "mult")])
648 (define_insn "mulhisi3_internal2"
649   [(set (match_operand:SI 0 "register_operand" "=r,r")
650         (mult:SI
651           (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
652           (match_operand:HI 2 "const_int_operand" "J,K")))]
653   ""
654   "@
655    mulh %2,%0
656    mulhi %2,%1,%0"
657   [(set_attr "length" "2,4")
658    (set_attr "cc" "none_0hit,none_0hit")
659    (set_attr "type" "mult")])
661 ;; ??? The scheduling info is probably wrong.
663 ;; ??? This instruction can also generate the 32-bit highpart, but using it
664 ;; may increase code size counter to the desired result.
666 ;; ??? This instructions can also give a DImode result.
668 ;; ??? There is unsigned version, but it matters only for the DImode/highpart
669 ;; results.
671 (define_insn "mulsi3"
672   [(set (match_operand:SI 0 "register_operand" "=r")
673         (mult:SI (match_operand:SI 1 "register_operand" "%0")
674                  (match_operand:SI 2 "reg_or_int9_operand" "rO")))]
675   "(TARGET_V850E_UP)"
676   "mul %2,%1,%."
677   [(set_attr "length" "4")
678    (set_attr "cc" "none_0hit")
679    (set_attr "type" "mult")])
681 ;; ----------------------------------------------------------------------
682 ;; DIVIDE INSTRUCTIONS
683 ;; ----------------------------------------------------------------------
685 ;; ??? These insns do set the Z/N condition codes, except that they are based
686 ;; on only one of the two results, so it doesn't seem to make sense to use
687 ;; them.
689 ;; ??? The scheduling info is probably wrong.
691 (define_insn "divmodsi4"
692   [(set (match_operand:SI 0 "register_operand" "=r")
693         (div:SI (match_operand:SI 1 "register_operand" "0")
694                 (match_operand:SI 2 "register_operand" "r")))
695    (set (match_operand:SI 3 "register_operand" "=r")
696         (mod:SI (match_dup 1)
697                 (match_dup 2)))
698    (clobber (reg:CC CC_REGNUM))]
699   "TARGET_V850E_UP"
701   if (TARGET_V850E2_UP)
702     return "divq %2,%0,%3";
703    else
704     return "div %2,%0,%3";
706   [(set_attr "length" "4")
707    (set_attr "cc" "clobber")
708    (set_attr "type" "div")])
709         
710 (define_insn "udivmodsi4"
711   [(set (match_operand:SI 0 "register_operand" "=r")
712         (udiv:SI (match_operand:SI 1 "register_operand" "0")
713                  (match_operand:SI 2 "register_operand" "r")))
714    (set (match_operand:SI 3 "register_operand" "=r")
715         (umod:SI (match_dup 1)
716                  (match_dup 2)))
717    (clobber (reg:CC CC_REGNUM))]
718   "TARGET_V850E_UP"
720   if (TARGET_V850E2_UP)
721     return "divqu %2,%0,%3";
722   else
723     return "divu %2,%0,%3";
725   [(set_attr "length" "4")
726    (set_attr "cc" "clobber")
727    (set_attr "type" "div")])
728         
729 ;; ??? There is a 2 byte instruction for generating only the quotient.
730 ;; However, it isn't clear how to compute the length field correctly.
732 (define_insn "divmodhi4"
733   [(set (match_operand:HI 0 "register_operand" "=r")
734         (div:HI (match_operand:HI 1 "register_operand" "0")
735                 (match_operand:HI 2 "register_operand" "r")))
736    (set (match_operand:HI 3 "register_operand" "=r")
737         (mod:HI (match_dup 1)
738                 (match_dup 2)))
739    (clobber (reg:CC CC_REGNUM))]
740   "TARGET_V850E_UP"
741   "divh %2,%0,%3"
742   [(set_attr "length" "4")
743    (set_attr "cc" "clobber")
744    (set_attr "type" "div")])
746 ;; Half-words are sign-extended by default, so we must zero extend to a word
747 ;; here before doing the divide.
749 (define_insn "udivmodhi4"
750   [(set (match_operand:HI 0 "register_operand" "=r")
751         (udiv:HI (match_operand:HI 1 "register_operand" "0")
752                  (match_operand:HI 2 "register_operand" "r")))
753    (set (match_operand:HI 3 "register_operand" "=r")
754         (umod:HI (match_dup 1)
755                  (match_dup 2)))
756    (clobber (reg:CC CC_REGNUM))]
757   "TARGET_V850E_UP"
758   "zxh %0 ; divhu %2,%0,%3"
759   [(set_attr "length" "4")
760    (set_attr "cc" "clobber")
761    (set_attr "type" "div")])
763 ;; ----------------------------------------------------------------------
764 ;; AND INSTRUCTIONS
765 ;; ----------------------------------------------------------------------
767 (define_insn "*v850_clr1_1"
768   [(set (match_operand:QI 0 "memory_operand" "=m")
769         (subreg:QI
770           (and:SI (subreg:SI (match_dup 0) 0)
771                   (match_operand:QI 1 "not_power_of_two_operand" "")) 0))
772    (clobber (reg:CC CC_REGNUM))]
773   ""
775   rtx xoperands[2];
776   xoperands[0] = operands[0];
777   xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
778   output_asm_insn ("clr1 %M1,%0", xoperands);
779   return "";
781   [(set_attr "length" "4")
782    (set_attr "cc" "clobber")
783    (set_attr "type" "bit1")])
785 (define_insn "*v850_clr1_2"
786   [(set (match_operand:HI 0 "indirect_operand" "=m")
787         (subreg:HI
788           (and:SI (subreg:SI (match_dup 0) 0)
789                   (match_operand:HI 1 "not_power_of_two_operand" "")) 0))
790    (clobber (reg:CC CC_REGNUM))]
791   ""
793   int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
795   rtx xoperands[2];
796   xoperands[0] = gen_rtx_MEM (QImode,
797                               plus_constant (Pmode, XEXP (operands[0], 0),
798                                              log2 / 8));
799   xoperands[1] = GEN_INT (log2 % 8);
800   output_asm_insn ("clr1 %1,%0", xoperands);
801   return "";
803   [(set_attr "length" "4")
804    (set_attr "cc" "clobber")
805    (set_attr "type" "bit1")])
807 (define_insn "*v850_clr1_3"
808   [(set (match_operand:SI 0 "indirect_operand" "=m")
809         (and:SI (match_dup 0)
810                 (match_operand:SI 1 "not_power_of_two_operand" "")))
811    (clobber (reg:CC CC_REGNUM))]
812   ""
814   int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
816   rtx xoperands[2];
817   xoperands[0] = gen_rtx_MEM (QImode,
818                               plus_constant (Pmode, XEXP (operands[0], 0),
819                                              log2 / 8));
820   xoperands[1] = GEN_INT (log2 % 8);
821   output_asm_insn ("clr1 %1,%0", xoperands);
822   return "";
824   [(set_attr "length" "4")
825    (set_attr "cc" "clobber")
826    (set_attr "type" "bit1")])
828 (define_insn "andsi3"
829   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
830         (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
831                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
832    (clobber (reg:CC CC_REGNUM))]
833   ""
834   "@
835   and %2,%0
836   and %.,%0
837   andi %2,%1,%0"
838   [(set_attr "length" "2,2,4")
839    (set_attr "cc" "set_zn")])
841 ;; ----------------------------------------------------------------------
842 ;; OR INSTRUCTIONS
843 ;; ----------------------------------------------------------------------
845 (define_insn "*v850_set1_1"
846   [(set (match_operand:QI 0 "memory_operand" "=m")
847         (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
848                            (match_operand 1 "power_of_two_operand" "")) 0))
849    (clobber (reg:CC CC_REGNUM))]
850   ""
851   "set1 %M1,%0"
852   [(set_attr "length" "4")
853    (set_attr "cc" "clobber")
854    (set_attr "type" "bit1")])
856 (define_insn "*v850_set1_2"
857   [(set (match_operand:HI 0 "indirect_operand" "=m")
858         (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
859                            (match_operand 1 "power_of_two_operand" "")) 0))]
860   ""
862   int log2 = exact_log2 (INTVAL (operands[1]));
864   if (log2 < 8)
865     return "set1 %M1,%0";
866   else
867     {
868       rtx xoperands[2];
869       xoperands[0] = gen_rtx_MEM (QImode,
870                                   plus_constant (Pmode, XEXP (operands[0], 0),
871                                                  log2 / 8));
872       xoperands[1] = GEN_INT (log2 % 8);
873       output_asm_insn ("set1 %1,%0", xoperands);
874     }
875   return "";
877   [(set_attr "length" "4")
878    (set_attr "cc" "clobber")
879    (set_attr "type" "bit1")])
881 (define_insn "*v850_set1_3"
882   [(set (match_operand:SI 0 "indirect_operand" "=m")
883         (ior:SI (match_dup 0)
884                 (match_operand 1 "power_of_two_operand" "")))
885    (clobber (reg:CC CC_REGNUM))]
886   ""
888   int log2 = exact_log2 (INTVAL (operands[1]));
890   if (log2 < 8)
891     return "set1 %M1,%0";
892   else
893     {
894       rtx xoperands[2];
895       xoperands[0] = gen_rtx_MEM (QImode,
896                                   plus_constant (Pmode, XEXP (operands[0], 0),
897                                                  log2 / 8));
898       xoperands[1] = GEN_INT (log2 % 8);
899       output_asm_insn ("set1 %1,%0", xoperands);
900     }
901   return "";
903   [(set_attr "length" "4")
904    (set_attr "cc" "clobber")
905    (set_attr "type" "bit1")])
907 (define_insn "iorsi3"
908   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
909         (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
910                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
911    (clobber (reg:CC CC_REGNUM))]
912   ""
913   "@
914   or %2,%0
915   or %.,%0
916   ori %2,%1,%0"
917   [(set_attr "length" "2,2,4")
918    (set_attr "cc" "set_zn")])
920 ;; ----------------------------------------------------------------------
921 ;; XOR INSTRUCTIONS
922 ;; ----------------------------------------------------------------------
924 (define_insn "*v850_not1_1"
925   [(set (match_operand:QI 0 "memory_operand" "=m")
926         (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0)
927                            (match_operand 1 "power_of_two_operand" "")) 0))
928    (clobber (reg:CC CC_REGNUM))]
929   ""
930   "not1 %M1,%0"
931   [(set_attr "length" "4")
932    (set_attr "cc" "clobber")
933    (set_attr "type" "bit1")])
935 (define_insn "*v850_not1_2"
936   [(set (match_operand:HI 0 "indirect_operand" "=m")
937         (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
938                            (match_operand 1 "power_of_two_operand" "")) 0))]
939   ""
941   int log2 = exact_log2 (INTVAL (operands[1]));
943   if (log2 < 8)
944     return "not1 %M1,%0";
945   else
946     {
947       rtx xoperands[2];
948       xoperands[0] = gen_rtx_MEM (QImode,
949                                   plus_constant (Pmode, XEXP (operands[0], 0),
950                                                  log2 / 8));
951       xoperands[1] = GEN_INT (log2 % 8);
952       output_asm_insn ("not1 %1,%0", xoperands);
953     }
954   return "";
956   [(set_attr "length" "4")
957    (set_attr "cc" "clobber")
958    (set_attr "type" "bit1")])
960 (define_insn "*v850_not1_3"
961   [(set (match_operand:SI 0 "indirect_operand" "=m")
962         (xor:SI (match_dup 0)
963                 (match_operand 1 "power_of_two_operand" "")))
964    (clobber (reg:CC CC_REGNUM))]
965   ""
967   int log2 = exact_log2 (INTVAL (operands[1]));
969   if (log2 < 8)
970     return "not1 %M1,%0";
971   else
972     {
973       rtx xoperands[2];
974       xoperands[0] = gen_rtx_MEM (QImode,
975                                   plus_constant (Pmode, XEXP (operands[0], 0),
976                                                  log2 / 8));
977       xoperands[1] = GEN_INT (log2 % 8);
978       output_asm_insn ("not1 %1,%0", xoperands);
979     }
980   return "";
982   [(set_attr "length" "4")
983    (set_attr "cc" "clobber")
984    (set_attr "type" "bit1")])
986 (define_insn "xorsi3"
987   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
988         (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
989                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
990    (clobber (reg:CC CC_REGNUM))]
991   ""
992   "@
993   xor %2,%0
994   xor %.,%0
995   xori %2,%1,%0"
996   [(set_attr "length" "2,2,4")
997    (set_attr "cc" "set_zn")])
999 ;; ----------------------------------------------------------------------
1000 ;; NOT INSTRUCTIONS
1001 ;; ----------------------------------------------------------------------
1003 (define_insn "one_cmplsi2"
1004   [(set (match_operand:SI 0 "register_operand" "=r")
1005         (not:SI (match_operand:SI 1 "register_operand" "r")))
1006    (clobber (reg:CC CC_REGNUM))]
1007   ""
1008   "not %1,%0"
1009   [(set_attr "length" "2")
1010    (set_attr "cc" "set_zn")])
1012 ;; -----------------------------------------------------------------
1013 ;; BIT FIELDS
1014 ;; -----------------------------------------------------------------
1016 ;; ??? Is it worth defining insv and extv for the V850 series?!?
1018 ;; An insv pattern would be useful, but does not get used because
1019 ;; store_bit_field never calls insv when storing a constant value into a
1020 ;; single-bit bitfield.
1022 ;; extv/extzv patterns would be useful, but do not get used because
1023 ;; optimize_bitfield_compare in fold-const usually converts single
1024 ;; bit extracts into an AND with a mask.
1026 (define_insn "insv"
1027   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1028                          (match_operand:SI 1 "immediate_operand" "n")
1029                          (match_operand:SI 2 "immediate_operand" "n"))
1030         (match_operand:SI 3 "register_operand" "r"))]
1031   "TARGET_V850E3V5_UP"
1032   "bins %3, %2, %1, %0"
1033   [(set_attr "length" "4")
1034    (set_attr "cc" "set_zn")]
1037 ;; -----------------------------------------------------------------
1038 ;; Scc INSTRUCTIONS
1039 ;; -----------------------------------------------------------------
1041 (define_insn "*setcc"
1042   [(set (match_operand:SI 0 "register_operand" "=r")
1043         (match_operator:SI 1 "comparison_operator"
1044          [(cc0) (const_int 0)]))]
1045   ""
1047   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1048       && (GET_CODE (operands[1]) == GT
1049           || GET_CODE (operands[1]) == GE
1050           || GET_CODE (operands[1]) == LE
1051           || GET_CODE (operands[1]) == LT))
1052     return 0;
1054   return "setf %c1,%0";
1056   [(set_attr "length" "4")
1057    (set_attr "cc" "none_0hit")])
1059 (define_insn "setf_insn"
1060   [(set (match_operand:SI 0 "register_operand" "=r")
1061         (match_operator:SI 1 "comparison_operator"
1062                           [(reg:CC CC_REGNUM) (const_int 0)]))]
1063   ""
1064   "setf %b1,%0"
1065   [(set_attr "length" "4")
1066    (set_attr "cc" "none_0hit")])
1068 (define_insn "set_z_insn"
1069   [(set (match_operand:SI 0 "register_operand" "=r")
1070         (match_operand 1 "v850_float_z_comparison_operator" ""))]
1071   "TARGET_V850E2V3_UP"
1072   "setf z,%0"
1073   [(set_attr "length" "4")
1074    (set_attr "cc" "none_0hit")])
1076 (define_insn "set_nz_insn" 
1077   [(set (match_operand:SI 0 "register_operand" "=r")
1078         (match_operand 1 "v850_float_nz_comparison_operator" ""))]
1079   "TARGET_V850E2V3_UP"
1080   "setf nz,%0"
1081   [(set_attr "length" "4")
1082    (set_attr "cc" "none_0hit")])
1084 ;; ----------------------------------------------------------------------
1085 ;; CONDITIONAL MOVE INSTRUCTIONS
1086 ;; ----------------------------------------------------------------------
1088 ;; Instructions using cc0 aren't allowed to have input reloads, so we must
1089 ;; hide the fact that this instruction uses cc0.  We do so by including the
1090 ;; compare instruction inside it.
1092 (define_expand "movsicc"
1093   [(set (match_operand:SI 0 "register_operand" "=r")
1094         (if_then_else:SI
1095          (match_operand 1 "comparison_operator")
1096          (match_operand:SI 2 "reg_or_const_operand" "rJ")
1097          (match_operand:SI 3 "reg_or_const_operand" "rI")))]
1098   "(TARGET_V850E_UP)"
1099   {
1100     /* Make sure that we have an integer comparison...  */
1101     if (GET_MODE (XEXP (operands[1], 0)) != CCmode
1102         && GET_MODE (XEXP (operands[1], 0)) != SImode)
1103       FAIL;
1105     if ((GET_CODE (operands[2]) == CONST_INT
1106         && GET_CODE (operands[3]) == CONST_INT))
1107       {
1108         int o2 = INTVAL (operands[2]);
1109         int o3 = INTVAL (operands[3]);
1111         if (o2 == 1 && o3 == 0)
1112           FAIL;   /* setf */
1113         if (o3 == 1 && o2 == 0)
1114           FAIL;   /* setf */
1115         if (o2 == 0 && (o3 < -16 || o3 > 15) && exact_log2 (o3) >= 0)
1116           FAIL;   /* setf + shift */
1117         if (o3 == 0 && (o2 < -16 || o2 > 15) && exact_log2 (o2) >=0)
1118           FAIL;   /* setf + shift */
1119         if (o2 != 0)
1120           operands[2] = copy_to_mode_reg (SImode, operands[2]);
1121         if (o3 !=0 )
1122           operands[3] = copy_to_mode_reg (SImode, operands[3]);
1123       }
1124     else
1125       {
1126         if (GET_CODE (operands[2]) != REG)
1127           operands[2] = copy_to_mode_reg (SImode,operands[2]);
1128         if (GET_CODE (operands[3]) != REG)
1129           operands[3] = copy_to_mode_reg (SImode, operands[3]);
1130       }
1131   })
1133 ;; ??? Clobbering the condition codes is overkill.
1135 ;; ??? We sometimes emit an unnecessary compare instruction because the
1136 ;; condition codes may have already been set by an earlier instruction,
1137 ;; but we have no code here to avoid the compare if it is unnecessary.
1139 (define_insn "movsicc_normal_cc"
1140   [(set (match_operand:SI 0 "register_operand" "=r")
1141         (if_then_else:SI
1142          (match_operator 1 "comparison_operator"
1143                          [(reg:CC CC_REGNUM) (const_int 0)])
1144          (match_operand:SI 2 "reg_or_int5_operand" "rJ")
1145          (match_operand:SI 3 "reg_or_0_operand" "rI")))]
1146   "(TARGET_V850E_UP)"
1147   "cmov %c1,%2,%z3,%0";
1148   [(set_attr "length" "6")
1149    (set_attr "cc" "compare")])
1151 (define_insn "movsicc_reversed_cc"
1152   [(set (match_operand:SI 0 "register_operand" "=r")
1153         (if_then_else:SI
1154          (match_operator 1 "comparison_operator"
1155                          [(reg:CC CC_REGNUM) (const_int 0)])
1156          (match_operand:SI 2 "reg_or_0_operand" "rI")
1157          (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
1158   "(TARGET_V850E_UP)"
1159   "cmov %C1,%3,%z2,%0"
1160   [(set_attr "length" "6")
1161    (set_attr "cc" "compare")])
1163 (define_insn "*movsicc_normal"
1164   [(set (match_operand:SI 0 "register_operand" "=r")
1165         (if_then_else:SI
1166          (match_operator 1 "comparison_operator"
1167                          [(match_operand:SI 4 "register_operand" "r")
1168                           (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
1169          (match_operand:SI 2 "reg_or_int5_operand" "rJ")
1170          (match_operand:SI 3 "reg_or_0_operand" "rI")))]
1171   "(TARGET_V850E_UP)"
1172   "cmp %5,%4 ; cmov %c1,%2,%z3,%0"
1173   [(set_attr "length" "6")
1174    (set_attr "cc" "clobber")])
1176 (define_insn "*movsicc_reversed"
1177   [(set (match_operand:SI 0 "register_operand" "=r")
1178         (if_then_else:SI
1179          (match_operator 1 "comparison_operator"
1180                          [(match_operand:SI 4 "register_operand" "r")
1181                           (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
1182          (match_operand:SI 2 "reg_or_0_operand" "rI")
1183          (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
1184   "(TARGET_V850E_UP)"
1185   "cmp %5,%4 ; cmov %C1,%3,%z2,%0"
1186   [(set_attr "length" "6")
1187    (set_attr "cc" "clobber")])
1189 (define_insn "*movsicc_tst1"
1190   [(set (match_operand:SI 0 "register_operand" "=r")
1191         (if_then_else:SI
1192          (match_operator 1 "comparison_operator"
1193                          [(zero_extract:SI
1194                            (match_operand:QI 2 "memory_operand" "m")
1195                            (const_int 1)
1196                            (match_operand 3 "const_int_operand" "n"))
1197                           (const_int 0)])
1198          (match_operand:SI 4 "reg_or_int5_operand" "rJ")
1199          (match_operand:SI 5 "reg_or_0_operand" "rI")))]
1200   "(TARGET_V850E_UP)"
1201   "tst1 %3,%2 ; cmov %c1,%4,%z5,%0"
1202   [(set_attr "length" "8")
1203    (set_attr "cc" "clobber")])
1205 (define_insn "*movsicc_tst1_reversed"
1206   [(set (match_operand:SI 0 "register_operand" "=r")
1207         (if_then_else:SI
1208          (match_operator 1 "comparison_operator"
1209                          [(zero_extract:SI
1210                            (match_operand:QI 2 "memory_operand" "m")
1211                            (const_int 1)
1212                            (match_operand 3 "const_int_operand" "n"))
1213                           (const_int 0)])
1214          (match_operand:SI 4 "reg_or_0_operand" "rI")
1215          (match_operand:SI 5 "reg_or_int5_operand" "rJ")))]
1216   "(TARGET_V850E_UP)"
1217   "tst1 %3,%2 ; cmov %C1,%5,%z4,%0"
1218   [(set_attr "length" "8")
1219    (set_attr "cc" "clobber")])
1221 ;; Matching for sasf requires combining 4 instructions, so we provide a
1222 ;; dummy pattern to match the first 3, which will always be turned into the
1223 ;; second pattern by subsequent combining.  As above, we must include the
1224 ;; comparison to avoid input reloads in an insn using cc0.
1226 (define_insn "*sasf"
1227   [(set (match_operand:SI 0 "register_operand" "=r")
1228         (ior:SI
1229          (match_operator 1 "comparison_operator"
1230                          [(match_operand:SI 3 "register_operand" "r")
1231                           (match_operand:SI 4 "reg_or_int5_operand" "rJ")])
1232          (ashift:SI (match_operand:SI 2 "register_operand" "0")
1233                     (const_int 1))))
1234    (clobber (reg:CC CC_REGNUM))]
1235   "(TARGET_V850E_UP)"
1236   "cmp %4,%3 ; sasf %c1,%0"
1237   [(set_attr "length" "6")
1238    (set_attr "cc" "clobber")])
1240 (define_split
1241   [(set (match_operand:SI 0 "register_operand" "")
1242         (if_then_else:SI
1243          (match_operator 1 "comparison_operator"
1244                          [(match_operand:SI 4 "register_operand" "")
1245                           (match_operand:SI 5 "reg_or_int5_operand" "")])
1246          (match_operand:SI 2 "const_int_operand" "")
1247          (match_operand:SI 3 "const_int_operand" "")))
1248    (clobber (reg:CC CC_REGNUM))]
1249   "(TARGET_V850E_UP)
1250    && ((INTVAL (operands[2]) ^ INTVAL (operands[3])) == 1)
1251    && ((INTVAL (operands[2]) + INTVAL (operands[3])) != 1)
1252    && (GET_CODE (operands[5]) == CONST_INT
1253       || REGNO (operands[0]) != REGNO (operands[5]))
1254    && REGNO (operands[0]) != REGNO (operands[4])"
1255   [(set (match_dup 0) (match_dup 6))
1256    (parallel [(set (match_dup 0)
1257                    (ior:SI (match_op_dup 7 [(match_dup 4) (match_dup 5)])
1258                            (ashift:SI (match_dup 0) (const_int 1))))
1259               (clobber (reg:CC CC_REGNUM))])]
1260   {
1261     operands[6] = GEN_INT (INTVAL (operands[2]) >> 1);
1262     if (INTVAL (operands[2]) & 0x1)
1263       operands[7] = operands[1];
1264     else
1265       operands[7] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
1266                                     GET_MODE (operands[1]),
1267                                     XEXP (operands[1], 0), XEXP (operands[1], 1));
1268   })
1270 ;; ---------------------------------------------------------------------
1271 ;; BYTE SWAP INSTRUCTIONS
1272 ;; ---------------------------------------------------------------------
1273 (define_expand "rotlhi3"
1274   [(parallel [(set (match_operand:HI 0 "register_operand" "")
1275                    (rotate:HI (match_operand:HI 1 "register_operand" "")
1276                               (match_operand:HI 2 "const_int_operand" "")))
1277               (clobber (reg:CC CC_REGNUM))])]
1278   "(TARGET_V850E_UP)"
1279   {
1280     if (INTVAL (operands[2]) != 8)
1281       FAIL;
1282   })
1284 (define_insn "*rotlhi3_8"
1285   [(set (match_operand:HI 0 "register_operand" "=r")
1286         (rotate:HI (match_operand:HI 1 "register_operand" "r")
1287                    (const_int 8)))
1288    (clobber (reg:CC CC_REGNUM))]
1289   "(TARGET_V850E_UP)"
1290   "bsh %1,%0"
1291   [(set_attr "length" "4")
1292    (set_attr "cc" "clobber")])
1294 (define_expand "rotlsi3"
1295   [(parallel [(set (match_operand:SI 0 "register_operand" "")
1296                    (rotate:SI (match_operand:SI 1 "register_operand" "")
1297                               (match_operand:SI 2 "const_int_operand" "")))
1298               (clobber (reg:CC CC_REGNUM))])]
1299   "(TARGET_V850E_UP)"
1300   {
1301     if (INTVAL (operands[2]) != 16)
1302       FAIL;
1303   })
1305 (define_insn "rotlsi3_a"
1306   [(set (match_operand:SI 0 "register_operand" "=r")
1307      (match_operator:SI 4 "ior_operator"
1308        [(ashift:SI (match_operand:SI 1 "register_operand" "r")
1309                    (match_operand:SI 2 "const_int_operand" "n"))
1310         (lshiftrt:SI (match_dup 1)
1311         (match_operand:SI 3 "const_int_operand" "n"))]))]
1312   "TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)"
1313   "rotl %2, %1, %0"
1314   [(set_attr "length" "4")
1315    (set_attr "cc" "set_zn")]
1318 (define_insn "rotlsi3_b"
1319   [(set (match_operand:SI 0 "register_operand" "=r")
1320      (match_operator:SI 4 "ior_operator"
1321        [(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1322                      (match_operand:SI 3 "const_int_operand" "n"))
1323         (ashift:SI (match_dup 1)
1324                    (match_operand:SI 2 "const_int_operand" "n"))]))]
1325   "TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)"
1326   "rotl %2, %1, %0"
1327   [(set_attr "length" "4")
1328    (set_attr "cc" "set_zn")]
1331 (define_insn "rotlsi3_v850e3v5"
1332   [(set (match_operand:SI 0 "register_operand" "=r")
1333         (rotate:SI (match_operand:SI 1 "register_operand" "r")
1334                    (match_operand:SI 2 "e3v5_shift_operand" "rn")))
1335               (clobber (reg:CC CC_REGNUM))]
1336   "TARGET_V850E3V5_UP"
1337   "rotl %2, %1, %0"
1338   [(set_attr "length" "4")
1339    (set_attr "cc" "set_zn")]
1342 (define_insn "*rotlsi3_16"
1343   [(set (match_operand:SI 0 "register_operand" "=r")
1344         (rotate:SI (match_operand:SI 1 "register_operand" "r")
1345                    (const_int 16)))
1346    (clobber (reg:CC CC_REGNUM))]
1347   "(TARGET_V850E_UP)"
1348   "hsw %1,%0"
1349   [(set_attr "length" "4")
1350    (set_attr "cc" "clobber")])
1352 ;; ----------------------------------------------------------------------
1353 ;; JUMP INSTRUCTIONS
1354 ;; ----------------------------------------------------------------------
1356 ;; Doloop
1358 (define_expand "doloop_begin"
1359  [(use (match_operand 0 "" ""))        ; loop pseudo
1360   (use (match_operand 1 "" ""))        ; iterations; zero if unknown
1361   (use (match_operand 2 "" ""))        ; max iterations
1362   (use (match_operand 3 "" ""))        ; loop level
1363   (use (match_operand 4 "" ""))]       ; condition
1364   "TARGET_V850E3V5_UP && TARGET_LOOP"
1365   {
1366     rtx loop_cnt   = operands[0];
1367     rtx loop_level = operands[3];
1369     if (INTVAL (loop_level) > 1)
1370       FAIL;
1371     if (GET_MODE (loop_cnt) != SImode)
1372       FAIL;
1374     emit_insn (gen_fix_loop_counter (loop_cnt));
1375     DONE;
1376   }
1379 (define_insn "fix_loop_counter"
1380   [(unspec:SI [(match_operand:SI          0 "register_operand" "+r,!m")
1381                (clobber (match_scratch:SI 1                    "=X,r"))] UNSPEC_LOOP)]
1382   "TARGET_V850E3V5_UP && TARGET_LOOP"
1383   {
1384     switch (which_alternative)
1385     {
1386     case 0:  return "add 1, %0 # LOOP_BEGIN";
1387     case 1:  return "ld.w %0, %1; add 1, %1; st.w %1, %0 # LOOP_BEGIN";
1388     default: gcc_unreachable ();
1389     }
1390   }
1391   [(set_attr "length" "2,6")
1392    (set_attr "cc" "none")]
1395 (define_expand "doloop_end"
1396  [(use (match_operand 0 "" ""))        ; loop pseudo
1397   (use (match_operand 1 "" ""))        ; iterations; zero if unknown
1398   (use (match_operand 2 "" ""))        ; max iterations
1399   (use (match_operand 3 "" ""))        ; loop level
1400   (use (match_operand 4 "" ""))        ; label
1401   (use (match_operand 5 "" ""))]       ; entered at top
1402   "TARGET_V850E3V5_UP && TARGET_LOOP"
1403   {
1404     rtx loop_cnt   = operands[0];
1405     rtx loop_level = operands[3];
1406     rtx label      = operands[4];
1408     if (INTVAL (loop_level) > 1)
1409       FAIL;
1410     if (GET_MODE (loop_cnt) != SImode)
1411       FAIL;
1413     emit_jump_insn (gen_doloop_end_internal_loop (label, loop_cnt));
1414     DONE;
1415   }
1418 (define_insn "doloop_end_internal_loop"
1419  [(set (pc)
1420        (if_then_else (ne (match_operand:SI 1 "register_operand" "+r,!m")
1421                          (const_int 0))
1422                      (label_ref (match_operand 0 "" ""))
1423                      (pc)))
1424   (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))
1425   (clobber (match_scratch:SI 2 "=X,r"))
1426   (clobber (reg:CC CC_REGNUM))]
1427   "TARGET_V850E3V5_UP && TARGET_LOOP"
1428   {
1429     switch (which_alternative)
1430     {
1431     case 0:
1432       if (get_attr_length (insn) == 4)
1433         return "loop %1, %0 # LOOP.1.0";
1435       return "add -1, %1; bne %l0 # LOOP.1.1";
1436     case 1:
1437       return "ld.w %1, %2; add -1, %2; st.w %2, %1; bne %l0 # LOOP.2.1";
1438     default:
1439       gcc_unreachable ();
1440     }
1441   }
1442  [(set (attr "length")
1443        (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1444                      (const_int 65534))
1445                      (const_int 4)
1446                      (const_int 14)))
1447   (set_attr "cc" "none")])
1449 ;; Conditional jump instructions
1451 (define_insn "*branch_normal"
1452   [(set (pc)
1453         (if_then_else (match_operator 1 "comparison_operator"
1454                                       [(cc0) (const_int 0)])
1455                       (label_ref (match_operand 0 "" ""))
1456                       (pc)))]
1457   ""
1459   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1460       && (GET_CODE (operands[1]) == GT
1461           || GET_CODE (operands[1]) == GE
1462           || GET_CODE (operands[1]) == LE
1463           || GET_CODE (operands[1]) == LT))
1464     return 0;
1466   if (get_attr_length (insn) == 2)
1467     return "b%b1 %l0";
1468   if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1469     return "b%b1 %l0";
1470   return "b%B1 .+6 ; jr %l0";
1472  [(set (attr "length")
1473     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1474                       (const_int 256))
1475                   (const_int 2)
1476                   (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1477                       (const_int 65536))
1478                       (const_int 4)
1479                       (const_int 6))))
1480   (set_attr "cc" "none")])
1482 (define_insn "*branch_invert"
1483   [(set (pc)
1484         (if_then_else (match_operator 1 "comparison_operator"
1485                                       [(cc0) (const_int 0)])
1486                       (pc)
1487                       (label_ref (match_operand 0 "" ""))))]
1488   ""
1490   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1491       && (GET_CODE (operands[1]) == GT
1492           || GET_CODE (operands[1]) == GE
1493           || GET_CODE (operands[1]) == LE
1494           || GET_CODE (operands[1]) == LT))
1495     return NULL;
1497   if (get_attr_length (insn) == 2)
1498     return "b%B1 %l0";
1500   if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1501     return "b%B1 %l0";
1502     
1503   return "b%b1 .+6 ; jr %l0";
1505  [(set (attr "length")
1506     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1507                       (const_int 256))
1508                   (const_int 2)
1509                   (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1510                       (const_int 65536))
1511                       (const_int 4)
1512                       (const_int 6))))
1513   (set_attr "cc" "none")])
1515 (define_insn "branch_z_normal"  
1516   [(set (pc)
1517         (if_then_else (match_operand 1 "v850_float_z_comparison_operator" "")
1518                       (label_ref (match_operand 0 "" ""))
1519                       (pc)))]
1520   "TARGET_V850E2V3_UP"
1522   if (get_attr_length (insn) == 2)
1523     return "bz %l0";
1525   if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1526     return "bz %l0";
1528   return "bnz 1f ; jr %l0 ; 1:";
1530  [(set (attr "length")
1531     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1532                       (const_int 256))
1533                   (const_int 2)
1534                   (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1535                       (const_int 65536))
1536                       (const_int 4)
1537                       (const_int 6))))
1538   (set_attr "cc" "none")])
1540 (define_insn "*branch_z_invert"
1541   [(set (pc)
1542         (if_then_else (match_operand 1 "v850_float_z_comparison_operator" "")
1543                       (pc)
1544                       (label_ref (match_operand 0 "" ""))))]
1545   "TARGET_V850E2V3_UP"
1547   if (get_attr_length (insn) == 2)
1548     return "bnz %l0";
1550   if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1551     return "bnz %l0";
1553   return "bz 1f ; jr %l0 ; 1:";
1555  [(set (attr "length")
1556     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1557                            (const_int 256))
1558                   (const_int 2)
1559                   (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1560                       (const_int 65536))
1561                       (const_int 4)
1562                       (const_int 6))))
1563   (set_attr "cc" "none")])
1565 (define_insn "branch_nz_normal"
1566   [(set (pc)
1567         (if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "")
1568                       (label_ref (match_operand 0 "" ""))
1569                       (pc)))]
1570   "TARGET_V850E2V3_UP"
1572   if (get_attr_length (insn) == 2)
1573     return "bnz %l0";
1575   if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1576     return "bnz %l0";
1578   return "bz 1f ; jr %l0 ; 1:";
1580 [(set (attr "length")
1581     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1582                            (const_int 256))
1583                   (const_int 2)
1584                   (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1585                       (const_int 65536))
1586                       (const_int 4)
1587                       (const_int 6))))
1588   (set_attr "cc" "none")])
1590 (define_insn "*branch_nz_invert"
1591   [(set (pc)
1592         (if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "")
1593                       (pc)
1594                       (label_ref (match_operand 0 "" ""))))]
1595   "TARGET_V850E2V3_UP"
1597   if (get_attr_length (insn) == 2)
1598     return "bz %l0";
1600   if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1601     return "bz %l0";
1603   return "bnz 1f ; jr %l0 ; 1:";
1605  [(set (attr "length")
1606     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1607                       (const_int 256))
1608                   (const_int 2)
1609                   (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1610                       (const_int 65536))
1611                       (const_int 4)
1612                       (const_int 6))))
1613   (set_attr "cc" "none")])
1615 ;; Unconditional and other jump instructions.
1617 (define_insn "jump"
1618   [(set (pc)
1619         (label_ref (match_operand 0 "" "")))]
1620   ""
1622  if (get_attr_length (insn) == 2)
1623     return "br %0";
1624   else
1625     return "jr %0";
1627  [(set (attr "length")
1628     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1629                       (const_int 256))
1630                   (const_int 2)
1631                   (const_int 4)))
1632   (set_attr "cc" "none")])
1634 (define_insn "indirect_jump"
1635   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1636   ""
1637   "jmp %0"
1638   [(set_attr "length" "2")
1639    (set_attr "cc" "none")])
1641 (define_insn "tablejump"
1642   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1643    (use (label_ref (match_operand 1 "" "")))]
1644   ""
1645   "jmp  %0"
1646   [(set_attr "length" "2")
1647    (set_attr "cc" "none")])
1649 (define_insn "switch"
1650   [(set (pc)
1651         (plus:SI
1652          (sign_extend:SI
1653          (mem:HI
1654           (plus:SI (ashift:SI (match_operand:SI 0 "register_operand" "r")
1655                               (const_int 1))
1656                    (label_ref (match_operand 1 "" "")))))
1657         (label_ref (match_dup 1))))]
1658   "(TARGET_V850E_UP)"
1659   "switch %0"
1660   [(set_attr "length" "2")
1661    (set_attr "cc" "none")])
1663 (define_expand "casesi"
1664   [(match_operand:SI 0 "register_operand" "")
1665    (match_operand:SI 1 "register_operand" "")
1666    (match_operand:SI 2 "register_operand" "")
1667    (match_operand 3 "" "") (match_operand 4 "" "")]
1668   ""
1669   {
1670     rtx reg = gen_reg_rtx (SImode);
1671     rtx tableaddress = gen_reg_rtx (SImode);
1672     rtx test;
1673     rtx mem;
1675     /* Subtract the lower bound from the index.  */
1676     emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
1678     /* Compare the result against the number of table entries;
1679        branch to the default label if out of range of the table.  */
1680     test = gen_rtx_fmt_ee (GTU, VOIDmode, reg, operands[2]);
1681     emit_jump_insn (gen_cbranchsi4 (test, reg, operands[2], operands[4]));
1683     /* Shift index for the table array access.  */
1684     emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
1685     /* Load the table address into a pseudo.  */
1686     emit_insn (gen_movsi (tableaddress,
1687                           gen_rtx_LABEL_REF (Pmode, operands[3])));
1688     /* Add the table address to the index.  */
1689     emit_insn (gen_addsi3 (reg, reg, tableaddress));
1690     /* Load the table entry.  */
1691     mem = gen_const_mem (CASE_VECTOR_MODE, reg);
1692     if (! TARGET_BIG_SWITCH)
1693       {
1694         rtx reg2 = gen_reg_rtx (HImode);
1695         emit_insn (gen_movhi (reg2, mem));
1696         emit_insn (gen_extendhisi2 (reg, reg2));
1697       }
1698     else
1699       emit_insn (gen_movsi (reg, mem));
1700     /* Add the table address.  */
1701     emit_insn (gen_addsi3 (reg, reg, tableaddress));
1702     /* Branch to the switch label.  */
1703     emit_jump_insn (gen_tablejump (reg, operands[3]));
1704     DONE;
1705   })
1707 ;; Call subroutine with no return value.
1709 (define_expand "call"
1710   [(call (match_operand:QI 0 "general_operand" "")
1711          (match_operand:SI 1 "general_operand" ""))]
1712   ""
1713   {
1714     if (! call_address_operand (XEXP (operands[0], 0), QImode)
1715         || TARGET_LONG_CALLS)
1716       XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1717     if (TARGET_LONG_CALLS)
1718       emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));
1719     else
1720       emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
1721   
1722     DONE;
1723   })
1725 (define_insn "call_internal_short"
1726   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1727          (match_operand:SI 1 "general_operand" "g,g"))
1728    (clobber (reg:SI 31))]
1729   "! TARGET_LONG_CALLS"
1730   {
1731     if (which_alternative == 1)
1732       {
1733         if (TARGET_V850E3V5_UP)
1734           return "jarl [%0], r31";
1736         return "jarl .+4, r31 ; add 4, r31 ; jmp %0";
1737       }
1739     return "jarl %0, r31";
1740   }
1741   [(set_attr "length" "4,8")
1742    (set_attr "cc" "clobber,clobber")]
1745 (define_insn "call_internal_long"
1746   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1747          (match_operand:SI 1 "general_operand" "g,g"))
1748    (clobber (reg:SI 31))]
1749   "TARGET_LONG_CALLS"
1751   if (which_alternative == 0)
1752     {
1753       if (GET_CODE (operands[0]) == REG)
1754         return "jarl %0,r31";
1756       if (TARGET_V850E3V5_UP)
1757         return "mov hilo(%0), r11 ; jarl [r11], r31";
1759       return "movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11";
1760     }
1762   if (TARGET_V850E3V5_UP)
1763     return "jarl [%0], r31";
1765   return "jarl .+4,r31 ; add 4,r31 ; jmp %0";
1767   [(set_attr "length" "16,8")
1768    (set_attr "cc" "clobber,clobber")]
1771 ;; Call subroutine, returning value in operand 0
1772 ;; (which must be a hard register).
1774 (define_expand "call_value"
1775   [(set (match_operand 0 "" "")
1776         (call (match_operand:QI 1 "general_operand" "")
1777               (match_operand:SI 2 "general_operand" "")))]
1778   ""
1779   {
1780     if (! call_address_operand (XEXP (operands[1], 0), QImode)
1781         || TARGET_LONG_CALLS)
1782       XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1783     if (TARGET_LONG_CALLS)
1784       emit_call_insn (gen_call_value_internal_long (operands[0],
1785                                                     XEXP (operands[1], 0),
1786                                                     operands[2]));
1787     else
1788       emit_call_insn (gen_call_value_internal_short (operands[0],
1789                                                      XEXP (operands[1], 0),
1790                                                      operands[2]));
1791     DONE;
1792   })
1794 (define_insn "call_value_internal_short"
1795   [(set (match_operand 0 "" "=r,r")
1796         (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1797               (match_operand:SI 2 "general_operand" "g,g")))
1798    (clobber (reg:SI 31))]
1799   "! TARGET_LONG_CALLS"
1800   {
1801     if (which_alternative == 1)
1802       {
1803         if (TARGET_V850E3V5_UP)
1804           return "jarl [%1], r31";
1806         return "jarl .+4, r31 ; add 4, r31 ; jmp %1";
1807       }
1809     return "jarl %1, r31";
1810   }
1811   [(set_attr "length" "4,8")
1812    (set_attr "cc" "clobber,clobber")]
1815 (define_insn "call_value_internal_long"
1816   [(set (match_operand 0 "" "=r,r")
1817         (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1818               (match_operand:SI 2 "general_operand" "g,g")))
1819    (clobber (reg:SI 31))]
1820   "TARGET_LONG_CALLS"
1822   if (which_alternative == 0)
1823     {
1824       if (GET_CODE (operands[1]) == REG)
1825         return "jarl %1, r31";
1827       /* Reload can generate this pattern....  */
1828       if (TARGET_V850E3V5_UP)
1829         return "mov hilo(%1), r11 ; jarl [r11], r31";
1831       return "movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11";
1832     }
1833   
1834   if (TARGET_V850E3V5_UP)
1835     return "jarl [%1], r31";
1837   return "jarl .+4, r31 ; add 4, r31 ; jmp %1";
1839   [(set_attr "length" "16,8")
1840    (set_attr "cc" "clobber,clobber")]
1843 (define_insn "nop"
1844   [(const_int 0)]
1845   ""
1846   "nop"
1847   [(set_attr "length" "2")
1848    (set_attr "cc" "none")])
1850 ;; ----------------------------------------------------------------------
1851 ;; EXTEND INSTRUCTIONS
1852 ;; ----------------------------------------------------------------------
1854 (define_insn "*zero_extendhisi2_v850e"
1855   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1856         (zero_extend:SI
1857         (match_operand:HI 1 "nonimmediate_operand" "0,r,T,m")))
1858    (clobber (reg:CC CC_REGNUM))]
1859   "(TARGET_V850E_UP)"
1860   "@
1861    zxh %0
1862    andi 65535,%1,%0
1863    sld.hu %1,%0
1864    ld.hu %1,%0"
1865   [(set_attr "length" "2,4,2,4")
1866    (set_attr "cc" "none_0hit,set_zn,none_0hit,none_0hit")])
1868 (define_insn "*zero_extendhisi2_v850"
1869   [(set (match_operand:SI 0 "register_operand" "=r")
1870         (zero_extend:SI
1871         (match_operand:HI 1 "register_operand" "r")))
1872    (clobber (reg:CC CC_REGNUM))]  ;; A lie, but we have to match the expander
1873   ""
1874   "andi 65535,%1,%0"
1875   [(set_attr "length" "4")
1876    (set_attr "cc" "set_zn")])
1878 (define_expand "zero_extendhisi2"
1879   [(parallel [(set (match_operand:SI 0 "register_operand")
1880                    (zero_extend:SI
1881                     (match_operand:HI 1 "nonimmediate_operand")))
1882               (clobber (reg:CC CC_REGNUM))])]
1883   ""
1884   {
1885     if (! (TARGET_V850E_UP))
1886       operands[1] = force_reg (HImode, operands[1]);
1887   })
1889 (define_insn "*zero_extendqisi2_v850e"
1890   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1891         (zero_extend:SI
1892         (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m")))
1893    (clobber (reg:CC CC_REGNUM))]
1894   "(TARGET_V850E_UP)"
1895   "@
1896    zxb %0
1897    andi 255,%1,%0
1898    sld.bu %1,%0
1899    ld.bu %1,%0"
1900   [(set_attr "length" "2,4,2,4")
1901    (set_attr "cc" "none_0hit,set_zn,none_0hit,none_0hit")])
1903 (define_insn "*zero_extendqisi2_v850"
1904   [(set (match_operand:SI 0 "register_operand" "=r")
1905         (zero_extend:SI
1906           (match_operand:QI 1 "register_operand" "r")))
1907    (clobber (reg:CC CC_REGNUM))] ;; A lie, but we have to match the expander
1908   ""
1909   "andi 255,%1,%0"
1910   [(set_attr "length" "4")
1911    (set_attr "cc" "set_zn")])
1913 (define_expand "zero_extendqisi2"
1914   [(parallel [(set (match_operand:SI 0 "register_operand")
1915                    (zero_extend:SI
1916                      (match_operand:QI 1 "nonimmediate_operand")))
1917               (clobber (reg:CC CC_REGNUM))])]
1918   ""
1919   {
1920     if (! (TARGET_V850E_UP))
1921       operands[1] = force_reg (QImode, operands[1]);
1922   })
1924 ;;- sign extension instructions
1926 ;; ??? The extendhisi2 pattern should not emit shifts for v850e?
1928 (define_insn "*extendhisi_insn"
1929   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1930         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))
1931    (clobber (reg:CC CC_REGNUM))]
1932   "(TARGET_V850E_UP)"
1933   "@
1934    sxh %0
1935    sld.h %1,%0
1936    ld.h %1,%0"
1937   [(set_attr "length" "2,2,4")
1938    (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1940 ;; ??? This is missing a sign extend from memory pattern to match the ld.h
1941 ;; instruction.
1943 (define_expand "extendhisi2"
1944   [(parallel [(set (match_dup 2)
1945                    (ashift:SI (match_operand:HI 1 "register_operand" "")
1946                               (const_int 16)))
1947               (clobber (reg:CC CC_REGNUM))])
1948    (parallel [(set (match_operand:SI 0 "register_operand" "")
1949                    (ashiftrt:SI (match_dup 2)
1950                                 (const_int 16)))
1951               (clobber (reg:CC CC_REGNUM))])]
1952   ""
1953   {
1954     operands[1] = gen_lowpart (SImode, operands[1]);
1955     operands[2] = gen_reg_rtx (SImode);
1956   })
1958 ;; ??? The extendqisi2 pattern should not emit shifts for v850e?
1960 (define_insn "*extendqisi_insn"
1961   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1962         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))
1963    (clobber (reg:CC CC_REGNUM))]
1964   "(TARGET_V850E_UP)"
1965   "@
1966    sxb %0
1967    sld.b %1,%0
1968    ld.b %1,%0"
1969   [(set_attr "length" "2,2,4")
1970    (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1972 ;; ??? This is missing a sign extend from memory pattern to match the ld.b
1973 ;; instruction.
1975 (define_expand "extendqisi2"
1976   [(parallel [(set (match_dup 2)
1977                    (ashift:SI (match_operand:QI 1 "register_operand" "")
1978                               (const_int 24)))
1979               (clobber (reg:CC CC_REGNUM))])
1980    (parallel [(set (match_operand:SI 0 "register_operand" "")
1981                    (ashiftrt:SI (match_dup 2)
1982                               (const_int 24)))
1983               (clobber (reg:CC CC_REGNUM))])]
1984   ""
1985   {
1986     operands[1] = gen_lowpart (SImode, operands[1]);
1987     operands[2] = gen_reg_rtx (SImode);
1988   })
1990 ;; ----------------------------------------------------------------------
1991 ;; SHIFTS
1992 ;; ----------------------------------------------------------------------
1994 (define_insn "ashlsi3"
1995   [(set (match_operand:SI 0 "register_operand" "=r,r")
1996       (ashift:SI
1997         (match_operand:SI 1 "register_operand" "0,0")
1998         (match_operand:SI 2 "nonmemory_operand" "r,N")))
1999    (clobber (reg:CC CC_REGNUM))]
2000   ""
2001   "@
2002   shl %2,%0
2003   shl %2,%0"
2004   [(set_attr "length" "4,2")
2005    (set_attr "cc" "set_zn")])
2007 (define_insn "ashlsi3_v850e2"
2008   [(set (match_operand:SI 0 "register_operand" "=r")
2009       (ashift:SI
2010         (match_operand:SI 1 "register_operand" "r")
2011         (match_operand:SI 2 "nonmemory_operand" "r")))
2012    (clobber (reg:CC CC_REGNUM))]
2013   "TARGET_V850E2_UP"
2014   "shl %2,%1,%0"
2015   [(set_attr "length" "4")
2016    (set_attr "cc" "set_znv")])
2018 (define_insn "lshrsi3"
2019   [(set (match_operand:SI 0 "register_operand" "=r,r")
2020       (lshiftrt:SI
2021         (match_operand:SI 1 "register_operand" "0,0")
2022         (match_operand:SI 2 "nonmemory_operand" "r,N")))
2023    (clobber (reg:CC CC_REGNUM))]
2024   ""
2025   "@
2026   shr %2,%0
2027   shr %2,%0"
2028   [(set_attr "length" "4,2")
2029    (set_attr "cc" "set_zn")])
2031 (define_insn "lshrsi3_v850e2"
2032   [(set (match_operand:SI 0 "register_operand" "=r")
2033       (lshiftrt:SI
2034         (match_operand:SI 1 "register_operand" "r")
2035         (match_operand:SI 2 "nonmemory_operand" "r")))
2036    (clobber (reg:CC CC_REGNUM))]
2037   "TARGET_V850E2_UP"
2038   "shr %2,%1,%0"
2039   [(set_attr "length" "4")
2040    (set_attr "cc" "set_zn")])
2042 (define_insn "ashrsi3"
2043   [(set (match_operand:SI 0 "register_operand" "=r,r")
2044       (ashiftrt:SI
2045         (match_operand:SI 1 "register_operand" "0,0")
2046         (match_operand:SI 2 "nonmemory_operand" "r,N")))
2047    (clobber (reg:CC CC_REGNUM))]
2048   ""
2049   "@
2050   sar %2,%0
2051   sar %2,%0"
2052   [(set_attr "length" "4,2")
2053    (set_attr "cc" "set_zn, set_zn")])
2055 (define_insn "ashrsi3_v850e2"
2056   [(set (match_operand:SI 0 "register_operand" "=r")
2057       (ashiftrt:SI
2058         (match_operand:SI 1 "register_operand" "r")
2059         (match_operand:SI 2 "nonmemory_operand" "r")))
2060    (clobber (reg:CC CC_REGNUM))]
2061   "TARGET_V850E2_UP"
2062   "sar %2,%1,%0"
2063   [(set_attr "length" "4")
2064    (set_attr "cc" "set_zn")])
2066 ;; ----------------------------------------------------------------------
2067 ;; FIND FIRST BIT INSTRUCTION
2068 ;; ----------------------------------------------------------------------
2070 (define_insn "ffssi2"
2071   [(set (match_operand:SI 0 "register_operand" "=r")
2072        (ffs:SI (match_operand:SI 1 "register_operand" "r")))
2073    (clobber (reg:CC CC_REGNUM))]
2074   "TARGET_V850E2_UP"
2075   "sch1r %1,%0"
2076   [(set_attr "length" "4")
2077    (set_attr "cc" "clobber")])
2079 ;; ----------------------------------------------------------------------
2080 ;; PROLOGUE/EPILOGUE
2081 ;; ----------------------------------------------------------------------
2082 (define_expand "prologue"
2083   [(const_int 0)]
2084   ""
2085   {
2086     expand_prologue ();
2087     DONE;
2088   })
2090 (define_expand "epilogue"
2091   [(return)]
2092   ""
2093   {
2094     expand_epilogue ();
2095     DONE;
2096   })
2098 (define_insn "return_simple"
2099   [(return)]
2100   "reload_completed"
2101   "jmp [r31]"
2102   [(set_attr "length" "2")
2103    (set_attr "cc" "none")])
2105 (define_insn "return_internal"
2106   [(return)
2107    (use (reg:SI 31))]
2108   ""
2109   "jmp [r31]"
2110   [(set_attr "length" "2")
2111    (set_attr "cc" "none")])
2113 ;; ----------------------------------------------------------------------
2114 ;; v850e2V3 floating-point hardware support
2115 ;; ----------------------------------------------------------------------
2118 (define_insn "addsf3"
2119   [(set (match_operand:SF 0 "register_operand" "=r")
2120         (plus:SF (match_operand:SF 1 "register_operand" "r")
2121                  (match_operand:SF 2 "register_operand" "r")))]
2122   "TARGET_USE_FPU"
2123   "addf.s %1,%2,%0"
2124   [(set_attr "length" "4")
2125    (set_attr "cc" "none_0hit")
2126    (set_attr "type" "fpu")])
2128 (define_insn "adddf3"
2129   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2130         (plus:DF (match_operand:DF 1 "even_reg_operand" "r")
2131         (match_operand:DF 2 "even_reg_operand" "r")))]
2132   "TARGET_USE_FPU"
2133   "addf.d %1,%2,%0"
2134   [(set_attr "length" "4")
2135    (set_attr "cc" "none_0hit")
2136    (set_attr "type" "fpu")])
2138 (define_insn "subsf3"
2139   [(set (match_operand:SF 0 "register_operand" "=r")
2140         (minus:SF (match_operand:SF 1 "register_operand" "r")
2141                   (match_operand:SF 2 "register_operand" "r")))]
2142   "TARGET_USE_FPU"
2143   "subf.s %2,%1,%0"
2144   [(set_attr "length" "4")
2145    (set_attr "cc" "none_0hit")
2146    (set_attr "type" "fpu")])
2148 (define_insn "subdf3"
2149   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2150         (minus:DF (match_operand:DF 1 "even_reg_operand" "r")
2151                   (match_operand:DF 2 "even_reg_operand" "r")))]
2152   "TARGET_USE_FPU"
2153   "subf.d %2,%1,%0"
2154   [(set_attr "length" "4")
2155    (set_attr "cc" "none_0hit")
2156    (set_attr "type" "fpu")])
2158 (define_insn "mulsf3"
2159   [(set (match_operand:SF 0 "register_operand" "=r")
2160         (mult:SF (match_operand:SF 1 "register_operand" "r")
2161                  (match_operand:SF 2 "register_operand" "r")))]
2162   "TARGET_USE_FPU"
2163   "mulf.s %1,%2,%0"
2164   [(set_attr "length" "4")
2165    (set_attr "cc" "none_0hit")
2166    (set_attr "type" "fpu")])
2168 (define_insn "muldf3"
2169   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2170         (mult:DF (match_operand:DF 1 "even_reg_operand" "r")
2171                  (match_operand:DF 2 "even_reg_operand" "r")))]
2172   "TARGET_USE_FPU"
2173   "mulf.d %1,%2,%0"
2174   [(set_attr "length" "4")
2175    (set_attr "cc" "none_0hit")
2176    (set_attr "type" "fpu")])
2178 (define_insn "divsf3"
2179   [(set (match_operand:SF 0 "register_operand" "=r")
2180         (div:SF (match_operand:SF 1 "register_operand" "r")
2181                 (match_operand:SF 2 "register_operand" "r")))]
2182   "TARGET_USE_FPU"
2183   "divf.s %2,%1,%0"
2184   [(set_attr "length" "4")
2185    (set_attr "cc" "none_0hit")
2186    (set_attr "type" "fpu")])
2188 (define_insn "divdf3"
2189   [(set (match_operand:DF 0 "register_operand" "=r")
2190         (div:DF (match_operand:DF 1 "even_reg_operand" "r")
2191                 (match_operand:DF 2 "even_reg_operand" "r")))]
2192   "TARGET_USE_FPU"
2193   "divf.d %2,%1,%0"
2194   [(set_attr "length" "4")
2195    (set_attr "cc" "none_0hit")
2196    (set_attr "type" "fpu")])
2198 (define_insn "minsf3"
2199   [(set (match_operand:SF 0 "register_operand" "=r")
2200         (smin:SF (match_operand:SF 1 "reg_or_0_operand" "r")
2201                  (match_operand:SF 2 "reg_or_0_operand" "r")))]
2202   "TARGET_USE_FPU"
2203   "minf.s %z1,%z2,%0"
2204   [(set_attr "length" "4")
2205    (set_attr "cc" "none_0hit")
2206    (set_attr "type" "fpu")])
2208 (define_insn "mindf3"
2209   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2210         (smin:DF (match_operand:DF 1 "even_reg_operand" "r")
2211                  (match_operand:DF 2 "even_reg_operand" "r")))]
2212   "TARGET_USE_FPU"
2213   "minf.d %1,%2,%0"
2214   [(set_attr "length" "4")
2215    (set_attr "cc" "none_0hit")
2216    (set_attr "type" "fpu")])
2218 (define_insn "maxsf3"
2219   [(set (match_operand:SF 0 "register_operand" "=r")
2220         (smax:SF (match_operand:SF 1 "reg_or_0_operand" "r")
2221                  (match_operand:SF 2 "reg_or_0_operand" "r")))]
2222   "TARGET_USE_FPU"
2223   "maxf.s %z1,%z2,%0"
2224   [(set_attr "length" "4")
2225    (set_attr "cc" "none_0hit")
2226    (set_attr "type" "fpu")])
2228 (define_insn "maxdf3"
2229   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2230         (smax:DF (match_operand:DF 1 "even_reg_operand" "r")
2231                  (match_operand:DF 2 "even_reg_operand" "r")))]
2232   "TARGET_USE_FPU"
2233   "maxf.d %1,%2,%0"
2234   [(set_attr "length" "4")
2235    (set_attr "cc" "none_0hit")
2236    (set_attr "type" "fpu")])
2238 (define_insn "abssf2"
2239   [(set (match_operand:SF 0 "register_operand" "=r")
2240         (abs:SF (match_operand:SF 1 "register_operand" "r")))]
2241   "TARGET_USE_FPU"
2242   "absf.s %1,%0"
2243   [(set_attr "length" "4")
2244    (set_attr "cc" "none_0hit")
2245    (set_attr "type" "fpu")])
2247 (define_insn "absdf2"
2248   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2249         (abs:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2250   "TARGET_USE_FPU"
2251   "absf.d %1,%0"
2252   [(set_attr "length" "4")
2253    (set_attr "cc" "none_0hit")
2254    (set_attr "type" "fpu")])
2256 (define_insn "negsf2"
2257   [(set (match_operand:SF 0 "register_operand" "=r")
2258         (neg:SF (match_operand:SF 1 "register_operand" "r")))]
2259   "TARGET_USE_FPU"
2260   "negf.s %1,%0"
2261   [(set_attr "length" "4")
2262    (set_attr "cc" "none_0hit")
2263    (set_attr "type" "fpu")])
2265 (define_insn "negdf2"
2266   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2267         (neg:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2268   "TARGET_USE_FPU"
2269   "negf.d %1,%0"
2270   [(set_attr "length" "4")
2271    (set_attr "cc" "none_0hit")
2272    (set_attr "type" "fpu")])
2274 ;; square-root
2275 (define_insn "sqrtsf2"
2276   [(set (match_operand:SF 0 "register_operand" "=r")
2277         (sqrt:SF (match_operand:SF 1 "register_operand" "r")))]
2278   "TARGET_USE_FPU"
2279   "sqrtf.s %1,%0"
2280   [(set_attr "length" "4")
2281    (set_attr "cc" "none_0hit")
2282    (set_attr "type" "fpu")])
2284 (define_insn "sqrtdf2"
2285   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2286         (sqrt:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2287   "TARGET_USE_FPU"
2288   "sqrtf.d %1,%0"
2289   [(set_attr "length" "4")
2290    (set_attr "cc" "none_0hit")
2291    (set_attr "type" "fpu")])
2293 ;; float -> int
2294 (define_insn "fix_truncsfsi2"
2295   [(set (match_operand:SI 0 "register_operand" "=r")
2296         (fix:SI (match_operand:SF 1 "register_operand" "r")))]
2297   "TARGET_USE_FPU"
2298   "trncf.sw %1,%0"
2299   [(set_attr "length" "4")
2300    (set_attr "cc" "none_0hit")
2301    (set_attr "type" "fpu")])
2303 (define_insn "fixuns_truncsfsi2"
2304   [(set (match_operand:SI                  0 "register_operand" "=r")
2305         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "r")))]
2306   "TARGET_USE_FPU"
2307   "trncf.suw %1, %0"
2308   [(set_attr "length" "4")
2309    (set_attr "cc" "none_0hit")
2310    (set_attr "type" "fpu")]
2313 (define_insn "fix_truncdfsi2"
2314   [(set (match_operand:SI 0 "register_operand" "=r")
2315         (fix:SI (match_operand:DF 1 "even_reg_operand" "r")))]
2316   "TARGET_USE_FPU"
2317   "trncf.dw %1,%0"
2318   [(set_attr "length" "4")
2319    (set_attr "cc" "none_0hit")
2320    (set_attr "type" "fpu")])
2322 (define_insn "fixuns_truncdfsi2"
2323   [(set (match_operand:SI                  0 "register_operand" "=r")
2324         (unsigned_fix:SI (match_operand:DF 1 "even_reg_operand" "r")))]
2325   "TARGET_USE_FPU"
2326   "trncf.duw %1, %0"
2327   [(set_attr "length" "4")
2328    (set_attr "cc" "none_0hit")
2329    (set_attr "type" "fpu")]
2332 (define_insn "fix_truncsfdi2"
2333   [(set (match_operand:DI         0 "register_operand" "=r")
2334         (fix:DI (match_operand:SF 1 "register_operand" "r")))]
2335   "TARGET_USE_FPU"
2336   "trncf.sl %1, %0"
2337   [(set_attr "length" "4")
2338    (set_attr "cc" "none_0hit")
2339    (set_attr "type" "fpu")])
2341 (define_insn "fixuns_truncsfdi2"
2342   [(set (match_operand:DI                  0 "register_operand" "=r")
2343         (unsigned_fix:DI (match_operand:SF 1 "register_operand" "r")))]
2344   "TARGET_USE_FPU"
2345   "trncf.sul %1, %0"
2346   [(set_attr "length" "4")
2347    (set_attr "cc" "none_0hit")
2348    (set_attr "type" "fpu")]
2351 (define_insn "fix_truncdfdi2"
2352   [(set (match_operand:DI         0 "register_operand" "=r")
2353         (fix:DI (match_operand:DF 1 "even_reg_operand" "r")))]
2354   "TARGET_USE_FPU"
2355   "trncf.dl %1, %0"
2356   [(set_attr "length" "4")
2357    (set_attr "cc" "none_0hit")
2358    (set_attr "type" "fpu")])
2360 (define_insn "fixuns_truncdfdi2"
2361   [(set (match_operand:DI                  0 "register_operand" "=r")
2362         (unsigned_fix:DI (match_operand:DF 1 "even_reg_operand" "r")))]
2363   "TARGET_USE_FPU"
2364   "trncf.dul %1, %0"
2365   [(set_attr "length" "4")
2366    (set_attr "cc" "none_0hit")
2367    (set_attr "type" "fpu")]
2370 ;; int -> float
2371 (define_insn "floatsisf2"
2372   [(set (match_operand:SF 0 "register_operand" "=r")
2373         (float:SF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2374   "TARGET_USE_FPU"
2375   "cvtf.ws %z1, %0"
2376   [(set_attr "length" "4")
2377    (set_attr "cc" "none_0hit")
2378    (set_attr "type" "fpu")])
2380 (define_insn "unsfloatsisf2"
2381   [(set (match_operand:SF                    0 "register_operand" "=r")
2382         (unsigned_float:SF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2383   "TARGET_USE_FPU"
2384   "cvtf.uws %z1, %0"
2385   [(set_attr "length" "4")
2386    (set_attr "cc" "none_0hit")
2387    (set_attr "type" "fpu")])
2389 (define_insn "floatsidf2"
2390   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2391         (float:DF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2392   "TARGET_USE_FPU"
2393   "cvtf.wd %z1,%0"
2394   [(set_attr "length" "4")
2395    (set_attr "cc" "none_0hit")
2396    (set_attr "type" "fpu")])
2398 (define_insn "unsfloatsidf2"
2399   [(set (match_operand:DF                    0 "even_reg_operand" "=r")
2400         (unsigned_float:DF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2401   "TARGET_USE_FPU"
2402   "cvtf.uwd %z1, %0"
2403   [(set_attr "length" "4")
2404    (set_attr "cc" "none_0hit")
2405    (set_attr "type" "fpu")])
2407 (define_insn "floatdisf2"
2408   [(set (match_operand:SF           0 "even_reg_operand" "=r")
2409         (float:SF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2410   "TARGET_USE_FPU"
2411   "cvtf.ls %z1, %0"
2412   [(set_attr "length" "4")
2413    (set_attr "cc" "none_0hit")
2414    (set_attr "type" "fpu")])
2416 (define_insn "unsfloatdisf2"
2417   [(set (match_operand:SF                    0 "even_reg_operand" "=r")
2418         (unsigned_float:SF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2419   "TARGET_USE_FPU"
2420   "cvtf.uls %z1, %0"
2421   [(set_attr "length" "4")
2422    (set_attr "cc" "none_0hit")
2423    (set_attr "type" "fpu")])
2425 (define_insn "floatdidf2"
2426   [(set (match_operand:DF           0 "even_reg_operand" "=r")
2427         (float:DF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2428   "TARGET_USE_FPU"
2429   "cvtf.ld %z1, %0"
2430   [(set_attr "length" "4")
2431    (set_attr "cc" "none_0hit")
2432    (set_attr "type" "fpu")])
2434 (define_insn "unsfloatdidf2"
2435   [(set (match_operand:DF                    0 "even_reg_operand" "=r")
2436         (unsigned_float:DF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2437   "TARGET_USE_FPU"
2438   "cvtf.uld %z1, %0"
2439   [(set_attr "length" "4")
2440    (set_attr "cc" "none_0hit")
2441    (set_attr "type" "fpu")])
2443 ;; single-float -> double-float
2444 (define_insn "extendsfdf2"
2445   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2446         (float_extend:DF
2447          (match_operand:SF 1 "reg_or_0_operand" "rI")))]
2448   "TARGET_USE_FPU"
2449   "cvtf.sd %z1,%0"
2450   [(set_attr "length" "4")
2451    (set_attr "cc" "none_0hit")
2452    (set_attr "type" "fpu")])
2454 ;; double-float -> single-float
2455 (define_insn "truncdfsf2"
2456   [(set (match_operand:SF 0 "register_operand" "=r")
2457         (float_truncate:SF
2458          (match_operand:DF 1 "even_reg_operand" "r")))]
2459   "TARGET_USE_FPU"
2460   "cvtf.ds %1,%0"
2461   [(set_attr "length" "4")
2462    (set_attr "cc" "none_0hit")
2463    (set_attr "type" "fpu")])
2466 ;; ---------------- special insns
2469 ;;; reciprocal
2470 (define_insn "recipsf2"
2471   [(set (match_operand:SF 0 "register_operand" "=r")
2472         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2473                 (match_operand:SF 2 "register_operand" "r")))]
2474   "TARGET_USE_FPU"
2475   "recipf.s %2,%0"
2476   [(set_attr "length" "4")
2477    (set_attr "cc" "none_0hit")
2478    (set_attr "type" "fpu")])
2480 (define_insn "recipdf2"
2481   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2482         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2483                 (match_operand:DF 2 "even_reg_operand" "r")))]
2484   "TARGET_USE_FPU"
2485   "recipf.d %2,%0"
2486   [(set_attr "length" "4")
2487    (set_attr "cc" "none_0hit")
2488    (set_attr "type" "fpu")])
2490 ;;; reciprocal of square-root
2491 (define_insn "rsqrtsf2"
2492   [(set (match_operand:SF 0 "register_operand" "=r")
2493         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2494                 (sqrt:SF (match_operand:SF 2 "register_operand" "r"))))]
2495   "TARGET_USE_FPU"
2496   "rsqrtf.s %2,%0"
2497   [(set_attr "length" "4")
2498    (set_attr "cc" "none_0hit")
2499    (set_attr "type" "fpu")])
2501 (define_insn "rsqrtdf2"
2502   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2503         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2504                 (sqrt:DF (match_operand:DF 2 "even_reg_operand" "r"))))]
2505   "TARGET_USE_FPU"
2506   "rsqrtf.d %2,%0"
2507   [(set_attr "length" "4")
2508    (set_attr "cc" "none_0hit")
2509    (set_attr "type" "fpu")])
2511 ;;; multiply-add
2512 (define_insn "fmasf4"
2513   [(set (match_operand:SF         0 "register_operand" "=r")
2514         (fma:SF (match_operand:SF 1 "register_operand" "r")
2515                 (match_operand:SF 2 "register_operand" "r")
2516                 (match_operand:SF 3 "register_operand" "r")))]
2517   "TARGET_USE_FPU"
2518   "maddf.s %2,%1,%3,%0"
2519   [(set_attr "length" "4")
2520    (set_attr "cc" "none_0hit")
2521    (set_attr "type" "fpu")])
2523 ;;; multiply-subtract
2524 (define_insn "fmssf4"
2525   [(set (match_operand:SF                 0 "register_operand" "=r")
2526         (fma:SF (match_operand:SF         1 "register_operand" "r")
2527                 (match_operand:SF         2 "register_operand" "r")
2528                 (neg:SF (match_operand:SF 3 "register_operand" "r"))))]
2529   "TARGET_USE_FPU"
2530   "msubf.s %2,%1,%3,%0"
2531   [(set_attr "length" "4")
2532    (set_attr "cc" "none_0hit")
2533    (set_attr "type" "fpu")])
2535 ;;; negative-multiply-add
2536 (define_insn "fnmasf4"
2537   [(set (match_operand:SF                 0 "register_operand" "=r")
2538         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "r")
2539                         (match_operand:SF 2 "register_operand" "r")
2540                         (match_operand:SF 3 "register_operand" "r"))))]
2541   "TARGET_USE_FPU"
2542   "nmaddf.s %2,%1,%3,%0"
2543   [(set_attr "length" "4")
2544    (set_attr "cc" "none_0hit")
2545    (set_attr "type" "fpu")])
2547 ;; negative-multiply-subtract
2548 (define_insn "fnmssf4"
2549   [(set (match_operand:SF                 0 "register_operand" "=r")
2550         (neg:SF (fma:SF (match_operand:SF         1 "register_operand" "r")
2551                         (match_operand:SF         2 "register_operand" "r")
2552                         (neg:SF (match_operand:SF 3 "register_operand" "r")))))]
2553   "TARGET_USE_FPU"
2554   "nmsubf.s %2,%1,%3,%0"
2555   [(set_attr "length" "4")
2556    (set_attr "cc" "none_0hit")
2557    (set_attr "type" "fpu")])
2559 ; ---------------- comparison/conditionals
2561 ; SF
2563 (define_insn "cmpsf_le_insn"
2564   [(set (reg:CC_FPU_LE FCC_REGNUM)
2565         (compare:CC_FPU_LE (match_operand:SF 0 "register_operand" "r")
2566                            (match_operand:SF 1 "register_operand" "r")))]
2567   "TARGET_USE_FPU"
2568   "cmpf.s le, %z0, %z1"
2569   [(set_attr "length" "4")
2570    (set_attr "cc" "none_0hit")
2571    (set_attr "type" "fpu")])
2573 (define_insn "cmpsf_lt_insn"
2574   [(set (reg:CC_FPU_LT FCC_REGNUM)
2575         (compare:CC_FPU_LT (match_operand:SF 0 "register_operand" "r")
2576                            (match_operand:SF 1 "register_operand" "r")))]
2577   "TARGET_USE_FPU"
2578   "cmpf.s lt, %z0, %z1"
2579   [(set_attr "length" "4")
2580    (set_attr "cc" "none_0hit")
2581    (set_attr "type" "fpu")])
2583 (define_insn "cmpsf_ge_insn"
2584   [(set (reg:CC_FPU_GE FCC_REGNUM)
2585         (compare:CC_FPU_GE (match_operand:SF 0 "register_operand" "r")
2586                            (match_operand:SF 1 "register_operand" "r")))]
2587   "TARGET_USE_FPU"
2588   "cmpf.s le, %z1, %z0"
2589   [(set_attr "length" "4")
2590    (set_attr "cc" "none_0hit")
2591    (set_attr "type" "fpu")])
2593 (define_insn "cmpsf_gt_insn"
2594   [(set (reg:CC_FPU_GT FCC_REGNUM)
2595         (compare:CC_FPU_GT (match_operand:SF 0 "register_operand" "r")
2596                            (match_operand:SF 1 "register_operand" "r")))]
2597   "TARGET_USE_FPU"
2598   "cmpf.s lt, %z1, %z0"
2599   [(set_attr "length" "4")
2600    (set_attr "cc" "none_0hit")
2601    (set_attr "type" "fpu")])
2603 (define_insn "cmpsf_eq_insn"
2604   [(set (reg:CC_FPU_EQ FCC_REGNUM)
2605         (compare:CC_FPU_EQ (match_operand:SF 0 "register_operand" "r")
2606                            (match_operand:SF 1 "register_operand" "r")))]
2607   "TARGET_USE_FPU"
2608   "cmpf.s eq, %z0, %z1"
2609   [(set_attr "length" "4")
2610    (set_attr "cc" "none_0hit")
2611    (set_attr "type" "fpu")])
2613 ; DF
2615 (define_insn "cmpdf_le_insn"
2616   [(set (reg:CC_FPU_LE FCC_REGNUM)
2617         (compare:CC_FPU_LE (match_operand:DF 0 "even_reg_operand" "r")
2618                            (match_operand:DF 1 "even_reg_operand" "r")))]
2619   "TARGET_USE_FPU"
2620   "cmpf.d le, %z0, %z1"
2621   [(set_attr "length" "4")
2622    (set_attr "cc" "none_0hit")
2623    (set_attr "type" "fpu")])
2625 (define_insn "cmpdf_lt_insn"
2626   [(set (reg:CC_FPU_LT FCC_REGNUM)
2627         (compare:CC_FPU_LT (match_operand:DF 0 "even_reg_operand" "r")
2628                            (match_operand:DF 1 "even_reg_operand" "r")))]
2629   "TARGET_USE_FPU"
2630   "cmpf.d lt, %z0, %z1"
2631   [(set_attr "length" "4")
2632    (set_attr "cc" "none_0hit")
2633    (set_attr "type" "fpu")])
2635 (define_insn "cmpdf_ge_insn"
2636   [(set (reg:CC_FPU_GE FCC_REGNUM)
2637         (compare:CC_FPU_GE (match_operand:DF 0 "even_reg_operand" "r")
2638                            (match_operand:DF 1 "even_reg_operand" "r")))]
2639   "TARGET_USE_FPU"
2640   "cmpf.d le, %z1, %z0"
2641   [(set_attr "length" "4")
2642    (set_attr "cc" "none_0hit")
2643    (set_attr "type" "fpu")])
2645 (define_insn "cmpdf_gt_insn"
2646   [(set (reg:CC_FPU_GT FCC_REGNUM)
2647         (compare:CC_FPU_GT (match_operand:DF 0 "even_reg_operand" "r")
2648                            (match_operand:DF 1 "even_reg_operand" "r")))]
2649   "TARGET_USE_FPU"
2650   "cmpf.d lt, %z1, %z0"
2651   [(set_attr "length" "4")
2652    (set_attr "cc" "none_0hit")
2653    (set_attr "type" "fpu")])
2655 (define_insn "cmpdf_eq_insn"
2656   [(set (reg:CC_FPU_EQ FCC_REGNUM)
2657         (compare:CC_FPU_EQ (match_operand:DF 0 "even_reg_operand" "r")
2658                            (match_operand:DF 1 "even_reg_operand" "r")))]
2659   "TARGET_USE_FPU"
2660   "cmpf.d eq, %z0, %z1"
2661   [(set_attr "length" "4")
2662    (set_attr "cc" "none_0hit")
2663    (set_attr "type" "fpu")])
2666 ;; Transfer a v850e2v3 fcc to the Z bit of CC0 (this is necessary to do a
2667 ;; conditional branch based on a floating-point compare)
2670 (define_insn "trfsr"
2671   [(set (match_operand 0 "" "") (match_operand 1 "" ""))]
2672   "TARGET_USE_FPU
2673    && GET_MODE(operands[0]) == GET_MODE(operands[1])
2674    && GET_CODE(operands[0]) == REG && REGNO (operands[0]) == CC_REGNUM
2675    && GET_CODE(operands[1]) == REG && REGNO (operands[1]) == FCC_REGNUM
2676    && (GET_MODE(operands[0]) == CC_FPU_LEmode
2677        || GET_MODE(operands[0]) == CC_FPU_GEmode
2678        || GET_MODE(operands[0]) == CC_FPU_LTmode
2679        || GET_MODE(operands[0]) == CC_FPU_GTmode
2680        || GET_MODE(operands[0]) == CC_FPU_EQmode
2681        || GET_MODE(operands[0]) == CC_FPU_NEmode)"
2682   "trfsr"
2683   [(set_attr "length" "4")
2684    (set_attr "cc" "set_z")
2685    (set_attr "type" "fpu")])
2688 ;; Floating-point conditional moves for the v850e2v3.
2691 ;; The actual v850e2v3 conditional move instructions
2693 (define_insn "movsfcc_z_insn"
2694   [(set (match_operand:SF 0 "register_operand" "=r")
2695         (if_then_else:SF
2696          (match_operand 3 "v850_float_z_comparison_operator" "")
2697          (match_operand:SF 1 "reg_or_0_operand" "rIG")
2698          (match_operand:SF 2 "reg_or_0_operand" "rIG")))]
2699   "TARGET_USE_FPU"
2700   "cmovf.s 0,%z1,%z2,%0"
2701   [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2703 (define_insn "movsfcc_nz_insn"
2704   [(set (match_operand:SF 0 "register_operand" "=r")
2705         (if_then_else:SF
2706          (match_operand 3 "v850_float_nz_comparison_operator" "")
2707          (match_operand:SF 1 "reg_or_0_operand" "rIG")
2708          (match_operand:SF 2 "reg_or_0_operand" "rIG")))]
2709   "TARGET_USE_FPU"
2710   "cmovf.s 0,%z2,%z1,%0"
2711   [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2713 (define_insn "movdfcc_z_insn"
2714   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2715         (if_then_else:DF
2716          (match_operand 3 "v850_float_z_comparison_operator" "")
2717          (match_operand:DF 1 "even_reg_operand" "r")
2718          (match_operand:DF 2 "even_reg_operand" "r")))]
2719   "TARGET_USE_FPU"
2720   "cmovf.d 0,%z1,%z2,%0"
2721   [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2723 (define_insn "movdfcc_nz_insn"
2724   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2725         (if_then_else:DF
2726          (match_operand 3 "v850_float_nz_comparison_operator" "")
2727          (match_operand:DF 1 "even_reg_operand" "r")
2728          (match_operand:DF 2 "even_reg_operand" "r")))]
2729   "TARGET_USE_FPU"
2730   "cmovf.d 0,%z2,%z1,%0"
2731   [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2733 (define_insn "movedfcc_z_zero"
2734   [(set (match_operand:DF 0 "register_operand" "=r")
2735         (if_then_else:DF
2736          (match_operand 3 "v850_float_z_comparison_operator" "")
2737          (match_operand:DF 1 "reg_or_0_operand" "rIG")
2738          (match_operand:DF 2 "reg_or_0_operand" "rIG")))]
2739   "TARGET_USE_FPU"
2740   "cmovf.s 0,%z1,%z2,%0 ; cmovf.s 0,%Z1,%Z2,%R0"
2741   [(set_attr "length" "8")
2742    (set_attr "cc" "clobber")]) ;; ??? or none_0hit
2744 (define_insn "movedfcc_nz_zero"
2745   [(set (match_operand:DF 0 "register_operand" "=r")
2746         (if_then_else:DF
2747          (match_operand 3 "v850_float_nz_comparison_operator" "")
2748          (match_operand:DF 1 "reg_or_0_operand" "rIG")
2749          (match_operand:DF 2 "reg_or_0_operand" "rIG")))]
2750   "TARGET_USE_FPU"
2751   "cmovf.s 0,%z2,%z1,%0 ; cmovf.s 0,%Z2,%Z1,%R0"
2752   [(set_attr "length" "8")
2753    (set_attr "cc" "clobber")]) ;; ??? or none_0hit
2756 ;; ----------------------------------------------------------------------
2757 ;; HELPER INSTRUCTIONS for saving the prologue and epilogue registers
2758 ;; ----------------------------------------------------------------------
2760 ;; This pattern will match a stack adjust RTX followed by any number of push
2761 ;; RTXs.  These RTXs will then be turned into a suitable call to a worker
2762 ;; function.
2765 ;; Actually, convert the RTXs into a PREPARE instruction.
2768 (define_insn ""
2769  [(match_parallel 0 "pattern_is_ok_for_prepare"
2770    [(set (reg:SI 3)
2771          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2772     (set (mem:SI (plus:SI (reg:SI 3)
2773                           (match_operand:SI 2 "immediate_operand" "i")))
2774          (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
2775  "TARGET_PROLOG_FUNCTION && (TARGET_V850E_UP)"
2777   return construct_prepare_instruction (operands[0]);
2779  [(set_attr "length" "4")
2780   (set_attr "cc"     "clobber")])
2782 (define_insn ""
2783  [(match_parallel 0 "pattern_is_ok_for_prologue"
2784    [(set (reg:SI 3)
2785          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2786     (set (mem:SI (plus:SI (reg:SI 3)
2787                            (match_operand:SI 2 "immediate_operand" "i")))
2788          (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
2789  "TARGET_PROLOG_FUNCTION"
2791   return construct_save_jarl (operands[0]);
2793  [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
2794                                      (const_string "16")
2795                                      (const_string "4")))
2796   (set_attr "cc"     "clobber")])
2799 ;; Actually, turn the RTXs into a DISPOSE instruction.
2801 (define_insn ""
2802  [(match_parallel 0 "pattern_is_ok_for_dispose"
2803    [(return)
2804     (set (reg:SI 3)
2805          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2806     (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
2807          (mem:SI (plus:SI (reg:SI 3)
2808                           (match_operand:SI 3 "immediate_operand" "i"))))])]
2809  "TARGET_PROLOG_FUNCTION && (TARGET_V850E_UP)"
2811   return construct_dispose_instruction (operands[0]);
2813  [(set_attr "length" "4")
2814   (set_attr "cc"     "clobber")])
2816 ;; This pattern will match a return RTX followed by any number of pop RTXs
2817 ;; and possible a stack adjustment as well.  These RTXs will be turned into
2818 ;; a suitable call to a worker function.
2820 (define_insn ""
2821 [(match_parallel 0 "pattern_is_ok_for_epilogue"
2822    [(return)
2823     (set (reg:SI 3)
2824          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2825     (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
2826          (mem:SI (plus:SI (reg:SI 3)
2827                           (match_operand:SI 3 "immediate_operand" "i"))))])]
2828  "TARGET_PROLOG_FUNCTION"
2830   return construct_restore_jr (operands[0]);
2832  [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
2833                                      (const_string "12")
2834                                      (const_string "4")))
2835   (set_attr "cc"     "clobber")])
2837 ;; Initialize an interrupt function.  Do not depend on TARGET_PROLOG_FUNCTION.
2838 (define_insn "callt_save_interrupt"
2839   [(unspec_volatile [(const_int 0)] 2)]
2840     "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2841     ;; The CALLT instruction stores the next address of CALLT to CTPC register
2842     ;; without saving its previous value.  So if the interrupt handler
2843     ;; or its caller could possibly execute the CALLT insn, save_interrupt 
2844     ;; MUST NOT be called via CALLT.
2846   output_asm_insn ("addi -28,   sp, sp", operands);
2847   output_asm_insn ("st.w r1,    24[sp]", operands);
2848   output_asm_insn ("st.w r10,   12[sp]", operands);
2849   output_asm_insn ("st.w r11,   16[sp]", operands);
2850   output_asm_insn ("stsr ctpc,  r10",    operands);
2851   output_asm_insn ("st.w r10,   20[sp]", operands);
2852   output_asm_insn ("stsr ctpsw, r10",    operands);
2853   output_asm_insn ("st.w r10,   24[sp]", operands);
2854   output_asm_insn ("callt ctoff(__callt_save_interrupt)", operands);
2855   return "";
2857    [(set_attr "length" "26")
2858     (set_attr "cc" "clobber")])
2860 (define_insn "callt_return_interrupt"
2861   [(unspec_volatile [(const_int 0)] 3)]
2862   "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2863   "callt ctoff(__callt_return_interrupt)"
2864   [(set_attr "length" "2")
2865    (set_attr "cc" "clobber")])
2867 (define_insn "save_interrupt"
2868   [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -20)))
2869    (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 30))
2870    (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 4))
2871    (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))
2872    (set (mem:SI (plus:SI (reg:SI 3) (const_int  -8))) (reg:SI 10))
2873    (set (mem:SI (plus:SI (reg:SI 3) (const_int  -4))) (reg:SI 11))]
2874   ""
2876   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2877     return "addi -20,sp,sp \; st.w r11,16[sp] \; st.w r10,12[sp] \; jarl __save_interrupt,r10";
2878   else
2879     {
2880       output_asm_insn ("addi  -20, sp, sp", operands);
2881       output_asm_insn ("st.w  r11, 16[sp]", operands);
2882       output_asm_insn ("st.w  r10, 12[sp]", operands);
2883       output_asm_insn ("st.w  ep, 0[sp]", operands);
2884       output_asm_insn ("st.w  gp, 4[sp]", operands);
2885       output_asm_insn ("st.w  r1, 8[sp]", operands);
2886       output_asm_insn ("movhi hi(__ep), r0, ep", operands);
2887       output_asm_insn ("movea lo(__ep), ep, ep", operands);
2888       output_asm_insn ("movhi hi(__gp), r0, gp", operands);
2889       output_asm_insn ("movea lo(__gp), gp, gp", operands);
2890       return "";
2891     }
2893   [(set (attr "length")
2894         (if_then_else (match_test "TARGET_LONG_CALLS")
2895                        (const_int 10)
2896                        (const_int 34)))
2897    (set_attr "cc" "clobber")])
2898   
2899 ;; Restore r1, r4, r10, and return from the interrupt
2900 (define_insn "return_interrupt"
2901   [(return)
2902    (set (reg:SI 3)  (plus:SI (reg:SI 3) (const_int 20)))
2903    (set (reg:SI 11) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))
2904    (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
2905    (set (reg:SI 1)  (mem:SI (plus:SI (reg:SI 3) (const_int  8))))
2906    (set (reg:SI 4)  (mem:SI (plus:SI (reg:SI 3) (const_int  4))))
2907    (set (reg:SI 30) (mem:SI (reg:SI 3)))]
2908   ""
2910   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2911     return "jr __return_interrupt";
2912   else 
2913     {
2914       output_asm_insn ("ld.w 0[sp],  ep",   operands);
2915       output_asm_insn ("ld.w 4[sp],  gp",   operands);
2916       output_asm_insn ("ld.w 8[sp],  r1",   operands);
2917       output_asm_insn ("ld.w 12[sp], r10", operands);
2918       output_asm_insn ("ld.w 16[sp], r11", operands);
2919       output_asm_insn ("addi 20, sp, sp",   operands);
2920       output_asm_insn ("reti",            operands);
2921       return "";
2922     }
2924   [(set (attr "length")
2925         (if_then_else (match_test "TARGET_LONG_CALLS")
2926                        (const_int 4)
2927                        (const_int 24)))
2928    (set_attr "cc" "clobber")])
2930 ;; Save all registers except for the registers saved in save_interrupt when
2931 ;; an interrupt function makes a call.
2932 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2933 ;; all of memory.  This blocks insns from being moved across this point.
2934 ;; This is needed because the rest of the compiler is not ready to handle
2935 ;; insns this complicated.
2937 (define_insn "callt_save_all_interrupt"
2938   [(unspec_volatile [(const_int 0)] 0)]
2939   "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2940   "callt ctoff(__callt_save_all_interrupt)"
2941   [(set_attr "length" "2")
2942    (set_attr "cc" "none")])
2944 (define_insn "save_all_interrupt"
2945   [(unspec_volatile [(const_int 0)] 0)]
2946   ""
2948   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2949     return "jarl __save_all_interrupt,r10";
2951   output_asm_insn ("addi -120, sp, sp", operands);
2953   if (TARGET_EP)
2954     {
2955       output_asm_insn ("mov ep, r1", operands);
2956       output_asm_insn ("mov sp, ep", operands);
2957       output_asm_insn ("sst.w r31, 116[ep]", operands);
2958       output_asm_insn ("sst.w r2,  112[ep]", operands);
2959       output_asm_insn ("sst.w gp,  108[ep]", operands);
2960       output_asm_insn ("sst.w r6,  104[ep]", operands);
2961       output_asm_insn ("sst.w r7,  100[ep]", operands);
2962       output_asm_insn ("sst.w r8,   96[ep]", operands);
2963       output_asm_insn ("sst.w r9,   92[ep]", operands);
2964       output_asm_insn ("sst.w r11,  88[ep]", operands);
2965       output_asm_insn ("sst.w r12,  84[ep]", operands);
2966       output_asm_insn ("sst.w r13,  80[ep]", operands);
2967       output_asm_insn ("sst.w r14,  76[ep]", operands);
2968       output_asm_insn ("sst.w r15,  72[ep]", operands);
2969       output_asm_insn ("sst.w r16,  68[ep]", operands);
2970       output_asm_insn ("sst.w r17,  64[ep]", operands);
2971       output_asm_insn ("sst.w r18,  60[ep]", operands);
2972       output_asm_insn ("sst.w r19,  56[ep]", operands);
2973       output_asm_insn ("sst.w r20,  52[ep]", operands);
2974       output_asm_insn ("sst.w r21,  48[ep]", operands);
2975       output_asm_insn ("sst.w r22,  44[ep]", operands);
2976       output_asm_insn ("sst.w r23,  40[ep]", operands);
2977       output_asm_insn ("sst.w r24,  36[ep]", operands);
2978       output_asm_insn ("sst.w r25,  32[ep]", operands);
2979       output_asm_insn ("sst.w r26,  28[ep]", operands);
2980       output_asm_insn ("sst.w r27,  24[ep]", operands);
2981       output_asm_insn ("sst.w r28,  20[ep]", operands);
2982       output_asm_insn ("sst.w r29,  16[ep]", operands);
2983       output_asm_insn ("mov   r1,   ep", operands);
2984     }
2985   else
2986     {
2987       output_asm_insn ("st.w r31, 116[sp]", operands);
2988       output_asm_insn ("st.w r2,  112[sp]", operands);
2989       output_asm_insn ("st.w gp,  108[sp]", operands);
2990       output_asm_insn ("st.w r6,  104[sp]", operands);
2991       output_asm_insn ("st.w r7,  100[sp]", operands);
2992       output_asm_insn ("st.w r8,   96[sp]", operands);
2993       output_asm_insn ("st.w r9,   92[sp]", operands);
2994       output_asm_insn ("st.w r11,  88[sp]", operands);
2995       output_asm_insn ("st.w r12,  84[sp]", operands);
2996       output_asm_insn ("st.w r13,  80[sp]", operands);
2997       output_asm_insn ("st.w r14,  76[sp]", operands);
2998       output_asm_insn ("st.w r15,  72[sp]", operands);
2999       output_asm_insn ("st.w r16,  68[sp]", operands);
3000       output_asm_insn ("st.w r17,  64[sp]", operands);
3001       output_asm_insn ("st.w r18,  60[sp]", operands);
3002       output_asm_insn ("st.w r19,  56[sp]", operands);
3003       output_asm_insn ("st.w r20,  52[sp]", operands);
3004       output_asm_insn ("st.w r21,  48[sp]", operands);
3005       output_asm_insn ("st.w r22,  44[sp]", operands);
3006       output_asm_insn ("st.w r23,  40[sp]", operands);
3007       output_asm_insn ("st.w r24,  36[sp]", operands);
3008       output_asm_insn ("st.w r25,  32[sp]", operands);
3009       output_asm_insn ("st.w r26,  28[sp]", operands);
3010       output_asm_insn ("st.w r27,  24[sp]", operands);
3011       output_asm_insn ("st.w r28,  20[sp]", operands);
3012       output_asm_insn ("st.w r29,  16[sp]", operands);
3013     }
3014     
3015   return "";
3017   [(set (attr "length")
3018         (if_then_else (match_test "TARGET_LONG_CALLS")
3019                        (const_int 4)
3020                        (const_int 62)
3021         ))
3022    (set_attr "cc" "clobber")])
3024 (define_insn "_save_all_interrupt"
3025   [(unspec_volatile [(const_int 0)] 0)]
3026   "TARGET_V850 && ! TARGET_LONG_CALLS"
3027   "jarl __save_all_interrupt,r10"
3028   [(set_attr "length" "4")
3029    (set_attr "cc" "clobber")])
3031 ;; Restore all registers saved when an interrupt function makes a call.
3032 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3033 ;; all of memory.  This blocks insns from being moved across this point.
3034 ;; This is needed because the rest of the compiler is not ready to handle
3035 ;; insns this complicated.
3037 (define_insn "callt_restore_all_interrupt"
3038   [(unspec_volatile [(const_int 0)] 1)]
3039   "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
3040   "callt ctoff(__callt_restore_all_interrupt)"
3041   [(set_attr "length" "2")
3042    (set_attr "cc" "none")])
3044 (define_insn "restore_all_interrupt"
3045   [(unspec_volatile [(const_int 0)] 1)]
3046   ""
3048   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
3049     return "jarl __restore_all_interrupt,r10";
3051   if (TARGET_EP)
3052     {
3053       output_asm_insn ("mov   ep,      r1", operands);
3054       output_asm_insn ("mov   sp,      ep", operands);
3055       output_asm_insn ("sld.w 116[ep], r31", operands);
3056       output_asm_insn ("sld.w 112[ep], r2", operands);
3057       output_asm_insn ("sld.w 108[ep], gp", operands);
3058       output_asm_insn ("sld.w 104[ep], r6", operands);
3059       output_asm_insn ("sld.w 100[ep], r7", operands);
3060       output_asm_insn ("sld.w 96[ep],  r8", operands);
3061       output_asm_insn ("sld.w 92[ep],  r9", operands);
3062       output_asm_insn ("sld.w 88[ep],  r11", operands);
3063       output_asm_insn ("sld.w 84[ep],  r12", operands);
3064       output_asm_insn ("sld.w 80[ep],  r13", operands);
3065       output_asm_insn ("sld.w 76[ep],  r14", operands);
3066       output_asm_insn ("sld.w 72[ep],  r15", operands);
3067       output_asm_insn ("sld.w 68[ep],  r16", operands);
3068       output_asm_insn ("sld.w 64[ep],  r17", operands);
3069       output_asm_insn ("sld.w 60[ep],  r18", operands);
3070       output_asm_insn ("sld.w 56[ep],  r19", operands);
3071       output_asm_insn ("sld.w 52[ep],  r20", operands);
3072       output_asm_insn ("sld.w 48[ep],  r21", operands);
3073       output_asm_insn ("sld.w 44[ep],  r22", operands);
3074       output_asm_insn ("sld.w 40[ep],  r23", operands);
3075       output_asm_insn ("sld.w 36[ep],  r24", operands);
3076       output_asm_insn ("sld.w 32[ep],  r25", operands);
3077       output_asm_insn ("sld.w 28[ep],  r26", operands);
3078       output_asm_insn ("sld.w 24[ep],  r27", operands);
3079       output_asm_insn ("sld.w 20[ep],  r28", operands);
3080       output_asm_insn ("sld.w 16[ep],  r29", operands);
3081       output_asm_insn ("mov   r1,      ep", operands);
3082     }
3083   else
3084     {
3085       output_asm_insn ("ld.w 116[sp], r31", operands);
3086       output_asm_insn ("ld.w 112[sp], r2", operands);
3087       output_asm_insn ("ld.w 108[sp], gp", operands);
3088       output_asm_insn ("ld.w 104[sp], r6", operands);
3089       output_asm_insn ("ld.w 100[sp], r7", operands);
3090       output_asm_insn ("ld.w 96[sp],  r8", operands);
3091       output_asm_insn ("ld.w 92[sp],  r9", operands);
3092       output_asm_insn ("ld.w 88[sp],  r11", operands);
3093       output_asm_insn ("ld.w 84[sp],  r12", operands);
3094       output_asm_insn ("ld.w 80[sp],  r13", operands);
3095       output_asm_insn ("ld.w 76[sp],  r14", operands);
3096       output_asm_insn ("ld.w 72[sp],  r15", operands);
3097       output_asm_insn ("ld.w 68[sp],  r16", operands);
3098       output_asm_insn ("ld.w 64[sp],  r17", operands);
3099       output_asm_insn ("ld.w 60[sp],  r18", operands);
3100       output_asm_insn ("ld.w 56[sp],  r19", operands);
3101       output_asm_insn ("ld.w 52[sp],  r20", operands);
3102       output_asm_insn ("ld.w 48[sp],  r21", operands);
3103       output_asm_insn ("ld.w 44[sp],  r22", operands);
3104       output_asm_insn ("ld.w 40[sp],  r23", operands);
3105       output_asm_insn ("ld.w 36[sp],  r24", operands);
3106       output_asm_insn ("ld.w 32[sp],  r25", operands);
3107       output_asm_insn ("ld.w 28[sp],  r26", operands);
3108       output_asm_insn ("ld.w 24[sp],  r27", operands);
3109       output_asm_insn ("ld.w 20[sp],  r28", operands);
3110       output_asm_insn ("ld.w 16[sp],  r29", operands);
3111     }
3112   output_asm_insn ("addi  120, sp, sp", operands);
3113   return "";
3115   [(set (attr "length")
3116         (if_then_else (match_test "TARGET_LONG_CALLS")
3117                        (const_int 4)
3118                        (const_int 62)
3119         ))
3120    (set_attr "cc" "clobber")])
3122 (define_insn "_restore_all_interrupt"
3123   [(unspec_volatile [(const_int 0)] 1)]
3124   "TARGET_V850 && ! TARGET_LONG_CALLS"
3125   "jarl __restore_all_interrupt,r10"
3126   [(set_attr "length" "4")
3127    (set_attr "cc" "clobber")])