OSDN Git Service

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