* config/v850/v850-modes.def (CCZ, CCNZ): Add new modes.
[official-gcc.git] / gcc / config / v850 / v850.md
blob0fad9ea501dec8e003f2baa615dffc7f3326d3b4
1 ;; GCC machine description for NEC V850
2 ;; Copyright (C) 1996-2018 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   ]
50 (define_c_enum "unspec" [
51   UNSPEC_LOOP
52   UNSPEC_RCP
53   UNSPEC_RSQRT
56 (define_attr "length" ""
57   (const_int 4))
59 (define_attr "long_calls" "yes,no"
60   (const (if_then_else (symbol_ref "TARGET_LONG_CALLS")
61                        (const_string "yes")
62                        (const_string "no"))))
63             
64 ;; Types of instructions (for scheduling purposes).
66 (define_attr "type" "load,store,bit1,mult,macc,div,fpu,single,other"
67   (const_string "other"))
69 (define_attr "cpu" "none,v850,v850e,v850e1,v850e2,v850e2v3,v850e3v5"
70   (cond [(match_test "TARGET_V850")
71          (const_string "v850")
72          (match_test "TARGET_V850E")
73          (const_string "v850e")
74          (match_test "TARGET_V850E1")
75          (const_string "v850e1")
76          (match_test "TARGET_V850E2")
77          (const_string "v850e2")
78          (match_test "TARGET_V850E2V3")
79          (const_string "v850e2v3")
80          (match_test "TARGET_V850E3V5")
81          (const_string "v850e3v5")]      
82          (const_string "none")))
85 ;; Function units for the V850.  As best as I can tell, there's
86 ;; a traditional memory load/use stall as well as a stall if
87 ;; the result of a multiply is used too early.
89 (define_insn_reservation "v850_other" 1
90                          (eq_attr "type" "other")
91                          "nothing")
92 (define_insn_reservation "v850_mult" 2
93                          (eq_attr "type" "mult")
94                          "nothing")
95 (define_insn_reservation "v850_memory" 2
96                          (eq_attr "type" "load")
97                          "nothing")
99 (include "predicates.md")
100 (include "constraints.md")
102 ;; ----------------------------------------------------------------------
103 ;; MOVE INSTRUCTIONS
104 ;; ----------------------------------------------------------------------
105 (define_insn "sign23byte_load"
106   [(set (match_operand:SI 0 "register_operand" "=r")
107         (sign_extend:SI
108         (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
109                          (match_operand 2 "disp23_operand" "W")))))]
110   "TARGET_V850E2V3_UP"
111   "ld.b %2[%1],%0"
112   [(set_attr "length" "4")])
113   
114 (define_insn "unsign23byte_load"
115   [(set (match_operand:SI 0 "register_operand" "=r")
116         (zero_extend:SI
117         (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
118                          (match_operand 2 "disp23_operand" "W")))))]
119   "TARGET_V850E2V3_UP"
120   "ld.bu %2[%1],%0"
121   [(set_attr "length" "4")])
123 (define_insn "sign23hword_load"
124   [(set (match_operand:SI 0 "register_operand" "=r")
125         (sign_extend:SI
126         (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
127                          (match_operand 2 "disp23_operand" "W")))))]
128   "TARGET_V850E2V3_UP"
129   "ld.h %2[%1],%0"
130   [(set_attr "length" "4")])
132 (define_insn "unsign23hword_load"
133   [(set (match_operand:SI 0 "register_operand" "=r")
134         (zero_extend:SI
135         (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
136                          (match_operand 2 "disp23_operand" "W")))))]
137   "TARGET_V850E2V3_UP"
138   "ld.hu %2[%1],%0"
139   [(set_attr "length" "4")])
141 (define_insn "23word_load"
142   [(set (match_operand:SI 0 "register_operand" "=r")
143         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
144                          (match_operand 2 "disp23_operand" "W"))))]
145   "TARGET_V850E2V3_UP"
146   "ld.w %2[%1],%0"
147   [(set_attr "length" "4")])
149 (define_insn "23byte_store"
150   [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "r")
151                          (match_operand 1 "disp23_operand" "W")))
152         (match_operand:QI 2 "register_operand" "r"))]
153   "TARGET_V850E2V3_UP"
154   "st.b %2,%1[%0]"
155   [(set_attr "length" "4")])
157 (define_insn "23hword_store"
158   [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "r")
159                          (match_operand 1 "disp23_operand" "W")))
160         (match_operand:HI 2 "register_operand" "r"))]
161   "TARGET_V850E2V3_UP"
162   "st.h %2,%1[%0]"
163   [(set_attr "length" "4")])
165 (define_insn "23word_store"
166   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
167                          (match_operand 1 "disp23_operand" "W")))
168         (match_operand:SI 2 "register_operand" "r"))]
169   "TARGET_V850E2V3_UP"
170   "st.w %2,%1[%0]"
171   [(set_attr "length" "4")])
173 ;; movdi
175 (define_expand "movdi"
176   [(set (match_operand:DI 0 "general_operand")
177         (match_operand:DI 1 "general_operand"))]
178   "TARGET_V850E3V5_UP"
179   {
180     /* One of the ops has to be in a register or 0.  */
181     if (!register_operand (operand0, DImode)
182         && !register_operand (operand1, DImode))
183       operands[1] = copy_to_mode_reg (DImode, operand1);
185     if (register_operand (operand0, DImode)
186         && (CONST_INT_P (operands[1]) || CONST_DOUBLE_P (operands[1])))
187       {
188         int i;
190         for (i = 0; i < UNITS_PER_WORD * 2; i += UNITS_PER_WORD)
191           emit_move_insn (simplify_gen_subreg (SImode, operands[0], DImode, i),
192                           simplify_gen_subreg (SImode, operands[1], DImode, i));
193         DONE;
194       }
195   }
198 (define_insn "*movdi_internal"
199   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,e!r,m")
200         (match_operand:DI 1 "nonimmediate_operand"  "r,m,e!r"))]
201   "TARGET_V850E3V5_UP
202    || (register_operand (operands[0], DImode) && register_operand (operands[1], DImode))"
203   { return v850_gen_movdi (operands); }
204   [(set_attr "length" "4,12,12")
205    (set_attr "type" "other,load,store")])
207 ;; movqi
209 (define_expand "movqi"
210   [(set (match_operand:QI 0 "general_operand" "")
211         (match_operand:QI 1 "general_operand" ""))]
212   ""
213   {
214     /* One of the ops has to be in a register or 0 */
215     if (!register_operand (operand0, QImode)
216         && !reg_or_0_operand (operand1, QImode))
217       operands[1] = copy_to_mode_reg (QImode, operand1);
218   })
220 (define_insn "*movqi_internal"
221   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,Q,r,m,m")
222         (match_operand:QI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
223   "register_operand (operands[0], QImode)
224    || reg_or_0_operand (operands[1], QImode)"
226   return output_move_single (operands);
228   [(set_attr "length" "2,4,2,2,4,4,4")
229    (set_attr "type" "other,other,load,other,load,store,store")])
231 ;; movhi
233 (define_expand "movhi"
234   [(set (match_operand:HI 0 "general_operand" "")
235         (match_operand:HI 1 "general_operand" ""))]
236   ""
238   /* One of the ops has to be in a register or 0 */
239   if (!register_operand (operand0, HImode)
240       && !reg_or_0_operand (operand1, HImode))
241     operands[1] = copy_to_mode_reg (HImode, operand1);
244 (define_insn "*movhi_internal"
245   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,Q,r,m,m")
246         (match_operand:HI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
247   "register_operand (operands[0], HImode)
248    || reg_or_0_operand (operands[1], HImode)"
250   return output_move_single (operands);
252   [(set_attr "length" "2,4,2,2,4,4,4")
253    (set_attr "type" "other,other,load,other,load,store,store")])
255 ;; movsi and helpers
257 (define_insn "*movsi_high"
258   [(set (match_operand:SI 0 "register_operand" "=r")
259         (high:SI (match_operand 1 "immediate_operand" "i")))]
260   ""
261   "movhi hi(%1),%.,%0"
262   [(set_attr "length" "4")
263    (set_attr "type" "other")])
265 (define_insn "*movsi_lo"
266   [(set (match_operand:SI 0 "register_operand" "=r")
267         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
268                    (match_operand:SI 2 "immediate_operand" "i")))]
269   ""
270   "movea lo(%2),%1,%0"
271   [(set_attr "length" "4")
272    (set_attr "type" "other")])
274 (define_expand "movsi"
275   [(set (match_operand:SI 0 "general_operand" "")
276         (match_operand:SI 1 "general_operand" ""))]
277   ""
278   {
279     /* One of the ops has to be in a register or 0 */
280     if (!register_operand (operand0, SImode)
281         && !reg_or_0_operand (operand1, SImode))
282       operands[1] = copy_to_mode_reg (SImode, operand1);
284     /* Some constants, as well as symbolic operands
285        must be done with HIGH & LO_SUM patterns.  */
286     if (CONSTANT_P (operands[1])        
287         && GET_CODE (operands[1]) != HIGH
288         && ! (TARGET_V850E_UP)
289         && !special_symbolref_operand (operands[1], VOIDmode)
290         && !(GET_CODE (operands[1]) == CONST_INT
291              && (CONST_OK_FOR_J (INTVAL (operands[1]))
292                  || CONST_OK_FOR_K (INTVAL (operands[1]))
293                  || CONST_OK_FOR_L (INTVAL (operands[1])))))
294       {
295         rtx temp;
297         if (reload_in_progress || reload_completed)
298           temp = operands[0];
299         else
300           temp = gen_reg_rtx (SImode);
302         emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (SImode, operand1)));
303         emit_insn (gen_rtx_SET (operand0,
304                                 gen_rtx_LO_SUM (SImode, temp, operand1)));
305         DONE;
306       }
307   })
309 ;; This is the same as the following pattern, except that it includes
310 ;; support for arbitrary 32-bit immediates.
312 ;; ??? This always loads addresses using hilo.  If the only use of this address
313 ;; was in a load/store, then we would get smaller code if we only loaded the
314 ;; upper part with hi, and then put the lower part in the load/store insn.
316 (define_insn "*movsi_internal_v850e"
317   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,Q,r,r,m,m,r")
318         (match_operand:SI 1 "general_operand" "Jr,K,L,Q,Ir,m,R,r,I,i"))]
319   "(TARGET_V850E_UP)
320    && (register_operand (operands[0], SImode)
321        || reg_or_0_operand (operands[1], SImode))"
323   return output_move_single (operands);
325   [(set_attr "length" "2,4,4,2,2,4,4,4,4,6")
326    (set_attr "type" "other,other,other,load,other,load,other,store,store,other")])
328 (define_insn "*movsi_internal"
329   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,Q,r,r,m,m")
330         (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))]
331   "register_operand (operands[0], SImode)
332    || reg_or_0_operand (operands[1], SImode)"
334   return output_move_single (operands);
336   [(set_attr "length" "2,4,4,2,2,4,4,4,4")
337    (set_attr "type" "other,other,other,load,other,load,store,store,other")])
339 (define_insn "*movsf_internal"
340   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,Q,r,m,m,r")
341         (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))]
342   "register_operand (operands[0], SFmode)
343    || reg_or_0_operand (operands[1], SFmode)"
345   return output_move_single (operands);
347   [(set_attr "length" "2,4,4,8,2,2,4,4,4,8")
348    (set_attr "type" "other,other,other,other,load,other,load,store,store,other")])
350 ;; ----------------------------------------------------------------------
351 ;; TEST INSTRUCTIONS
352 ;; ----------------------------------------------------------------------
354 (define_insn "*v850_tst1"
355   [(set (cc0)
356         (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
357                                   (const_int 1)
358                                   (match_operand:QI 1 "const_int_operand" "n"))
359                  (const_int 0)))]
360   ""
361   "tst1 %1,%0"
362   [(set_attr "length" "4")])
364 ;; This replaces ld.b;sar;andi with tst1;setf nz.
366 (define_split
367   [(set (match_operand:SI 0 "register_operand" "")
368         (compare (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
369                                   (const_int 1)
370                                   (match_operand 2 "const_int_operand" ""))
371                  (const_int 0)))]
372   ""
373   [(set (cc0) (compare (zero_extract:SI (match_dup 1)
374                                         (const_int 1)
375                                         (match_dup 2))
376                        (const_int 0)))
377    (set (match_dup 0) (ne:SI (cc0) (const_int 0)))])
379 (define_expand "cbranchsi4"
380   [(set (cc0)
381         (compare (match_operand:SI 1 "register_operand" "")
382                  (match_operand:SI 2 "reg_or_int5_operand" "")))
383    (set (pc)
384         (if_then_else
385               (match_operator 0 "ordered_comparison_operator" [(cc0)
386                                                                (const_int 0)])
387               (label_ref (match_operand 3 "" ""))
388               (pc)))]
389  "")
391 (define_expand "cstoresi4"
392   [(set (cc0)
393         (compare (match_operand:SI 2 "register_operand" "")
394                  (match_operand:SI 3 "reg_or_int5_operand" "")))
395    (set (match_operand:SI 0 "register_operand")
396         (match_operator:SI 1 "ordered_comparison_operator" [(cc0)
397                                                             (const_int 0)]))]
398   "")
400 (define_expand "cmpsi"
401   [(set (cc0)
402         (compare (match_operand:SI 0 "register_operand" "r,r")
403                  (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
404    ""
405   {
406     v850_compare_op0 = operands[0];
407     v850_compare_op1 = operands[1];
408     DONE;
409   })
411 (define_insn "cmpsi_insn"
412   [(set (cc0)
413         (compare (match_operand:SI 0 "register_operand" "r,r")
414                  (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
415   ""
416   "@
417   cmp %1,%0
418   cmp %1,%0"
419   [(set_attr "length" "2,2")])
421 (define_expand "cbranchsf4"
422   [(set (pc)
423        (if_then_else (match_operator     0 "ordered_comparison_operator"
424                       [(match_operand:SF 1 "register_operand")
425                        (match_operand:SF 2 "register_operand")])
426                      (label_ref (match_operand 3 ""))
427                      (pc)))
428   (clobber (cc0))]
429   "TARGET_USE_FPU"
431   enum rtx_code cond = GET_CODE (operands[0]);
432   machine_mode mode;
433   rtx fcc_reg;
434   rtx cc_reg;
435   rtx tmp;
437   v850_compare_op0 = operands[1];
438   v850_compare_op1 = operands[2];
440   if (GET_MODE_CLASS (GET_MODE (v850_compare_op0)) != MODE_FLOAT)
441     FAIL;
443   mode = v850_gen_float_compare (cond, VOIDmode, v850_compare_op0, v850_compare_op1);
444   fcc_reg = gen_rtx_REG (mode, FCC_REGNUM);
445   cc_reg = gen_rtx_REG (mode, CC_REGNUM);
446   emit_insn (gen_rtx_SET (cc_reg, fcc_reg));
447   tmp = gen_rtx_fmt_ee (cond, mode, cc_reg, const0_rtx);
448   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
449                               gen_rtx_LABEL_REF (VOIDmode, operands[3]), pc_rtx);
450   emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
451   DONE;
454 (define_insn "cstoresf4"
455   [(set (match_operand:SI   0 "register_operand" "=r")
456         (match_operator:SI  1 "ordered_comparison_operator"
457          [(match_operand:SF 2 "register_operand" "r")
458           (match_operand:SF 3 "register_operand" "r")]))]
459   "TARGET_USE_FPU"
461   if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
462     return "cmpf.s %c1, %z2, %z3 ; trfsr ; setf nz, %0";
463   if (GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE)
464     return "cmpf.s %c1, %z2, %z3 ; trfsr ; setf z, %0";
465   if (GET_CODE (operands[1]) == EQ)
466     return "cmpf.s eq, %z2, %z3 ; trfsr ; setf z, %0";
467   if (GET_CODE (operands[1]) == NE)
468     return "cmpf.s neq, %z2, %z3 ; trfsr ; setf nz, %0";
469   gcc_unreachable ();
471   [(set_attr "length" "12")
472    (set_attr "type" "fpu")])
474 (define_expand "cbranchdf4"
475   [(set (pc)
476        (if_then_else (match_operator     0 "ordered_comparison_operator"
477                       [(match_operand:DF 1 "even_reg_operand")
478                        (match_operand:DF 2 "even_reg_operand")])
479                      (label_ref (match_operand 3 ""))
480                      (pc)))
481   (clobber (cc0))]
482   "TARGET_USE_FPU"
484   enum rtx_code cond = GET_CODE (operands[0]);
485   machine_mode mode;
486   rtx fcc_reg;
487   rtx cc_reg;
488   rtx tmp;
490     v850_compare_op0 = operands[1];
491     v850_compare_op1 = operands[2];
493   if (GET_MODE_CLASS (GET_MODE (v850_compare_op0)) != MODE_FLOAT)
494     FAIL;
496   mode = v850_gen_float_compare (cond, VOIDmode, v850_compare_op0, v850_compare_op1);
497   fcc_reg = gen_rtx_REG (mode, FCC_REGNUM);
498   cc_reg = gen_rtx_REG (mode, CC_REGNUM);
499   emit_insn (gen_rtx_SET (cc_reg, fcc_reg));
500   tmp = gen_rtx_fmt_ee (cond, mode, cc_reg, const0_rtx);
501   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
502                               gen_rtx_LABEL_REF (VOIDmode, operands[3]), pc_rtx);
503   emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
504   DONE;
507 (define_insn "cstoredf4"
508   [(set (match_operand:SI   0 "register_operand" "=r")
509         (match_operator:SI  1 "ordered_comparison_operator"
510          [(match_operand:DF 2 "even_reg_operand"  "r")
511           (match_operand:DF 3 "even_reg_operand" "r")]))]
512   "TARGET_USE_FPU"
514   if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
515     return "cmpf.d %c1, %z2, %z3 ; trfsr ; setf nz, %0";
516   if (GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE)
517     return "cmpf.d %c1, %z2, %z3 ; trfsr ; setf z, %0";
518   if (GET_CODE (operands[1]) == EQ)
519     return "cmpf.d eq, %z2, %z3 ; trfsr ; setf z ,%0";
520   if (GET_CODE (operands[1]) == NE)
521     return "cmpf.d neq, %z2, %z3 ; trfsr ; setf nz, %0";
522   gcc_unreachable ();
524   [(set_attr "length" "12")
525    (set_attr "type" "fpu")])
527 (define_expand "cmpsf"
528   [(set (reg:CC CC_REGNUM)
529         (compare (match_operand:SF 0 "register_operand" "r")
530                  (match_operand:SF 1 "register_operand" "r")))]
531   "TARGET_USE_FPU"
532   {
533     v850_compare_op0 = operands[0];
534     v850_compare_op1 = operands[1];
535     DONE;
536   })
538 (define_expand "cmpdf"
539   [(set (reg:CC CC_REGNUM)
540         (compare (match_operand:DF 0 "even_reg_operand" "r")
541                  (match_operand:DF 1 "even_reg_operand" "r")))]
542   "TARGET_USE_FPU"
543   {
544     v850_compare_op0 = operands[0];
545     v850_compare_op1 = operands[1];
546     DONE;
547   })
549 ;; ----------------------------------------------------------------------
550 ;; ADD INSTRUCTIONS
551 ;; ----------------------------------------------------------------------
553 (define_insn "addsi3"
554   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
555         (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
556                  (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))
557    (clobber (reg:CC CC_REGNUM))]
559   ""
560   "@
561    add %2,%0
562    addi %2,%1,%0
563    addi %O2(%P2),%1,%0"
564   [(set_attr "length" "2,4,4")])
566 ;; ----------------------------------------------------------------------
567 ;; SUBTRACT INSTRUCTIONS
568 ;; ----------------------------------------------------------------------
570 (define_insn "subsi3"
571   [(set (match_operand:SI 0 "register_operand" "=r,r")
572         (minus:SI (match_operand:SI 1 "register_operand" "0,r")
573                   (match_operand:SI 2 "register_operand" "r,0")))
574    (clobber (reg:CC CC_REGNUM))]
575   ""
576   "@
577   sub %2,%0
578   subr %1,%0"
579   [(set_attr "length" "2,2")])
581 (define_insn "negsi2"
582   [(set (match_operand:SI 0 "register_operand" "=r")
583         (neg:SI (match_operand:SI 1 "register_operand" "0")))
584    (clobber (reg:CC CC_REGNUM))]
585   ""
586   "subr %.,%0"
587   [(set_attr "length" "2")])
589 ;; ----------------------------------------------------------------------
590 ;; MULTIPLY INSTRUCTIONS
591 ;; ----------------------------------------------------------------------
593 (define_expand "mulhisi3"
594   [(set (match_operand:SI 0 "register_operand" "")
595         (mult:SI
596           (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
597           (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
598   ""
599   {
600     if (GET_CODE (operands[2]) == CONST_INT)
601       {
602         emit_insn (gen_mulhisi3_internal2 (operands[0], operands[1], operands[2]));
603         DONE;
604       }
605   })
607 (define_insn "*mulhisi3_internal1"
608   [(set (match_operand:SI 0 "register_operand" "=r")
609         (mult:SI
610           (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
611           (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
612   ""
613   "mulh %2,%0"
614   [(set_attr "length" "2")
615    (set_attr "type" "mult")])
617 (define_insn "mulhisi3_internal2"
618   [(set (match_operand:SI 0 "register_operand" "=r,r")
619         (mult:SI
620           (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
621           (match_operand:HI 2 "const_int_operand" "J,K")))]
622   ""
623   "@
624    mulh %2,%0
625    mulhi %2,%1,%0"
626   [(set_attr "length" "2,4")
627    (set_attr "type" "mult")])
629 ;; ??? The scheduling info is probably wrong.
631 ;; ??? This instruction can also generate the 32-bit highpart, but using it
632 ;; may increase code size counter to the desired result.
634 ;; ??? This instructions can also give a DImode result.
636 ;; ??? There is unsigned version, but it matters only for the DImode/highpart
637 ;; results.
639 (define_insn "mulsi3"
640   [(set (match_operand:SI 0 "register_operand" "=r")
641         (mult:SI (match_operand:SI 1 "register_operand" "%0")
642                  (match_operand:SI 2 "reg_or_int9_operand" "rO")))]
643   "(TARGET_V850E_UP)"
644   "mul %2,%1,%."
645   [(set_attr "length" "4")
646    (set_attr "type" "mult")])
648 ;; ----------------------------------------------------------------------
649 ;; DIVIDE INSTRUCTIONS
650 ;; ----------------------------------------------------------------------
652 ;; ??? These insns do set the Z/N condition codes, except that they are based
653 ;; on only one of the two results, so it doesn't seem to make sense to use
654 ;; them.
656 ;; ??? The scheduling info is probably wrong.
658 (define_insn "divmodsi4"
659   [(set (match_operand:SI 0 "register_operand" "=r")
660         (div:SI (match_operand:SI 1 "register_operand" "0")
661                 (match_operand:SI 2 "register_operand" "r")))
662    (set (match_operand:SI 3 "register_operand" "=r")
663         (mod:SI (match_dup 1)
664                 (match_dup 2)))
665    (clobber (reg:CC CC_REGNUM))]
666   "TARGET_V850E_UP"
668   if (TARGET_V850E2_UP)
669     return "divq %2,%0,%3";
670    else
671     return "div %2,%0,%3";
673   [(set_attr "length" "4")
674    (set_attr "type" "div")])
675         
676 (define_insn "udivmodsi4"
677   [(set (match_operand:SI 0 "register_operand" "=r")
678         (udiv:SI (match_operand:SI 1 "register_operand" "0")
679                  (match_operand:SI 2 "register_operand" "r")))
680    (set (match_operand:SI 3 "register_operand" "=r")
681         (umod:SI (match_dup 1)
682                  (match_dup 2)))
683    (clobber (reg:CC CC_REGNUM))]
684   "TARGET_V850E_UP"
686   if (TARGET_V850E2_UP)
687     return "divqu %2,%0,%3";
688   else
689     return "divu %2,%0,%3";
691   [(set_attr "length" "4")
692    (set_attr "type" "div")])
693         
694 ;; ??? There is a 2 byte instruction for generating only the quotient.
695 ;; However, it isn't clear how to compute the length field correctly.
697 (define_insn "divmodhi4"
698   [(set (match_operand:HI 0 "register_operand" "=r")
699         (div:HI (match_operand:HI 1 "register_operand" "0")
700                 (match_operand:HI 2 "register_operand" "r")))
701    (set (match_operand:HI 3 "register_operand" "=r")
702         (mod:HI (match_dup 1)
703                 (match_dup 2)))
704    (clobber (reg:CC CC_REGNUM))]
705   "TARGET_V850E_UP"
706   "sxh %0\n\tdivh %2,%0,%3"
707   [(set_attr "length" "6")
708    (set_attr "type" "div")])
710 ;; The half word needs to be zero/sign extended to 32 bits before doing
711 ;; the division/modulo operation.
713 (define_insn "udivmodhi4"
714   [(set (match_operand:HI 0 "register_operand" "=r")
715         (udiv:HI (match_operand:HI 1 "register_operand" "0")
716                  (match_operand:HI 2 "register_operand" "r")))
717    (set (match_operand:HI 3 "register_operand" "=r")
718         (umod:HI (match_dup 1)
719                  (match_dup 2)))
720    (clobber (reg:CC CC_REGNUM))]
721   "TARGET_V850E_UP"
722   "zxh %0\n\tdivhu %2,%0,%3"
723   [(set_attr "length" "6")
724    (set_attr "type" "div")])
726 ;; ----------------------------------------------------------------------
727 ;; AND INSTRUCTIONS
728 ;; ----------------------------------------------------------------------
730 (define_insn "*v850_clr1_1"
731   [(set (match_operand:QI 0 "memory_operand" "=m")
732         (subreg:QI
733           (and:SI (subreg:SI (match_dup 0) 0)
734                   (match_operand:QI 1 "not_power_of_two_operand" "")) 0))
735    (clobber (reg:CC CC_REGNUM))]
736   ""
738   rtx xoperands[2];
739   xoperands[0] = operands[0];
740   xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
741   output_asm_insn ("clr1 %M1,%0", xoperands);
742   return "";
744   [(set_attr "length" "4")
745    (set_attr "type" "bit1")])
747 (define_insn "*v850_clr1_2"
748   [(set (match_operand:HI 0 "indirect_operand" "=m")
749         (subreg:HI
750           (and:SI (subreg:SI (match_dup 0) 0)
751                   (match_operand:HI 1 "not_power_of_two_operand" "")) 0))
752    (clobber (reg:CC CC_REGNUM))]
753   ""
755   int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
757   rtx xoperands[2];
758   xoperands[0] = gen_rtx_MEM (QImode,
759                               plus_constant (Pmode, XEXP (operands[0], 0),
760                                              log2 / 8));
761   xoperands[1] = GEN_INT (log2 % 8);
762   output_asm_insn ("clr1 %1,%0", xoperands);
763   return "";
765   [(set_attr "length" "4")
766    (set_attr "type" "bit1")])
768 (define_insn "*v850_clr1_3"
769   [(set (match_operand:SI 0 "indirect_operand" "=m")
770         (and:SI (match_dup 0)
771                 (match_operand:SI 1 "not_power_of_two_operand" "")))
772    (clobber (reg:CC CC_REGNUM))]
773   ""
775   int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
777   rtx xoperands[2];
778   xoperands[0] = gen_rtx_MEM (QImode,
779                               plus_constant (Pmode, XEXP (operands[0], 0),
780                                              log2 / 8));
781   xoperands[1] = GEN_INT (log2 % 8);
782   output_asm_insn ("clr1 %1,%0", xoperands);
783   return "";
785   [(set_attr "length" "4")
786    (set_attr "type" "bit1")])
788 (define_insn "andsi3"
789   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
790         (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
791                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
792    (clobber (reg:CC CC_REGNUM))]
793   ""
794   "@
795   and %2,%0
796   and %.,%0
797   andi %2,%1,%0"
798   [(set_attr "length" "2,2,4")])
800 ;; ----------------------------------------------------------------------
801 ;; OR INSTRUCTIONS
802 ;; ----------------------------------------------------------------------
804 (define_insn "*v850_set1_1"
805   [(set (match_operand:QI 0 "memory_operand" "=m")
806         (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
807                            (match_operand 1 "power_of_two_operand" "")) 0))
808    (clobber (reg:CC CC_REGNUM))]
809   ""
810   "set1 %M1,%0"
811   [(set_attr "length" "4")
812    (set_attr "type" "bit1")])
814 (define_insn "*v850_set1_2"
815   [(set (match_operand:HI 0 "indirect_operand" "=m")
816         (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
817                            (match_operand 1 "power_of_two_operand" "")) 0))]
818   ""
820   int log2 = exact_log2 (INTVAL (operands[1]));
822   if (log2 < 8)
823     return "set1 %M1,%0";
824   else
825     {
826       rtx xoperands[2];
827       xoperands[0] = gen_rtx_MEM (QImode,
828                                   plus_constant (Pmode, XEXP (operands[0], 0),
829                                                  log2 / 8));
830       xoperands[1] = GEN_INT (log2 % 8);
831       output_asm_insn ("set1 %1,%0", xoperands);
832     }
833   return "";
835   [(set_attr "length" "4")
836    (set_attr "type" "bit1")])
838 (define_insn "*v850_set1_3"
839   [(set (match_operand:SI 0 "indirect_operand" "=m")
840         (ior:SI (match_dup 0)
841                 (match_operand 1 "power_of_two_operand" "")))
842    (clobber (reg:CC CC_REGNUM))]
843   ""
845   int log2 = exact_log2 (INTVAL (operands[1]));
847   if (log2 < 8)
848     return "set1 %M1,%0";
849   else
850     {
851       rtx xoperands[2];
852       xoperands[0] = gen_rtx_MEM (QImode,
853                                   plus_constant (Pmode, XEXP (operands[0], 0),
854                                                  log2 / 8));
855       xoperands[1] = GEN_INT (log2 % 8);
856       output_asm_insn ("set1 %1,%0", xoperands);
857     }
858   return "";
860   [(set_attr "length" "4")
861    (set_attr "type" "bit1")])
863 (define_insn "iorsi3"
864   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
865         (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
866                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
867    (clobber (reg:CC CC_REGNUM))]
868   ""
869   "@
870   or %2,%0
871   or %.,%0
872   ori %2,%1,%0"
873   [(set_attr "length" "2,2,4")])
875 ;; ----------------------------------------------------------------------
876 ;; XOR INSTRUCTIONS
877 ;; ----------------------------------------------------------------------
879 (define_insn "*v850_not1_1"
880   [(set (match_operand:QI 0 "memory_operand" "=m")
881         (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0)
882                            (match_operand 1 "power_of_two_operand" "")) 0))
883    (clobber (reg:CC CC_REGNUM))]
884   ""
885   "not1 %M1,%0"
886   [(set_attr "length" "4")
887    (set_attr "type" "bit1")])
889 (define_insn "*v850_not1_2"
890   [(set (match_operand:HI 0 "indirect_operand" "=m")
891         (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
892                            (match_operand 1 "power_of_two_operand" "")) 0))]
893   ""
895   int log2 = exact_log2 (INTVAL (operands[1]));
897   if (log2 < 8)
898     return "not1 %M1,%0";
899   else
900     {
901       rtx xoperands[2];
902       xoperands[0] = gen_rtx_MEM (QImode,
903                                   plus_constant (Pmode, XEXP (operands[0], 0),
904                                                  log2 / 8));
905       xoperands[1] = GEN_INT (log2 % 8);
906       output_asm_insn ("not1 %1,%0", xoperands);
907     }
908   return "";
910   [(set_attr "length" "4")
911    (set_attr "type" "bit1")])
913 (define_insn "*v850_not1_3"
914   [(set (match_operand:SI 0 "indirect_operand" "=m")
915         (xor:SI (match_dup 0)
916                 (match_operand 1 "power_of_two_operand" "")))
917    (clobber (reg:CC CC_REGNUM))]
918   ""
920   int log2 = exact_log2 (INTVAL (operands[1]));
922   if (log2 < 8)
923     return "not1 %M1,%0";
924   else
925     {
926       rtx xoperands[2];
927       xoperands[0] = gen_rtx_MEM (QImode,
928                                   plus_constant (Pmode, XEXP (operands[0], 0),
929                                                  log2 / 8));
930       xoperands[1] = GEN_INT (log2 % 8);
931       output_asm_insn ("not1 %1,%0", xoperands);
932     }
933   return "";
935   [(set_attr "length" "4")
936    (set_attr "type" "bit1")])
938 (define_insn "xorsi3"
939   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
940         (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
941                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
942    (clobber (reg:CC CC_REGNUM))]
943   ""
944   "@
945   xor %2,%0
946   xor %.,%0
947   xori %2,%1,%0"
948   [(set_attr "length" "2,2,4")])
950 ;; ----------------------------------------------------------------------
951 ;; NOT INSTRUCTIONS
952 ;; ----------------------------------------------------------------------
954 (define_insn "one_cmplsi2"
955   [(set (match_operand:SI 0 "register_operand" "=r")
956         (not:SI (match_operand:SI 1 "register_operand" "r")))
957    (clobber (reg:CC CC_REGNUM))]
958   ""
959   "not %1,%0"
960   [(set_attr "length" "2")])
962 ;; -----------------------------------------------------------------
963 ;; BIT FIELDS
964 ;; -----------------------------------------------------------------
966 ;; ??? Is it worth defining insv and extv for the V850 series?!?
968 ;; An insv pattern would be useful, but does not get used because
969 ;; store_bit_field never calls insv when storing a constant value into a
970 ;; single-bit bitfield.
972 ;; extv/extzv patterns would be useful, but do not get used because
973 ;; optimize_bitfield_compare in fold-const usually converts single
974 ;; bit extracts into an AND with a mask.
976 (define_insn "insv"
977   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
978                          (match_operand:SI 1 "immediate_operand" "n")
979                          (match_operand:SI 2 "immediate_operand" "n"))
980         (match_operand:SI 3 "register_operand" "r"))]
981   "TARGET_V850E3V5_UP"
982   "bins %3, %2, %1, %0"
983   [(set_attr "length" "4")])
985 ;; -----------------------------------------------------------------
986 ;; Scc INSTRUCTIONS
987 ;; -----------------------------------------------------------------
989 (define_insn "*setcc"
990   [(set (match_operand:SI 0 "register_operand" "=r")
991         (match_operator:SI 1 "comparison_operator"
992          [(cc0) (const_int 0)]))]
993   ""
994   "setf %c1,%0"
995   [(set_attr "length" "4")])
997 (define_insn "setf_insn"
998   [(set (match_operand:SI 0 "register_operand" "=r")
999         (match_operator:SI 1 "comparison_operator"
1000                           [(reg:CC CC_REGNUM) (const_int 0)]))]
1001   ""
1002   "setf %b1,%0"
1003   [(set_attr "length" "4")])
1005 (define_insn "set_z_insn"
1006   [(set (match_operand:SI 0 "register_operand" "=r")
1007         (match_operand 1 "v850_float_z_comparison_operator" ""))]
1008   "TARGET_V850E2V3_UP"
1009   "setf z,%0"
1010   [(set_attr "length" "4")])
1012 (define_insn "set_nz_insn" 
1013   [(set (match_operand:SI 0 "register_operand" "=r")
1014         (match_operand 1 "v850_float_nz_comparison_operator" ""))]
1015   "TARGET_V850E2V3_UP"
1016   "setf nz,%0"
1017   [(set_attr "length" "4")])
1019 ;; ----------------------------------------------------------------------
1020 ;; CONDITIONAL MOVE INSTRUCTIONS
1021 ;; ----------------------------------------------------------------------
1023 ;; Instructions using cc0 aren't allowed to have input reloads, so we must
1024 ;; hide the fact that this instruction uses cc0.  We do so by including the
1025 ;; compare instruction inside it.
1027 (define_expand "movsicc"
1028   [(set (match_operand:SI 0 "register_operand" "=r")
1029         (if_then_else:SI
1030          (match_operand 1 "comparison_operator")
1031          (match_operand:SI 2 "reg_or_const_operand" "rJ")
1032          (match_operand:SI 3 "reg_or_const_operand" "rI")))]
1033   "(TARGET_V850E_UP)"
1034   {
1035     /* Make sure that we have an integer comparison...  */
1036     if (GET_MODE (XEXP (operands[1], 0)) != CCmode
1037         && GET_MODE (XEXP (operands[1], 0)) != SImode)
1038       FAIL;
1040     if ((GET_CODE (operands[2]) == CONST_INT
1041         && GET_CODE (operands[3]) == CONST_INT))
1042       {
1043         int o2 = INTVAL (operands[2]);
1044         int o3 = INTVAL (operands[3]);
1046         if (o2 == 1 && o3 == 0)
1047           FAIL;   /* setf */
1048         if (o3 == 1 && o2 == 0)
1049           FAIL;   /* setf */
1050         if (o2 == 0 && (o3 < -16 || o3 > 15) && exact_log2 (o3) >= 0)
1051           FAIL;   /* setf + shift */
1052         if (o3 == 0 && (o2 < -16 || o2 > 15) && exact_log2 (o2) >=0)
1053           FAIL;   /* setf + shift */
1054         if (o2 != 0)
1055           operands[2] = copy_to_mode_reg (SImode, operands[2]);
1056         if (o3 !=0 )
1057           operands[3] = copy_to_mode_reg (SImode, operands[3]);
1058       }
1059     else
1060       {
1061         if (GET_CODE (operands[2]) != REG)
1062           operands[2] = copy_to_mode_reg (SImode,operands[2]);
1063         if (GET_CODE (operands[3]) != REG)
1064           operands[3] = copy_to_mode_reg (SImode, operands[3]);
1065       }
1066   })
1068 ;; ??? Clobbering the condition codes is overkill.
1070 ;; ??? We sometimes emit an unnecessary compare instruction because the
1071 ;; condition codes may have already been set by an earlier instruction,
1072 ;; but we have no code here to avoid the compare if it is unnecessary.
1074 (define_insn "movsicc_normal_cc"
1075   [(set (match_operand:SI 0 "register_operand" "=r")
1076         (if_then_else:SI
1077          (match_operator 1 "comparison_operator"
1078                          [(reg:CC CC_REGNUM) (const_int 0)])
1079          (match_operand:SI 2 "reg_or_int5_operand" "rJ")
1080          (match_operand:SI 3 "reg_or_0_operand" "rI")))]
1081   "(TARGET_V850E_UP)"
1082   "cmov %c1,%2,%z3,%0";
1083   [(set_attr "length" "6")])
1085 (define_insn "movsicc_reversed_cc"
1086   [(set (match_operand:SI 0 "register_operand" "=r")
1087         (if_then_else:SI
1088          (match_operator 1 "comparison_operator"
1089                          [(reg:CC CC_REGNUM) (const_int 0)])
1090          (match_operand:SI 2 "reg_or_0_operand" "rI")
1091          (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
1092   "(TARGET_V850E_UP)"
1093   "cmov %C1,%3,%z2,%0"
1094   [(set_attr "length" "6")])
1096 (define_insn "*movsicc_normal"
1097   [(set (match_operand:SI 0 "register_operand" "=r")
1098         (if_then_else:SI
1099          (match_operator 1 "comparison_operator"
1100                          [(match_operand:SI 4 "register_operand" "r")
1101                           (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
1102          (match_operand:SI 2 "reg_or_int5_operand" "rJ")
1103          (match_operand:SI 3 "reg_or_0_operand" "rI")))]
1104   "(TARGET_V850E_UP)"
1105   "cmp %5,%4 ; cmov %c1,%2,%z3,%0"
1106   [(set_attr "length" "6")])
1108 (define_insn "*movsicc_reversed"
1109   [(set (match_operand:SI 0 "register_operand" "=r")
1110         (if_then_else:SI
1111          (match_operator 1 "comparison_operator"
1112                          [(match_operand:SI 4 "register_operand" "r")
1113                           (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
1114          (match_operand:SI 2 "reg_or_0_operand" "rI")
1115          (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
1116   "(TARGET_V850E_UP)"
1117   "cmp %5,%4 ; cmov %C1,%3,%z2,%0"
1118   [(set_attr "length" "6")])
1120 (define_insn "*movsicc_tst1"
1121   [(set (match_operand:SI 0 "register_operand" "=r")
1122         (if_then_else:SI
1123          (match_operator 1 "comparison_operator"
1124                          [(zero_extract:SI
1125                            (match_operand:QI 2 "memory_operand" "m")
1126                            (const_int 1)
1127                            (match_operand 3 "const_int_operand" "n"))
1128                           (const_int 0)])
1129          (match_operand:SI 4 "reg_or_int5_operand" "rJ")
1130          (match_operand:SI 5 "reg_or_0_operand" "rI")))]
1131   "(TARGET_V850E_UP)"
1132   "tst1 %3,%2 ; cmov %c1,%4,%z5,%0"
1133   [(set_attr "length" "8")])
1135 (define_insn "*movsicc_tst1_reversed"
1136   [(set (match_operand:SI 0 "register_operand" "=r")
1137         (if_then_else:SI
1138          (match_operator 1 "comparison_operator"
1139                          [(zero_extract:SI
1140                            (match_operand:QI 2 "memory_operand" "m")
1141                            (const_int 1)
1142                            (match_operand 3 "const_int_operand" "n"))
1143                           (const_int 0)])
1144          (match_operand:SI 4 "reg_or_0_operand" "rI")
1145          (match_operand:SI 5 "reg_or_int5_operand" "rJ")))]
1146   "(TARGET_V850E_UP)"
1147   "tst1 %3,%2 ; cmov %C1,%5,%z4,%0"
1148   [(set_attr "length" "8")])
1150 ;; Matching for sasf requires combining 4 instructions, so we provide a
1151 ;; dummy pattern to match the first 3, which will always be turned into the
1152 ;; second pattern by subsequent combining.  As above, we must include the
1153 ;; comparison to avoid input reloads in an insn using cc0.
1155 (define_insn "*sasf"
1156   [(set (match_operand:SI 0 "register_operand" "=r")
1157         (ior:SI
1158          (match_operator 1 "comparison_operator"
1159                          [(match_operand:SI 3 "register_operand" "r")
1160                           (match_operand:SI 4 "reg_or_int5_operand" "rJ")])
1161          (ashift:SI (match_operand:SI 2 "register_operand" "0")
1162                     (const_int 1))))
1163    (clobber (reg:CC CC_REGNUM))]
1164   "(TARGET_V850E_UP)"
1165   "cmp %4,%3 ; sasf %c1,%0"
1166   [(set_attr "length" "6")])
1168 (define_split
1169   [(set (match_operand:SI 0 "register_operand" "")
1170         (if_then_else:SI
1171          (match_operator 1 "comparison_operator"
1172                          [(match_operand:SI 4 "register_operand" "")
1173                           (match_operand:SI 5 "reg_or_int5_operand" "")])
1174          (match_operand:SI 2 "const_int_operand" "")
1175          (match_operand:SI 3 "const_int_operand" "")))
1176    (clobber (reg:CC CC_REGNUM))]
1177   "(TARGET_V850E_UP)
1178    && ((INTVAL (operands[2]) ^ INTVAL (operands[3])) == 1)
1179    && ((INTVAL (operands[2]) + INTVAL (operands[3])) != 1)
1180    && (GET_CODE (operands[5]) == CONST_INT
1181       || REGNO (operands[0]) != REGNO (operands[5]))
1182    && REGNO (operands[0]) != REGNO (operands[4])"
1183   [(set (match_dup 0) (match_dup 6))
1184    (parallel [(set (match_dup 0)
1185                    (ior:SI (match_op_dup 7 [(match_dup 4) (match_dup 5)])
1186                            (ashift:SI (match_dup 0) (const_int 1))))
1187               (clobber (reg:CC CC_REGNUM))])]
1188   {
1189     operands[6] = GEN_INT (INTVAL (operands[2]) >> 1);
1190     if (INTVAL (operands[2]) & 0x1)
1191       operands[7] = operands[1];
1192     else
1193       operands[7] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
1194                                     GET_MODE (operands[1]),
1195                                     XEXP (operands[1], 0), XEXP (operands[1], 1));
1196   })
1198 ;; ---------------------------------------------------------------------
1199 ;; BYTE SWAP INSTRUCTIONS
1200 ;; ---------------------------------------------------------------------
1201 (define_expand "rotlhi3"
1202   [(parallel [(set (match_operand:HI 0 "register_operand" "")
1203                    (rotate:HI (match_operand:HI 1 "register_operand" "")
1204                               (match_operand:HI 2 "const_int_operand" "")))
1205               (clobber (reg:CC CC_REGNUM))])]
1206   "(TARGET_V850E_UP)"
1207   {
1208     if (INTVAL (operands[2]) != 8)
1209       FAIL;
1210   })
1212 (define_insn "*rotlhi3_8"
1213   [(set (match_operand:HI 0 "register_operand" "=r")
1214         (rotate:HI (match_operand:HI 1 "register_operand" "r")
1215                    (const_int 8)))
1216    (clobber (reg:CC CC_REGNUM))]
1217   "(TARGET_V850E_UP)"
1218   "bsh %1,%0"
1219   [(set_attr "length" "4")])
1221 (define_expand "rotlsi3"
1222   [(parallel [(set (match_operand:SI 0 "register_operand" "")
1223                    (rotate:SI (match_operand:SI 1 "register_operand" "")
1224                               (match_operand:SI 2 "const_int_operand" "")))
1225               (clobber (reg:CC CC_REGNUM))])]
1226   "(TARGET_V850E_UP)"
1227   {
1228     if (INTVAL (operands[2]) != 16)
1229       FAIL;
1230   })
1232 (define_insn "rotlsi3_a"
1233   [(set (match_operand:SI 0 "register_operand" "=r")
1234      (match_operator:SI 4 "ior_operator"
1235        [(ashift:SI (match_operand:SI 1 "register_operand" "r")
1236                    (match_operand:SI 2 "const_int_operand" "n"))
1237         (lshiftrt:SI (match_dup 1)
1238         (match_operand:SI 3 "const_int_operand" "n"))]))]
1239   "TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)"
1240   "rotl %2, %1, %0"
1241   [(set_attr "length" "4")])
1243 (define_insn "rotlsi3_b"
1244   [(set (match_operand:SI 0 "register_operand" "=r")
1245      (match_operator:SI 4 "ior_operator"
1246        [(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1247                      (match_operand:SI 3 "const_int_operand" "n"))
1248         (ashift:SI (match_dup 1)
1249                    (match_operand:SI 2 "const_int_operand" "n"))]))]
1250   "TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)"
1251   "rotl %2, %1, %0"
1252   [(set_attr "length" "4")])
1254 (define_insn "rotlsi3_v850e3v5"
1255   [(set (match_operand:SI 0 "register_operand" "=r")
1256         (rotate:SI (match_operand:SI 1 "register_operand" "r")
1257                    (match_operand:SI 2 "e3v5_shift_operand" "rn")))
1258               (clobber (reg:CC CC_REGNUM))]
1259   "TARGET_V850E3V5_UP"
1260   "rotl %2, %1, %0"
1261   [(set_attr "length" "4")])
1263 (define_insn "*rotlsi3_16"
1264   [(set (match_operand:SI 0 "register_operand" "=r")
1265         (rotate:SI (match_operand:SI 1 "register_operand" "r")
1266                    (const_int 16)))
1267    (clobber (reg:CC CC_REGNUM))]
1268   "(TARGET_V850E_UP)"
1269   "hsw %1,%0"
1270   [(set_attr "length" "4")])
1272 ;; ----------------------------------------------------------------------
1273 ;; JUMP INSTRUCTIONS
1274 ;; ----------------------------------------------------------------------
1276 ;; Doloop
1278 (define_expand "doloop_begin"
1279  [(use (match_operand 0 "" ""))        ; loop pseudo
1280   (use (match_operand 1 "" ""))]       ; doloop_end pattern
1281   "TARGET_V850E3V5_UP && TARGET_LOOP"
1282   {
1283     rtx loop_cnt = operands[0];
1284     gcc_assert (GET_MODE (loop_cnt) == SImode);
1285     emit_insn (gen_fix_loop_counter (loop_cnt));
1286     DONE;
1287   }
1290 (define_insn "fix_loop_counter"
1291   [(unspec:SI [(match_operand:SI          0 "register_operand" "+r,!m")
1292                (clobber (match_scratch:SI 1                    "=X,r"))] UNSPEC_LOOP)]
1293   "TARGET_V850E3V5_UP && TARGET_LOOP"
1294   {
1295     switch (which_alternative)
1296     {
1297     case 0:  return "add 1, %0 # LOOP_BEGIN";
1298     case 1:  return "ld.w %0, %1; add 1, %1; st.w %1, %0 # LOOP_BEGIN";
1299     default: gcc_unreachable ();
1300     }
1301   }
1302   [(set_attr "length" "2,6")])
1304 (define_expand "doloop_end"
1305  [(use (match_operand 0 "" ""))        ; loop pseudo
1306   (use (match_operand 1 "" ""))]       ; label
1307   "TARGET_V850E3V5_UP && TARGET_LOOP"
1308   {
1309     rtx loop_cnt = operands[0];
1310     rtx label    = operands[1];
1312     if (GET_MODE (loop_cnt) != SImode)
1313       FAIL;
1315     emit_jump_insn (gen_doloop_end_internal_loop (label, loop_cnt));
1316     DONE;
1317   }
1320 (define_insn "doloop_end_internal_loop"
1321  [(set (pc)
1322        (if_then_else (ne (match_operand:SI 1 "register_operand" "+r,!m")
1323                          (const_int 0))
1324                      (label_ref (match_operand 0 "" ""))
1325                      (pc)))
1326   (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))
1327   (clobber (match_scratch:SI 2 "=X,r"))
1328   (clobber (reg:CC CC_REGNUM))]
1329   "TARGET_V850E3V5_UP && TARGET_LOOP"
1330   {
1331     switch (which_alternative)
1332     {
1333     case 0:
1334       if (get_attr_length (insn) == 4)
1335         return "loop %1, %0 # LOOP.1.0";
1337       return "add -1, %1; bne %l0 # LOOP.1.1";
1338     case 1:
1339       return "ld.w %1, %2; add -1, %2; st.w %2, %1; bne %l0 # LOOP.2.1";
1340     default:
1341       gcc_unreachable ();
1342     }
1343   }
1344  [(set (attr "length")
1345        (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1346                      (const_int 65534))
1347                      (const_int 4)
1348                      (const_int 14)))])
1350 ;; Conditional jump instructions
1352 (define_insn "*branch_normal"
1353   [(set (pc)
1354         (if_then_else (match_operator 1 "comparison_operator"
1355                                       [(cc0) (const_int 0)])
1356                       (label_ref (match_operand 0 "" ""))
1357                       (pc)))]
1358   ""
1360   if (get_attr_length (insn) == 2)
1361     return "b%b1 %l0";
1362   if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1363     return "b%b1 %l0";
1364   return "b%B1 .+6 ; jr %l0";
1366  [(set (attr "length")
1367     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1368                       (const_int 256))
1369                   (const_int 2)
1370                   (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1371                       (const_int 65536))
1372                       (const_int 4)
1373                       (const_int 6))))])
1375 (define_insn "*branch_invert"
1376   [(set (pc)
1377         (if_then_else (match_operator 1 "comparison_operator"
1378                                       [(cc0) (const_int 0)])
1379                       (pc)
1380                       (label_ref (match_operand 0 "" ""))))]
1381   ""
1383   if (get_attr_length (insn) == 2)
1384     return "b%B1 %l0";
1386   if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1387     return "b%B1 %l0";
1388     
1389   return "b%b1 .+6 ; jr %l0";
1391  [(set (attr "length")
1392     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1393                       (const_int 256))
1394                   (const_int 2)
1395                   (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1396                       (const_int 65536))
1397                       (const_int 4)
1398                       (const_int 6))))])
1400 (define_insn "branch_z_normal"  
1401   [(set (pc)
1402         (if_then_else (match_operand 1 "v850_float_z_comparison_operator" "")
1403                       (label_ref (match_operand 0 "" ""))
1404                       (pc)))]
1405   "TARGET_V850E2V3_UP"
1407   if (get_attr_length (insn) == 2)
1408     return "bz %l0";
1410   if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1411     return "bz %l0";
1413   return "bnz 1f ; jr %l0 ; 1:";
1415  [(set (attr "length")
1416     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1417                       (const_int 256))
1418                   (const_int 2)
1419                   (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1420                       (const_int 65536))
1421                       (const_int 4)
1422                       (const_int 6))))])
1424 (define_insn "*branch_z_invert"
1425   [(set (pc)
1426         (if_then_else (match_operand 1 "v850_float_z_comparison_operator" "")
1427                       (pc)
1428                       (label_ref (match_operand 0 "" ""))))]
1429   "TARGET_V850E2V3_UP"
1431   if (get_attr_length (insn) == 2)
1432     return "bnz %l0";
1434   if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1435     return "bnz %l0";
1437   return "bz 1f ; jr %l0 ; 1:";
1439  [(set (attr "length")
1440     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1441                            (const_int 256))
1442                   (const_int 2)
1443                   (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1444                       (const_int 65536))
1445                       (const_int 4)
1446                       (const_int 6))))])
1448 (define_insn "branch_nz_normal"
1449   [(set (pc)
1450         (if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "")
1451                       (label_ref (match_operand 0 "" ""))
1452                       (pc)))]
1453   "TARGET_V850E2V3_UP"
1455   if (get_attr_length (insn) == 2)
1456     return "bnz %l0";
1458   if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1459     return "bnz %l0";
1461   return "bz 1f ; jr %l0 ; 1:";
1463 [(set (attr "length")
1464     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1465                            (const_int 256))
1466                   (const_int 2)
1467                   (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1468                       (const_int 65536))
1469                       (const_int 4)
1470                       (const_int 6))))])
1472 (define_insn "*branch_nz_invert"
1473   [(set (pc)
1474         (if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "")
1475                       (pc)
1476                       (label_ref (match_operand 0 "" ""))))]
1477   "TARGET_V850E2V3_UP"
1479   if (get_attr_length (insn) == 2)
1480     return "bz %l0";
1482   if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1483     return "bz %l0";
1485   return "bnz 1f ; jr %l0 ; 1:";
1487  [(set (attr "length")
1488     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1489                       (const_int 256))
1490                   (const_int 2)
1491                   (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1492                       (const_int 65536))
1493                       (const_int 4)
1494                       (const_int 6))))])
1496 ;; Unconditional and other jump instructions.
1498 (define_insn "jump"
1499   [(set (pc)
1500         (label_ref (match_operand 0 "" "")))]
1501   ""
1503  if (get_attr_length (insn) == 2)
1504     return "br %0";
1505   else
1506     return "jr %0";
1508  [(set (attr "length")
1509     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1510                       (const_int 256))
1511                   (const_int 2)
1512                   (const_int 4)))])
1514 (define_insn "indirect_jump"
1515   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1516   ""
1517   "jmp %0"
1518   [(set_attr "length" "2")])
1520 (define_insn "tablejump"
1521   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1522    (use (label_ref (match_operand 1 "" "")))]
1523   ""
1524   "jmp  %0"
1525   [(set_attr "length" "2")])
1527 (define_insn "switch"
1528   [(set (pc)
1529         (plus:SI
1530          (sign_extend:SI
1531          (mem:HI
1532           (plus:SI (ashift:SI (match_operand:SI 0 "register_operand" "r")
1533                               (const_int 1))
1534                    (label_ref (match_operand 1 "" "")))))
1535         (label_ref (match_dup 1))))]
1536   "(TARGET_V850E_UP)"
1537   "switch %0"
1538   [(set_attr "length" "2")])
1540 (define_expand "casesi"
1541   [(match_operand:SI 0 "register_operand" "")
1542    (match_operand:SI 1 "register_operand" "")
1543    (match_operand:SI 2 "register_operand" "")
1544    (match_operand 3 "" "") (match_operand 4 "" "")]
1545   ""
1546   {
1547     rtx reg = gen_reg_rtx (SImode);
1548     rtx tableaddress = gen_reg_rtx (SImode);
1549     rtx test;
1550     rtx mem;
1552     /* Subtract the lower bound from the index.  */
1553     emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
1555     /* Compare the result against the number of table entries;
1556        branch to the default label if out of range of the table.  */
1557     test = gen_rtx_fmt_ee (GTU, VOIDmode, reg, operands[2]);
1558     emit_jump_insn (gen_cbranchsi4 (test, reg, operands[2], operands[4]));
1560     /* Shift index for the table array access.  */
1561     emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
1562     /* Load the table address into a pseudo.  */
1563     emit_insn (gen_movsi (tableaddress,
1564                           gen_rtx_LABEL_REF (Pmode, operands[3])));
1565     /* Add the table address to the index.  */
1566     emit_insn (gen_addsi3 (reg, reg, tableaddress));
1567     /* Load the table entry.  */
1568     mem = gen_const_mem (CASE_VECTOR_MODE, reg);
1569     if (! TARGET_BIG_SWITCH)
1570       {
1571         rtx reg2 = gen_reg_rtx (HImode);
1572         emit_insn (gen_movhi (reg2, mem));
1573         emit_insn (gen_extendhisi2 (reg, reg2));
1574       }
1575     else
1576       emit_insn (gen_movsi (reg, mem));
1577     /* Add the table address.  */
1578     emit_insn (gen_addsi3 (reg, reg, tableaddress));
1579     /* Branch to the switch label.  */
1580     emit_jump_insn (gen_tablejump (reg, operands[3]));
1581     DONE;
1582   })
1584 ;; Call subroutine with no return value.
1586 (define_expand "call"
1587   [(call (match_operand:QI 0 "general_operand" "")
1588          (match_operand:SI 1 "general_operand" ""))]
1589   ""
1590   {
1591     if (! call_address_operand (XEXP (operands[0], 0), QImode)
1592         || TARGET_LONG_CALLS)
1593       XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1594     if (TARGET_LONG_CALLS)
1595       emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));
1596     else
1597       emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
1598   
1599     DONE;
1600   })
1602 (define_insn "call_internal_short"
1603   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1604          (match_operand:SI 1 "general_operand" "g,g"))
1605    (clobber (reg:SI 31))]
1606   "! TARGET_LONG_CALLS"
1607   {
1608     if (which_alternative == 1)
1609       {
1610         if (TARGET_V850E3V5_UP)
1611           return "jarl [%0], r31";
1613         return "jarl .+4, r31 ; add 4, r31 ; jmp %0";
1614       }
1616     return "jarl %0, r31";
1617   }
1618   [(set_attr "length" "4,8")])
1620 (define_insn "call_internal_long"
1621   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1622          (match_operand:SI 1 "general_operand" "g,g"))
1623    (clobber (reg:SI 31))]
1624   "TARGET_LONG_CALLS"
1626   if (which_alternative == 0)
1627     {
1628       if (GET_CODE (operands[0]) == REG)
1629         return "jarl %0,r31";
1631       if (TARGET_V850E3V5_UP)
1632         return "mov hilo(%0), r11 ; jarl [r11], r31";
1634       return "movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11";
1635     }
1637   if (TARGET_V850E3V5_UP)
1638     return "jarl [%0], r31";
1640   return "jarl .+4,r31 ; add 4,r31 ; jmp %0";
1642   [(set_attr "length" "16,8")])
1644 ;; Call subroutine, returning value in operand 0
1645 ;; (which must be a hard register).
1647 (define_expand "call_value"
1648   [(set (match_operand 0 "" "")
1649         (call (match_operand:QI 1 "general_operand" "")
1650               (match_operand:SI 2 "general_operand" "")))]
1651   ""
1652   {
1653     if (! call_address_operand (XEXP (operands[1], 0), QImode)
1654         || TARGET_LONG_CALLS)
1655       XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1656     if (TARGET_LONG_CALLS)
1657       emit_call_insn (gen_call_value_internal_long (operands[0],
1658                                                     XEXP (operands[1], 0),
1659                                                     operands[2]));
1660     else
1661       emit_call_insn (gen_call_value_internal_short (operands[0],
1662                                                      XEXP (operands[1], 0),
1663                                                      operands[2]));
1664     DONE;
1665   })
1667 (define_insn "call_value_internal_short"
1668   [(set (match_operand 0 "" "=r,r")
1669         (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1670               (match_operand:SI 2 "general_operand" "g,g")))
1671    (clobber (reg:SI 31))]
1672   "! TARGET_LONG_CALLS"
1673   {
1674     if (which_alternative == 1)
1675       {
1676         if (TARGET_V850E3V5_UP)
1677           return "jarl [%1], r31";
1679         return "jarl .+4, r31 ; add 4, r31 ; jmp %1";
1680       }
1682     return "jarl %1, r31";
1683   }
1684   [(set_attr "length" "4,8")])
1686 (define_insn "call_value_internal_long"
1687   [(set (match_operand 0 "" "=r,r")
1688         (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1689               (match_operand:SI 2 "general_operand" "g,g")))
1690    (clobber (reg:SI 31))]
1691   "TARGET_LONG_CALLS"
1693   if (which_alternative == 0)
1694     {
1695       if (GET_CODE (operands[1]) == REG)
1696         return "jarl %1, r31";
1698       /* Reload can generate this pattern....  */
1699       if (TARGET_V850E3V5_UP)
1700         return "mov hilo(%1), r11 ; jarl [r11], r31";
1702       return "movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11";
1703     }
1704   
1705   if (TARGET_V850E3V5_UP)
1706     return "jarl [%1], r31";
1708   return "jarl .+4, r31 ; add 4, r31 ; jmp %1";
1710   [(set_attr "length" "16,8")])
1712 (define_insn "nop"
1713   [(const_int 0)]
1714   ""
1715   "nop"
1716   [(set_attr "length" "2")])
1718 ;; ----------------------------------------------------------------------
1719 ;; EXTEND INSTRUCTIONS
1720 ;; ----------------------------------------------------------------------
1722 (define_insn "*zero_extendhisi2_v850e"
1723   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1724         (zero_extend:SI
1725         (match_operand:HI 1 "nonimmediate_operand" "0,r,T,m")))
1726    (clobber (reg:CC CC_REGNUM))]
1727   "(TARGET_V850E_UP)"
1728   "@
1729    zxh %0
1730    andi 65535,%1,%0
1731    sld.hu %1,%0
1732    ld.hu %1,%0"
1733   [(set_attr "length" "2,4,2,4")])
1735 (define_insn "*zero_extendhisi2_v850"
1736   [(set (match_operand:SI 0 "register_operand" "=r")
1737         (zero_extend:SI
1738         (match_operand:HI 1 "register_operand" "r")))
1739    (clobber (reg:CC CC_REGNUM))]  ;; A lie, but we have to match the expander
1740   ""
1741   "andi 65535,%1,%0"
1742   [(set_attr "length" "4")])
1744 (define_expand "zero_extendhisi2"
1745   [(parallel [(set (match_operand:SI 0 "register_operand")
1746                    (zero_extend:SI
1747                     (match_operand:HI 1 "nonimmediate_operand")))
1748               (clobber (reg:CC CC_REGNUM))])]
1749   ""
1750   {
1751     if (! (TARGET_V850E_UP))
1752       operands[1] = force_reg (HImode, operands[1]);
1753   })
1755 (define_insn "*zero_extendqisi2_v850e"
1756   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1757         (zero_extend:SI
1758         (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m")))
1759    (clobber (reg:CC CC_REGNUM))]
1760   "(TARGET_V850E_UP)"
1761   "@
1762    zxb %0
1763    andi 255,%1,%0
1764    sld.bu %1,%0
1765    ld.bu %1,%0"
1766   [(set_attr "length" "2,4,2,4")])
1768 (define_insn "*zero_extendqisi2_v850"
1769   [(set (match_operand:SI 0 "register_operand" "=r")
1770         (zero_extend:SI
1771           (match_operand:QI 1 "register_operand" "r")))
1772    (clobber (reg:CC CC_REGNUM))] ;; A lie, but we have to match the expander
1773   ""
1774   "andi 255,%1,%0"
1775   [(set_attr "length" "4")])
1777 (define_expand "zero_extendqisi2"
1778   [(parallel [(set (match_operand:SI 0 "register_operand")
1779                    (zero_extend:SI
1780                      (match_operand:QI 1 "nonimmediate_operand")))
1781               (clobber (reg:CC CC_REGNUM))])]
1782   ""
1783   {
1784     if (! (TARGET_V850E_UP))
1785       operands[1] = force_reg (QImode, operands[1]);
1786   })
1788 ;;- sign extension instructions
1790 ;; ??? The extendhisi2 pattern should not emit shifts for v850e?
1792 (define_insn "*extendhisi_insn"
1793   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1794         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))
1795    (clobber (reg:CC CC_REGNUM))]
1796   "(TARGET_V850E_UP)"
1797   "@
1798    sxh %0
1799    sld.h %1,%0
1800    ld.h %1,%0"
1801   [(set_attr "length" "2,2,4")])
1803 ;; ??? This is missing a sign extend from memory pattern to match the ld.h
1804 ;; instruction.
1806 (define_expand "extendhisi2"
1807   [(parallel [(set (match_dup 2)
1808                    (ashift:SI (match_operand:HI 1 "register_operand" "")
1809                               (const_int 16)))
1810               (clobber (reg:CC CC_REGNUM))])
1811    (parallel [(set (match_operand:SI 0 "register_operand" "")
1812                    (ashiftrt:SI (match_dup 2)
1813                                 (const_int 16)))
1814               (clobber (reg:CC CC_REGNUM))])]
1815   ""
1816   {
1817     operands[1] = gen_lowpart (SImode, operands[1]);
1818     operands[2] = gen_reg_rtx (SImode);
1819   })
1821 ;; ??? The extendqisi2 pattern should not emit shifts for v850e?
1823 (define_insn "*extendqisi_insn"
1824   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1825         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))
1826    (clobber (reg:CC CC_REGNUM))]
1827   "(TARGET_V850E_UP)"
1828   "@
1829    sxb %0
1830    sld.b %1,%0
1831    ld.b %1,%0"
1832   [(set_attr "length" "2,2,4")])
1834 ;; ??? This is missing a sign extend from memory pattern to match the ld.b
1835 ;; instruction.
1837 (define_expand "extendqisi2"
1838   [(parallel [(set (match_dup 2)
1839                    (ashift:SI (match_operand:QI 1 "register_operand" "")
1840                               (const_int 24)))
1841               (clobber (reg:CC CC_REGNUM))])
1842    (parallel [(set (match_operand:SI 0 "register_operand" "")
1843                    (ashiftrt:SI (match_dup 2)
1844                               (const_int 24)))
1845               (clobber (reg:CC CC_REGNUM))])]
1846   ""
1847   {
1848     operands[1] = gen_lowpart (SImode, operands[1]);
1849     operands[2] = gen_reg_rtx (SImode);
1850   })
1852 ;; ----------------------------------------------------------------------
1853 ;; SHIFTS
1854 ;; ----------------------------------------------------------------------
1856 (define_insn "ashlsi3"
1857   [(set (match_operand:SI 0 "register_operand" "=r,r")
1858       (ashift:SI
1859         (match_operand:SI 1 "register_operand" "0,0")
1860         (match_operand:SI 2 "nonmemory_operand" "r,N")))
1861    (clobber (reg:CC CC_REGNUM))]
1862   ""
1863   "@
1864   shl %2,%0
1865   shl %2,%0"
1866   [(set_attr "length" "4,2")])
1868 (define_insn "ashlsi3_v850e2"
1869   [(set (match_operand:SI 0 "register_operand" "=r")
1870       (ashift:SI
1871         (match_operand:SI 1 "register_operand" "r")
1872         (match_operand:SI 2 "nonmemory_operand" "r")))
1873    (clobber (reg:CC CC_REGNUM))]
1874   "TARGET_V850E2_UP"
1875   "shl %2,%1,%0"
1876   [(set_attr "length" "4")])
1878 (define_insn "lshrsi3"
1879   [(set (match_operand:SI 0 "register_operand" "=r,r")
1880       (lshiftrt:SI
1881         (match_operand:SI 1 "register_operand" "0,0")
1882         (match_operand:SI 2 "nonmemory_operand" "r,N")))
1883    (clobber (reg:CC CC_REGNUM))]
1884   ""
1885   "@
1886   shr %2,%0
1887   shr %2,%0"
1888   [(set_attr "length" "4,2")])
1890 (define_insn "lshrsi3_v850e2"
1891   [(set (match_operand:SI 0 "register_operand" "=r")
1892       (lshiftrt:SI
1893         (match_operand:SI 1 "register_operand" "r")
1894         (match_operand:SI 2 "nonmemory_operand" "r")))
1895    (clobber (reg:CC CC_REGNUM))]
1896   "TARGET_V850E2_UP"
1897   "shr %2,%1,%0"
1898   [(set_attr "length" "4")])
1900 (define_insn "ashrsi3"
1901   [(set (match_operand:SI 0 "register_operand" "=r,r")
1902       (ashiftrt:SI
1903         (match_operand:SI 1 "register_operand" "0,0")
1904         (match_operand:SI 2 "nonmemory_operand" "r,N")))
1905    (clobber (reg:CC CC_REGNUM))]
1906   ""
1907   "@
1908   sar %2,%0
1909   sar %2,%0"
1910   [(set_attr "length" "4,2")])
1912 (define_insn "ashrsi3_v850e2"
1913   [(set (match_operand:SI 0 "register_operand" "=r")
1914       (ashiftrt:SI
1915         (match_operand:SI 1 "register_operand" "r")
1916         (match_operand:SI 2 "nonmemory_operand" "r")))
1917    (clobber (reg:CC CC_REGNUM))]
1918   "TARGET_V850E2_UP"
1919   "sar %2,%1,%0"
1920   [(set_attr "length" "4")])
1922 ;; ----------------------------------------------------------------------
1923 ;; FIND FIRST BIT INSTRUCTION
1924 ;; ----------------------------------------------------------------------
1926 (define_insn "ffssi2"
1927   [(set (match_operand:SI 0 "register_operand" "=r")
1928        (ffs:SI (match_operand:SI 1 "register_operand" "r")))
1929    (clobber (reg:CC CC_REGNUM))]
1930   "TARGET_V850E2_UP"
1931   "sch1r %1,%0"
1932   [(set_attr "length" "4")])
1934 ;; ----------------------------------------------------------------------
1935 ;; PROLOGUE/EPILOGUE
1936 ;; ----------------------------------------------------------------------
1937 (define_expand "prologue"
1938   [(const_int 0)]
1939   ""
1940   {
1941     expand_prologue ();
1942     DONE;
1943   })
1945 (define_expand "epilogue"
1946   [(return)]
1947   ""
1948   {
1949     expand_epilogue ();
1950     DONE;
1951   })
1953 (define_insn "return_simple"
1954   [(return)]
1955   "reload_completed"
1956   "jmp [r31]"
1957   [(set_attr "length" "2")])
1959 (define_insn "return_internal"
1960   [(return)
1961    (use (reg:SI 31))]
1962   ""
1963   "jmp [r31]"
1964   [(set_attr "length" "2")])
1966 ;; ----------------------------------------------------------------------
1967 ;; v850e2V3 floating-point hardware support
1968 ;; ----------------------------------------------------------------------
1971 (define_insn "addsf3"
1972   [(set (match_operand:SF 0 "register_operand" "=r")
1973         (plus:SF (match_operand:SF 1 "register_operand" "r")
1974                  (match_operand:SF 2 "register_operand" "r")))]
1975   "TARGET_USE_FPU"
1976   "addf.s %1,%2,%0"
1977   [(set_attr "length" "4")
1978    (set_attr "type" "fpu")])
1980 (define_insn "adddf3"
1981   [(set (match_operand:DF 0 "even_reg_operand" "=r")
1982         (plus:DF (match_operand:DF 1 "even_reg_operand" "r")
1983         (match_operand:DF 2 "even_reg_operand" "r")))]
1984   "TARGET_USE_FPU"
1985   "addf.d %1,%2,%0"
1986   [(set_attr "length" "4")
1987    (set_attr "type" "fpu")])
1989 (define_insn "subsf3"
1990   [(set (match_operand:SF 0 "register_operand" "=r")
1991         (minus:SF (match_operand:SF 1 "register_operand" "r")
1992                   (match_operand:SF 2 "register_operand" "r")))]
1993   "TARGET_USE_FPU"
1994   "subf.s %2,%1,%0"
1995   [(set_attr "length" "4")
1996    (set_attr "type" "fpu")])
1998 (define_insn "subdf3"
1999   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2000         (minus:DF (match_operand:DF 1 "even_reg_operand" "r")
2001                   (match_operand:DF 2 "even_reg_operand" "r")))]
2002   "TARGET_USE_FPU"
2003   "subf.d %2,%1,%0"
2004   [(set_attr "length" "4")
2005    (set_attr "type" "fpu")])
2007 (define_insn "mulsf3"
2008   [(set (match_operand:SF 0 "register_operand" "=r")
2009         (mult:SF (match_operand:SF 1 "register_operand" "r")
2010                  (match_operand:SF 2 "register_operand" "r")))]
2011   "TARGET_USE_FPU"
2012   "mulf.s %1,%2,%0"
2013   [(set_attr "length" "4")
2014    (set_attr "type" "fpu")])
2016 (define_insn "muldf3"
2017   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2018         (mult:DF (match_operand:DF 1 "even_reg_operand" "r")
2019                  (match_operand:DF 2 "even_reg_operand" "r")))]
2020   "TARGET_USE_FPU"
2021   "mulf.d %1,%2,%0"
2022   [(set_attr "length" "4")
2023    (set_attr "type" "fpu")])
2025 (define_insn "divsf3"
2026   [(set (match_operand:SF 0 "register_operand" "=r")
2027         (div:SF (match_operand:SF 1 "register_operand" "r")
2028                 (match_operand:SF 2 "register_operand" "r")))]
2029   "TARGET_USE_FPU"
2030   "divf.s %2,%1,%0"
2031   [(set_attr "length" "4")
2032    (set_attr "type" "fpu")])
2034 (define_insn "divdf3"
2035   [(set (match_operand:DF 0 "register_operand" "=r")
2036         (div:DF (match_operand:DF 1 "even_reg_operand" "r")
2037                 (match_operand:DF 2 "even_reg_operand" "r")))]
2038   "TARGET_USE_FPU"
2039   "divf.d %2,%1,%0"
2040   [(set_attr "length" "4")
2041    (set_attr "type" "fpu")])
2043 (define_insn "minsf3"
2044   [(set (match_operand:SF 0 "register_operand" "=r")
2045         (smin:SF (match_operand:SF 1 "reg_or_0_operand" "r")
2046                  (match_operand:SF 2 "reg_or_0_operand" "r")))]
2047   "TARGET_USE_FPU"
2048   "minf.s %z1,%z2,%0"
2049   [(set_attr "length" "4")
2050    (set_attr "type" "fpu")])
2052 (define_insn "mindf3"
2053   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2054         (smin:DF (match_operand:DF 1 "even_reg_operand" "r")
2055                  (match_operand:DF 2 "even_reg_operand" "r")))]
2056   "TARGET_USE_FPU"
2057   "minf.d %1,%2,%0"
2058   [(set_attr "length" "4")
2059    (set_attr "type" "fpu")])
2061 (define_insn "maxsf3"
2062   [(set (match_operand:SF 0 "register_operand" "=r")
2063         (smax:SF (match_operand:SF 1 "reg_or_0_operand" "r")
2064                  (match_operand:SF 2 "reg_or_0_operand" "r")))]
2065   "TARGET_USE_FPU"
2066   "maxf.s %z1,%z2,%0"
2067   [(set_attr "length" "4")
2068    (set_attr "type" "fpu")])
2070 (define_insn "maxdf3"
2071   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2072         (smax:DF (match_operand:DF 1 "even_reg_operand" "r")
2073                  (match_operand:DF 2 "even_reg_operand" "r")))]
2074   "TARGET_USE_FPU"
2075   "maxf.d %1,%2,%0"
2076   [(set_attr "length" "4")
2077    (set_attr "type" "fpu")])
2079 (define_insn "abssf2"
2080   [(set (match_operand:SF 0 "register_operand" "=r")
2081         (abs:SF (match_operand:SF 1 "register_operand" "r")))]
2082   "TARGET_USE_FPU"
2083   "absf.s %1,%0"
2084   [(set_attr "length" "4")
2085    (set_attr "type" "fpu")])
2087 (define_insn "absdf2"
2088   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2089         (abs:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2090   "TARGET_USE_FPU"
2091   "absf.d %1,%0"
2092   [(set_attr "length" "4")
2093    (set_attr "type" "fpu")])
2095 (define_insn "negsf2"
2096   [(set (match_operand:SF 0 "register_operand" "=r")
2097         (neg:SF (match_operand:SF 1 "register_operand" "r")))]
2098   "TARGET_USE_FPU"
2099   "negf.s %1,%0"
2100   [(set_attr "length" "4")
2101    (set_attr "type" "fpu")])
2103 (define_insn "negdf2"
2104   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2105         (neg:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2106   "TARGET_USE_FPU"
2107   "negf.d %1,%0"
2108   [(set_attr "length" "4")
2109    (set_attr "type" "fpu")])
2111 ;; square-root
2112 (define_insn "sqrtsf2"
2113   [(set (match_operand:SF 0 "register_operand" "=r")
2114         (sqrt:SF (match_operand:SF 1 "register_operand" "r")))]
2115   "TARGET_USE_FPU"
2116   "sqrtf.s %1,%0"
2117   [(set_attr "length" "4")
2118    (set_attr "type" "fpu")])
2120 (define_insn "sqrtdf2"
2121   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2122         (sqrt:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2123   "TARGET_USE_FPU"
2124   "sqrtf.d %1,%0"
2125   [(set_attr "length" "4")
2126    (set_attr "type" "fpu")])
2128 ;; float -> int
2129 (define_insn "fix_truncsfsi2"
2130   [(set (match_operand:SI 0 "register_operand" "=r")
2131         (fix:SI (match_operand:SF 1 "register_operand" "r")))]
2132   "TARGET_USE_FPU"
2133   "trncf.sw %1,%0"
2134   [(set_attr "length" "4")
2135    (set_attr "type" "fpu")])
2137 (define_insn "fixuns_truncsfsi2"
2138   [(set (match_operand:SI                  0 "register_operand" "=r")
2139         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "r")))]
2140   "TARGET_USE_FPU"
2141   "trncf.suw %1, %0"
2142   [(set_attr "length" "4")
2143    (set_attr "type" "fpu")])
2145 (define_insn "fix_truncdfsi2"
2146   [(set (match_operand:SI 0 "register_operand" "=r")
2147         (fix:SI (match_operand:DF 1 "even_reg_operand" "r")))]
2148   "TARGET_USE_FPU"
2149   "trncf.dw %1,%0"
2150   [(set_attr "length" "4")
2151    (set_attr "type" "fpu")])
2153 (define_insn "fixuns_truncdfsi2"
2154   [(set (match_operand:SI                  0 "register_operand" "=r")
2155         (unsigned_fix:SI (match_operand:DF 1 "even_reg_operand" "r")))]
2156   "TARGET_USE_FPU"
2157   "trncf.duw %1, %0"
2158   [(set_attr "length" "4")
2159    (set_attr "type" "fpu")])
2161 (define_insn "fix_truncsfdi2"
2162   [(set (match_operand:DI         0 "register_operand" "=r")
2163         (fix:DI (match_operand:SF 1 "register_operand" "r")))]
2164   "TARGET_USE_FPU"
2165   "trncf.sl %1, %0"
2166   [(set_attr "length" "4")
2167    (set_attr "type" "fpu")])
2169 (define_insn "fixuns_truncsfdi2"
2170   [(set (match_operand:DI                  0 "register_operand" "=r")
2171         (unsigned_fix:DI (match_operand:SF 1 "register_operand" "r")))]
2172   "TARGET_USE_FPU"
2173   "trncf.sul %1, %0"
2174   [(set_attr "length" "4")
2175    (set_attr "type" "fpu")])
2177 (define_insn "fix_truncdfdi2"
2178   [(set (match_operand:DI         0 "register_operand" "=r")
2179         (fix:DI (match_operand:DF 1 "even_reg_operand" "r")))]
2180   "TARGET_USE_FPU"
2181   "trncf.dl %1, %0"
2182   [(set_attr "length" "4")
2183    (set_attr "type" "fpu")])
2185 (define_insn "fixuns_truncdfdi2"
2186   [(set (match_operand:DI                  0 "register_operand" "=r")
2187         (unsigned_fix:DI (match_operand:DF 1 "even_reg_operand" "r")))]
2188   "TARGET_USE_FPU"
2189   "trncf.dul %1, %0"
2190   [(set_attr "length" "4")
2191    (set_attr "type" "fpu")])
2193 ;; int -> float
2194 (define_insn "floatsisf2"
2195   [(set (match_operand:SF 0 "register_operand" "=r")
2196         (float:SF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2197   "TARGET_USE_FPU"
2198   "cvtf.ws %z1, %0"
2199   [(set_attr "length" "4")
2200    (set_attr "type" "fpu")])
2202 (define_insn "unsfloatsisf2"
2203   [(set (match_operand:SF                    0 "register_operand" "=r")
2204         (unsigned_float:SF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2205   "TARGET_USE_FPU"
2206   "cvtf.uws %z1, %0"
2207   [(set_attr "length" "4")
2208    (set_attr "type" "fpu")])
2210 (define_insn "floatsidf2"
2211   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2212         (float:DF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2213   "TARGET_USE_FPU"
2214   "cvtf.wd %z1,%0"
2215   [(set_attr "length" "4")
2216    (set_attr "type" "fpu")])
2218 (define_insn "unsfloatsidf2"
2219   [(set (match_operand:DF                    0 "even_reg_operand" "=r")
2220         (unsigned_float:DF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2221   "TARGET_USE_FPU"
2222   "cvtf.uwd %z1, %0"
2223   [(set_attr "length" "4")
2224    (set_attr "type" "fpu")])
2226 (define_insn "floatdisf2"
2227   [(set (match_operand:SF           0 "even_reg_operand" "=r")
2228         (float:SF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2229   "TARGET_USE_FPU"
2230   "cvtf.ls %z1, %0"
2231   [(set_attr "length" "4")
2232    (set_attr "type" "fpu")])
2234 (define_insn "unsfloatdisf2"
2235   [(set (match_operand:SF                    0 "even_reg_operand" "=r")
2236         (unsigned_float:SF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2237   "TARGET_USE_FPU"
2238   "cvtf.uls %z1, %0"
2239   [(set_attr "length" "4")
2240    (set_attr "type" "fpu")])
2242 (define_insn "floatdidf2"
2243   [(set (match_operand:DF           0 "even_reg_operand" "=r")
2244         (float:DF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2245   "TARGET_USE_FPU"
2246   "cvtf.ld %z1, %0"
2247   [(set_attr "length" "4")
2248    (set_attr "type" "fpu")])
2250 (define_insn "unsfloatdidf2"
2251   [(set (match_operand:DF                    0 "even_reg_operand" "=r")
2252         (unsigned_float:DF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2253   "TARGET_USE_FPU"
2254   "cvtf.uld %z1, %0"
2255   [(set_attr "length" "4")
2256    (set_attr "type" "fpu")])
2258 ;; single-float -> double-float
2259 (define_insn "extendsfdf2"
2260   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2261         (float_extend:DF
2262          (match_operand:SF 1 "reg_or_0_operand" "rI")))]
2263   "TARGET_USE_FPU"
2264   "cvtf.sd %z1,%0"
2265   [(set_attr "length" "4")
2266    (set_attr "type" "fpu")])
2268 ;; double-float -> single-float
2269 (define_insn "truncdfsf2"
2270   [(set (match_operand:SF 0 "register_operand" "=r")
2271         (float_truncate:SF
2272          (match_operand:DF 1 "even_reg_operand" "r")))]
2273   "TARGET_USE_FPU"
2274   "cvtf.ds %1,%0"
2275   [(set_attr "length" "4")
2276    (set_attr "type" "fpu")])
2279 ;; ---------------- special insns
2282 ;; Generic code demands that the recip and rsqrt named patterns
2283 ;; have precisely one operand.  So that's what we expose in the
2284 ;; expander via the strange UNSPEC.  However, those expanders
2285 ;; generate normal looking recip and rsqrt patterns.
2287 (define_expand "recipsf2"
2288   [(set (match_operand:SF 0 "register_operand" "")
2289         (unspec:SF [(match_operand:SF 1 "register_operand" "")]
2290                    UNSPEC_RCP))]
2291   "TARGET_USE_FPU"
2292   {
2293     emit_insn (gen_recipsf2_insn (operands[0], CONST1_RTX (SFmode), operands[1]));
2294     DONE;
2295   })
2297 (define_insn "recipsf2_insn"
2298   [(set (match_operand:SF 0 "register_operand" "=r")
2299         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2300                 (match_operand:SF 2 "register_operand" "r")))]
2301   "TARGET_USE_FPU"
2302   "recipf.s %2,%0"
2303   [(set_attr "length" "4")
2304    (set_attr "type" "fpu")])
2306 (define_expand "recipdf2"
2307   [(set (match_operand:DF 0 "even_reg_operand" "")
2308         (unspec:DF [(match_operand:SF 1 "even_reg_operand" "")]
2309                    UNSPEC_RCP))]
2310   "TARGET_USE_FPU"
2311   {
2312     emit_insn (gen_recipdf2_insn (operands[0], CONST1_RTX (DFmode), operands[1]));
2313     DONE;
2314   })
2316 (define_insn "recipdf2_insn"
2317   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2318         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2319                 (match_operand:DF 2 "even_reg_operand" "r")))]
2320   "TARGET_USE_FPU"
2321   "recipf.d %2,%0"
2322   [(set_attr "length" "4")
2323    (set_attr "type" "fpu")])
2325 ;;; reciprocal of square-root
2326 (define_expand "rsqrtsf2"
2327   [(set (match_operand:SF 0 "register_operand" "=")
2328         (unspec:SF [(match_operand:SF 1 "register_operand" "")]
2329                    UNSPEC_RSQRT))]
2330   "TARGET_USE_FPU"
2331   {
2332     emit_insn (gen_rsqrtsf2_insn (operands[0], CONST1_RTX (SFmode), operands[1]));
2333     DONE;
2334   })
2336 (define_insn "rsqrtsf2_insn"
2337   [(set (match_operand:SF 0 "register_operand" "=r")
2338         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2339                 (sqrt:SF (match_operand:SF 2 "register_operand" "r"))))]
2340   "TARGET_USE_FPU"
2341   "rsqrtf.s %2,%0"
2342   [(set_attr "length" "4")
2343    (set_attr "type" "fpu")])
2345 (define_expand "rsqrtdf2"
2346   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2347         (unspec:DF [(match_operand:DF 1 "even_reg_operand" "r")]
2348                    UNSPEC_RSQRT))]
2349   "TARGET_USE_FPU"
2350   {
2351     emit_insn (gen_rsqrtdf2_insn (operands[0], CONST1_RTX (DFmode), operands[1]));
2352     DONE;
2353   })
2355 (define_insn "rsqrtdf2_insn"
2356   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2357         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2358                 (sqrt:DF (match_operand:DF 2 "even_reg_operand" "r"))))]
2359   "TARGET_USE_FPU"
2360   "rsqrtf.d %2,%0"
2361   [(set_attr "length" "4")
2362    (set_attr "type" "fpu")])
2364 ;; Note: The FPU-2.0 (ie pre e3v5) versions of these routines do not actually
2365 ;; need operand 4 to be the same as operand 0.  But the FPU-2.0 versions are
2366 ;; also deprecated so the loss of flexibility is unimportant.
2368 ;;; multiply-add
2369 (define_insn "fmasf4"
2370   [(set (match_operand:SF         0 "register_operand" "=r")
2371         (fma:SF (match_operand:SF 1 "register_operand" "r")
2372                 (match_operand:SF 2 "register_operand" "r")
2373                 (match_operand:SF 3 "register_operand" "0")))]
2374   "TARGET_USE_FPU"
2375   { return TARGET_V850E3V5_UP ? "fmaf.s %1, %2, %0" : "maddf.s %2, %1, %3, %0"; }
2376   [(set_attr "length" "4")
2377    (set_attr "type" "fpu")])
2379 ;;; multiply-subtract
2380 (define_insn "fmssf4"
2381   [(set (match_operand:SF                 0 "register_operand" "=r")
2382         (fma:SF (match_operand:SF         1 "register_operand" "r")
2383                 (match_operand:SF         2 "register_operand" "r")
2384                 (neg:SF (match_operand:SF 3 "register_operand" "0"))))]
2385   "TARGET_USE_FPU"
2386   { return TARGET_V850E3V5_UP ? "fmsf.s %1, %2, %0" : "msubf.s %2, %1, %3, %0"; }
2387   [(set_attr "length" "4")
2388    (set_attr "type" "fpu")])
2390 ;;; negative-multiply-add
2391 (define_insn "fnmasf4"
2392   [(set (match_operand:SF                 0 "register_operand" "=r")
2393         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "r")
2394                         (match_operand:SF 2 "register_operand" "r")
2395                         (match_operand:SF 3 "register_operand" "0"))))]
2396   "TARGET_USE_FPU"
2397   { return TARGET_V850E3V5_UP ? "fnmaf.s %1, %2, %0" : "nmaddf.s %2, %1, %3, %0"; }
2398   [(set_attr "length" "4")
2399    (set_attr "type" "fpu")])
2401 ;; negative-multiply-subtract
2402 (define_insn "fnmssf4"
2403   [(set (match_operand:SF                         0 "register_operand" "=r")
2404         (neg:SF (fma:SF (match_operand:SF         1 "register_operand" "r")
2405                         (match_operand:SF         2 "register_operand" "r")
2406                         (neg:SF (match_operand:SF 3 "register_operand" "0")))))]
2407   "TARGET_USE_FPU"
2408   { return TARGET_V850E3V5_UP ? "fnmsf.s %1, %2, %0" : "nmsubf.s %2, %1, %3, %0"; }
2409   [(set_attr "length" "4")
2410    (set_attr "type" "fpu")])
2412 ; ---------------- comparison/conditionals
2414 ; SF
2416 (define_insn "cmpsf_le_insn"
2417   [(set (reg:CC_FPU_LE FCC_REGNUM)
2418         (compare:CC_FPU_LE (match_operand:SF 0 "register_operand" "r")
2419                            (match_operand:SF 1 "register_operand" "r")))]
2420   "TARGET_USE_FPU"
2421   "cmpf.s le, %z0, %z1"
2422   [(set_attr "length" "4")
2423    (set_attr "type" "fpu")])
2425 (define_insn "cmpsf_lt_insn"
2426   [(set (reg:CC_FPU_LT FCC_REGNUM)
2427         (compare:CC_FPU_LT (match_operand:SF 0 "register_operand" "r")
2428                            (match_operand:SF 1 "register_operand" "r")))]
2429   "TARGET_USE_FPU"
2430   "cmpf.s lt, %z0, %z1"
2431   [(set_attr "length" "4")
2432    (set_attr "type" "fpu")])
2434 (define_insn "cmpsf_ge_insn"
2435   [(set (reg:CC_FPU_GE FCC_REGNUM)
2436         (compare:CC_FPU_GE (match_operand:SF 0 "register_operand" "r")
2437                            (match_operand:SF 1 "register_operand" "r")))]
2438   "TARGET_USE_FPU"
2439   "cmpf.s le, %z1, %z0"
2440   [(set_attr "length" "4")
2441    (set_attr "type" "fpu")])
2443 (define_insn "cmpsf_gt_insn"
2444   [(set (reg:CC_FPU_GT FCC_REGNUM)
2445         (compare:CC_FPU_GT (match_operand:SF 0 "register_operand" "r")
2446                            (match_operand:SF 1 "register_operand" "r")))]
2447   "TARGET_USE_FPU"
2448   "cmpf.s lt, %z1, %z0"
2449   [(set_attr "length" "4")
2450    (set_attr "type" "fpu")])
2452 (define_insn "cmpsf_eq_insn"
2453   [(set (reg:CC_FPU_EQ FCC_REGNUM)
2454         (compare:CC_FPU_EQ (match_operand:SF 0 "register_operand" "r")
2455                            (match_operand:SF 1 "register_operand" "r")))]
2456   "TARGET_USE_FPU"
2457   "cmpf.s eq, %z0, %z1"
2458   [(set_attr "length" "4")
2459    (set_attr "type" "fpu")])
2461 ; DF
2463 (define_insn "cmpdf_le_insn"
2464   [(set (reg:CC_FPU_LE FCC_REGNUM)
2465         (compare:CC_FPU_LE (match_operand:DF 0 "even_reg_operand" "r")
2466                            (match_operand:DF 1 "even_reg_operand" "r")))]
2467   "TARGET_USE_FPU"
2468   "cmpf.d le, %z0, %z1"
2469   [(set_attr "length" "4")
2470    (set_attr "type" "fpu")])
2472 (define_insn "cmpdf_lt_insn"
2473   [(set (reg:CC_FPU_LT FCC_REGNUM)
2474         (compare:CC_FPU_LT (match_operand:DF 0 "even_reg_operand" "r")
2475                            (match_operand:DF 1 "even_reg_operand" "r")))]
2476   "TARGET_USE_FPU"
2477   "cmpf.d lt, %z0, %z1"
2478   [(set_attr "length" "4")
2479    (set_attr "type" "fpu")])
2481 (define_insn "cmpdf_ge_insn"
2482   [(set (reg:CC_FPU_GE FCC_REGNUM)
2483         (compare:CC_FPU_GE (match_operand:DF 0 "even_reg_operand" "r")
2484                            (match_operand:DF 1 "even_reg_operand" "r")))]
2485   "TARGET_USE_FPU"
2486   "cmpf.d le, %z1, %z0"
2487   [(set_attr "length" "4")
2488    (set_attr "type" "fpu")])
2490 (define_insn "cmpdf_gt_insn"
2491   [(set (reg:CC_FPU_GT FCC_REGNUM)
2492         (compare:CC_FPU_GT (match_operand:DF 0 "even_reg_operand" "r")
2493                            (match_operand:DF 1 "even_reg_operand" "r")))]
2494   "TARGET_USE_FPU"
2495   "cmpf.d lt, %z1, %z0"
2496   [(set_attr "length" "4")
2497    (set_attr "type" "fpu")])
2499 (define_insn "cmpdf_eq_insn"
2500   [(set (reg:CC_FPU_EQ FCC_REGNUM)
2501         (compare:CC_FPU_EQ (match_operand:DF 0 "even_reg_operand" "r")
2502                            (match_operand:DF 1 "even_reg_operand" "r")))]
2503   "TARGET_USE_FPU"
2504   "cmpf.d eq, %z0, %z1"
2505   [(set_attr "length" "4")
2506    (set_attr "type" "fpu")])
2509 ;; Transfer a v850e2v3 fcc to the Z bit of CC0 (this is necessary to do a
2510 ;; conditional branch based on a floating-point compare)
2513 (define_insn "trfsr"
2514   [(set (match_operand 0 "" "") (match_operand 1 "" ""))]
2515   "TARGET_USE_FPU
2516    && GET_MODE(operands[0]) == GET_MODE(operands[1])
2517    && GET_CODE(operands[0]) == REG && REGNO (operands[0]) == CC_REGNUM
2518    && GET_CODE(operands[1]) == REG && REGNO (operands[1]) == FCC_REGNUM
2519    && (GET_MODE(operands[0]) == CC_FPU_LEmode
2520        || GET_MODE(operands[0]) == CC_FPU_GEmode
2521        || GET_MODE(operands[0]) == CC_FPU_LTmode
2522        || GET_MODE(operands[0]) == CC_FPU_GTmode
2523        || GET_MODE(operands[0]) == CC_FPU_EQmode
2524        || GET_MODE(operands[0]) == CC_FPU_NEmode)"
2525   "trfsr"
2526   [(set_attr "length" "4")
2527    (set_attr "type" "fpu")])
2530 ;; Floating-point conditional moves for the v850e2v3.
2533 ;; The actual v850e2v3 conditional move instructions
2535 (define_insn "movsfcc_z_insn"
2536   [(set (match_operand:SF 0 "register_operand" "=r")
2537         (if_then_else:SF
2538          (match_operand 3 "v850_float_z_comparison_operator" "")
2539          (match_operand:SF 1 "reg_or_0_operand" "rIG")
2540          (match_operand:SF 2 "reg_or_0_operand" "rIG")))]
2541   "TARGET_USE_FPU"
2542   "cmovf.s 0,%z1,%z2,%0")
2544 (define_insn "movsfcc_nz_insn"
2545   [(set (match_operand:SF 0 "register_operand" "=r")
2546         (if_then_else:SF
2547          (match_operand 3 "v850_float_nz_comparison_operator" "")
2548          (match_operand:SF 1 "reg_or_0_operand" "rIG")
2549          (match_operand:SF 2 "reg_or_0_operand" "rIG")))]
2550   "TARGET_USE_FPU"
2551   "cmovf.s 0,%z2,%z1,%0")
2553 (define_insn "movdfcc_z_insn"
2554   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2555         (if_then_else:DF
2556          (match_operand 3 "v850_float_z_comparison_operator" "")
2557          (match_operand:DF 1 "even_reg_operand" "r")
2558          (match_operand:DF 2 "even_reg_operand" "r")))]
2559   "TARGET_USE_FPU"
2560   "cmovf.d 0,%z1,%z2,%0")
2562 (define_insn "movdfcc_nz_insn"
2563   [(set (match_operand:DF 0 "even_reg_operand" "=r")
2564         (if_then_else:DF
2565          (match_operand 3 "v850_float_nz_comparison_operator" "")
2566          (match_operand:DF 1 "even_reg_operand" "r")
2567          (match_operand:DF 2 "even_reg_operand" "r")))]
2568   "TARGET_USE_FPU"
2569   "cmovf.d 0,%z2,%z1,%0")
2571 (define_insn "movedfcc_z_zero"
2572   [(set (match_operand:DF 0 "register_operand" "=r")
2573         (if_then_else:DF
2574          (match_operand 3 "v850_float_z_comparison_operator" "")
2575          (match_operand:DF 1 "reg_or_0_operand" "rIG")
2576          (match_operand:DF 2 "reg_or_0_operand" "rIG")))]
2577   "TARGET_USE_FPU"
2578   "cmovf.s 0,%z1,%z2,%0 ; cmovf.s 0,%Z1,%Z2,%R0"
2579   [(set_attr "length" "8")])
2581 (define_insn "movedfcc_nz_zero"
2582   [(set (match_operand:DF 0 "register_operand" "=r")
2583         (if_then_else:DF
2584          (match_operand 3 "v850_float_nz_comparison_operator" "")
2585          (match_operand:DF 1 "reg_or_0_operand" "rIG")
2586          (match_operand:DF 2 "reg_or_0_operand" "rIG")))]
2587   "TARGET_USE_FPU"
2588   "cmovf.s 0,%z2,%z1,%0 ; cmovf.s 0,%Z2,%Z1,%R0"
2589   [(set_attr "length" "8")])
2592 ;; ----------------------------------------------------------------------
2593 ;; HELPER INSTRUCTIONS for saving the prologue and epilogue registers
2594 ;; ----------------------------------------------------------------------
2596 ;; This pattern will match a stack adjust RTX followed by any number of push
2597 ;; RTXs.  These RTXs will then be turned into a suitable call to a worker
2598 ;; function.
2601 ;; Actually, convert the RTXs into a PREPARE instruction.
2604 (define_insn ""
2605  [(match_parallel 0 "pattern_is_ok_for_prepare"
2606    [(set (reg:SI 3)
2607          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2608     (set (mem:SI (plus:SI (reg:SI 3)
2609                           (match_operand:SI 2 "immediate_operand" "i")))
2610          (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
2611  "TARGET_PROLOG_FUNCTION && (TARGET_V850E_UP)"
2613   return construct_prepare_instruction (operands[0]);
2615  [(set_attr "length" "4")])
2617 (define_insn ""
2618  [(match_parallel 0 "pattern_is_ok_for_prologue"
2619    [(set (reg:SI 3)
2620          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2621     (set (mem:SI (plus:SI (reg:SI 3)
2622                            (match_operand:SI 2 "immediate_operand" "i")))
2623          (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
2624  "TARGET_PROLOG_FUNCTION"
2626   return construct_save_jarl (operands[0]);
2628  [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
2629                                      (const_string "16")
2630                                      (const_string "4")))])
2633 ;; Actually, turn the RTXs into a DISPOSE instruction.
2635 (define_insn ""
2636  [(match_parallel 0 "pattern_is_ok_for_dispose"
2637    [(return)
2638     (set (reg:SI 3)
2639          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2640     (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
2641          (mem:SI (plus:SI (reg:SI 3)
2642                           (match_operand:SI 3 "immediate_operand" "i"))))])]
2643  "TARGET_PROLOG_FUNCTION && (TARGET_V850E_UP)"
2645   return construct_dispose_instruction (operands[0]);
2647  [(set_attr "length" "4")])
2649 ;; This pattern will match a return RTX followed by any number of pop RTXs
2650 ;; and possible a stack adjustment as well.  These RTXs will be turned into
2651 ;; a suitable call to a worker function.
2653 (define_insn ""
2654 [(match_parallel 0 "pattern_is_ok_for_epilogue"
2655    [(return)
2656     (set (reg:SI 3)
2657          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2658     (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
2659          (mem:SI (plus:SI (reg:SI 3)
2660                           (match_operand:SI 3 "immediate_operand" "i"))))])]
2661  "TARGET_PROLOG_FUNCTION"
2663   return construct_restore_jr (operands[0]);
2665  [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
2666                                      (const_string "12")
2667                                      (const_string "4")))])
2669 ;; Initialize an interrupt function.  Do not depend on TARGET_PROLOG_FUNCTION.
2670 (define_insn "callt_save_interrupt"
2671   [(unspec_volatile [(const_int 0)] 2)]
2672     "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2673     ;; The CALLT instruction stores the next address of CALLT to CTPC register
2674     ;; without saving its previous value.  So if the interrupt handler
2675     ;; or its caller could possibly execute the CALLT insn, save_interrupt 
2676     ;; MUST NOT be called via CALLT.
2678   output_asm_insn ("addi -28,   sp, sp", operands);
2679   output_asm_insn ("st.w r1,    24[sp]", operands);
2680   output_asm_insn ("st.w r10,   12[sp]", operands);
2681   output_asm_insn ("st.w r11,   16[sp]", operands);
2682   output_asm_insn ("stsr ctpc,  r10",    operands);
2683   output_asm_insn ("st.w r10,   20[sp]", operands);
2684   output_asm_insn ("stsr ctpsw, r10",    operands);
2685   output_asm_insn ("st.w r10,   24[sp]", operands);
2686   output_asm_insn ("callt ctoff(__callt_save_interrupt)", operands);
2687   return "";
2689    [(set_attr "length" "26")])
2691 (define_insn "callt_return_interrupt"
2692   [(unspec_volatile [(const_int 0)] 3)]
2693   "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2694   "callt ctoff(__callt_return_interrupt)"
2695   [(set_attr "length" "2")])
2697 (define_insn "save_interrupt"
2698   [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -20)))
2699    (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 30))
2700    (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 4))
2701    (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))
2702    (set (mem:SI (plus:SI (reg:SI 3) (const_int  -8))) (reg:SI 10))
2703    (set (mem:SI (plus:SI (reg:SI 3) (const_int  -4))) (reg:SI 11))]
2704   ""
2706   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2707     return "addi -20,sp,sp \; st.w r11,16[sp] \; st.w r10,12[sp] \; jarl __save_interrupt,r10";
2708   else
2709     {
2710       output_asm_insn ("addi  -20, sp, sp", operands);
2711       output_asm_insn ("st.w  r11, 16[sp]", operands);
2712       output_asm_insn ("st.w  r10, 12[sp]", operands);
2713       output_asm_insn ("st.w  ep, 0[sp]", operands);
2714       output_asm_insn ("st.w  gp, 4[sp]", operands);
2715       output_asm_insn ("st.w  r1, 8[sp]", operands);
2716       output_asm_insn ("movhi hi(__ep), r0, ep", operands);
2717       output_asm_insn ("movea lo(__ep), ep, ep", operands);
2718       output_asm_insn ("movhi hi(__gp), r0, gp", operands);
2719       output_asm_insn ("movea lo(__gp), gp, gp", operands);
2720       return "";
2721     }
2723   [(set (attr "length")
2724         (if_then_else (match_test "TARGET_LONG_CALLS")
2725                        (const_int 10)
2726                        (const_int 34)))])
2727   
2728 ;; Restore r1, r4, r10, and return from the interrupt
2729 (define_insn "return_interrupt"
2730   [(return)
2731    (set (reg:SI 3)  (plus:SI (reg:SI 3) (const_int 20)))
2732    (set (reg:SI 11) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))
2733    (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
2734    (set (reg:SI 1)  (mem:SI (plus:SI (reg:SI 3) (const_int  8))))
2735    (set (reg:SI 4)  (mem:SI (plus:SI (reg:SI 3) (const_int  4))))
2736    (set (reg:SI 30) (mem:SI (reg:SI 3)))]
2737   ""
2739   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2740     return "jr __return_interrupt";
2741   else 
2742     {
2743       output_asm_insn ("ld.w 0[sp],  ep",   operands);
2744       output_asm_insn ("ld.w 4[sp],  gp",   operands);
2745       output_asm_insn ("ld.w 8[sp],  r1",   operands);
2746       output_asm_insn ("ld.w 12[sp], r10", operands);
2747       output_asm_insn ("ld.w 16[sp], r11", operands);
2748       output_asm_insn ("addi 20, sp, sp",   operands);
2749       output_asm_insn ("reti",            operands);
2750       return "";
2751     }
2753   [(set (attr "length")
2754         (if_then_else (match_test "TARGET_LONG_CALLS")
2755                        (const_int 4)
2756                        (const_int 24)))])
2758 ;; Save all registers except for the registers saved in save_interrupt when
2759 ;; an interrupt function makes a call.
2760 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2761 ;; all of memory.  This blocks insns from being moved across this point.
2762 ;; This is needed because the rest of the compiler is not ready to handle
2763 ;; insns this complicated.
2765 (define_insn "callt_save_all_interrupt"
2766   [(unspec_volatile [(const_int 0)] 0)]
2767   "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2768   "callt ctoff(__callt_save_all_interrupt)"
2769   [(set_attr "length" "2")])
2771 (define_insn "save_all_interrupt"
2772   [(unspec_volatile [(const_int 0)] 0)]
2773   ""
2775   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2776     return "jarl __save_all_interrupt,r10";
2778   output_asm_insn ("addi -120, sp, sp", operands);
2780   if (TARGET_EP)
2781     {
2782       output_asm_insn ("mov ep, r1", operands);
2783       output_asm_insn ("mov sp, ep", operands);
2784       output_asm_insn ("sst.w r31, 116[ep]", operands);
2785       output_asm_insn ("sst.w r2,  112[ep]", operands);
2786       output_asm_insn ("sst.w gp,  108[ep]", operands);
2787       output_asm_insn ("sst.w r6,  104[ep]", operands);
2788       output_asm_insn ("sst.w r7,  100[ep]", operands);
2789       output_asm_insn ("sst.w r8,   96[ep]", operands);
2790       output_asm_insn ("sst.w r9,   92[ep]", operands);
2791       output_asm_insn ("sst.w r11,  88[ep]", operands);
2792       output_asm_insn ("sst.w r12,  84[ep]", operands);
2793       output_asm_insn ("sst.w r13,  80[ep]", operands);
2794       output_asm_insn ("sst.w r14,  76[ep]", operands);
2795       output_asm_insn ("sst.w r15,  72[ep]", operands);
2796       output_asm_insn ("sst.w r16,  68[ep]", operands);
2797       output_asm_insn ("sst.w r17,  64[ep]", operands);
2798       output_asm_insn ("sst.w r18,  60[ep]", operands);
2799       output_asm_insn ("sst.w r19,  56[ep]", operands);
2800       output_asm_insn ("sst.w r20,  52[ep]", operands);
2801       output_asm_insn ("sst.w r21,  48[ep]", operands);
2802       output_asm_insn ("sst.w r22,  44[ep]", operands);
2803       output_asm_insn ("sst.w r23,  40[ep]", operands);
2804       output_asm_insn ("sst.w r24,  36[ep]", operands);
2805       output_asm_insn ("sst.w r25,  32[ep]", operands);
2806       output_asm_insn ("sst.w r26,  28[ep]", operands);
2807       output_asm_insn ("sst.w r27,  24[ep]", operands);
2808       output_asm_insn ("sst.w r28,  20[ep]", operands);
2809       output_asm_insn ("sst.w r29,  16[ep]", operands);
2810       output_asm_insn ("mov   r1,   ep", operands);
2811     }
2812   else
2813     {
2814       output_asm_insn ("st.w r31, 116[sp]", operands);
2815       output_asm_insn ("st.w r2,  112[sp]", operands);
2816       output_asm_insn ("st.w gp,  108[sp]", operands);
2817       output_asm_insn ("st.w r6,  104[sp]", operands);
2818       output_asm_insn ("st.w r7,  100[sp]", operands);
2819       output_asm_insn ("st.w r8,   96[sp]", operands);
2820       output_asm_insn ("st.w r9,   92[sp]", operands);
2821       output_asm_insn ("st.w r11,  88[sp]", operands);
2822       output_asm_insn ("st.w r12,  84[sp]", operands);
2823       output_asm_insn ("st.w r13,  80[sp]", operands);
2824       output_asm_insn ("st.w r14,  76[sp]", operands);
2825       output_asm_insn ("st.w r15,  72[sp]", operands);
2826       output_asm_insn ("st.w r16,  68[sp]", operands);
2827       output_asm_insn ("st.w r17,  64[sp]", operands);
2828       output_asm_insn ("st.w r18,  60[sp]", operands);
2829       output_asm_insn ("st.w r19,  56[sp]", operands);
2830       output_asm_insn ("st.w r20,  52[sp]", operands);
2831       output_asm_insn ("st.w r21,  48[sp]", operands);
2832       output_asm_insn ("st.w r22,  44[sp]", operands);
2833       output_asm_insn ("st.w r23,  40[sp]", operands);
2834       output_asm_insn ("st.w r24,  36[sp]", operands);
2835       output_asm_insn ("st.w r25,  32[sp]", operands);
2836       output_asm_insn ("st.w r26,  28[sp]", operands);
2837       output_asm_insn ("st.w r27,  24[sp]", operands);
2838       output_asm_insn ("st.w r28,  20[sp]", operands);
2839       output_asm_insn ("st.w r29,  16[sp]", operands);
2840     }
2841     
2842   return "";
2844   [(set (attr "length")
2845         (if_then_else (match_test "TARGET_LONG_CALLS")
2846                        (const_int 4)
2847                        (const_int 62)))])
2849 (define_insn "_save_all_interrupt"
2850   [(unspec_volatile [(const_int 0)] 0)]
2851   "TARGET_V850 && ! TARGET_LONG_CALLS"
2852   "jarl __save_all_interrupt,r10"
2853   [(set_attr "length" "4")])
2855 ;; Restore all registers saved when an interrupt function makes a call.
2856 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2857 ;; all of memory.  This blocks insns from being moved across this point.
2858 ;; This is needed because the rest of the compiler is not ready to handle
2859 ;; insns this complicated.
2861 (define_insn "callt_restore_all_interrupt"
2862   [(unspec_volatile [(const_int 0)] 1)]
2863   "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2864   "callt ctoff(__callt_restore_all_interrupt)"
2865   [(set_attr "length" "2")])
2867 (define_insn "restore_all_interrupt"
2868   [(unspec_volatile [(const_int 0)] 1)]
2869   ""
2871   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2872     return "jarl __restore_all_interrupt,r10";
2874   if (TARGET_EP)
2875     {
2876       output_asm_insn ("mov   ep,      r1", operands);
2877       output_asm_insn ("mov   sp,      ep", operands);
2878       output_asm_insn ("sld.w 116[ep], r31", operands);
2879       output_asm_insn ("sld.w 112[ep], r2", operands);
2880       output_asm_insn ("sld.w 108[ep], gp", operands);
2881       output_asm_insn ("sld.w 104[ep], r6", operands);
2882       output_asm_insn ("sld.w 100[ep], r7", operands);
2883       output_asm_insn ("sld.w 96[ep],  r8", operands);
2884       output_asm_insn ("sld.w 92[ep],  r9", operands);
2885       output_asm_insn ("sld.w 88[ep],  r11", operands);
2886       output_asm_insn ("sld.w 84[ep],  r12", operands);
2887       output_asm_insn ("sld.w 80[ep],  r13", operands);
2888       output_asm_insn ("sld.w 76[ep],  r14", operands);
2889       output_asm_insn ("sld.w 72[ep],  r15", operands);
2890       output_asm_insn ("sld.w 68[ep],  r16", operands);
2891       output_asm_insn ("sld.w 64[ep],  r17", operands);
2892       output_asm_insn ("sld.w 60[ep],  r18", operands);
2893       output_asm_insn ("sld.w 56[ep],  r19", operands);
2894       output_asm_insn ("sld.w 52[ep],  r20", operands);
2895       output_asm_insn ("sld.w 48[ep],  r21", operands);
2896       output_asm_insn ("sld.w 44[ep],  r22", operands);
2897       output_asm_insn ("sld.w 40[ep],  r23", operands);
2898       output_asm_insn ("sld.w 36[ep],  r24", operands);
2899       output_asm_insn ("sld.w 32[ep],  r25", operands);
2900       output_asm_insn ("sld.w 28[ep],  r26", operands);
2901       output_asm_insn ("sld.w 24[ep],  r27", operands);
2902       output_asm_insn ("sld.w 20[ep],  r28", operands);
2903       output_asm_insn ("sld.w 16[ep],  r29", operands);
2904       output_asm_insn ("mov   r1,      ep", operands);
2905     }
2906   else
2907     {
2908       output_asm_insn ("ld.w 116[sp], r31", operands);
2909       output_asm_insn ("ld.w 112[sp], r2", operands);
2910       output_asm_insn ("ld.w 108[sp], gp", operands);
2911       output_asm_insn ("ld.w 104[sp], r6", operands);
2912       output_asm_insn ("ld.w 100[sp], r7", operands);
2913       output_asm_insn ("ld.w 96[sp],  r8", operands);
2914       output_asm_insn ("ld.w 92[sp],  r9", operands);
2915       output_asm_insn ("ld.w 88[sp],  r11", operands);
2916       output_asm_insn ("ld.w 84[sp],  r12", operands);
2917       output_asm_insn ("ld.w 80[sp],  r13", operands);
2918       output_asm_insn ("ld.w 76[sp],  r14", operands);
2919       output_asm_insn ("ld.w 72[sp],  r15", operands);
2920       output_asm_insn ("ld.w 68[sp],  r16", operands);
2921       output_asm_insn ("ld.w 64[sp],  r17", operands);
2922       output_asm_insn ("ld.w 60[sp],  r18", operands);
2923       output_asm_insn ("ld.w 56[sp],  r19", operands);
2924       output_asm_insn ("ld.w 52[sp],  r20", operands);
2925       output_asm_insn ("ld.w 48[sp],  r21", operands);
2926       output_asm_insn ("ld.w 44[sp],  r22", operands);
2927       output_asm_insn ("ld.w 40[sp],  r23", operands);
2928       output_asm_insn ("ld.w 36[sp],  r24", operands);
2929       output_asm_insn ("ld.w 32[sp],  r25", operands);
2930       output_asm_insn ("ld.w 28[sp],  r26", operands);
2931       output_asm_insn ("ld.w 24[sp],  r27", operands);
2932       output_asm_insn ("ld.w 20[sp],  r28", operands);
2933       output_asm_insn ("ld.w 16[sp],  r29", operands);
2934     }
2935   output_asm_insn ("addi  120, sp, sp", operands);
2936   return "";
2938   [(set (attr "length")
2939         (if_then_else (match_test "TARGET_LONG_CALLS")
2940                        (const_int 4)
2941                        (const_int 62)
2942         ))])
2944 (define_insn "_restore_all_interrupt"
2945   [(unspec_volatile [(const_int 0)] 1)]
2946   "TARGET_V850 && ! TARGET_LONG_CALLS"
2947   "jarl __restore_all_interrupt,r10"
2948   [(set_attr "length" "4")])