PR jit/66539: Properly add testcase
[official-gcc.git] / gcc / config / v850 / v850.md
blob7f2c5bb1bfbc641701bbc3ccdcd79a20333420be
1 ;; GCC machine description for NEC V850
2 ;; Copyright (C) 1996-2015 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 "nonimmediate_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 "nonimmediate_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 (temp, gen_rtx_HIGH (SImode, operand1)));
322         emit_insn (gen_rtx_SET (operand0,
323                                 gen_rtx_LO_SUM (SImode, temp, operand1)));
324         DONE;
325       }
326   })
328 ;; This is the same as the following pattern, except that it includes
329 ;; support for arbitrary 32-bit immediates.
331 ;; ??? This always loads addresses using hilo.  If the only use of this address
332 ;; was in a load/store, then we would get smaller code if we only loaded the
333 ;; upper part with hi, and then put the lower part in the load/store insn.
335 (define_insn "*movsi_internal_v850e"
336   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,Q,r,r,m,m,r")
337         (match_operand:SI 1 "general_operand" "Jr,K,L,Q,Ir,m,R,r,I,i"))]
338   "(TARGET_V850E_UP)
339    && (register_operand (operands[0], SImode)
340        || reg_or_0_operand (operands[1], SImode))"
342   return output_move_single (operands);
344   [(set_attr "length" "2,4,4,2,2,4,4,4,4,6")
345    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
346    (set_attr "type" "other,other,other,load,other,load,other,store,store,other")])
348 (define_insn "*movsi_internal"
349   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,Q,r,r,m,m")
350         (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))]
351   "register_operand (operands[0], SImode)
352    || reg_or_0_operand (operands[1], SImode)"
354   return output_move_single (operands);
356   [(set_attr "length" "2,4,4,2,2,4,4,4,4")
357    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
358    (set_attr "type" "other,other,other,load,other,load,store,store,other")])
360 (define_insn "*movsf_internal"
361   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,Q,r,m,m,r")
362         (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))]
363   "register_operand (operands[0], SFmode)
364    || reg_or_0_operand (operands[1], SFmode)"
366   return output_move_single (operands);
368   [(set_attr "length" "2,4,4,8,2,2,4,4,4,8")
369    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
370    (set_attr "type" "other,other,other,other,load,other,load,store,store,other")])
372 ;; ----------------------------------------------------------------------
373 ;; TEST INSTRUCTIONS
374 ;; ----------------------------------------------------------------------
376 (define_insn "*v850_tst1"
377   [(set (cc0)
378         (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
379                                   (const_int 1)
380                                   (match_operand:QI 1 "const_int_operand" "n"))
381                  (const_int 0)))]
382   ""
383   "tst1 %1,%0"
384   [(set_attr "length" "4")
385    (set_attr "cc" "clobber")])
387 ;; This replaces ld.b;sar;andi with tst1;setf nz.
389 (define_split
390   [(set (match_operand:SI 0 "register_operand" "")
391         (compare (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
392                                   (const_int 1)
393                                   (match_operand 2 "const_int_operand" ""))
394                  (const_int 0)))]
395   ""
396   [(set (cc0) (compare (zero_extract:SI (match_dup 1)
397                                         (const_int 1)
398                                         (match_dup 2))
399                        (const_int 0)))
400    (set (match_dup 0) (ne:SI (cc0) (const_int 0)))])
402 (define_expand "cbranchsi4"
403   [(set (cc0)
404         (compare (match_operand:SI 1 "register_operand" "")
405                  (match_operand:SI 2 "reg_or_int5_operand" "")))
406    (set (pc)
407         (if_then_else
408               (match_operator 0 "ordered_comparison_operator" [(cc0)
409                                                                (const_int 0)])
410               (label_ref (match_operand 3 "" ""))
411               (pc)))]
412  "")
414 (define_expand "cstoresi4"
415   [(set (cc0)
416         (compare (match_operand:SI 2 "register_operand" "")
417                  (match_operand:SI 3 "reg_or_int5_operand" "")))
418    (set (match_operand:SI 0 "register_operand")
419         (match_operator:SI 1 "ordered_comparison_operator" [(cc0)
420                                                             (const_int 0)]))]
421   "")
423 (define_expand "cmpsi"
424   [(set (cc0)
425         (compare (match_operand:SI 0 "register_operand" "r,r")
426                  (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
427    ""
428   {
429     v850_compare_op0 = operands[0];
430     v850_compare_op1 = operands[1];
431     DONE;
432   })
434 (define_insn "cmpsi_insn"
435   [(set (cc0)
436         (compare (match_operand:SI 0 "register_operand" "r,r")
437                  (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
438   ""
439   "@
440   cmp %1,%0
441   cmp %1,%0"
442   [(set_attr "length" "2,2")
443    (set_attr "cc" "compare")])
445 (define_expand "cbranchsf4"
446   [(set (pc)
447        (if_then_else (match_operator     0 "ordered_comparison_operator"
448                       [(match_operand:SF 1 "register_operand")
449                        (match_operand:SF 2 "register_operand")])
450                      (label_ref (match_operand 3 ""))
451                      (pc)))
452   (clobber (cc0))]
453   "TARGET_USE_FPU"
455   enum rtx_code cond = GET_CODE (operands[0]);
456   machine_mode mode;
457   rtx fcc_reg;
458   rtx cc_reg;
459   rtx tmp;
461   v850_compare_op0 = operands[1];
462   v850_compare_op1 = operands[2];
464   if (GET_MODE_CLASS (GET_MODE (v850_compare_op0)) != MODE_FLOAT)
465     FAIL;
467   mode = v850_gen_float_compare (cond, VOIDmode, v850_compare_op0, v850_compare_op1);
468   fcc_reg = gen_rtx_REG (mode, FCC_REGNUM);
469   cc_reg = gen_rtx_REG (mode, CC_REGNUM);
470   emit_insn (gen_rtx_SET (cc_reg, fcc_reg));
471   tmp = gen_rtx_fmt_ee (cond, mode, cc_reg, const0_rtx);
472   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
473                               gen_rtx_LABEL_REF (VOIDmode, operands[3]), pc_rtx);
474   emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
475   DONE;
478 (define_insn "cstoresf4"
479   [(set (match_operand:SI   0 "register_operand" "=r")
480         (match_operator:SI  1 "ordered_comparison_operator"
481          [(match_operand:SF 2 "register_operand" "r")
482           (match_operand:SF 3 "register_operand" "r")]))]
483   "TARGET_USE_FPU"
485   if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
486     return "cmpf.s %c1, %z2, %z3 ; trfsr ; setf nz, %0";
487   if (GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE)
488     return "cmpf.s %c1, %z2, %z3 ; trfsr ; setf z, %0";
489   if (GET_CODE (operands[1]) == EQ)
490     return "cmpf.s eq, %z2, %z3 ; trfsr ; setf z, %0";
491   if (GET_CODE (operands[1]) == NE)
492     return "cmpf.s neq, %z2, %z3 ; trfsr ; setf nz, %0";
493   gcc_unreachable ();
495   [(set_attr "length" "12")
496    (set_attr "type" "fpu")]
499 (define_expand "cbranchdf4"
500   [(set (pc)
501        (if_then_else (match_operator     0 "ordered_comparison_operator"
502                       [(match_operand:DF 1 "even_reg_operand")
503                        (match_operand:DF 2 "even_reg_operand")])
504                      (label_ref (match_operand 3 ""))
505                      (pc)))
506   (clobber (cc0))]
507   "TARGET_USE_FPU"
509   enum rtx_code cond = GET_CODE (operands[0]);
510   machine_mode mode;
511   rtx fcc_reg;
512   rtx cc_reg;
513   rtx tmp;
515     v850_compare_op0 = operands[1];
516     v850_compare_op1 = operands[2];
518   if (GET_MODE_CLASS (GET_MODE (v850_compare_op0)) != MODE_FLOAT)
519     FAIL;
521   mode = v850_gen_float_compare (cond, VOIDmode, v850_compare_op0, v850_compare_op1);
522   fcc_reg = gen_rtx_REG (mode, FCC_REGNUM);
523   cc_reg = gen_rtx_REG (mode, CC_REGNUM);
524   emit_insn (gen_rtx_SET (cc_reg, fcc_reg));
525   tmp = gen_rtx_fmt_ee (cond, mode, cc_reg, const0_rtx);
526   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
527                               gen_rtx_LABEL_REF (VOIDmode, operands[3]), pc_rtx);
528   emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
529   DONE;
532 (define_insn "cstoredf4"
533   [(set (match_operand:SI   0 "register_operand" "=r")
534         (match_operator:SI  1 "ordered_comparison_operator"
535          [(match_operand:DF 2 "even_reg_operand"  "r")
536           (match_operand:DF 3 "even_reg_operand" "r")]))]
537   "TARGET_USE_FPU"
539   if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
540     return "cmpf.d %c1, %z2, %z3 ; trfsr ; setf nz, %0";
541   if (GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE)
542     return "cmpf.d %c1, %z2, %z3 ; trfsr ; setf z, %0";
543   if (GET_CODE (operands[1]) == EQ)
544     return "cmpf.d eq, %z2, %z3 ; trfsr ; setf z ,%0";
545   if (GET_CODE (operands[1]) == NE)
546     return "cmpf.d neq, %z2, %z3 ; trfsr ; setf nz, %0";
547   gcc_unreachable ();
549   [(set_attr "length" "12")
550    (set_attr "type" "fpu")]
553 (define_expand "cmpsf"
554   [(set (reg:CC CC_REGNUM)
555         (compare (match_operand:SF 0 "register_operand" "r")
556                  (match_operand:SF 1 "register_operand" "r")))]
557   "TARGET_USE_FPU"
558   {
559     v850_compare_op0 = operands[0];
560     v850_compare_op1 = operands[1];
561     DONE;
562   })
564 (define_expand "cmpdf"
565   [(set (reg:CC CC_REGNUM)
566         (compare (match_operand:DF 0 "even_reg_operand" "r")
567                  (match_operand:DF 1 "even_reg_operand" "r")))]
568   "TARGET_USE_FPU"
569   {
570     v850_compare_op0 = operands[0];
571     v850_compare_op1 = operands[1];
572     DONE;
573   })
575 ;; ----------------------------------------------------------------------
576 ;; ADD INSTRUCTIONS
577 ;; ----------------------------------------------------------------------
579 (define_insn "addsi3"
580   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
581         (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
582                  (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))
583    (clobber (reg:CC CC_REGNUM))]
585   ""
586   "@
587    add %2,%0
588    addi %2,%1,%0
589    addi %O2(%P2),%1,%0"
590   [(set_attr "length" "2,4,4")
591    (set_attr "cc" "set_zn,set_zn,set_zn")])
593 ;; ----------------------------------------------------------------------
594 ;; SUBTRACT INSTRUCTIONS
595 ;; ----------------------------------------------------------------------
597 (define_insn "subsi3"
598   [(set (match_operand:SI 0 "register_operand" "=r,r")
599         (minus:SI (match_operand:SI 1 "register_operand" "0,r")
600                   (match_operand:SI 2 "register_operand" "r,0")))
601    (clobber (reg:CC CC_REGNUM))]
602   ""
603   "@
604   sub %2,%0
605   subr %1,%0"
606   [(set_attr "length" "2,2")
607    (set_attr "cc" "set_zn,set_zn")])
609 (define_insn "negsi2"
610   [(set (match_operand:SI 0 "register_operand" "=r")
611         (neg:SI (match_operand:SI 1 "register_operand" "0")))
612    (clobber (reg:CC CC_REGNUM))]
613   ""
614   "subr %.,%0"
615   [(set_attr "length" "2")
616    (set_attr "cc" "set_zn")])
618 ;; ----------------------------------------------------------------------
619 ;; MULTIPLY INSTRUCTIONS
620 ;; ----------------------------------------------------------------------
622 (define_expand "mulhisi3"
623   [(set (match_operand:SI 0 "register_operand" "")
624         (mult:SI
625           (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
626           (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
627   ""
628   {
629     if (GET_CODE (operands[2]) == CONST_INT)
630       {
631         emit_insn (gen_mulhisi3_internal2 (operands[0], operands[1], operands[2]));
632         DONE;
633       }
634   })
636 (define_insn "*mulhisi3_internal1"
637   [(set (match_operand:SI 0 "register_operand" "=r")
638         (mult:SI
639           (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
640           (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
641   ""
642   "mulh %2,%0"
643   [(set_attr "length" "2")
644    (set_attr "cc" "none_0hit")
645    (set_attr "type" "mult")])
647 (define_insn "mulhisi3_internal2"
648   [(set (match_operand:SI 0 "register_operand" "=r,r")
649         (mult:SI
650           (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
651           (match_operand:HI 2 "const_int_operand" "J,K")))]
652   ""
653   "@
654    mulh %2,%0
655    mulhi %2,%1,%0"
656   [(set_attr "length" "2,4")
657    (set_attr "cc" "none_0hit,none_0hit")
658    (set_attr "type" "mult")])
660 ;; ??? The scheduling info is probably wrong.
662 ;; ??? This instruction can also generate the 32-bit highpart, but using it
663 ;; may increase code size counter to the desired result.
665 ;; ??? This instructions can also give a DImode result.
667 ;; ??? There is unsigned version, but it matters only for the DImode/highpart
668 ;; results.
670 (define_insn "mulsi3"
671   [(set (match_operand:SI 0 "register_operand" "=r")
672         (mult:SI (match_operand:SI 1 "register_operand" "%0")
673                  (match_operand:SI 2 "reg_or_int9_operand" "rO")))]
674   "(TARGET_V850E_UP)"
675   "mul %2,%1,%."
676   [(set_attr "length" "4")
677    (set_attr "cc" "none_0hit")
678    (set_attr "type" "mult")])
680 ;; ----------------------------------------------------------------------
681 ;; DIVIDE INSTRUCTIONS
682 ;; ----------------------------------------------------------------------
684 ;; ??? These insns do set the Z/N condition codes, except that they are based
685 ;; on only one of the two results, so it doesn't seem to make sense to use
686 ;; them.
688 ;; ??? The scheduling info is probably wrong.
690 (define_insn "divmodsi4"
691   [(set (match_operand:SI 0 "register_operand" "=r")
692         (div:SI (match_operand:SI 1 "register_operand" "0")
693                 (match_operand:SI 2 "register_operand" "r")))
694    (set (match_operand:SI 3 "register_operand" "=r")
695         (mod:SI (match_dup 1)
696                 (match_dup 2)))
697    (clobber (reg:CC CC_REGNUM))]
698   "TARGET_V850E_UP"
700   if (TARGET_V850E2_UP)
701     return "divq %2,%0,%3";
702    else
703     return "div %2,%0,%3";
705   [(set_attr "length" "4")
706    (set_attr "cc" "clobber")
707    (set_attr "type" "div")])
708         
709 (define_insn "udivmodsi4"
710   [(set (match_operand:SI 0 "register_operand" "=r")
711         (udiv:SI (match_operand:SI 1 "register_operand" "0")
712                  (match_operand:SI 2 "register_operand" "r")))
713    (set (match_operand:SI 3 "register_operand" "=r")
714         (umod:SI (match_dup 1)
715                  (match_dup 2)))
716    (clobber (reg:CC CC_REGNUM))]
717   "TARGET_V850E_UP"
719   if (TARGET_V850E2_UP)
720     return "divqu %2,%0,%3";
721   else
722     return "divu %2,%0,%3";
724   [(set_attr "length" "4")
725    (set_attr "cc" "clobber")
726    (set_attr "type" "div")])
727         
728 ;; ??? There is a 2 byte instruction for generating only the quotient.
729 ;; However, it isn't clear how to compute the length field correctly.
731 (define_insn "divmodhi4"
732   [(set (match_operand:HI 0 "register_operand" "=r")
733         (div:HI (match_operand:HI 1 "register_operand" "0")
734                 (match_operand:HI 2 "register_operand" "r")))
735    (set (match_operand:HI 3 "register_operand" "=r")
736         (mod:HI (match_dup 1)
737                 (match_dup 2)))
738    (clobber (reg:CC CC_REGNUM))]
739   "TARGET_V850E_UP"
740   "divh %2,%0,%3"
741   [(set_attr "length" "4")
742    (set_attr "cc" "clobber")
743    (set_attr "type" "div")])
745 ;; Half-words are sign-extended by default, so we must zero extend to a word
746 ;; here before doing the divide.
748 (define_insn "udivmodhi4"
749   [(set (match_operand:HI 0 "register_operand" "=r")
750         (udiv:HI (match_operand:HI 1 "register_operand" "0")
751                  (match_operand:HI 2 "register_operand" "r")))
752    (set (match_operand:HI 3 "register_operand" "=r")
753         (umod:HI (match_dup 1)
754                  (match_dup 2)))
755    (clobber (reg:CC CC_REGNUM))]
756   "TARGET_V850E_UP"
757   "zxh %0 ; divhu %2,%0,%3"
758   [(set_attr "length" "4")
759    (set_attr "cc" "clobber")
760    (set_attr "type" "div")])
762 ;; ----------------------------------------------------------------------
763 ;; AND INSTRUCTIONS
764 ;; ----------------------------------------------------------------------
766 (define_insn "*v850_clr1_1"
767   [(set (match_operand:QI 0 "memory_operand" "=m")
768         (subreg:QI
769           (and:SI (subreg:SI (match_dup 0) 0)
770                   (match_operand:QI 1 "not_power_of_two_operand" "")) 0))
771    (clobber (reg:CC CC_REGNUM))]
772   ""
774   rtx xoperands[2];
775   xoperands[0] = operands[0];
776   xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
777   output_asm_insn ("clr1 %M1,%0", xoperands);
778   return "";
780   [(set_attr "length" "4")
781    (set_attr "cc" "clobber")
782    (set_attr "type" "bit1")])
784 (define_insn "*v850_clr1_2"
785   [(set (match_operand:HI 0 "indirect_operand" "=m")
786         (subreg:HI
787           (and:SI (subreg:SI (match_dup 0) 0)
788                   (match_operand:HI 1 "not_power_of_two_operand" "")) 0))
789    (clobber (reg:CC CC_REGNUM))]
790   ""
792   int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
794   rtx xoperands[2];
795   xoperands[0] = gen_rtx_MEM (QImode,
796                               plus_constant (Pmode, XEXP (operands[0], 0),
797                                              log2 / 8));
798   xoperands[1] = GEN_INT (log2 % 8);
799   output_asm_insn ("clr1 %1,%0", xoperands);
800   return "";
802   [(set_attr "length" "4")
803    (set_attr "cc" "clobber")
804    (set_attr "type" "bit1")])
806 (define_insn "*v850_clr1_3"
807   [(set (match_operand:SI 0 "indirect_operand" "=m")
808         (and:SI (match_dup 0)
809                 (match_operand:SI 1 "not_power_of_two_operand" "")))
810    (clobber (reg:CC CC_REGNUM))]
811   ""
813   int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
815   rtx xoperands[2];
816   xoperands[0] = gen_rtx_MEM (QImode,
817                               plus_constant (Pmode, XEXP (operands[0], 0),
818                                              log2 / 8));
819   xoperands[1] = GEN_INT (log2 % 8);
820   output_asm_insn ("clr1 %1,%0", xoperands);
821   return "";
823   [(set_attr "length" "4")
824    (set_attr "cc" "clobber")
825    (set_attr "type" "bit1")])
827 (define_insn "andsi3"
828   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
829         (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
830                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
831    (clobber (reg:CC CC_REGNUM))]
832   ""
833   "@
834   and %2,%0
835   and %.,%0
836   andi %2,%1,%0"
837   [(set_attr "length" "2,2,4")
838    (set_attr "cc" "set_zn")])
840 ;; ----------------------------------------------------------------------
841 ;; OR INSTRUCTIONS
842 ;; ----------------------------------------------------------------------
844 (define_insn "*v850_set1_1"
845   [(set (match_operand:QI 0 "memory_operand" "=m")
846         (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
847                            (match_operand 1 "power_of_two_operand" "")) 0))
848    (clobber (reg:CC CC_REGNUM))]
849   ""
850   "set1 %M1,%0"
851   [(set_attr "length" "4")
852    (set_attr "cc" "clobber")
853    (set_attr "type" "bit1")])
855 (define_insn "*v850_set1_2"
856   [(set (match_operand:HI 0 "indirect_operand" "=m")
857         (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
858                            (match_operand 1 "power_of_two_operand" "")) 0))]
859   ""
861   int log2 = exact_log2 (INTVAL (operands[1]));
863   if (log2 < 8)
864     return "set1 %M1,%0";
865   else
866     {
867       rtx xoperands[2];
868       xoperands[0] = gen_rtx_MEM (QImode,
869                                   plus_constant (Pmode, XEXP (operands[0], 0),
870                                                  log2 / 8));
871       xoperands[1] = GEN_INT (log2 % 8);
872       output_asm_insn ("set1 %1,%0", xoperands);
873     }
874   return "";
876   [(set_attr "length" "4")
877    (set_attr "cc" "clobber")
878    (set_attr "type" "bit1")])
880 (define_insn "*v850_set1_3"
881   [(set (match_operand:SI 0 "indirect_operand" "=m")
882         (ior:SI (match_dup 0)
883                 (match_operand 1 "power_of_two_operand" "")))
884    (clobber (reg:CC CC_REGNUM))]
885   ""
887   int log2 = exact_log2 (INTVAL (operands[1]));
889   if (log2 < 8)
890     return "set1 %M1,%0";
891   else
892     {
893       rtx xoperands[2];
894       xoperands[0] = gen_rtx_MEM (QImode,
895                                   plus_constant (Pmode, XEXP (operands[0], 0),
896                                                  log2 / 8));
897       xoperands[1] = GEN_INT (log2 % 8);
898       output_asm_insn ("set1 %1,%0", xoperands);
899     }
900   return "";
902   [(set_attr "length" "4")
903    (set_attr "cc" "clobber")
904    (set_attr "type" "bit1")])
906 (define_insn "iorsi3"
907   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
908         (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
909                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
910    (clobber (reg:CC CC_REGNUM))]
911   ""
912   "@
913   or %2,%0
914   or %.,%0
915   ori %2,%1,%0"
916   [(set_attr "length" "2,2,4")
917    (set_attr "cc" "set_zn")])
919 ;; ----------------------------------------------------------------------
920 ;; XOR INSTRUCTIONS
921 ;; ----------------------------------------------------------------------
923 (define_insn "*v850_not1_1"
924   [(set (match_operand:QI 0 "memory_operand" "=m")
925         (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0)
926                            (match_operand 1 "power_of_two_operand" "")) 0))
927    (clobber (reg:CC CC_REGNUM))]
928   ""
929   "not1 %M1,%0"
930   [(set_attr "length" "4")
931    (set_attr "cc" "clobber")
932    (set_attr "type" "bit1")])
934 (define_insn "*v850_not1_2"
935   [(set (match_operand:HI 0 "indirect_operand" "=m")
936         (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
937                            (match_operand 1 "power_of_two_operand" "")) 0))]
938   ""
940   int log2 = exact_log2 (INTVAL (operands[1]));
942   if (log2 < 8)
943     return "not1 %M1,%0";
944   else
945     {
946       rtx xoperands[2];
947       xoperands[0] = gen_rtx_MEM (QImode,
948                                   plus_constant (Pmode, XEXP (operands[0], 0),
949                                                  log2 / 8));
950       xoperands[1] = GEN_INT (log2 % 8);
951       output_asm_insn ("not1 %1,%0", xoperands);
952     }
953   return "";
955   [(set_attr "length" "4")
956    (set_attr "cc" "clobber")
957    (set_attr "type" "bit1")])
959 (define_insn "*v850_not1_3"
960   [(set (match_operand:SI 0 "indirect_operand" "=m")
961         (xor:SI (match_dup 0)
962                 (match_operand 1 "power_of_two_operand" "")))
963    (clobber (reg:CC CC_REGNUM))]
964   ""
966   int log2 = exact_log2 (INTVAL (operands[1]));
968   if (log2 < 8)
969     return "not1 %M1,%0";
970   else
971     {
972       rtx xoperands[2];
973       xoperands[0] = gen_rtx_MEM (QImode,
974                                   plus_constant (Pmode, XEXP (operands[0], 0),
975                                                  log2 / 8));
976       xoperands[1] = GEN_INT (log2 % 8);
977       output_asm_insn ("not1 %1,%0", xoperands);
978     }
979   return "";
981   [(set_attr "length" "4")
982    (set_attr "cc" "clobber")
983    (set_attr "type" "bit1")])
985 (define_insn "xorsi3"
986   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
987         (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
988                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
989    (clobber (reg:CC CC_REGNUM))]
990   ""
991   "@
992   xor %2,%0
993   xor %.,%0
994   xori %2,%1,%0"
995   [(set_attr "length" "2,2,4")
996    (set_attr "cc" "set_zn")])
998 ;; ----------------------------------------------------------------------
999 ;; NOT INSTRUCTIONS
1000 ;; ----------------------------------------------------------------------
1002 (define_insn "one_cmplsi2"
1003   [(set (match_operand:SI 0 "register_operand" "=r")
1004         (not:SI (match_operand:SI 1 "register_operand" "r")))
1005    (clobber (reg:CC CC_REGNUM))]
1006   ""
1007   "not %1,%0"
1008   [(set_attr "length" "2")
1009    (set_attr "cc" "set_zn")])
1011 ;; -----------------------------------------------------------------
1012 ;; BIT FIELDS
1013 ;; -----------------------------------------------------------------
1015 ;; ??? Is it worth defining insv and extv for the V850 series?!?
1017 ;; An insv pattern would be useful, but does not get used because
1018 ;; store_bit_field never calls insv when storing a constant value into a
1019 ;; single-bit bitfield.
1021 ;; extv/extzv patterns would be useful, but do not get used because
1022 ;; optimize_bitfield_compare in fold-const usually converts single
1023 ;; bit extracts into an AND with a mask.
1025 (define_insn "insv"
1026   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1027                          (match_operand:SI 1 "immediate_operand" "n")
1028                          (match_operand:SI 2 "immediate_operand" "n"))
1029         (match_operand:SI 3 "register_operand" "r"))]
1030   "TARGET_V850E3V5_UP"
1031   "bins %3, %2, %1, %0"
1032   [(set_attr "length" "4")
1033    (set_attr "cc" "set_zn")]
1036 ;; -----------------------------------------------------------------
1037 ;; Scc INSTRUCTIONS
1038 ;; -----------------------------------------------------------------
1040 (define_insn "*setcc"
1041   [(set (match_operand:SI 0 "register_operand" "=r")
1042         (match_operator:SI 1 "comparison_operator"
1043          [(cc0) (const_int 0)]))]
1044   ""
1046   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1047       && (GET_CODE (operands[1]) == GT
1048           || GET_CODE (operands[1]) == GE
1049           || GET_CODE (operands[1]) == LE
1050           || GET_CODE (operands[1]) == LT))
1051     return 0;
1053   return "setf %c1,%0";
1055   [(set_attr "length" "4")
1056    (set_attr "cc" "none_0hit")])
1058 (define_insn "setf_insn"
1059   [(set (match_operand:SI 0 "register_operand" "=r")
1060         (match_operator:SI 1 "comparison_operator"
1061                           [(reg:CC CC_REGNUM) (const_int 0)]))]
1062   ""
1063   "setf %b1,%0"
1064   [(set_attr "length" "4")
1065    (set_attr "cc" "none_0hit")])
1067 (define_insn "set_z_insn"
1068   [(set (match_operand:SI 0 "register_operand" "=r")
1069         (match_operand 1 "v850_float_z_comparison_operator" ""))]
1070   "TARGET_V850E2V3_UP"
1071   "setf z,%0"
1072   [(set_attr "length" "4")
1073    (set_attr "cc" "none_0hit")])
1075 (define_insn "set_nz_insn" 
1076   [(set (match_operand:SI 0 "register_operand" "=r")
1077         (match_operand 1 "v850_float_nz_comparison_operator" ""))]
1078   "TARGET_V850E2V3_UP"
1079   "setf nz,%0"
1080   [(set_attr "length" "4")
1081    (set_attr "cc" "none_0hit")])
1083 ;; ----------------------------------------------------------------------
1084 ;; CONDITIONAL MOVE INSTRUCTIONS
1085 ;; ----------------------------------------------------------------------
1087 ;; Instructions using cc0 aren't allowed to have input reloads, so we must
1088 ;; hide the fact that this instruction uses cc0.  We do so by including the
1089 ;; compare instruction inside it.
1091 (define_expand "movsicc"
1092   [(set (match_operand:SI 0 "register_operand" "=r")
1093         (if_then_else:SI
1094          (match_operand 1 "comparison_operator")
1095          (match_operand:SI 2 "reg_or_const_operand" "rJ")
1096          (match_operand:SI 3 "reg_or_const_operand" "rI")))]
1097   "(TARGET_V850E_UP)"
1098   {
1099     /* Make sure that we have an integer comparison...  */
1100     if (GET_MODE (XEXP (operands[1], 0)) != CCmode
1101         && GET_MODE (XEXP (operands[1], 0)) != SImode)
1102       FAIL;
1104     if ((GET_CODE (operands[2]) == CONST_INT
1105         && GET_CODE (operands[3]) == CONST_INT))
1106       {
1107         int o2 = INTVAL (operands[2]);
1108         int o3 = INTVAL (operands[3]);
1110         if (o2 == 1 && o3 == 0)
1111           FAIL;   /* setf */
1112         if (o3 == 1 && o2 == 0)
1113           FAIL;   /* setf */
1114         if (o2 == 0 && (o3 < -16 || o3 > 15) && exact_log2 (o3) >= 0)
1115           FAIL;   /* setf + shift */
1116         if (o3 == 0 && (o2 < -16 || o2 > 15) && exact_log2 (o2) >=0)
1117           FAIL;   /* setf + shift */
1118         if (o2 != 0)
1119           operands[2] = copy_to_mode_reg (SImode, operands[2]);
1120         if (o3 !=0 )
1121           operands[3] = copy_to_mode_reg (SImode, operands[3]);
1122       }
1123     else
1124       {
1125         if (GET_CODE (operands[2]) != REG)
1126           operands[2] = copy_to_mode_reg (SImode,operands[2]);
1127         if (GET_CODE (operands[3]) != REG)
1128           operands[3] = copy_to_mode_reg (SImode, operands[3]);
1129       }
1130   })
1132 ;; ??? Clobbering the condition codes is overkill.
1134 ;; ??? We sometimes emit an unnecessary compare instruction because the
1135 ;; condition codes may have already been set by an earlier instruction,
1136 ;; but we have no code here to avoid the compare if it is unnecessary.
1138 (define_insn "movsicc_normal_cc"
1139   [(set (match_operand:SI 0 "register_operand" "=r")
1140         (if_then_else:SI
1141          (match_operator 1 "comparison_operator"
1142                          [(reg:CC CC_REGNUM) (const_int 0)])
1143          (match_operand:SI 2 "reg_or_int5_operand" "rJ")
1144          (match_operand:SI 3 "reg_or_0_operand" "rI")))]
1145   "(TARGET_V850E_UP)"
1146   "cmov %c1,%2,%z3,%0";
1147   [(set_attr "length" "6")
1148    (set_attr "cc" "compare")])
1150 (define_insn "movsicc_reversed_cc"
1151   [(set (match_operand:SI 0 "register_operand" "=r")
1152         (if_then_else:SI
1153          (match_operator 1 "comparison_operator"
1154                          [(reg:CC CC_REGNUM) (const_int 0)])
1155          (match_operand:SI 2 "reg_or_0_operand" "rI")
1156          (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
1157   "(TARGET_V850E_UP)"
1158   "cmov %C1,%3,%z2,%0"
1159   [(set_attr "length" "6")
1160    (set_attr "cc" "compare")])
1162 (define_insn "*movsicc_normal"
1163   [(set (match_operand:SI 0 "register_operand" "=r")
1164         (if_then_else:SI
1165          (match_operator 1 "comparison_operator"
1166                          [(match_operand:SI 4 "register_operand" "r")
1167                           (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
1168          (match_operand:SI 2 "reg_or_int5_operand" "rJ")
1169          (match_operand:SI 3 "reg_or_0_operand" "rI")))]
1170   "(TARGET_V850E_UP)"
1171   "cmp %5,%4 ; cmov %c1,%2,%z3,%0"
1172   [(set_attr "length" "6")
1173    (set_attr "cc" "clobber")])
1175 (define_insn "*movsicc_reversed"
1176   [(set (match_operand:SI 0 "register_operand" "=r")
1177         (if_then_else:SI
1178          (match_operator 1 "comparison_operator"
1179                          [(match_operand:SI 4 "register_operand" "r")
1180                           (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
1181          (match_operand:SI 2 "reg_or_0_operand" "rI")
1182          (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
1183   "(TARGET_V850E_UP)"
1184   "cmp %5,%4 ; cmov %C1,%3,%z2,%0"
1185   [(set_attr "length" "6")
1186    (set_attr "cc" "clobber")])
1188 (define_insn "*movsicc_tst1"
1189   [(set (match_operand:SI 0 "register_operand" "=r")
1190         (if_then_else:SI
1191          (match_operator 1 "comparison_operator"
1192                          [(zero_extract:SI
1193                            (match_operand:QI 2 "memory_operand" "m")
1194                            (const_int 1)
1195                            (match_operand 3 "const_int_operand" "n"))
1196                           (const_int 0)])
1197          (match_operand:SI 4 "reg_or_int5_operand" "rJ")
1198          (match_operand:SI 5 "reg_or_0_operand" "rI")))]
1199   "(TARGET_V850E_UP)"
1200   "tst1 %3,%2 ; cmov %c1,%4,%z5,%0"
1201   [(set_attr "length" "8")
1202    (set_attr "cc" "clobber")])
1204 (define_insn "*movsicc_tst1_reversed"
1205   [(set (match_operand:SI 0 "register_operand" "=r")
1206         (if_then_else:SI
1207          (match_operator 1 "comparison_operator"
1208                          [(zero_extract:SI
1209                            (match_operand:QI 2 "memory_operand" "m")
1210                            (const_int 1)
1211                            (match_operand 3 "const_int_operand" "n"))
1212                           (const_int 0)])
1213          (match_operand:SI 4 "reg_or_0_operand" "rI")
1214          (match_operand:SI 5 "reg_or_int5_operand" "rJ")))]
1215   "(TARGET_V850E_UP)"
1216   "tst1 %3,%2 ; cmov %C1,%5,%z4,%0"
1217   [(set_attr "length" "8")
1218    (set_attr "cc" "clobber")])
1220 ;; Matching for sasf requires combining 4 instructions, so we provide a
1221 ;; dummy pattern to match the first 3, which will always be turned into the
1222 ;; second pattern by subsequent combining.  As above, we must include the
1223 ;; comparison to avoid input reloads in an insn using cc0.
1225 (define_insn "*sasf"
1226   [(set (match_operand:SI 0 "register_operand" "=r")
1227         (ior:SI
1228          (match_operator 1 "comparison_operator"
1229                          [(match_operand:SI 3 "register_operand" "r")
1230                           (match_operand:SI 4 "reg_or_int5_operand" "rJ")])
1231          (ashift:SI (match_operand:SI 2 "register_operand" "0")
1232                     (const_int 1))))
1233    (clobber (reg:CC CC_REGNUM))]
1234   "(TARGET_V850E_UP)"
1235   "cmp %4,%3 ; sasf %c1,%0"
1236   [(set_attr "length" "6")
1237    (set_attr "cc" "clobber")])
1239 (define_split
1240   [(set (match_operand:SI 0 "register_operand" "")
1241         (if_then_else:SI
1242          (match_operator 1 "comparison_operator"
1243                          [(match_operand:SI 4 "register_operand" "")
1244                           (match_operand:SI 5 "reg_or_int5_operand" "")])
1245          (match_operand:SI 2 "const_int_operand" "")
1246          (match_operand:SI 3 "const_int_operand" "")))
1247    (clobber (reg:CC CC_REGNUM))]
1248   "(TARGET_V850E_UP)
1249    && ((INTVAL (operands[2]) ^ INTVAL (operands[3])) == 1)
1250    && ((INTVAL (operands[2]) + INTVAL (operands[3])) != 1)
1251    && (GET_CODE (operands[5]) == CONST_INT
1252       || REGNO (operands[0]) != REGNO (operands[5]))
1253    && REGNO (operands[0]) != REGNO (operands[4])"
1254   [(set (match_dup 0) (match_dup 6))
1255    (parallel [(set (match_dup 0)
1256                    (ior:SI (match_op_dup 7 [(match_dup 4) (match_dup 5)])
1257                            (ashift:SI (match_dup 0) (const_int 1))))
1258               (clobber (reg:CC CC_REGNUM))])]
1259   {
1260     operands[6] = GEN_INT (INTVAL (operands[2]) >> 1);
1261     if (INTVAL (operands[2]) & 0x1)
1262       operands[7] = operands[1];
1263     else
1264       operands[7] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
1265                                     GET_MODE (operands[1]),
1266                                     XEXP (operands[1], 0), XEXP (operands[1], 1));
1267   })
1269 ;; ---------------------------------------------------------------------
1270 ;; BYTE SWAP INSTRUCTIONS
1271 ;; ---------------------------------------------------------------------
1272 (define_expand "rotlhi3"
1273   [(parallel [(set (match_operand:HI 0 "register_operand" "")
1274                    (rotate:HI (match_operand:HI 1 "register_operand" "")
1275                               (match_operand:HI 2 "const_int_operand" "")))
1276               (clobber (reg:CC CC_REGNUM))])]
1277   "(TARGET_V850E_UP)"
1278   {
1279     if (INTVAL (operands[2]) != 8)
1280       FAIL;
1281   })
1283 (define_insn "*rotlhi3_8"
1284   [(set (match_operand:HI 0 "register_operand" "=r")
1285         (rotate:HI (match_operand:HI 1 "register_operand" "r")
1286                    (const_int 8)))
1287    (clobber (reg:CC CC_REGNUM))]
1288   "(TARGET_V850E_UP)"
1289   "bsh %1,%0"
1290   [(set_attr "length" "4")
1291    (set_attr "cc" "clobber")])
1293 (define_expand "rotlsi3"
1294   [(parallel [(set (match_operand:SI 0 "register_operand" "")
1295                    (rotate:SI (match_operand:SI 1 "register_operand" "")
1296                               (match_operand:SI 2 "const_int_operand" "")))
1297               (clobber (reg:CC CC_REGNUM))])]
1298   "(TARGET_V850E_UP)"
1299   {
1300     if (INTVAL (operands[2]) != 16)
1301       FAIL;
1302   })
1304 (define_insn "rotlsi3_a"
1305   [(set (match_operand:SI 0 "register_operand" "=r")
1306      (match_operator:SI 4 "ior_operator"
1307        [(ashift:SI (match_operand:SI 1 "register_operand" "r")
1308                    (match_operand:SI 2 "const_int_operand" "n"))
1309         (lshiftrt:SI (match_dup 1)
1310         (match_operand:SI 3 "const_int_operand" "n"))]))]
1311   "TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)"
1312   "rotl %2, %1, %0"
1313   [(set_attr "length" "4")
1314    (set_attr "cc" "set_zn")]
1317 (define_insn "rotlsi3_b"
1318   [(set (match_operand:SI 0 "register_operand" "=r")
1319      (match_operator:SI 4 "ior_operator"
1320        [(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1321                      (match_operand:SI 3 "const_int_operand" "n"))
1322         (ashift:SI (match_dup 1)
1323                    (match_operand:SI 2 "const_int_operand" "n"))]))]
1324   "TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)"
1325   "rotl %2, %1, %0"
1326   [(set_attr "length" "4")
1327    (set_attr "cc" "set_zn")]
1330 (define_insn "rotlsi3_v850e3v5"
1331   [(set (match_operand:SI 0 "register_operand" "=r")
1332         (rotate:SI (match_operand:SI 1 "register_operand" "r")
1333                    (match_operand:SI 2 "e3v5_shift_operand" "rn")))
1334               (clobber (reg:CC CC_REGNUM))]
1335   "TARGET_V850E3V5_UP"
1336   "rotl %2, %1, %0"
1337   [(set_attr "length" "4")
1338    (set_attr "cc" "set_zn")]
1341 (define_insn "*rotlsi3_16"
1342   [(set (match_operand:SI 0 "register_operand" "=r")
1343         (rotate:SI (match_operand:SI 1 "register_operand" "r")
1344                    (const_int 16)))
1345    (clobber (reg:CC CC_REGNUM))]
1346   "(TARGET_V850E_UP)"
1347   "hsw %1,%0"
1348   [(set_attr "length" "4")
1349    (set_attr "cc" "clobber")])
1351 ;; ----------------------------------------------------------------------
1352 ;; JUMP INSTRUCTIONS
1353 ;; ----------------------------------------------------------------------
1355 ;; Doloop
1357 (define_expand "doloop_begin"
1358  [(use (match_operand 0 "" ""))        ; loop pseudo
1359   (use (match_operand 1 "" ""))]       ; doloop_end pattern
1360   "TARGET_V850E3V5_UP && TARGET_LOOP"
1361   {
1362     rtx loop_cnt = operands[0];
1363     gcc_assert (GET_MODE (loop_cnt) == SImode);
1364     emit_insn (gen_fix_loop_counter (loop_cnt));
1365     DONE;
1366   }
1369 (define_insn "fix_loop_counter"
1370   [(unspec:SI [(match_operand:SI          0 "register_operand" "+r,!m")
1371                (clobber (match_scratch:SI 1                    "=X,r"))] UNSPEC_LOOP)]
1372   "TARGET_V850E3V5_UP && TARGET_LOOP"
1373   {
1374     switch (which_alternative)
1375     {
1376     case 0:  return "add 1, %0 # LOOP_BEGIN";
1377     case 1:  return "ld.w %0, %1; add 1, %1; st.w %1, %0 # LOOP_BEGIN";
1378     default: gcc_unreachable ();
1379     }
1380   }
1381   [(set_attr "length" "2,6")
1382    (set_attr "cc" "none")]
1385 (define_expand "doloop_end"
1386  [(use (match_operand 0 "" ""))        ; loop pseudo
1387   (use (match_operand 1 "" ""))]       ; label
1388   "TARGET_V850E3V5_UP && TARGET_LOOP"
1389   {
1390     rtx loop_cnt = operands[0];
1391     rtx label    = operands[1];
1393     if (GET_MODE (loop_cnt) != SImode)
1394       FAIL;
1396     emit_jump_insn (gen_doloop_end_internal_loop (label, loop_cnt));
1397     DONE;
1398   }
1401 (define_insn "doloop_end_internal_loop"
1402  [(set (pc)
1403        (if_then_else (ne (match_operand:SI 1 "register_operand" "+r,!m")
1404                          (const_int 0))
1405                      (label_ref (match_operand 0 "" ""))
1406                      (pc)))
1407   (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))
1408   (clobber (match_scratch:SI 2 "=X,r"))
1409   (clobber (reg:CC CC_REGNUM))]
1410   "TARGET_V850E3V5_UP && TARGET_LOOP"
1411   {
1412     switch (which_alternative)
1413     {
1414     case 0:
1415       if (get_attr_length (insn) == 4)
1416         return "loop %1, %0 # LOOP.1.0";
1418       return "add -1, %1; bne %l0 # LOOP.1.1";
1419     case 1:
1420       return "ld.w %1, %2; add -1, %2; st.w %2, %1; bne %l0 # LOOP.2.1";
1421     default:
1422       gcc_unreachable ();
1423     }
1424   }
1425  [(set (attr "length")
1426        (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1427                      (const_int 65534))
1428                      (const_int 4)
1429                      (const_int 14)))
1430   (set_attr "cc" "none")])
1432 ;; Conditional jump instructions
1434 (define_insn "*branch_normal"
1435   [(set (pc)
1436         (if_then_else (match_operator 1 "comparison_operator"
1437                                       [(cc0) (const_int 0)])
1438                       (label_ref (match_operand 0 "" ""))
1439                       (pc)))]
1440   ""
1442   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1443       && (GET_CODE (operands[1]) == GT
1444           || GET_CODE (operands[1]) == GE
1445           || GET_CODE (operands[1]) == LE
1446           || GET_CODE (operands[1]) == LT))
1447     return 0;
1449   if (get_attr_length (insn) == 2)
1450     return "b%b1 %l0";
1451   if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1452     return "b%b1 %l0";
1453   return "b%B1 .+6 ; jr %l0";
1455  [(set (attr "length")
1456     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1457                       (const_int 256))
1458                   (const_int 2)
1459                   (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1460                       (const_int 65536))
1461                       (const_int 4)
1462                       (const_int 6))))
1463   (set_attr "cc" "none")])
1465 (define_insn "*branch_invert"
1466   [(set (pc)
1467         (if_then_else (match_operator 1 "comparison_operator"
1468                                       [(cc0) (const_int 0)])
1469                       (pc)
1470                       (label_ref (match_operand 0 "" ""))))]
1471   ""
1473   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1474       && (GET_CODE (operands[1]) == GT
1475           || GET_CODE (operands[1]) == GE
1476           || GET_CODE (operands[1]) == LE
1477           || GET_CODE (operands[1]) == LT))
1478     return NULL;
1480   if (get_attr_length (insn) == 2)
1481     return "b%B1 %l0";
1483   if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1484     return "b%B1 %l0";
1485     
1486   return "b%b1 .+6 ; jr %l0";
1488  [(set (attr "length")
1489     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1490                       (const_int 256))
1491                   (const_int 2)
1492                   (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1493                       (const_int 65536))
1494                       (const_int 4)
1495                       (const_int 6))))
1496   (set_attr "cc" "none")])
1498 (define_insn "branch_z_normal"  
1499   [(set (pc)
1500         (if_then_else (match_operand 1 "v850_float_z_comparison_operator" "")
1501                       (label_ref (match_operand 0 "" ""))
1502                       (pc)))]
1503   "TARGET_V850E2V3_UP"
1505   if (get_attr_length (insn) == 2)
1506     return "bz %l0";
1508   if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1509     return "bz %l0";
1511   return "bnz 1f ; jr %l0 ; 1:";
1513  [(set (attr "length")
1514     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1515                       (const_int 256))
1516                   (const_int 2)
1517                   (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1518                       (const_int 65536))
1519                       (const_int 4)
1520                       (const_int 6))))
1521   (set_attr "cc" "none")])
1523 (define_insn "*branch_z_invert"
1524   [(set (pc)
1525         (if_then_else (match_operand 1 "v850_float_z_comparison_operator" "")
1526                       (pc)
1527                       (label_ref (match_operand 0 "" ""))))]
1528   "TARGET_V850E2V3_UP"
1530   if (get_attr_length (insn) == 2)
1531     return "bnz %l0";
1533   if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1534     return "bnz %l0";
1536   return "bz 1f ; jr %l0 ; 1:";
1538  [(set (attr "length")
1539     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1540                            (const_int 256))
1541                   (const_int 2)
1542                   (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1543                       (const_int 65536))
1544                       (const_int 4)
1545                       (const_int 6))))
1546   (set_attr "cc" "none")])
1548 (define_insn "branch_nz_normal"
1549   [(set (pc)
1550         (if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "")
1551                       (label_ref (match_operand 0 "" ""))
1552                       (pc)))]
1553   "TARGET_V850E2V3_UP"
1555   if (get_attr_length (insn) == 2)
1556     return "bnz %l0";
1558   if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1559     return "bnz %l0";
1561   return "bz 1f ; jr %l0 ; 1:";
1563 [(set (attr "length")
1564     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1565                            (const_int 256))
1566                   (const_int 2)
1567                   (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1568                       (const_int 65536))
1569                       (const_int 4)
1570                       (const_int 6))))
1571   (set_attr "cc" "none")])
1573 (define_insn "*branch_nz_invert"
1574   [(set (pc)
1575         (if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "")
1576                       (pc)
1577                       (label_ref (match_operand 0 "" ""))))]
1578   "TARGET_V850E2V3_UP"
1580   if (get_attr_length (insn) == 2)
1581     return "bz %l0";
1583   if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1584     return "bz %l0";
1586   return "bnz 1f ; jr %l0 ; 1:";
1588  [(set (attr "length")
1589     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1590                       (const_int 256))
1591                   (const_int 2)
1592                   (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1593                       (const_int 65536))
1594                       (const_int 4)
1595                       (const_int 6))))
1596   (set_attr "cc" "none")])
1598 ;; Unconditional and other jump instructions.
1600 (define_insn "jump"
1601   [(set (pc)
1602         (label_ref (match_operand 0 "" "")))]
1603   ""
1605  if (get_attr_length (insn) == 2)
1606     return "br %0";
1607   else
1608     return "jr %0";
1610  [(set (attr "length")
1611     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1612                       (const_int 256))
1613                   (const_int 2)
1614                   (const_int 4)))
1615   (set_attr "cc" "none")])
1617 (define_insn "indirect_jump"
1618   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1619   ""
1620   "jmp %0"
1621   [(set_attr "length" "2")
1622    (set_attr "cc" "none")])
1624 (define_insn "tablejump"
1625   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1626    (use (label_ref (match_operand 1 "" "")))]
1627   ""
1628   "jmp  %0"
1629   [(set_attr "length" "2")
1630    (set_attr "cc" "none")])
1632 (define_insn "switch"
1633   [(set (pc)
1634         (plus:SI
1635          (sign_extend:SI
1636          (mem:HI
1637           (plus:SI (ashift:SI (match_operand:SI 0 "register_operand" "r")
1638                               (const_int 1))
1639                    (label_ref (match_operand 1 "" "")))))
1640         (label_ref (match_dup 1))))]
1641   "(TARGET_V850E_UP)"
1642   "switch %0"
1643   [(set_attr "length" "2")
1644    (set_attr "cc" "none")])
1646 (define_expand "casesi"
1647   [(match_operand:SI 0 "register_operand" "")
1648    (match_operand:SI 1 "register_operand" "")
1649    (match_operand:SI 2 "register_operand" "")
1650    (match_operand 3 "" "") (match_operand 4 "" "")]
1651   ""
1652   {
1653     rtx reg = gen_reg_rtx (SImode);
1654     rtx tableaddress = gen_reg_rtx (SImode);
1655     rtx test;
1656     rtx mem;
1658     /* Subtract the lower bound from the index.  */
1659     emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
1661     /* Compare the result against the number of table entries;
1662        branch to the default label if out of range of the table.  */
1663     test = gen_rtx_fmt_ee (GTU, VOIDmode, reg, operands[2]);
1664     emit_jump_insn (gen_cbranchsi4 (test, reg, operands[2], operands[4]));
1666     /* Shift index for the table array access.  */
1667     emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
1668     /* Load the table address into a pseudo.  */
1669     emit_insn (gen_movsi (tableaddress,
1670                           gen_rtx_LABEL_REF (Pmode, operands[3])));
1671     /* Add the table address to the index.  */
1672     emit_insn (gen_addsi3 (reg, reg, tableaddress));
1673     /* Load the table entry.  */
1674     mem = gen_const_mem (CASE_VECTOR_MODE, reg);
1675     if (! TARGET_BIG_SWITCH)
1676       {
1677         rtx reg2 = gen_reg_rtx (HImode);
1678         emit_insn (gen_movhi (reg2, mem));
1679         emit_insn (gen_extendhisi2 (reg, reg2));
1680       }
1681     else
1682       emit_insn (gen_movsi (reg, mem));
1683     /* Add the table address.  */
1684     emit_insn (gen_addsi3 (reg, reg, tableaddress));
1685     /* Branch to the switch label.  */
1686     emit_jump_insn (gen_tablejump (reg, operands[3]));
1687     DONE;
1688   })
1690 ;; Call subroutine with no return value.
1692 (define_expand "call"
1693   [(call (match_operand:QI 0 "general_operand" "")
1694          (match_operand:SI 1 "general_operand" ""))]
1695   ""
1696   {
1697     if (! call_address_operand (XEXP (operands[0], 0), QImode)
1698         || TARGET_LONG_CALLS)
1699       XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1700     if (TARGET_LONG_CALLS)
1701       emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));
1702     else
1703       emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
1704   
1705     DONE;
1706   })
1708 (define_insn "call_internal_short"
1709   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1710          (match_operand:SI 1 "general_operand" "g,g"))
1711    (clobber (reg:SI 31))]
1712   "! TARGET_LONG_CALLS"
1713   {
1714     if (which_alternative == 1)
1715       {
1716         if (TARGET_V850E3V5_UP)
1717           return "jarl [%0], r31";
1719         return "jarl .+4, r31 ; add 4, r31 ; jmp %0";
1720       }
1722     return "jarl %0, r31";
1723   }
1724   [(set_attr "length" "4,8")
1725    (set_attr "cc" "clobber,clobber")]
1728 (define_insn "call_internal_long"
1729   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1730          (match_operand:SI 1 "general_operand" "g,g"))
1731    (clobber (reg:SI 31))]
1732   "TARGET_LONG_CALLS"
1734   if (which_alternative == 0)
1735     {
1736       if (GET_CODE (operands[0]) == REG)
1737         return "jarl %0,r31";
1739       if (TARGET_V850E3V5_UP)
1740         return "mov hilo(%0), r11 ; jarl [r11], r31";
1742       return "movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11";
1743     }
1745   if (TARGET_V850E3V5_UP)
1746     return "jarl [%0], r31";
1748   return "jarl .+4,r31 ; add 4,r31 ; jmp %0";
1750   [(set_attr "length" "16,8")
1751    (set_attr "cc" "clobber,clobber")]
1754 ;; Call subroutine, returning value in operand 0
1755 ;; (which must be a hard register).
1757 (define_expand "call_value"
1758   [(set (match_operand 0 "" "")
1759         (call (match_operand:QI 1 "general_operand" "")
1760               (match_operand:SI 2 "general_operand" "")))]
1761   ""
1762   {
1763     if (! call_address_operand (XEXP (operands[1], 0), QImode)
1764         || TARGET_LONG_CALLS)
1765       XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1766     if (TARGET_LONG_CALLS)
1767       emit_call_insn (gen_call_value_internal_long (operands[0],
1768                                                     XEXP (operands[1], 0),
1769                                                     operands[2]));
1770     else
1771       emit_call_insn (gen_call_value_internal_short (operands[0],
1772                                                      XEXP (operands[1], 0),
1773                                                      operands[2]));
1774     DONE;
1775   })
1777 (define_insn "call_value_internal_short"
1778   [(set (match_operand 0 "" "=r,r")
1779         (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1780               (match_operand:SI 2 "general_operand" "g,g")))
1781    (clobber (reg:SI 31))]
1782   "! TARGET_LONG_CALLS"
1783   {
1784     if (which_alternative == 1)
1785       {
1786         if (TARGET_V850E3V5_UP)
1787           return "jarl [%1], r31";
1789         return "jarl .+4, r31 ; add 4, r31 ; jmp %1";
1790       }
1792     return "jarl %1, r31";
1793   }
1794   [(set_attr "length" "4,8")
1795    (set_attr "cc" "clobber,clobber")]
1798 (define_insn "call_value_internal_long"
1799   [(set (match_operand 0 "" "=r,r")
1800         (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1801               (match_operand:SI 2 "general_operand" "g,g")))
1802    (clobber (reg:SI 31))]
1803   "TARGET_LONG_CALLS"
1805   if (which_alternative == 0)
1806     {
1807       if (GET_CODE (operands[1]) == REG)
1808         return "jarl %1, r31";
1810       /* Reload can generate this pattern....  */
1811       if (TARGET_V850E3V5_UP)
1812         return "mov hilo(%1), r11 ; jarl [r11], r31";
1814       return "movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11";
1815     }
1816   
1817   if (TARGET_V850E3V5_UP)
1818     return "jarl [%1], r31";
1820   return "jarl .+4, r31 ; add 4, r31 ; jmp %1";
1822   [(set_attr "length" "16,8")
1823    (set_attr "cc" "clobber,clobber")]
1826 (define_insn "nop"
1827   [(const_int 0)]
1828   ""
1829   "nop"
1830   [(set_attr "length" "2")
1831    (set_attr "cc" "none")])
1833 ;; ----------------------------------------------------------------------
1834 ;; EXTEND INSTRUCTIONS
1835 ;; ----------------------------------------------------------------------
1837 (define_insn "*zero_extendhisi2_v850e"
1838   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1839         (zero_extend:SI
1840         (match_operand:HI 1 "nonimmediate_operand" "0,r,T,m")))
1841    (clobber (reg:CC CC_REGNUM))]
1842   "(TARGET_V850E_UP)"
1843   "@
1844    zxh %0
1845    andi 65535,%1,%0
1846    sld.hu %1,%0
1847    ld.hu %1,%0"
1848   [(set_attr "length" "2,4,2,4")
1849    (set_attr "cc" "none_0hit,set_zn,none_0hit,none_0hit")])
1851 (define_insn "*zero_extendhisi2_v850"
1852   [(set (match_operand:SI 0 "register_operand" "=r")
1853         (zero_extend:SI
1854         (match_operand:HI 1 "register_operand" "r")))
1855    (clobber (reg:CC CC_REGNUM))]  ;; A lie, but we have to match the expander
1856   ""
1857   "andi 65535,%1,%0"
1858   [(set_attr "length" "4")
1859    (set_attr "cc" "set_zn")])
1861 (define_expand "zero_extendhisi2"
1862   [(parallel [(set (match_operand:SI 0 "register_operand")
1863                    (zero_extend:SI
1864                     (match_operand:HI 1 "nonimmediate_operand")))
1865               (clobber (reg:CC CC_REGNUM))])]
1866   ""
1867   {
1868     if (! (TARGET_V850E_UP))
1869       operands[1] = force_reg (HImode, operands[1]);
1870   })
1872 (define_insn "*zero_extendqisi2_v850e"
1873   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1874         (zero_extend:SI
1875         (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m")))
1876    (clobber (reg:CC CC_REGNUM))]
1877   "(TARGET_V850E_UP)"
1878   "@
1879    zxb %0
1880    andi 255,%1,%0
1881    sld.bu %1,%0
1882    ld.bu %1,%0"
1883   [(set_attr "length" "2,4,2,4")
1884    (set_attr "cc" "none_0hit,set_zn,none_0hit,none_0hit")])
1886 (define_insn "*zero_extendqisi2_v850"
1887   [(set (match_operand:SI 0 "register_operand" "=r")
1888         (zero_extend:SI
1889           (match_operand:QI 1 "register_operand" "r")))
1890    (clobber (reg:CC CC_REGNUM))] ;; A lie, but we have to match the expander
1891   ""
1892   "andi 255,%1,%0"
1893   [(set_attr "length" "4")
1894    (set_attr "cc" "set_zn")])
1896 (define_expand "zero_extendqisi2"
1897   [(parallel [(set (match_operand:SI 0 "register_operand")
1898                    (zero_extend:SI
1899                      (match_operand:QI 1 "nonimmediate_operand")))
1900               (clobber (reg:CC CC_REGNUM))])]
1901   ""
1902   {
1903     if (! (TARGET_V850E_UP))
1904       operands[1] = force_reg (QImode, operands[1]);
1905   })
1907 ;;- sign extension instructions
1909 ;; ??? The extendhisi2 pattern should not emit shifts for v850e?
1911 (define_insn "*extendhisi_insn"
1912   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1913         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))
1914    (clobber (reg:CC CC_REGNUM))]
1915   "(TARGET_V850E_UP)"
1916   "@
1917    sxh %0
1918    sld.h %1,%0
1919    ld.h %1,%0"
1920   [(set_attr "length" "2,2,4")
1921    (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1923 ;; ??? This is missing a sign extend from memory pattern to match the ld.h
1924 ;; instruction.
1926 (define_expand "extendhisi2"
1927   [(parallel [(set (match_dup 2)
1928                    (ashift:SI (match_operand:HI 1 "register_operand" "")
1929                               (const_int 16)))
1930               (clobber (reg:CC CC_REGNUM))])
1931    (parallel [(set (match_operand:SI 0 "register_operand" "")
1932                    (ashiftrt:SI (match_dup 2)
1933                                 (const_int 16)))
1934               (clobber (reg:CC CC_REGNUM))])]
1935   ""
1936   {
1937     operands[1] = gen_lowpart (SImode, operands[1]);
1938     operands[2] = gen_reg_rtx (SImode);
1939   })
1941 ;; ??? The extendqisi2 pattern should not emit shifts for v850e?
1943 (define_insn "*extendqisi_insn"
1944   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1945         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))
1946    (clobber (reg:CC CC_REGNUM))]
1947   "(TARGET_V850E_UP)"
1948   "@
1949    sxb %0
1950    sld.b %1,%0
1951    ld.b %1,%0"
1952   [(set_attr "length" "2,2,4")
1953    (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1955 ;; ??? This is missing a sign extend from memory pattern to match the ld.b
1956 ;; instruction.
1958 (define_expand "extendqisi2"
1959   [(parallel [(set (match_dup 2)
1960                    (ashift:SI (match_operand:QI 1 "register_operand" "")
1961                               (const_int 24)))
1962               (clobber (reg:CC CC_REGNUM))])
1963    (parallel [(set (match_operand:SI 0 "register_operand" "")
1964                    (ashiftrt:SI (match_dup 2)
1965                               (const_int 24)))
1966               (clobber (reg:CC CC_REGNUM))])]
1967   ""
1968   {
1969     operands[1] = gen_lowpart (SImode, operands[1]);
1970     operands[2] = gen_reg_rtx (SImode);
1971   })
1973 ;; ----------------------------------------------------------------------
1974 ;; SHIFTS
1975 ;; ----------------------------------------------------------------------
1977 (define_insn "ashlsi3"
1978   [(set (match_operand:SI 0 "register_operand" "=r,r")
1979       (ashift:SI
1980         (match_operand:SI 1 "register_operand" "0,0")
1981         (match_operand:SI 2 "nonmemory_operand" "r,N")))
1982    (clobber (reg:CC CC_REGNUM))]
1983   ""
1984   "@
1985   shl %2,%0
1986   shl %2,%0"
1987   [(set_attr "length" "4,2")
1988    (set_attr "cc" "set_zn")])
1990 (define_insn "ashlsi3_v850e2"
1991   [(set (match_operand:SI 0 "register_operand" "=r")
1992       (ashift:SI
1993         (match_operand:SI 1 "register_operand" "r")
1994         (match_operand:SI 2 "nonmemory_operand" "r")))
1995    (clobber (reg:CC CC_REGNUM))]
1996   "TARGET_V850E2_UP"
1997   "shl %2,%1,%0"
1998   [(set_attr "length" "4")
1999    (set_attr "cc" "set_znv")])
2001 (define_insn "lshrsi3"
2002   [(set (match_operand:SI 0 "register_operand" "=r,r")
2003       (lshiftrt:SI
2004         (match_operand:SI 1 "register_operand" "0,0")
2005         (match_operand:SI 2 "nonmemory_operand" "r,N")))
2006    (clobber (reg:CC CC_REGNUM))]
2007   ""
2008   "@
2009   shr %2,%0
2010   shr %2,%0"
2011   [(set_attr "length" "4,2")
2012    (set_attr "cc" "set_zn")])
2014 (define_insn "lshrsi3_v850e2"
2015   [(set (match_operand:SI 0 "register_operand" "=r")
2016       (lshiftrt:SI
2017         (match_operand:SI 1 "register_operand" "r")
2018         (match_operand:SI 2 "nonmemory_operand" "r")))
2019    (clobber (reg:CC CC_REGNUM))]
2020   "TARGET_V850E2_UP"
2021   "shr %2,%1,%0"
2022   [(set_attr "length" "4")
2023    (set_attr "cc" "set_zn")])
2025 (define_insn "ashrsi3"
2026   [(set (match_operand:SI 0 "register_operand" "=r,r")
2027       (ashiftrt:SI
2028         (match_operand:SI 1 "register_operand" "0,0")
2029         (match_operand:SI 2 "nonmemory_operand" "r,N")))
2030    (clobber (reg:CC CC_REGNUM))]
2031   ""
2032   "@
2033   sar %2,%0
2034   sar %2,%0"
2035   [(set_attr "length" "4,2")
2036    (set_attr "cc" "set_zn, set_zn")])
2038 (define_insn "ashrsi3_v850e2"
2039   [(set (match_operand:SI 0 "register_operand" "=r")
2040       (ashiftrt:SI
2041         (match_operand:SI 1 "register_operand" "r")
2042         (match_operand:SI 2 "nonmemory_operand" "r")))
2043    (clobber (reg:CC CC_REGNUM))]
2044   "TARGET_V850E2_UP"
2045   "sar %2,%1,%0"
2046   [(set_attr "length" "4")
2047    (set_attr "cc" "set_zn")])
2049 ;; ----------------------------------------------------------------------
2050 ;; FIND FIRST BIT INSTRUCTION
2051 ;; ----------------------------------------------------------------------
2053 (define_insn "ffssi2"
2054   [(set (match_operand:SI 0 "register_operand" "=r")
2055        (ffs:SI (match_operand:SI 1 "register_operand" "r")))
2056    (clobber (reg:CC CC_REGNUM))]
2057   "TARGET_V850E2_UP"
2058   "sch1r %1,%0"
2059   [(set_attr "length" "4")
2060    (set_attr "cc" "clobber")])
2062 ;; ----------------------------------------------------------------------
2063 ;; PROLOGUE/EPILOGUE
2064 ;; ----------------------------------------------------------------------
2065 (define_expand "prologue"
2066   [(const_int 0)]
2067   ""
2068   {
2069     expand_prologue ();
2070     DONE;
2071   })
2073 (define_expand "epilogue"
2074   [(return)]
2075   ""
2076   {
2077     expand_epilogue ();
2078     DONE;
2079   })
2081 (define_insn "return_simple"
2082   [(return)]
2083   "reload_completed"
2084   "jmp [r31]"
2085   [(set_attr "length" "2")
2086    (set_attr "cc" "none")])
2088 (define_insn "return_internal"
2089   [(return)
2090    (use (reg:SI 31))]
2091   ""
2092   "jmp [r31]"
2093   [(set_attr "length" "2")
2094    (set_attr "cc" "none")])
2096 ;; ----------------------------------------------------------------------
2097 ;; v850e2V3 floating-point hardware support
2098 ;; ----------------------------------------------------------------------
2101 (define_insn "addsf3"
2102   [(set (match_operand:SF 0 "register_operand" "=r")
2103         (plus:SF (match_operand:SF 1 "register_operand" "r")
2104                  (match_operand:SF 2 "register_operand" "r")))]
2105   "TARGET_USE_FPU"
2106   "addf.s %1,%2,%0"
2107   [(set_attr "length" "4")
2108    (set_attr "cc" "none_0hit")
2109    (set_attr "type" "fpu")])
2111 (define_insn "adddf3"
2112   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2113         (plus:DF (match_operand:DF 1 "even_reg_operand" "r")
2114         (match_operand:DF 2 "even_reg_operand" "r")))]
2115   "TARGET_USE_FPU"
2116   "addf.d %1,%2,%0"
2117   [(set_attr "length" "4")
2118    (set_attr "cc" "none_0hit")
2119    (set_attr "type" "fpu")])
2121 (define_insn "subsf3"
2122   [(set (match_operand:SF 0 "register_operand" "=r")
2123         (minus:SF (match_operand:SF 1 "register_operand" "r")
2124                   (match_operand:SF 2 "register_operand" "r")))]
2125   "TARGET_USE_FPU"
2126   "subf.s %2,%1,%0"
2127   [(set_attr "length" "4")
2128    (set_attr "cc" "none_0hit")
2129    (set_attr "type" "fpu")])
2131 (define_insn "subdf3"
2132   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2133         (minus:DF (match_operand:DF 1 "even_reg_operand" "r")
2134                   (match_operand:DF 2 "even_reg_operand" "r")))]
2135   "TARGET_USE_FPU"
2136   "subf.d %2,%1,%0"
2137   [(set_attr "length" "4")
2138    (set_attr "cc" "none_0hit")
2139    (set_attr "type" "fpu")])
2141 (define_insn "mulsf3"
2142   [(set (match_operand:SF 0 "register_operand" "=r")
2143         (mult:SF (match_operand:SF 1 "register_operand" "r")
2144                  (match_operand:SF 2 "register_operand" "r")))]
2145   "TARGET_USE_FPU"
2146   "mulf.s %1,%2,%0"
2147   [(set_attr "length" "4")
2148    (set_attr "cc" "none_0hit")
2149    (set_attr "type" "fpu")])
2151 (define_insn "muldf3"
2152   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2153         (mult:DF (match_operand:DF 1 "even_reg_operand" "r")
2154                  (match_operand:DF 2 "even_reg_operand" "r")))]
2155   "TARGET_USE_FPU"
2156   "mulf.d %1,%2,%0"
2157   [(set_attr "length" "4")
2158    (set_attr "cc" "none_0hit")
2159    (set_attr "type" "fpu")])
2161 (define_insn "divsf3"
2162   [(set (match_operand:SF 0 "register_operand" "=r")
2163         (div:SF (match_operand:SF 1 "register_operand" "r")
2164                 (match_operand:SF 2 "register_operand" "r")))]
2165   "TARGET_USE_FPU"
2166   "divf.s %2,%1,%0"
2167   [(set_attr "length" "4")
2168    (set_attr "cc" "none_0hit")
2169    (set_attr "type" "fpu")])
2171 (define_insn "divdf3"
2172   [(set (match_operand:DF 0 "register_operand" "=r")
2173         (div:DF (match_operand:DF 1 "even_reg_operand" "r")
2174                 (match_operand:DF 2 "even_reg_operand" "r")))]
2175   "TARGET_USE_FPU"
2176   "divf.d %2,%1,%0"
2177   [(set_attr "length" "4")
2178    (set_attr "cc" "none_0hit")
2179    (set_attr "type" "fpu")])
2181 (define_insn "minsf3"
2182   [(set (match_operand:SF 0 "register_operand" "=r")
2183         (smin:SF (match_operand:SF 1 "reg_or_0_operand" "r")
2184                  (match_operand:SF 2 "reg_or_0_operand" "r")))]
2185   "TARGET_USE_FPU"
2186   "minf.s %z1,%z2,%0"
2187   [(set_attr "length" "4")
2188    (set_attr "cc" "none_0hit")
2189    (set_attr "type" "fpu")])
2191 (define_insn "mindf3"
2192   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2193         (smin:DF (match_operand:DF 1 "even_reg_operand" "r")
2194                  (match_operand:DF 2 "even_reg_operand" "r")))]
2195   "TARGET_USE_FPU"
2196   "minf.d %1,%2,%0"
2197   [(set_attr "length" "4")
2198    (set_attr "cc" "none_0hit")
2199    (set_attr "type" "fpu")])
2201 (define_insn "maxsf3"
2202   [(set (match_operand:SF 0 "register_operand" "=r")
2203         (smax:SF (match_operand:SF 1 "reg_or_0_operand" "r")
2204                  (match_operand:SF 2 "reg_or_0_operand" "r")))]
2205   "TARGET_USE_FPU"
2206   "maxf.s %z1,%z2,%0"
2207   [(set_attr "length" "4")
2208    (set_attr "cc" "none_0hit")
2209    (set_attr "type" "fpu")])
2211 (define_insn "maxdf3"
2212   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2213         (smax:DF (match_operand:DF 1 "even_reg_operand" "r")
2214                  (match_operand:DF 2 "even_reg_operand" "r")))]
2215   "TARGET_USE_FPU"
2216   "maxf.d %1,%2,%0"
2217   [(set_attr "length" "4")
2218    (set_attr "cc" "none_0hit")
2219    (set_attr "type" "fpu")])
2221 (define_insn "abssf2"
2222   [(set (match_operand:SF 0 "register_operand" "=r")
2223         (abs:SF (match_operand:SF 1 "register_operand" "r")))]
2224   "TARGET_USE_FPU"
2225   "absf.s %1,%0"
2226   [(set_attr "length" "4")
2227    (set_attr "cc" "none_0hit")
2228    (set_attr "type" "fpu")])
2230 (define_insn "absdf2"
2231   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2232         (abs:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2233   "TARGET_USE_FPU"
2234   "absf.d %1,%0"
2235   [(set_attr "length" "4")
2236    (set_attr "cc" "none_0hit")
2237    (set_attr "type" "fpu")])
2239 (define_insn "negsf2"
2240   [(set (match_operand:SF 0 "register_operand" "=r")
2241         (neg:SF (match_operand:SF 1 "register_operand" "r")))]
2242   "TARGET_USE_FPU"
2243   "negf.s %1,%0"
2244   [(set_attr "length" "4")
2245    (set_attr "cc" "none_0hit")
2246    (set_attr "type" "fpu")])
2248 (define_insn "negdf2"
2249   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2250         (neg:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2251   "TARGET_USE_FPU"
2252   "negf.d %1,%0"
2253   [(set_attr "length" "4")
2254    (set_attr "cc" "none_0hit")
2255    (set_attr "type" "fpu")])
2257 ;; square-root
2258 (define_insn "sqrtsf2"
2259   [(set (match_operand:SF 0 "register_operand" "=r")
2260         (sqrt:SF (match_operand:SF 1 "register_operand" "r")))]
2261   "TARGET_USE_FPU"
2262   "sqrtf.s %1,%0"
2263   [(set_attr "length" "4")
2264    (set_attr "cc" "none_0hit")
2265    (set_attr "type" "fpu")])
2267 (define_insn "sqrtdf2"
2268   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2269         (sqrt:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2270   "TARGET_USE_FPU"
2271   "sqrtf.d %1,%0"
2272   [(set_attr "length" "4")
2273    (set_attr "cc" "none_0hit")
2274    (set_attr "type" "fpu")])
2276 ;; float -> int
2277 (define_insn "fix_truncsfsi2"
2278   [(set (match_operand:SI 0 "register_operand" "=r")
2279         (fix:SI (match_operand:SF 1 "register_operand" "r")))]
2280   "TARGET_USE_FPU"
2281   "trncf.sw %1,%0"
2282   [(set_attr "length" "4")
2283    (set_attr "cc" "none_0hit")
2284    (set_attr "type" "fpu")])
2286 (define_insn "fixuns_truncsfsi2"
2287   [(set (match_operand:SI                  0 "register_operand" "=r")
2288         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "r")))]
2289   "TARGET_USE_FPU"
2290   "trncf.suw %1, %0"
2291   [(set_attr "length" "4")
2292    (set_attr "cc" "none_0hit")
2293    (set_attr "type" "fpu")]
2296 (define_insn "fix_truncdfsi2"
2297   [(set (match_operand:SI 0 "register_operand" "=r")
2298         (fix:SI (match_operand:DF 1 "even_reg_operand" "r")))]
2299   "TARGET_USE_FPU"
2300   "trncf.dw %1,%0"
2301   [(set_attr "length" "4")
2302    (set_attr "cc" "none_0hit")
2303    (set_attr "type" "fpu")])
2305 (define_insn "fixuns_truncdfsi2"
2306   [(set (match_operand:SI                  0 "register_operand" "=r")
2307         (unsigned_fix:SI (match_operand:DF 1 "even_reg_operand" "r")))]
2308   "TARGET_USE_FPU"
2309   "trncf.duw %1, %0"
2310   [(set_attr "length" "4")
2311    (set_attr "cc" "none_0hit")
2312    (set_attr "type" "fpu")]
2315 (define_insn "fix_truncsfdi2"
2316   [(set (match_operand:DI         0 "register_operand" "=r")
2317         (fix:DI (match_operand:SF 1 "register_operand" "r")))]
2318   "TARGET_USE_FPU"
2319   "trncf.sl %1, %0"
2320   [(set_attr "length" "4")
2321    (set_attr "cc" "none_0hit")
2322    (set_attr "type" "fpu")])
2324 (define_insn "fixuns_truncsfdi2"
2325   [(set (match_operand:DI                  0 "register_operand" "=r")
2326         (unsigned_fix:DI (match_operand:SF 1 "register_operand" "r")))]
2327   "TARGET_USE_FPU"
2328   "trncf.sul %1, %0"
2329   [(set_attr "length" "4")
2330    (set_attr "cc" "none_0hit")
2331    (set_attr "type" "fpu")]
2334 (define_insn "fix_truncdfdi2"
2335   [(set (match_operand:DI         0 "register_operand" "=r")
2336         (fix:DI (match_operand:DF 1 "even_reg_operand" "r")))]
2337   "TARGET_USE_FPU"
2338   "trncf.dl %1, %0"
2339   [(set_attr "length" "4")
2340    (set_attr "cc" "none_0hit")
2341    (set_attr "type" "fpu")])
2343 (define_insn "fixuns_truncdfdi2"
2344   [(set (match_operand:DI                  0 "register_operand" "=r")
2345         (unsigned_fix:DI (match_operand:DF 1 "even_reg_operand" "r")))]
2346   "TARGET_USE_FPU"
2347   "trncf.dul %1, %0"
2348   [(set_attr "length" "4")
2349    (set_attr "cc" "none_0hit")
2350    (set_attr "type" "fpu")]
2353 ;; int -> float
2354 (define_insn "floatsisf2"
2355   [(set (match_operand:SF 0 "register_operand" "=r")
2356         (float:SF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2357   "TARGET_USE_FPU"
2358   "cvtf.ws %z1, %0"
2359   [(set_attr "length" "4")
2360    (set_attr "cc" "none_0hit")
2361    (set_attr "type" "fpu")])
2363 (define_insn "unsfloatsisf2"
2364   [(set (match_operand:SF                    0 "register_operand" "=r")
2365         (unsigned_float:SF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2366   "TARGET_USE_FPU"
2367   "cvtf.uws %z1, %0"
2368   [(set_attr "length" "4")
2369    (set_attr "cc" "none_0hit")
2370    (set_attr "type" "fpu")])
2372 (define_insn "floatsidf2"
2373   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2374         (float:DF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2375   "TARGET_USE_FPU"
2376   "cvtf.wd %z1,%0"
2377   [(set_attr "length" "4")
2378    (set_attr "cc" "none_0hit")
2379    (set_attr "type" "fpu")])
2381 (define_insn "unsfloatsidf2"
2382   [(set (match_operand:DF                    0 "even_reg_operand" "=r")
2383         (unsigned_float:DF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2384   "TARGET_USE_FPU"
2385   "cvtf.uwd %z1, %0"
2386   [(set_attr "length" "4")
2387    (set_attr "cc" "none_0hit")
2388    (set_attr "type" "fpu")])
2390 (define_insn "floatdisf2"
2391   [(set (match_operand:SF           0 "even_reg_operand" "=r")
2392         (float:SF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2393   "TARGET_USE_FPU"
2394   "cvtf.ls %z1, %0"
2395   [(set_attr "length" "4")
2396    (set_attr "cc" "none_0hit")
2397    (set_attr "type" "fpu")])
2399 (define_insn "unsfloatdisf2"
2400   [(set (match_operand:SF                    0 "even_reg_operand" "=r")
2401         (unsigned_float:SF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2402   "TARGET_USE_FPU"
2403   "cvtf.uls %z1, %0"
2404   [(set_attr "length" "4")
2405    (set_attr "cc" "none_0hit")
2406    (set_attr "type" "fpu")])
2408 (define_insn "floatdidf2"
2409   [(set (match_operand:DF           0 "even_reg_operand" "=r")
2410         (float:DF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2411   "TARGET_USE_FPU"
2412   "cvtf.ld %z1, %0"
2413   [(set_attr "length" "4")
2414    (set_attr "cc" "none_0hit")
2415    (set_attr "type" "fpu")])
2417 (define_insn "unsfloatdidf2"
2418   [(set (match_operand:DF                    0 "even_reg_operand" "=r")
2419         (unsigned_float:DF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2420   "TARGET_USE_FPU"
2421   "cvtf.uld %z1, %0"
2422   [(set_attr "length" "4")
2423    (set_attr "cc" "none_0hit")
2424    (set_attr "type" "fpu")])
2426 ;; single-float -> double-float
2427 (define_insn "extendsfdf2"
2428   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2429         (float_extend:DF
2430          (match_operand:SF 1 "reg_or_0_operand" "rI")))]
2431   "TARGET_USE_FPU"
2432   "cvtf.sd %z1,%0"
2433   [(set_attr "length" "4")
2434    (set_attr "cc" "none_0hit")
2435    (set_attr "type" "fpu")])
2437 ;; double-float -> single-float
2438 (define_insn "truncdfsf2"
2439   [(set (match_operand:SF 0 "register_operand" "=r")
2440         (float_truncate:SF
2441          (match_operand:DF 1 "even_reg_operand" "r")))]
2442   "TARGET_USE_FPU"
2443   "cvtf.ds %1,%0"
2444   [(set_attr "length" "4")
2445    (set_attr "cc" "none_0hit")
2446    (set_attr "type" "fpu")])
2449 ;; ---------------- special insns
2452 ;;; reciprocal
2453 (define_insn "recipsf2"
2454   [(set (match_operand:SF 0 "register_operand" "=r")
2455         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2456                 (match_operand:SF 2 "register_operand" "r")))]
2457   "TARGET_USE_FPU"
2458   "recipf.s %2,%0"
2459   [(set_attr "length" "4")
2460    (set_attr "cc" "none_0hit")
2461    (set_attr "type" "fpu")])
2463 (define_insn "recipdf2"
2464   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2465         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2466                 (match_operand:DF 2 "even_reg_operand" "r")))]
2467   "TARGET_USE_FPU"
2468   "recipf.d %2,%0"
2469   [(set_attr "length" "4")
2470    (set_attr "cc" "none_0hit")
2471    (set_attr "type" "fpu")])
2473 ;;; reciprocal of square-root
2474 (define_insn "rsqrtsf2"
2475   [(set (match_operand:SF 0 "register_operand" "=r")
2476         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2477                 (sqrt:SF (match_operand:SF 2 "register_operand" "r"))))]
2478   "TARGET_USE_FPU"
2479   "rsqrtf.s %2,%0"
2480   [(set_attr "length" "4")
2481    (set_attr "cc" "none_0hit")
2482    (set_attr "type" "fpu")])
2484 (define_insn "rsqrtdf2"
2485   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2486         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2487                 (sqrt:DF (match_operand:DF 2 "even_reg_operand" "r"))))]
2488   "TARGET_USE_FPU"
2489   "rsqrtf.d %2,%0"
2490   [(set_attr "length" "4")
2491    (set_attr "cc" "none_0hit")
2492    (set_attr "type" "fpu")])
2494 ;; Note: The FPU-2.0 (ie pre e3v5) versions of these routines do not actually
2495 ;; need operand 4 to be the same as operand 0.  But the FPU-2.0 versions are
2496 ;; also deprecated so the loss of flexibility is unimportant.
2498 ;;; multiply-add
2499 (define_insn "fmasf4"
2500   [(set (match_operand:SF         0 "register_operand" "=r")
2501         (fma:SF (match_operand:SF 1 "register_operand" "r")
2502                 (match_operand:SF 2 "register_operand" "r")
2503                 (match_operand:SF 3 "register_operand" "0")))]
2504   "TARGET_USE_FPU"
2505   { return TARGET_V850E3V5_UP ? "fmaf.s %1, %2, %0" : "maddf.s %2, %1, %3, %0"; }
2506   [(set_attr "length" "4")
2507    (set_attr "cc" "none_0hit")
2508    (set_attr "type" "fpu")])
2510 ;;; multiply-subtract
2511 (define_insn "fmssf4"
2512   [(set (match_operand:SF                 0 "register_operand" "=r")
2513         (fma:SF (match_operand:SF         1 "register_operand" "r")
2514                 (match_operand:SF         2 "register_operand" "r")
2515                 (neg:SF (match_operand:SF 3 "register_operand" "0"))))]
2516   "TARGET_USE_FPU"
2517   { return TARGET_V850E3V5_UP ? "fmsf.s %1, %2, %0" : "msubf.s %2, %1, %3, %0"; }
2518   [(set_attr "length" "4")
2519    (set_attr "cc" "none_0hit")
2520    (set_attr "type" "fpu")])
2522 ;;; negative-multiply-add
2523 (define_insn "fnmasf4"
2524   [(set (match_operand:SF                 0 "register_operand" "=r")
2525         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "r")
2526                         (match_operand:SF 2 "register_operand" "r")
2527                         (match_operand:SF 3 "register_operand" "0"))))]
2528   "TARGET_USE_FPU"
2529   { return TARGET_V850E3V5_UP ? "fnmaf.s %1, %2, %0" : "nmaddf.s %2, %1, %3, %0"; }
2530   [(set_attr "length" "4")
2531    (set_attr "cc" "none_0hit")
2532    (set_attr "type" "fpu")])
2534 ;; negative-multiply-subtract
2535 (define_insn "fnmssf4"
2536   [(set (match_operand:SF                         0 "register_operand" "=r")
2537         (neg:SF (fma:SF (match_operand:SF         1 "register_operand" "r")
2538                         (match_operand:SF         2 "register_operand" "r")
2539                         (neg:SF (match_operand:SF 3 "register_operand" "0")))))]
2540   "TARGET_USE_FPU"
2541   { return TARGET_V850E3V5_UP ? "fnmsf.s %1, %2, %0" : "nmsubf.s %2, %1, %3, %0"; }
2542   [(set_attr "length" "4")
2543    (set_attr "cc" "none_0hit")
2544    (set_attr "type" "fpu")])
2546 ; ---------------- comparison/conditionals
2548 ; SF
2550 (define_insn "cmpsf_le_insn"
2551   [(set (reg:CC_FPU_LE FCC_REGNUM)
2552         (compare:CC_FPU_LE (match_operand:SF 0 "register_operand" "r")
2553                            (match_operand:SF 1 "register_operand" "r")))]
2554   "TARGET_USE_FPU"
2555   "cmpf.s le, %z0, %z1"
2556   [(set_attr "length" "4")
2557    (set_attr "cc" "none_0hit")
2558    (set_attr "type" "fpu")])
2560 (define_insn "cmpsf_lt_insn"
2561   [(set (reg:CC_FPU_LT FCC_REGNUM)
2562         (compare:CC_FPU_LT (match_operand:SF 0 "register_operand" "r")
2563                            (match_operand:SF 1 "register_operand" "r")))]
2564   "TARGET_USE_FPU"
2565   "cmpf.s lt, %z0, %z1"
2566   [(set_attr "length" "4")
2567    (set_attr "cc" "none_0hit")
2568    (set_attr "type" "fpu")])
2570 (define_insn "cmpsf_ge_insn"
2571   [(set (reg:CC_FPU_GE FCC_REGNUM)
2572         (compare:CC_FPU_GE (match_operand:SF 0 "register_operand" "r")
2573                            (match_operand:SF 1 "register_operand" "r")))]
2574   "TARGET_USE_FPU"
2575   "cmpf.s le, %z1, %z0"
2576   [(set_attr "length" "4")
2577    (set_attr "cc" "none_0hit")
2578    (set_attr "type" "fpu")])
2580 (define_insn "cmpsf_gt_insn"
2581   [(set (reg:CC_FPU_GT FCC_REGNUM)
2582         (compare:CC_FPU_GT (match_operand:SF 0 "register_operand" "r")
2583                            (match_operand:SF 1 "register_operand" "r")))]
2584   "TARGET_USE_FPU"
2585   "cmpf.s lt, %z1, %z0"
2586   [(set_attr "length" "4")
2587    (set_attr "cc" "none_0hit")
2588    (set_attr "type" "fpu")])
2590 (define_insn "cmpsf_eq_insn"
2591   [(set (reg:CC_FPU_EQ FCC_REGNUM)
2592         (compare:CC_FPU_EQ (match_operand:SF 0 "register_operand" "r")
2593                            (match_operand:SF 1 "register_operand" "r")))]
2594   "TARGET_USE_FPU"
2595   "cmpf.s eq, %z0, %z1"
2596   [(set_attr "length" "4")
2597    (set_attr "cc" "none_0hit")
2598    (set_attr "type" "fpu")])
2600 ; DF
2602 (define_insn "cmpdf_le_insn"
2603   [(set (reg:CC_FPU_LE FCC_REGNUM)
2604         (compare:CC_FPU_LE (match_operand:DF 0 "even_reg_operand" "r")
2605                            (match_operand:DF 1 "even_reg_operand" "r")))]
2606   "TARGET_USE_FPU"
2607   "cmpf.d le, %z0, %z1"
2608   [(set_attr "length" "4")
2609    (set_attr "cc" "none_0hit")
2610    (set_attr "type" "fpu")])
2612 (define_insn "cmpdf_lt_insn"
2613   [(set (reg:CC_FPU_LT FCC_REGNUM)
2614         (compare:CC_FPU_LT (match_operand:DF 0 "even_reg_operand" "r")
2615                            (match_operand:DF 1 "even_reg_operand" "r")))]
2616   "TARGET_USE_FPU"
2617   "cmpf.d lt, %z0, %z1"
2618   [(set_attr "length" "4")
2619    (set_attr "cc" "none_0hit")
2620    (set_attr "type" "fpu")])
2622 (define_insn "cmpdf_ge_insn"
2623   [(set (reg:CC_FPU_GE FCC_REGNUM)
2624         (compare:CC_FPU_GE (match_operand:DF 0 "even_reg_operand" "r")
2625                            (match_operand:DF 1 "even_reg_operand" "r")))]
2626   "TARGET_USE_FPU"
2627   "cmpf.d le, %z1, %z0"
2628   [(set_attr "length" "4")
2629    (set_attr "cc" "none_0hit")
2630    (set_attr "type" "fpu")])
2632 (define_insn "cmpdf_gt_insn"
2633   [(set (reg:CC_FPU_GT FCC_REGNUM)
2634         (compare:CC_FPU_GT (match_operand:DF 0 "even_reg_operand" "r")
2635                            (match_operand:DF 1 "even_reg_operand" "r")))]
2636   "TARGET_USE_FPU"
2637   "cmpf.d lt, %z1, %z0"
2638   [(set_attr "length" "4")
2639    (set_attr "cc" "none_0hit")
2640    (set_attr "type" "fpu")])
2642 (define_insn "cmpdf_eq_insn"
2643   [(set (reg:CC_FPU_EQ FCC_REGNUM)
2644         (compare:CC_FPU_EQ (match_operand:DF 0 "even_reg_operand" "r")
2645                            (match_operand:DF 1 "even_reg_operand" "r")))]
2646   "TARGET_USE_FPU"
2647   "cmpf.d eq, %z0, %z1"
2648   [(set_attr "length" "4")
2649    (set_attr "cc" "none_0hit")
2650    (set_attr "type" "fpu")])
2653 ;; Transfer a v850e2v3 fcc to the Z bit of CC0 (this is necessary to do a
2654 ;; conditional branch based on a floating-point compare)
2657 (define_insn "trfsr"
2658   [(set (match_operand 0 "" "") (match_operand 1 "" ""))]
2659   "TARGET_USE_FPU
2660    && GET_MODE(operands[0]) == GET_MODE(operands[1])
2661    && GET_CODE(operands[0]) == REG && REGNO (operands[0]) == CC_REGNUM
2662    && GET_CODE(operands[1]) == REG && REGNO (operands[1]) == FCC_REGNUM
2663    && (GET_MODE(operands[0]) == CC_FPU_LEmode
2664        || GET_MODE(operands[0]) == CC_FPU_GEmode
2665        || GET_MODE(operands[0]) == CC_FPU_LTmode
2666        || GET_MODE(operands[0]) == CC_FPU_GTmode
2667        || GET_MODE(operands[0]) == CC_FPU_EQmode
2668        || GET_MODE(operands[0]) == CC_FPU_NEmode)"
2669   "trfsr"
2670   [(set_attr "length" "4")
2671    (set_attr "cc" "set_z")
2672    (set_attr "type" "fpu")])
2675 ;; Floating-point conditional moves for the v850e2v3.
2678 ;; The actual v850e2v3 conditional move instructions
2680 (define_insn "movsfcc_z_insn"
2681   [(set (match_operand:SF 0 "register_operand" "=r")
2682         (if_then_else:SF
2683          (match_operand 3 "v850_float_z_comparison_operator" "")
2684          (match_operand:SF 1 "reg_or_0_operand" "rIG")
2685          (match_operand:SF 2 "reg_or_0_operand" "rIG")))]
2686   "TARGET_USE_FPU"
2687   "cmovf.s 0,%z1,%z2,%0"
2688   [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2690 (define_insn "movsfcc_nz_insn"
2691   [(set (match_operand:SF 0 "register_operand" "=r")
2692         (if_then_else:SF
2693          (match_operand 3 "v850_float_nz_comparison_operator" "")
2694          (match_operand:SF 1 "reg_or_0_operand" "rIG")
2695          (match_operand:SF 2 "reg_or_0_operand" "rIG")))]
2696   "TARGET_USE_FPU"
2697   "cmovf.s 0,%z2,%z1,%0"
2698   [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2700 (define_insn "movdfcc_z_insn"
2701   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2702         (if_then_else:DF
2703          (match_operand 3 "v850_float_z_comparison_operator" "")
2704          (match_operand:DF 1 "even_reg_operand" "r")
2705          (match_operand:DF 2 "even_reg_operand" "r")))]
2706   "TARGET_USE_FPU"
2707   "cmovf.d 0,%z1,%z2,%0"
2708   [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2710 (define_insn "movdfcc_nz_insn"
2711   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2712         (if_then_else:DF
2713          (match_operand 3 "v850_float_nz_comparison_operator" "")
2714          (match_operand:DF 1 "even_reg_operand" "r")
2715          (match_operand:DF 2 "even_reg_operand" "r")))]
2716   "TARGET_USE_FPU"
2717   "cmovf.d 0,%z2,%z1,%0"
2718   [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2720 (define_insn "movedfcc_z_zero"
2721   [(set (match_operand:DF 0 "register_operand" "=r")
2722         (if_then_else:DF
2723          (match_operand 3 "v850_float_z_comparison_operator" "")
2724          (match_operand:DF 1 "reg_or_0_operand" "rIG")
2725          (match_operand:DF 2 "reg_or_0_operand" "rIG")))]
2726   "TARGET_USE_FPU"
2727   "cmovf.s 0,%z1,%z2,%0 ; cmovf.s 0,%Z1,%Z2,%R0"
2728   [(set_attr "length" "8")
2729    (set_attr "cc" "clobber")]) ;; ??? or none_0hit
2731 (define_insn "movedfcc_nz_zero"
2732   [(set (match_operand:DF 0 "register_operand" "=r")
2733         (if_then_else:DF
2734          (match_operand 3 "v850_float_nz_comparison_operator" "")
2735          (match_operand:DF 1 "reg_or_0_operand" "rIG")
2736          (match_operand:DF 2 "reg_or_0_operand" "rIG")))]
2737   "TARGET_USE_FPU"
2738   "cmovf.s 0,%z2,%z1,%0 ; cmovf.s 0,%Z2,%Z1,%R0"
2739   [(set_attr "length" "8")
2740    (set_attr "cc" "clobber")]) ;; ??? or none_0hit
2743 ;; ----------------------------------------------------------------------
2744 ;; HELPER INSTRUCTIONS for saving the prologue and epilogue registers
2745 ;; ----------------------------------------------------------------------
2747 ;; This pattern will match a stack adjust RTX followed by any number of push
2748 ;; RTXs.  These RTXs will then be turned into a suitable call to a worker
2749 ;; function.
2752 ;; Actually, convert the RTXs into a PREPARE instruction.
2755 (define_insn ""
2756  [(match_parallel 0 "pattern_is_ok_for_prepare"
2757    [(set (reg:SI 3)
2758          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2759     (set (mem:SI (plus:SI (reg:SI 3)
2760                           (match_operand:SI 2 "immediate_operand" "i")))
2761          (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
2762  "TARGET_PROLOG_FUNCTION && (TARGET_V850E_UP)"
2764   return construct_prepare_instruction (operands[0]);
2766  [(set_attr "length" "4")
2767   (set_attr "cc"     "clobber")])
2769 (define_insn ""
2770  [(match_parallel 0 "pattern_is_ok_for_prologue"
2771    [(set (reg:SI 3)
2772          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2773     (set (mem:SI (plus:SI (reg:SI 3)
2774                            (match_operand:SI 2 "immediate_operand" "i")))
2775          (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
2776  "TARGET_PROLOG_FUNCTION"
2778   return construct_save_jarl (operands[0]);
2780  [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
2781                                      (const_string "16")
2782                                      (const_string "4")))
2783   (set_attr "cc"     "clobber")])
2786 ;; Actually, turn the RTXs into a DISPOSE instruction.
2788 (define_insn ""
2789  [(match_parallel 0 "pattern_is_ok_for_dispose"
2790    [(return)
2791     (set (reg:SI 3)
2792          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2793     (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
2794          (mem:SI (plus:SI (reg:SI 3)
2795                           (match_operand:SI 3 "immediate_operand" "i"))))])]
2796  "TARGET_PROLOG_FUNCTION && (TARGET_V850E_UP)"
2798   return construct_dispose_instruction (operands[0]);
2800  [(set_attr "length" "4")
2801   (set_attr "cc"     "clobber")])
2803 ;; This pattern will match a return RTX followed by any number of pop RTXs
2804 ;; and possible a stack adjustment as well.  These RTXs will be turned into
2805 ;; a suitable call to a worker function.
2807 (define_insn ""
2808 [(match_parallel 0 "pattern_is_ok_for_epilogue"
2809    [(return)
2810     (set (reg:SI 3)
2811          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2812     (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
2813          (mem:SI (plus:SI (reg:SI 3)
2814                           (match_operand:SI 3 "immediate_operand" "i"))))])]
2815  "TARGET_PROLOG_FUNCTION"
2817   return construct_restore_jr (operands[0]);
2819  [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
2820                                      (const_string "12")
2821                                      (const_string "4")))
2822   (set_attr "cc"     "clobber")])
2824 ;; Initialize an interrupt function.  Do not depend on TARGET_PROLOG_FUNCTION.
2825 (define_insn "callt_save_interrupt"
2826   [(unspec_volatile [(const_int 0)] 2)]
2827     "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2828     ;; The CALLT instruction stores the next address of CALLT to CTPC register
2829     ;; without saving its previous value.  So if the interrupt handler
2830     ;; or its caller could possibly execute the CALLT insn, save_interrupt 
2831     ;; MUST NOT be called via CALLT.
2833   output_asm_insn ("addi -28,   sp, sp", operands);
2834   output_asm_insn ("st.w r1,    24[sp]", operands);
2835   output_asm_insn ("st.w r10,   12[sp]", operands);
2836   output_asm_insn ("st.w r11,   16[sp]", operands);
2837   output_asm_insn ("stsr ctpc,  r10",    operands);
2838   output_asm_insn ("st.w r10,   20[sp]", operands);
2839   output_asm_insn ("stsr ctpsw, r10",    operands);
2840   output_asm_insn ("st.w r10,   24[sp]", operands);
2841   output_asm_insn ("callt ctoff(__callt_save_interrupt)", operands);
2842   return "";
2844    [(set_attr "length" "26")
2845     (set_attr "cc" "clobber")])
2847 (define_insn "callt_return_interrupt"
2848   [(unspec_volatile [(const_int 0)] 3)]
2849   "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2850   "callt ctoff(__callt_return_interrupt)"
2851   [(set_attr "length" "2")
2852    (set_attr "cc" "clobber")])
2854 (define_insn "save_interrupt"
2855   [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -20)))
2856    (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 30))
2857    (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 4))
2858    (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))
2859    (set (mem:SI (plus:SI (reg:SI 3) (const_int  -8))) (reg:SI 10))
2860    (set (mem:SI (plus:SI (reg:SI 3) (const_int  -4))) (reg:SI 11))]
2861   ""
2863   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2864     return "addi -20,sp,sp \; st.w r11,16[sp] \; st.w r10,12[sp] \; jarl __save_interrupt,r10";
2865   else
2866     {
2867       output_asm_insn ("addi  -20, sp, sp", operands);
2868       output_asm_insn ("st.w  r11, 16[sp]", operands);
2869       output_asm_insn ("st.w  r10, 12[sp]", operands);
2870       output_asm_insn ("st.w  ep, 0[sp]", operands);
2871       output_asm_insn ("st.w  gp, 4[sp]", operands);
2872       output_asm_insn ("st.w  r1, 8[sp]", operands);
2873       output_asm_insn ("movhi hi(__ep), r0, ep", operands);
2874       output_asm_insn ("movea lo(__ep), ep, ep", operands);
2875       output_asm_insn ("movhi hi(__gp), r0, gp", operands);
2876       output_asm_insn ("movea lo(__gp), gp, gp", operands);
2877       return "";
2878     }
2880   [(set (attr "length")
2881         (if_then_else (match_test "TARGET_LONG_CALLS")
2882                        (const_int 10)
2883                        (const_int 34)))
2884    (set_attr "cc" "clobber")])
2885   
2886 ;; Restore r1, r4, r10, and return from the interrupt
2887 (define_insn "return_interrupt"
2888   [(return)
2889    (set (reg:SI 3)  (plus:SI (reg:SI 3) (const_int 20)))
2890    (set (reg:SI 11) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))
2891    (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
2892    (set (reg:SI 1)  (mem:SI (plus:SI (reg:SI 3) (const_int  8))))
2893    (set (reg:SI 4)  (mem:SI (plus:SI (reg:SI 3) (const_int  4))))
2894    (set (reg:SI 30) (mem:SI (reg:SI 3)))]
2895   ""
2897   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2898     return "jr __return_interrupt";
2899   else 
2900     {
2901       output_asm_insn ("ld.w 0[sp],  ep",   operands);
2902       output_asm_insn ("ld.w 4[sp],  gp",   operands);
2903       output_asm_insn ("ld.w 8[sp],  r1",   operands);
2904       output_asm_insn ("ld.w 12[sp], r10", operands);
2905       output_asm_insn ("ld.w 16[sp], r11", operands);
2906       output_asm_insn ("addi 20, sp, sp",   operands);
2907       output_asm_insn ("reti",            operands);
2908       return "";
2909     }
2911   [(set (attr "length")
2912         (if_then_else (match_test "TARGET_LONG_CALLS")
2913                        (const_int 4)
2914                        (const_int 24)))
2915    (set_attr "cc" "clobber")])
2917 ;; Save all registers except for the registers saved in save_interrupt when
2918 ;; an interrupt function makes a call.
2919 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2920 ;; all of memory.  This blocks insns from being moved across this point.
2921 ;; This is needed because the rest of the compiler is not ready to handle
2922 ;; insns this complicated.
2924 (define_insn "callt_save_all_interrupt"
2925   [(unspec_volatile [(const_int 0)] 0)]
2926   "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2927   "callt ctoff(__callt_save_all_interrupt)"
2928   [(set_attr "length" "2")
2929    (set_attr "cc" "none")])
2931 (define_insn "save_all_interrupt"
2932   [(unspec_volatile [(const_int 0)] 0)]
2933   ""
2935   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2936     return "jarl __save_all_interrupt,r10";
2938   output_asm_insn ("addi -120, sp, sp", operands);
2940   if (TARGET_EP)
2941     {
2942       output_asm_insn ("mov ep, r1", operands);
2943       output_asm_insn ("mov sp, ep", operands);
2944       output_asm_insn ("sst.w r31, 116[ep]", operands);
2945       output_asm_insn ("sst.w r2,  112[ep]", operands);
2946       output_asm_insn ("sst.w gp,  108[ep]", operands);
2947       output_asm_insn ("sst.w r6,  104[ep]", operands);
2948       output_asm_insn ("sst.w r7,  100[ep]", operands);
2949       output_asm_insn ("sst.w r8,   96[ep]", operands);
2950       output_asm_insn ("sst.w r9,   92[ep]", operands);
2951       output_asm_insn ("sst.w r11,  88[ep]", operands);
2952       output_asm_insn ("sst.w r12,  84[ep]", operands);
2953       output_asm_insn ("sst.w r13,  80[ep]", operands);
2954       output_asm_insn ("sst.w r14,  76[ep]", operands);
2955       output_asm_insn ("sst.w r15,  72[ep]", operands);
2956       output_asm_insn ("sst.w r16,  68[ep]", operands);
2957       output_asm_insn ("sst.w r17,  64[ep]", operands);
2958       output_asm_insn ("sst.w r18,  60[ep]", operands);
2959       output_asm_insn ("sst.w r19,  56[ep]", operands);
2960       output_asm_insn ("sst.w r20,  52[ep]", operands);
2961       output_asm_insn ("sst.w r21,  48[ep]", operands);
2962       output_asm_insn ("sst.w r22,  44[ep]", operands);
2963       output_asm_insn ("sst.w r23,  40[ep]", operands);
2964       output_asm_insn ("sst.w r24,  36[ep]", operands);
2965       output_asm_insn ("sst.w r25,  32[ep]", operands);
2966       output_asm_insn ("sst.w r26,  28[ep]", operands);
2967       output_asm_insn ("sst.w r27,  24[ep]", operands);
2968       output_asm_insn ("sst.w r28,  20[ep]", operands);
2969       output_asm_insn ("sst.w r29,  16[ep]", operands);
2970       output_asm_insn ("mov   r1,   ep", operands);
2971     }
2972   else
2973     {
2974       output_asm_insn ("st.w r31, 116[sp]", operands);
2975       output_asm_insn ("st.w r2,  112[sp]", operands);
2976       output_asm_insn ("st.w gp,  108[sp]", operands);
2977       output_asm_insn ("st.w r6,  104[sp]", operands);
2978       output_asm_insn ("st.w r7,  100[sp]", operands);
2979       output_asm_insn ("st.w r8,   96[sp]", operands);
2980       output_asm_insn ("st.w r9,   92[sp]", operands);
2981       output_asm_insn ("st.w r11,  88[sp]", operands);
2982       output_asm_insn ("st.w r12,  84[sp]", operands);
2983       output_asm_insn ("st.w r13,  80[sp]", operands);
2984       output_asm_insn ("st.w r14,  76[sp]", operands);
2985       output_asm_insn ("st.w r15,  72[sp]", operands);
2986       output_asm_insn ("st.w r16,  68[sp]", operands);
2987       output_asm_insn ("st.w r17,  64[sp]", operands);
2988       output_asm_insn ("st.w r18,  60[sp]", operands);
2989       output_asm_insn ("st.w r19,  56[sp]", operands);
2990       output_asm_insn ("st.w r20,  52[sp]", operands);
2991       output_asm_insn ("st.w r21,  48[sp]", operands);
2992       output_asm_insn ("st.w r22,  44[sp]", operands);
2993       output_asm_insn ("st.w r23,  40[sp]", operands);
2994       output_asm_insn ("st.w r24,  36[sp]", operands);
2995       output_asm_insn ("st.w r25,  32[sp]", operands);
2996       output_asm_insn ("st.w r26,  28[sp]", operands);
2997       output_asm_insn ("st.w r27,  24[sp]", operands);
2998       output_asm_insn ("st.w r28,  20[sp]", operands);
2999       output_asm_insn ("st.w r29,  16[sp]", operands);
3000     }
3001     
3002   return "";
3004   [(set (attr "length")
3005         (if_then_else (match_test "TARGET_LONG_CALLS")
3006                        (const_int 4)
3007                        (const_int 62)
3008         ))
3009    (set_attr "cc" "clobber")])
3011 (define_insn "_save_all_interrupt"
3012   [(unspec_volatile [(const_int 0)] 0)]
3013   "TARGET_V850 && ! TARGET_LONG_CALLS"
3014   "jarl __save_all_interrupt,r10"
3015   [(set_attr "length" "4")
3016    (set_attr "cc" "clobber")])
3018 ;; Restore all registers saved when an interrupt function makes a call.
3019 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3020 ;; all of memory.  This blocks insns from being moved across this point.
3021 ;; This is needed because the rest of the compiler is not ready to handle
3022 ;; insns this complicated.
3024 (define_insn "callt_restore_all_interrupt"
3025   [(unspec_volatile [(const_int 0)] 1)]
3026   "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
3027   "callt ctoff(__callt_restore_all_interrupt)"
3028   [(set_attr "length" "2")
3029    (set_attr "cc" "none")])
3031 (define_insn "restore_all_interrupt"
3032   [(unspec_volatile [(const_int 0)] 1)]
3033   ""
3035   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
3036     return "jarl __restore_all_interrupt,r10";
3038   if (TARGET_EP)
3039     {
3040       output_asm_insn ("mov   ep,      r1", operands);
3041       output_asm_insn ("mov   sp,      ep", operands);
3042       output_asm_insn ("sld.w 116[ep], r31", operands);
3043       output_asm_insn ("sld.w 112[ep], r2", operands);
3044       output_asm_insn ("sld.w 108[ep], gp", operands);
3045       output_asm_insn ("sld.w 104[ep], r6", operands);
3046       output_asm_insn ("sld.w 100[ep], r7", operands);
3047       output_asm_insn ("sld.w 96[ep],  r8", operands);
3048       output_asm_insn ("sld.w 92[ep],  r9", operands);
3049       output_asm_insn ("sld.w 88[ep],  r11", operands);
3050       output_asm_insn ("sld.w 84[ep],  r12", operands);
3051       output_asm_insn ("sld.w 80[ep],  r13", operands);
3052       output_asm_insn ("sld.w 76[ep],  r14", operands);
3053       output_asm_insn ("sld.w 72[ep],  r15", operands);
3054       output_asm_insn ("sld.w 68[ep],  r16", operands);
3055       output_asm_insn ("sld.w 64[ep],  r17", operands);
3056       output_asm_insn ("sld.w 60[ep],  r18", operands);
3057       output_asm_insn ("sld.w 56[ep],  r19", operands);
3058       output_asm_insn ("sld.w 52[ep],  r20", operands);
3059       output_asm_insn ("sld.w 48[ep],  r21", operands);
3060       output_asm_insn ("sld.w 44[ep],  r22", operands);
3061       output_asm_insn ("sld.w 40[ep],  r23", operands);
3062       output_asm_insn ("sld.w 36[ep],  r24", operands);
3063       output_asm_insn ("sld.w 32[ep],  r25", operands);
3064       output_asm_insn ("sld.w 28[ep],  r26", operands);
3065       output_asm_insn ("sld.w 24[ep],  r27", operands);
3066       output_asm_insn ("sld.w 20[ep],  r28", operands);
3067       output_asm_insn ("sld.w 16[ep],  r29", operands);
3068       output_asm_insn ("mov   r1,      ep", operands);
3069     }
3070   else
3071     {
3072       output_asm_insn ("ld.w 116[sp], r31", operands);
3073       output_asm_insn ("ld.w 112[sp], r2", operands);
3074       output_asm_insn ("ld.w 108[sp], gp", operands);
3075       output_asm_insn ("ld.w 104[sp], r6", operands);
3076       output_asm_insn ("ld.w 100[sp], r7", operands);
3077       output_asm_insn ("ld.w 96[sp],  r8", operands);
3078       output_asm_insn ("ld.w 92[sp],  r9", operands);
3079       output_asm_insn ("ld.w 88[sp],  r11", operands);
3080       output_asm_insn ("ld.w 84[sp],  r12", operands);
3081       output_asm_insn ("ld.w 80[sp],  r13", operands);
3082       output_asm_insn ("ld.w 76[sp],  r14", operands);
3083       output_asm_insn ("ld.w 72[sp],  r15", operands);
3084       output_asm_insn ("ld.w 68[sp],  r16", operands);
3085       output_asm_insn ("ld.w 64[sp],  r17", operands);
3086       output_asm_insn ("ld.w 60[sp],  r18", operands);
3087       output_asm_insn ("ld.w 56[sp],  r19", operands);
3088       output_asm_insn ("ld.w 52[sp],  r20", operands);
3089       output_asm_insn ("ld.w 48[sp],  r21", operands);
3090       output_asm_insn ("ld.w 44[sp],  r22", operands);
3091       output_asm_insn ("ld.w 40[sp],  r23", operands);
3092       output_asm_insn ("ld.w 36[sp],  r24", operands);
3093       output_asm_insn ("ld.w 32[sp],  r25", operands);
3094       output_asm_insn ("ld.w 28[sp],  r26", operands);
3095       output_asm_insn ("ld.w 24[sp],  r27", operands);
3096       output_asm_insn ("ld.w 20[sp],  r28", operands);
3097       output_asm_insn ("ld.w 16[sp],  r29", operands);
3098     }
3099   output_asm_insn ("addi  120, sp, sp", operands);
3100   return "";
3102   [(set (attr "length")
3103         (if_then_else (match_test "TARGET_LONG_CALLS")
3104                        (const_int 4)
3105                        (const_int 62)
3106         ))
3107    (set_attr "cc" "clobber")])
3109 (define_insn "_restore_all_interrupt"
3110   [(unspec_volatile [(const_int 0)] 1)]
3111   "TARGET_V850 && ! TARGET_LONG_CALLS"
3112   "jarl __restore_all_interrupt,r10"
3113   [(set_attr "length" "4")
3114    (set_attr "cc" "clobber")])