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