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