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