OSDN Git Service

* ChangeLog: Follow spelling conventions.
[pf3gnuchains/gcc-fork.git] / gcc / config / v850 / v850.md
1 ;; GCC machine description for NEC V850
2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2002 Free Software Foundation, Inc.
3 ;; Contributed by Jeff Law (law@cygnus.com).
4
5 ;; This file is part of GNU CC.
6
7 ;; GNU CC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; any later version.
11
12 ;; GNU CC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU CC; see the file COPYING.  If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
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 (define_attr "length" ""
36   (const_int 200))
37
38 (define_attr "long_calls" "yes,no"
39   (const (if_then_else (symbol_ref "TARGET_LONG_CALLS")
40                        (const_string "yes")
41                        (const_string "no"))))
42             
43 ;; Types of instructions (for scheduling purposes).
44
45 (define_attr "type" "load,mult,other"
46   (const_string "other"))
47
48 ;; Condition code settings.
49 ;; none - insn does not affect cc
50 ;; none_0hit - insn does not affect cc but it does modify operand 0
51 ;;      This attribute is used to keep track of when operand 0 changes.
52 ;;      See the description of NOTICE_UPDATE_CC for more info.
53 ;; set_znv - sets z,n,v to usable values; c is unknown.
54 ;; set_zn  - sets z,n to usable values; v,c is unknown.
55 ;; compare - compare instruction
56 ;; clobber - value of cc is unknown
57 (define_attr "cc" "none,none_0hit,set_zn,set_znv,compare,clobber"
58   (const_string "clobber"))
59 \f
60 ;; Function units for the V850.  As best as I can tell, there's
61 ;; a traditional memory load/use stall as well as a stall if
62 ;; the result of a multiply is used too early.
63 ;;
64 (define_function_unit "memory" 1 0 (eq_attr "type" "load") 2 0)
65 (define_function_unit "mult"   1 0 (eq_attr "type" "mult") 2 0)
66
67 \f
68 ;; ----------------------------------------------------------------------
69 ;; MOVE INSTRUCTIONS
70 ;; ----------------------------------------------------------------------
71
72 ;; movqi
73
74 (define_expand "movqi"
75   [(set (match_operand:QI 0 "general_operand" "")
76         (match_operand:QI 1 "general_operand" ""))]
77   ""
78   "
79 {
80   /* One of the ops has to be in a register or 0 */
81   if (!register_operand (operand0, QImode)
82       && !reg_or_0_operand (operand1, QImode))
83     operands[1] = copy_to_mode_reg (QImode, operand1);
84 }")
85
86 (define_insn "*movqi_internal"
87   [(set (match_operand:QI 0 "general_operand" "=r,r,r,Q,r,m,m")
88         (match_operand:QI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
89   "register_operand (operands[0], QImode)
90    || reg_or_0_operand (operands[1], QImode)"
91   "* return output_move_single (operands);"
92   [(set_attr "length" "2,4,2,2,4,4,4")
93    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
94    (set_attr "type" "other,other,load,other,load,other,other")])
95
96 ;; movhi
97
98 (define_expand "movhi"
99   [(set (match_operand:HI 0 "general_operand" "")
100         (match_operand:HI 1 "general_operand" ""))]
101   ""
102   "
103 {
104   /* One of the ops has to be in a register or 0 */
105   if (!register_operand (operand0, HImode)
106       && !reg_or_0_operand (operand1, HImode))
107     operands[1] = copy_to_mode_reg (HImode, operand1);
108 }")
109
110 (define_insn "*movhi_internal"
111   [(set (match_operand:HI 0 "general_operand" "=r,r,r,Q,r,m,m")
112         (match_operand:HI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
113   "register_operand (operands[0], HImode)
114    || reg_or_0_operand (operands[1], HImode)"
115   "* return output_move_single (operands);"
116   [(set_attr "length" "2,4,2,2,4,4,4")
117    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
118    (set_attr "type" "other,other,load,other,load,other,other")])
119
120 ;; movsi and helpers
121
122 (define_insn "*movsi_high"
123   [(set (match_operand:SI 0 "register_operand" "=r")
124         (high:SI (match_operand 1 "" "")))]
125   ""
126   "movhi hi(%1),%.,%0"
127   [(set_attr "length" "4")
128    (set_attr "cc" "none_0hit")
129    (set_attr "type" "other")])
130
131 (define_insn "*movsi_lo"
132   [(set (match_operand:SI 0 "register_operand" "=r")
133         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
134                    (match_operand:SI 2 "immediate_operand" "i")))]
135   ""
136   "movea lo(%2),%1,%0"
137   [(set_attr "length" "4")
138    (set_attr "cc" "none_0hit")
139    (set_attr "type" "other")])
140
141 (define_expand "movsi"
142   [(set (match_operand:SI 0 "general_operand" "")
143         (match_operand:SI 1 "general_operand" ""))]
144   ""
145   "
146 {
147   /* One of the ops has to be in a register or 0 */
148   if (!register_operand (operand0, SImode)
149       && !reg_or_0_operand (operand1, SImode))
150     operands[1] = copy_to_mode_reg (SImode, operand1);
151
152   /* Some constants, as well as symbolic operands
153      must be done with HIGH & LO_SUM patterns.  */
154   if (CONSTANT_P (operands[1])
155       && GET_CODE (operands[1]) != HIGH
156       && ! TARGET_V850E
157       && !special_symbolref_operand (operands[1], VOIDmode)
158       && !(GET_CODE (operands[1]) == CONST_INT
159            && (CONST_OK_FOR_J (INTVAL (operands[1]))
160                || CONST_OK_FOR_K (INTVAL (operands[1]))
161                || CONST_OK_FOR_L (INTVAL (operands[1])))))
162     {
163       rtx temp;
164
165       if (reload_in_progress || reload_completed)
166         temp = operands[0];
167       else
168         temp = gen_reg_rtx (SImode);
169
170       emit_insn (gen_rtx_SET (SImode, temp,
171                               gen_rtx_HIGH (SImode, operand1)));
172       emit_insn (gen_rtx_SET (SImode, operand0,
173                               gen_rtx_LO_SUM (SImode, temp, operand1)));
174       DONE;
175     }
176 }")
177
178 ;; This is the same as the following pattern, except that it includes
179 ;; support for arbitrary 32 bit immediates.
180
181 ;; ??? This always loads addresses using hilo.  If the only use of this address
182 ;; was in a load/store, then we would get smaller code if we only loaded the
183 ;; upper part with hi, and then put the lower part in the load/store insn.
184
185 (define_insn "*movsi_internal_v850e"
186   [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m,r")
187         (match_operand:SI 1 "general_operand" "Jr,K,L,Q,Ir,m,R,r,I,i"))]
188   "TARGET_V850E
189    && (register_operand (operands[0], SImode)
190        || reg_or_0_operand (operands[1], SImode))"
191   "* return output_move_single (operands);"
192   [(set_attr "length" "2,4,4,2,2,4,4,4,4,6")
193    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
194    (set_attr "type" "other,other,other,load,other,load,other,other,other,other")])
195
196 (define_insn "*movsi_internal"
197   [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m")
198         (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))]
199   "register_operand (operands[0], SImode)
200    || reg_or_0_operand (operands[1], SImode)"
201   "* return output_move_single (operands);"
202   [(set_attr "length" "2,4,4,2,2,4,4,4,4")
203    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
204    (set_attr "type" "other,other,other,load,other,load,other,other,other")])
205
206
207
208 (define_expand "movdi"
209   [(set (match_operand:DI 0 "general_operand" "")
210         (match_operand:DI 1 "general_operand" ""))]
211   ""
212   "
213 {
214   /* One of the ops has to be in a register or 0 */
215   if (!register_operand (operand0, DImode)
216       && !reg_or_0_operand (operand1, DImode))
217     operands[1] = copy_to_mode_reg (DImode, operand1);
218 }")
219
220 (define_insn "*movdi_internal"
221   [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,m,r")
222         (match_operand:DI 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
223   "register_operand (operands[0], DImode)
224    || reg_or_0_operand (operands[1], DImode)"
225   "* return output_move_double (operands);"
226   [(set_attr "length" "4,8,8,16,8,8,8,16")
227    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
228    (set_attr "type" "other,other,other,other,load,other,other,other")])
229
230 (define_expand "movsf"
231   [(set (match_operand:SF 0 "general_operand" "")
232         (match_operand:SF 1 "general_operand" ""))]
233   ""
234   "
235 {
236   /* One of the ops has to be in a register or 0 */
237   if (!register_operand (operand0, SFmode)
238       && !reg_or_0_operand (operand1, SFmode))
239     operands[1] = copy_to_mode_reg (SFmode, operand1);
240 }")
241
242 (define_insn "*movsf_internal"
243   [(set (match_operand:SF 0 "general_operand" "=r,r,r,r,r,Q,r,m,m,r")
244         (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))]
245   "register_operand (operands[0], SFmode)
246    || reg_or_0_operand (operands[1], SFmode)"
247   "* return output_move_single (operands);"
248   [(set_attr "length" "2,4,4,8,2,2,4,4,4,8")
249    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
250    (set_attr "type" "other,other,other,other,load,other,load,other,other,other")])
251
252 (define_expand "movdf"
253   [(set (match_operand:DF 0 "general_operand" "")
254         (match_operand:DF 1 "general_operand" ""))]
255   ""
256   "
257 {
258   /* One of the ops has to be in a register or 0 */
259   if (!register_operand (operand0, DFmode)
260       && !reg_or_0_operand (operand1, DFmode))
261     operands[1] = copy_to_mode_reg (DFmode, operand1);
262 }")
263
264 (define_insn "*movdf_internal"
265   [(set (match_operand:DF 0 "general_operand" "=r,r,r,r,r,m,m,r")
266         (match_operand:DF 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
267   "register_operand (operands[0], DFmode)
268    || reg_or_0_operand (operands[1], DFmode)"
269   "* return output_move_double (operands);"
270   [(set_attr "length" "4,8,8,16,8,8,8,16")
271    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
272    (set_attr "type" "other,other,other,other,load,other,other,other")])
273
274 \f
275 ;; ----------------------------------------------------------------------
276 ;; TEST INSTRUCTIONS
277 ;; ----------------------------------------------------------------------
278
279 (define_insn "*v850_tst1"
280   [(set (cc0) (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
281                                (const_int 1)
282                                (match_operand:QI 1 "const_int_operand" "n")))]
283   ""
284   "tst1 %1,%0"
285   [(set_attr "length" "4")
286    (set_attr "cc" "clobber")])
287
288 ;; This replaces ld.b;sar;andi with tst1;setf nz.
289
290 ;; ??? The zero_extract sets the Z bit to the opposite of what one would
291 ;; expect.  This perhaps should be wrapped in a (eq: X (const_int 0)).
292
293 (define_split
294   [(set (match_operand:SI 0 "register_operand" "")
295         (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
296                          (const_int 1)
297                          (match_operand 2 "const_int_operand" "")))]
298   ""
299   [(set (cc0) (zero_extract:SI (match_dup 1)
300                                (const_int 1)
301                                (match_dup 2)))
302    (set (match_dup 0) (ne:SI (cc0) (const_int 0)))])
303
304 (define_insn "tstsi"
305   [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
306   ""
307   "cmp %.,%0"
308   [(set_attr "length" "2")
309    (set_attr "cc" "set_znv")])
310
311 (define_insn "cmpsi"
312   [(set (cc0)
313         (compare (match_operand:SI 0 "register_operand" "r,r")
314                  (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
315   ""
316   "@
317   cmp %1,%0
318   cmp %1,%0"
319   [(set_attr "length" "2,2")
320    (set_attr "cc" "compare")])
321 \f
322 ;; ----------------------------------------------------------------------
323 ;; ADD INSTRUCTIONS
324 ;; ----------------------------------------------------------------------
325
326 (define_insn "addsi3"
327   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
328         (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
329                  (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))]
330   ""
331   "@
332    add %2,%0
333    addi %2,%1,%0
334    addi %O2(%P2),%1,%0"
335   [(set_attr "length" "2,4,4")
336    (set_attr "cc" "set_zn,set_zn,set_zn")])
337
338 ;; ----------------------------------------------------------------------
339 ;; SUBTRACT INSTRUCTIONS
340 ;; ----------------------------------------------------------------------
341
342 (define_insn "subsi3"
343   [(set (match_operand:SI 0 "register_operand" "=r,r")
344         (minus:SI (match_operand:SI 1 "register_operand" "0,r")
345                   (match_operand:SI 2 "register_operand" "r,0")))]
346   ""
347   "@
348   sub %2,%0
349   subr %1,%0"
350   [(set_attr "length" "2,2")
351    (set_attr "cc" "set_zn")])
352
353 (define_insn "negsi2"
354   [(set (match_operand:SI 0 "register_operand" "=r")
355         (neg:SI (match_operand:SI 1 "register_operand" "0")))]
356   ""
357   "subr %.,%0"
358   [(set_attr "length" "2")
359    (set_attr "cc" "set_zn")])
360
361 ;; ----------------------------------------------------------------------
362 ;; MULTIPLY INSTRUCTIONS
363 ;; ----------------------------------------------------------------------
364
365 (define_expand "mulhisi3"
366   [(set (match_operand:SI 0 "register_operand" "")
367         (mult:SI
368           (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
369           (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
370   ""
371   "")
372
373 (define_insn "*mulhisi3_internal1"
374   [(set (match_operand:SI 0 "register_operand" "=r")
375         (mult:SI
376           (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
377           (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
378   ""
379   "mulh %2,%0"
380   [(set_attr "length" "2")
381    (set_attr "cc" "none_0hit")
382    (set_attr "type" "mult")])
383
384 ;; ??? Sign extending constants isn't valid.  Fix?
385
386 (define_insn "*mulhisi3_internal2"
387   [(set (match_operand:SI 0 "register_operand" "=r,r")
388         (mult:SI
389           (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
390           (sign_extend:SI (match_operand 2 "const_int_operand" "J,K"))))]
391   ""
392   "@
393    mulh %2,%0
394    mulhi %2,%1,%0"
395   [(set_attr "length" "2,4")
396    (set_attr "cc" "none_0hit,none_0hit")
397    (set_attr "type" "mult")])
398
399 ;; ??? The scheduling info is probably wrong.
400
401 ;; ??? This instruction can also generate the 32 bit highpart, but using it
402 ;; may increase code size counter to the desired result.
403
404 ;; ??? This instructions can also give a DImode result.
405
406 ;; ??? There is unsigned version, but it matters only for the DImode/highpart
407 ;; results.
408
409 (define_insn "mulsi3"
410   [(set (match_operand:SI 0 "register_operand" "=r")
411         (mult:SI (match_operand:SI 1 "register_operand" "%0")
412                  (match_operand:SI 2 "reg_or_int9_operand" "rO")))]
413   "TARGET_V850E"
414   "mul %2,%1,%."
415   [(set_attr "length" "4")
416    (set_attr "cc" "none_0hit")
417    (set_attr "type" "mult")])
418
419 ;; ----------------------------------------------------------------------
420 ;; DIVIDE INSTRUCTIONS
421 ;; ----------------------------------------------------------------------
422
423 ;; ??? These insns do set the Z/N condition codes, except that they are based
424 ;; on only one of the two results, so it doesn't seem to make sense to use
425 ;; them.
426
427 ;; ??? The scheduling info is probably wrong.
428
429 (define_insn "divmodsi4"
430   [(set (match_operand:SI 0 "register_operand" "=r")
431         (div:SI (match_operand:SI 1 "register_operand" "0")
432                 (match_operand:SI 2 "register_operand" "r")))
433    (set (match_operand:SI 3 "register_operand" "=r")
434         (mod:SI (match_dup 1)
435                 (match_dup 2)))]
436   "TARGET_V850E"
437   "div %2,%0,%3"
438   [(set_attr "length" "4")
439    (set_attr "cc" "clobber")
440    (set_attr "type" "other")])
441         
442 (define_insn "udivmodsi4"
443   [(set (match_operand:SI 0 "register_operand" "=r")
444         (udiv:SI (match_operand:SI 1 "register_operand" "0")
445                  (match_operand:SI 2 "register_operand" "r")))
446    (set (match_operand:SI 3 "register_operand" "=r")
447         (umod:SI (match_dup 1)
448                  (match_dup 2)))]
449   "TARGET_V850E"
450   "divu %2,%0,%3"
451   [(set_attr "length" "4")
452    (set_attr "cc" "clobber")
453    (set_attr "type" "other")])
454         
455 ;; ??? There is a 2 byte instruction for generating only the quotient.
456 ;; However, it isn't clear how to compute the length field correctly.
457
458 (define_insn "divmodhi4"
459   [(set (match_operand:HI 0 "register_operand" "=r")
460         (div:HI (match_operand:HI 1 "register_operand" "0")
461                 (match_operand:HI 2 "register_operand" "r")))
462    (set (match_operand:HI 3 "register_operand" "=r")
463         (mod:HI (match_dup 1)
464                 (match_dup 2)))]
465   "TARGET_V850E"
466   "divh %2,%0,%3"
467   [(set_attr "length" "4")
468    (set_attr "cc" "clobber")
469    (set_attr "type" "other")])
470
471 ;; Half-words are sign-extended by default, so we must zero extend to a word
472 ;; here before doing the divide.
473
474 (define_insn "udivmodhi4"
475   [(set (match_operand:HI 0 "register_operand" "=r")
476         (udiv:HI (match_operand:HI 1 "register_operand" "0")
477                  (match_operand:HI 2 "register_operand" "r")))
478    (set (match_operand:HI 3 "register_operand" "=r")
479         (umod:HI (match_dup 1)
480                  (match_dup 2)))]
481   "TARGET_V850E"
482   "zxh %0 ; divhu %2,%0,%3"
483   [(set_attr "length" "4")
484    (set_attr "cc" "clobber")
485    (set_attr "type" "other")])
486 \f
487 ;; ----------------------------------------------------------------------
488 ;; AND INSTRUCTIONS
489 ;; ----------------------------------------------------------------------
490
491 (define_insn "*v850_clr1_1"
492   [(set (match_operand:QI 0 "memory_operand" "=m")
493         (subreg:QI
494           (and:SI (subreg:SI (match_dup 0) 0)
495                   (match_operand:QI 1 "not_power_of_two_operand" "")) 0))]
496   ""
497   "*
498 {
499   rtx xoperands[2];
500   xoperands[0] = operands[0];
501   xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
502   output_asm_insn (\"clr1 %M1,%0\", xoperands);
503   return \"\";
504 }"
505   [(set_attr "length" "4")
506    (set_attr "cc" "clobber")])
507
508 (define_insn "*v850_clr1_2"
509   [(set (match_operand:HI 0 "indirect_operand" "=m")
510         (subreg:HI
511           (and:SI (subreg:SI (match_dup 0) 0)
512                   (match_operand:HI 1 "not_power_of_two_operand" "")) 0))]
513   ""
514   "*
515 {
516   int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
517
518   rtx xoperands[2];
519   xoperands[0] = gen_rtx_MEM (QImode,
520                               plus_constant (XEXP (operands[0], 0), log2 / 8));
521   xoperands[1] = GEN_INT (log2 % 8);
522   output_asm_insn (\"clr1 %1,%0\", xoperands);
523   return \"\";
524 }"
525   [(set_attr "length" "4")
526    (set_attr "cc" "clobber")])
527
528 (define_insn "*v850_clr1_3"
529   [(set (match_operand:SI 0 "indirect_operand" "=m")
530         (and:SI (match_dup 0)
531                 (match_operand:SI 1 "not_power_of_two_operand" "")))]
532   ""
533   "*
534 {
535   int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
536
537   rtx xoperands[2];
538   xoperands[0] = gen_rtx_MEM (QImode,
539                               plus_constant (XEXP (operands[0], 0), log2 / 8));
540   xoperands[1] = GEN_INT (log2 % 8);
541   output_asm_insn (\"clr1 %1,%0\", xoperands);
542   return \"\";
543 }"
544   [(set_attr "length" "4")
545    (set_attr "cc" "clobber")])
546
547 (define_insn "andsi3"
548   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
549         (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
550                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
551   ""
552   "@
553   and %2,%0
554   and %.,%0
555   andi %2,%1,%0"
556   [(set_attr "length" "2,2,4")
557    (set_attr "cc" "set_znv")])
558
559 ;; ----------------------------------------------------------------------
560 ;; OR INSTRUCTIONS
561 ;; ----------------------------------------------------------------------
562
563 (define_insn "*v850_set1_1"
564   [(set (match_operand:QI 0 "memory_operand" "=m")
565         (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
566                            (match_operand 1 "power_of_two_operand" "")) 0))]
567   ""
568   "set1 %M1,%0"
569   [(set_attr "length" "4")
570    (set_attr "cc" "clobber")])
571
572 (define_insn "*v850_set1_2"
573   [(set (match_operand:HI 0 "indirect_operand" "=m")
574         (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
575                            (match_operand 1 "power_of_two_operand" "")) 0))]
576   ""
577   "*
578 {
579   int log2 = exact_log2 (INTVAL (operands[1]));
580
581   if (log2 < 8)
582     return \"set1 %M1,%0\";
583   else
584     {
585       rtx xoperands[2];
586       xoperands[0] = gen_rtx_MEM (QImode,
587                                   plus_constant (XEXP (operands[0], 0),
588                                                  log2 / 8));
589       xoperands[1] = GEN_INT (log2 % 8);
590       output_asm_insn (\"set1 %1,%0\", xoperands);
591     }
592   return \"\";
593 }"
594   [(set_attr "length" "4")
595    (set_attr "cc" "clobber")])
596
597 (define_insn "*v850_set1_3"
598   [(set (match_operand:SI 0 "indirect_operand" "=m")
599         (ior:SI (match_dup 0)
600                 (match_operand 1 "power_of_two_operand" "")))]
601   ""
602   "*
603 {
604   int log2 = exact_log2 (INTVAL (operands[1]));
605
606   if (log2 < 8)
607     return \"set1 %M1,%0\";
608   else
609     {
610       rtx xoperands[2];
611       xoperands[0] = gen_rtx_MEM (QImode,
612                                   plus_constant (XEXP (operands[0], 0),
613                                                  log2 / 8));
614       xoperands[1] = GEN_INT (log2 % 8);
615       output_asm_insn (\"set1 %1,%0\", xoperands);
616     }
617   return \"\";
618 }"
619   [(set_attr "length" "4")
620    (set_attr "cc" "clobber")])
621
622 (define_insn "iorsi3"
623   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
624         (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
625                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
626   ""
627   "@
628   or %2,%0
629   or %.,%0
630   ori %2,%1,%0"
631   [(set_attr "length" "2,2,4")
632    (set_attr "cc" "set_znv")])
633
634 ;; ----------------------------------------------------------------------
635 ;; XOR INSTRUCTIONS
636 ;; ----------------------------------------------------------------------
637
638 (define_insn "*v850_not1_1"
639   [(set (match_operand:QI 0 "memory_operand" "=m")
640         (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0)
641                            (match_operand 1 "power_of_two_operand" "")) 0))]
642   ""
643   "not1 %M1,%0"
644   [(set_attr "length" "4")
645    (set_attr "cc" "clobber")])
646
647 (define_insn "*v850_not1_2"
648   [(set (match_operand:HI 0 "indirect_operand" "=m")
649         (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
650                            (match_operand 1 "power_of_two_operand" "")) 0))]
651   ""
652   "*
653 {
654   int log2 = exact_log2 (INTVAL (operands[1]));
655
656   if (log2 < 8)
657     return \"not1 %M1,%0\";
658   else
659     {
660       rtx xoperands[2];
661       xoperands[0] = gen_rtx_MEM (QImode,
662                                   plus_constant (XEXP (operands[0], 0),
663                                                  log2 / 8));
664       xoperands[1] = GEN_INT (log2 % 8);
665       output_asm_insn (\"not1 %1,%0\", xoperands);
666     }
667   return \"\";
668 }"
669   [(set_attr "length" "4")
670    (set_attr "cc" "clobber")])
671
672 (define_insn "*v850_not1_3"
673   [(set (match_operand:SI 0 "indirect_operand" "=m")
674         (xor:SI (match_dup 0)
675                 (match_operand 1 "power_of_two_operand" "")))]
676   ""
677   "*
678 {
679   int log2 = exact_log2 (INTVAL (operands[1]));
680
681   if (log2 < 8)
682     return \"not1 %M1,%0\";
683   else
684     {
685       rtx xoperands[2];
686       xoperands[0] = gen_rtx_MEM (QImode,
687                                   plus_constant (XEXP (operands[0], 0),
688                                                  log2 / 8));
689       xoperands[1] = GEN_INT (log2 % 8);
690       output_asm_insn (\"not1 %1,%0\", xoperands);
691     }
692   return \"\";
693 }"
694   [(set_attr "length" "4")
695    (set_attr "cc" "clobber")])
696
697 (define_insn "xorsi3"
698   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
699         (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
700                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
701   ""
702   "@
703   xor %2,%0
704   xor %.,%0
705   xori %2,%1,%0"
706   [(set_attr "length" "2,2,4")
707    (set_attr "cc" "set_znv")])
708 \f
709 ;; ----------------------------------------------------------------------
710 ;; NOT INSTRUCTIONS
711 ;; ----------------------------------------------------------------------
712
713 (define_insn "one_cmplsi2"
714   [(set (match_operand:SI 0 "register_operand" "=r")
715         (not:SI (match_operand:SI 1 "register_operand" "r")))]
716   ""
717   "not %1,%0"
718   [(set_attr "length" "2")
719    (set_attr "cc" "set_znv")])
720 \f
721 ;; -----------------------------------------------------------------
722 ;; BIT FIELDS
723 ;; -----------------------------------------------------------------
724
725 ;; ??? Is it worth defining insv and extv for the V850 series?!?
726
727 ;; An insv pattern would be useful, but does not get used because
728 ;; store_bit_field never calls insv when storing a constant value into a
729 ;; single-bit bitfield.
730
731 ;; extv/extzv patterns would be useful, but do not get used because
732 ;; optimize_bitfield_compare in fold-const usually converts single
733 ;; bit extracts into an AND with a mask.
734
735 ;; -----------------------------------------------------------------
736 ;; Scc INSTRUCTIONS
737 ;; -----------------------------------------------------------------
738
739 (define_insn "sle"
740   [(set (match_operand:SI 0 "register_operand" "=r")
741         (le:SI (cc0) (const_int 0)))]
742   ""
743   "*
744 {
745   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
746     return 0;
747
748   return \"setf le,%0\";
749 }"
750   [(set_attr "length" "4")
751    (set_attr "cc" "none_0hit")])
752
753 (define_insn "sleu"
754   [(set (match_operand:SI 0 "register_operand" "=r")
755         (leu:SI (cc0) (const_int 0)))]
756   ""
757   "setf nh,%0"
758   [(set_attr "length" "4")
759    (set_attr "cc" "none_0hit")])
760
761 (define_insn "sge"
762   [(set (match_operand:SI 0 "register_operand" "=r")
763         (ge:SI (cc0) (const_int 0)))]
764   ""
765   "*
766 {
767   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
768     return 0;
769
770   return \"setf ge,%0\";
771 }"
772   [(set_attr "length" "4")
773    (set_attr "cc" "none_0hit")])
774
775 (define_insn "sgeu"
776   [(set (match_operand:SI 0 "register_operand" "=r")
777         (geu:SI (cc0) (const_int 0)))]
778   ""
779   "setf nl,%0"
780   [(set_attr "length" "4")
781    (set_attr "cc" "none_0hit")])
782
783 (define_insn "slt"
784   [(set (match_operand:SI 0 "register_operand" "=r")
785         (lt:SI (cc0) (const_int 0)))]
786   ""
787   "*
788 {
789   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
790     return 0;
791
792   return \"setf lt,%0\";
793 }"
794   [(set_attr "length" "4")
795    (set_attr "cc" "none_0hit")])
796
797 (define_insn "sltu"
798   [(set (match_operand:SI 0 "register_operand" "=r")
799         (ltu:SI (cc0) (const_int 0)))]
800   ""
801   "setf l,%0"
802   [(set_attr "length" "4")
803    (set_attr "cc" "none_0hit")])
804
805 (define_insn "sgt"
806   [(set (match_operand:SI 0 "register_operand" "=r")
807         (gt:SI (cc0) (const_int 0)))]
808   ""
809   "*
810 {
811   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
812     return 0;
813
814   return \"setf gt,%0\";
815 }"
816   [(set_attr "length" "4")
817    (set_attr "cc" "none_0hit")])
818
819 (define_insn "sgtu"
820   [(set (match_operand:SI 0 "register_operand" "=r")
821         (gtu:SI (cc0) (const_int 0)))]
822   ""
823   "setf h,%0"
824   [(set_attr "length" "4")
825    (set_attr "cc" "none_0hit")])
826
827 (define_insn "seq"
828   [(set (match_operand:SI 0 "register_operand" "=r")
829         (eq:SI (cc0) (const_int 0)))]
830   ""
831   "setf z,%0"
832   [(set_attr "length" "4")
833    (set_attr "cc" "none_0hit")])
834
835 (define_insn "sne"
836   [(set (match_operand:SI 0 "register_operand" "=r")
837         (ne:SI (cc0) (const_int 0)))]
838   ""
839   "setf nz,%0"
840   [(set_attr "length" "4")
841    (set_attr "cc" "none_0hit")])
842
843 ;; ----------------------------------------------------------------------
844 ;; CONDITIONAL MOVE INSTRUCTIONS
845 ;; ----------------------------------------------------------------------
846
847 ;; Instructions using cc0 aren't allowed to have input reloads, so we must
848 ;; hide the fact that this instruction uses cc0.  We do so by including the
849 ;; compare instruction inside it.
850
851 ;; ??? This is very ugly.  The right way to do this is to modify cmpsi so
852 ;; that it doesn't emit RTL, and then modify the bcc/scc patterns so that
853 ;; they emit RTL for the compare instruction.  Unfortunately, this requires
854 ;; lots of changes that will be hard to sanitize.  So for now, cmpsi still
855 ;; emits RTL, and I get the compare operands here from the previous insn.
856
857 (define_expand "movsicc"
858   [(set (match_operand:SI 0 "register_operand" "=r")
859         (if_then_else:SI
860          (match_operator 1 "comparison_operator"
861                          [(match_dup 4) (match_dup 5)])
862          (match_operand:SI 2 "reg_or_const_operand" "rJ")
863          (match_operand:SI 3 "reg_or_const_operand" "rI")))]
864   "TARGET_V850E"
865   "
866 {
867   rtx insn = get_last_insn_anywhere ();
868
869   if (   (GET_CODE (operands[2]) == CONST_INT
870        && GET_CODE (operands[3]) == CONST_INT))
871     {
872       int o2 = INTVAL (operands[2]);
873       int o3 = INTVAL (operands[3]);
874
875       if (o2 == 1 && o3 == 0)
876         FAIL;   /* setf */
877       if (o3 == 1 && o2 == 0)
878         FAIL;   /* setf */
879       if (o2 == 0 && (o3 < -16 || o3 > 15) && exact_log2 (o3) >= 0)
880         FAIL;   /* setf + shift */
881       if (o3 == 0 && (o2 < -16 || o2 > 15) && exact_log2 (o2) >=0)
882         FAIL;   /* setf + shift */
883       if (o2 != 0)
884         operands[2] = copy_to_mode_reg (SImode, operands[2]);
885       if (o3 !=0 )
886         operands[3] = copy_to_mode_reg (SImode, operands[3]);
887     }
888   else
889     {
890       if (GET_CODE (operands[2]) != REG)
891         operands[2] = copy_to_mode_reg (SImode,operands[2]);
892       if (GET_CODE (operands[3]) != REG)
893         operands[3] = copy_to_mode_reg (SImode, operands[3]);
894     }
895   if (GET_CODE (insn) == INSN
896       && GET_CODE (PATTERN (insn)) == SET
897       && SET_DEST (PATTERN (insn)) == cc0_rtx)
898     {
899       rtx src = SET_SRC (PATTERN (insn));
900
901       if (GET_CODE (src) == COMPARE)
902         {
903           operands[4] = XEXP (src, 0);
904           operands[5] = XEXP (src, 1);
905         }
906       else if (GET_CODE (src) == REG
907                || GET_CODE (src) == SUBREG)
908         {
909           operands[4] = src;
910           operands[5] = const0_rtx;
911         }
912       else
913         abort ();
914     }
915   else
916     abort ();
917 }")
918
919 ;; ??? Clobbering the condition codes is overkill.
920
921 ;; ??? We sometimes emit an unnecessary compare instruction because the
922 ;; condition codes may have already been set by an earlier instruction,
923 ;; but we have no code here to avoid the compare if it is unnecessary.
924
925 (define_insn "*movsicc_normal"
926   [(set (match_operand:SI 0 "register_operand" "=r")
927         (if_then_else:SI
928          (match_operator 1 "comparison_operator"
929                          [(match_operand:SI 4 "register_operand" "r")
930                           (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
931          (match_operand:SI 2 "reg_or_int5_operand" "rJ")
932          (match_operand:SI 3 "reg_or_0_operand" "rI")))]
933   "TARGET_V850E"
934   "cmp %5,%4 ; cmov %c1,%2,%z3,%0"
935   [(set_attr "length" "6")
936    (set_attr "cc" "clobber")])
937
938 (define_insn "*movsicc_reversed"
939   [(set (match_operand:SI 0 "register_operand" "=r")
940         (if_then_else:SI
941          (match_operator 1 "comparison_operator"
942                          [(match_operand:SI 4 "register_operand" "r")
943                           (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
944          (match_operand:SI 2 "reg_or_0_operand" "rI")
945          (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
946   "TARGET_V850E"
947   "cmp %5,%4 ; cmov %C1,%3,%z2,%0"
948   [(set_attr "length" "6")
949    (set_attr "cc" "clobber")])
950
951 (define_insn "*movsicc_tst1"
952   [(set (match_operand:SI 0 "register_operand" "=r")
953         (if_then_else:SI
954          (match_operator 1 "comparison_operator"
955                          [(zero_extract:SI
956                            (match_operand:QI 2 "memory_operand" "m")
957                            (const_int 1)
958                            (match_operand 3 "const_int_operand" "n"))
959                           (const_int 0)])
960          (match_operand:SI 4 "reg_or_int5_operand" "rJ")
961          (match_operand:SI 5 "reg_or_0_operand" "rI")))]
962   "TARGET_V850E"
963   "tst1 %3,%2 ; cmov %c1,%4,%z5,%0"
964   [(set_attr "length" "8")
965    (set_attr "cc" "clobber")])
966
967 (define_insn "*movsicc_tst1_reversed"
968   [(set (match_operand:SI 0 "register_operand" "=r")
969         (if_then_else:SI
970          (match_operator 1 "comparison_operator"
971                          [(zero_extract:SI
972                            (match_operand:QI 2 "memory_operand" "m")
973                            (const_int 1)
974                            (match_operand 3 "const_int_operand" "n"))
975                           (const_int 0)])
976          (match_operand:SI 4 "reg_or_0_operand" "rI")
977          (match_operand:SI 5 "reg_or_int5_operand" "rJ")))]
978   "TARGET_V850E"
979   "tst1 %3,%2 ; cmov %C1,%5,%z4,%0"
980   [(set_attr "length" "8")
981    (set_attr "cc" "clobber")])
982
983 ;; Matching for sasf requires combining 4 instructions, so we provide a
984 ;; dummy pattern to match the first 3, which will always be turned into the
985 ;; second pattern by subsequent combining.  As above, we must include the
986 ;; comparison to avoid input reloads in an insn using cc0.
987
988 (define_insn "*sasf_1"
989   [(set (match_operand:SI 0 "register_operand" "")
990         (ior:SI (match_operator 1 "comparison_operator" [(cc0) (const_int 0)])
991                 (ashift:SI (match_operand:SI 2 "register_operand" "")
992                            (const_int 1))))]
993   "TARGET_V850E"
994   "* abort ();")
995
996 (define_insn "*sasf_2"
997   [(set (match_operand:SI 0 "register_operand" "=r")
998         (ior:SI
999          (match_operator 1 "comparison_operator"
1000                          [(match_operand:SI 3 "register_operand" "r")
1001                           (match_operand:SI 4 "reg_or_int5_operand" "rJ")])
1002          (ashift:SI (match_operand:SI 2 "register_operand" "0")
1003                     (const_int 1))))]
1004   "TARGET_V850E"
1005   "cmp %4,%3 ; sasf %c1,%0"
1006   [(set_attr "length" "6")
1007    (set_attr "cc" "clobber")])
1008
1009 (define_split
1010   [(set (match_operand:SI 0 "register_operand" "")
1011         (if_then_else:SI
1012          (match_operator 1 "comparison_operator"
1013                          [(match_operand:SI 4 "register_operand" "")
1014                           (match_operand:SI 5 "reg_or_int5_operand" "")])
1015          (match_operand:SI 2 "const_int_operand" "")
1016          (match_operand:SI 3 "const_int_operand" "")))]
1017   "TARGET_V850E
1018    && ((INTVAL (operands[2]) ^ INTVAL (operands[3])) == 1)
1019    && ((INTVAL (operands[2]) + INTVAL (operands[3])) != 1)
1020    && (GET_CODE (operands[5]) == CONST_INT
1021       || REGNO (operands[0]) != REGNO (operands[5]))
1022    && REGNO (operands[0]) != REGNO (operands[4])"
1023   [(set (match_dup 0) (match_dup 6))
1024    (set (match_dup 0)
1025         (ior:SI (match_op_dup 7 [(match_dup 4) (match_dup 5)])
1026                 (ashift:SI (match_dup 0) (const_int 1))))]
1027   "
1028 {
1029   operands[6] = GEN_INT (INTVAL (operands[2]) >> 1);
1030   if (INTVAL (operands[2]) & 0x1)
1031     operands[7] = operands[1];
1032   else
1033     operands[7] = gen_rtx (reverse_condition (GET_CODE (operands[1])),
1034                            GET_MODE (operands[1]), XEXP (operands[1], 0),
1035                            XEXP (operands[1], 1));
1036 }")
1037 ;; ---------------------------------------------------------------------
1038 ;; BYTE SWAP INSTRUCTIONS
1039 ;; ---------------------------------------------------------------------
1040
1041 (define_expand "rotlhi3"
1042   [(set (match_operand:HI 0 "register_operand" "")
1043         (rotate:HI (match_operand:HI 1 "register_operand" "")
1044                    (match_operand:HI 2 "const_int_operand" "")))]
1045   "TARGET_V850E"
1046   "
1047 {
1048   if (INTVAL (operands[2]) != 8)
1049     FAIL;
1050 }")
1051
1052 (define_insn "*rotlhi3_8"
1053   [(set (match_operand:HI 0 "register_operand" "=r")
1054         (rotate:HI (match_operand:HI 1 "register_operand" "r")
1055                    (const_int 8)))]
1056   "TARGET_V850E"
1057   "bsh %1,%0"
1058   [(set_attr "length" "4")
1059    (set_attr "cc" "clobber")])
1060
1061 (define_expand "rotlsi3"
1062   [(set (match_operand:SI 0 "register_operand" "")
1063         (rotate:SI (match_operand:SI 1 "register_operand" "")
1064                    (match_operand:SI 2 "const_int_operand" "")))]
1065   "TARGET_V850E"
1066   "
1067 {
1068   if (INTVAL (operands[2]) != 16)
1069     FAIL;
1070 }")
1071
1072 (define_insn "*rotlsi3_16"
1073   [(set (match_operand:SI 0 "register_operand" "=r")
1074         (rotate:SI (match_operand:SI 1 "register_operand" "r")
1075                    (const_int 16)))]
1076   "TARGET_V850E"
1077   "hsw %1,%0"
1078   [(set_attr "length" "4")
1079    (set_attr "cc" "clobber")])
1080 \f
1081 ;; ----------------------------------------------------------------------
1082 ;; JUMP INSTRUCTIONS
1083 ;; ----------------------------------------------------------------------
1084
1085 ;; Conditional jump instructions
1086
1087 (define_expand "ble"
1088   [(set (pc)
1089         (if_then_else (le (cc0)
1090                           (const_int 0))
1091                       (label_ref (match_operand 0 "" ""))
1092                       (pc)))]
1093   ""
1094   "")
1095
1096 (define_expand "bleu"
1097   [(set (pc)
1098         (if_then_else (leu (cc0)
1099                            (const_int 0))
1100                       (label_ref (match_operand 0 "" ""))
1101                       (pc)))]
1102   ""
1103   "")
1104
1105 (define_expand "bge"
1106   [(set (pc)
1107         (if_then_else (ge (cc0)
1108                           (const_int 0))
1109                       (label_ref (match_operand 0 "" ""))
1110                       (pc)))]
1111   ""
1112   "")
1113
1114 (define_expand "bgeu"
1115   [(set (pc)
1116         (if_then_else (geu (cc0)
1117                            (const_int 0))
1118                       (label_ref (match_operand 0 "" ""))
1119                       (pc)))]
1120   ""
1121   "")
1122
1123 (define_expand "blt"
1124   [(set (pc)
1125         (if_then_else (lt (cc0)
1126                           (const_int 0))
1127                       (label_ref (match_operand 0 "" ""))
1128                       (pc)))]
1129   ""
1130   "")
1131
1132 (define_expand "bltu"
1133   [(set (pc)
1134         (if_then_else (ltu (cc0)
1135                            (const_int 0))
1136                       (label_ref (match_operand 0 "" ""))
1137                       (pc)))]
1138   ""
1139   "")
1140
1141 (define_expand "bgt"
1142   [(set (pc)
1143         (if_then_else (gt (cc0)
1144                           (const_int 0))
1145                       (label_ref (match_operand 0 "" ""))
1146                       (pc)))]
1147   ""
1148   "")
1149
1150 (define_expand "bgtu"
1151   [(set (pc)
1152         (if_then_else (gtu (cc0)
1153                            (const_int 0))
1154                       (label_ref (match_operand 0 "" ""))
1155                       (pc)))]
1156   ""
1157   "")
1158
1159 (define_expand "beq"
1160   [(set (pc)
1161         (if_then_else (eq (cc0)
1162                           (const_int 0))
1163                       (label_ref (match_operand 0 "" ""))
1164                       (pc)))]
1165   ""
1166   "")
1167
1168 (define_expand "bne"
1169   [(set (pc)
1170         (if_then_else (ne (cc0)
1171                           (const_int 0))
1172                       (label_ref (match_operand 0 "" ""))
1173                       (pc)))]
1174   ""
1175   "")
1176
1177 (define_insn "*branch_normal"
1178   [(set (pc)
1179         (if_then_else (match_operator 1 "comparison_operator"
1180                                       [(cc0) (const_int 0)])
1181                       (label_ref (match_operand 0 "" ""))
1182                       (pc)))]
1183   ""
1184   "*
1185 {
1186   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1187       && (GET_CODE (operands[1]) == GT
1188           || GET_CODE (operands[1]) == GE
1189           || GET_CODE (operands[1]) == LE
1190           || GET_CODE (operands[1]) == LT))
1191     return 0;
1192
1193   if (get_attr_length (insn) == 2)
1194     return \"b%b1 %l0\";
1195   else
1196     return \"b%B1 .+6 ; jr %l0\";
1197 }"
1198  [(set (attr "length")
1199     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1200                       (const_int 256))
1201                   (const_int 2)
1202                   (const_int 6)))
1203   (set_attr "cc" "none")])
1204
1205 (define_insn "*branch_invert"
1206   [(set (pc)
1207         (if_then_else (match_operator 1 "comparison_operator"
1208                                       [(cc0) (const_int 0)])
1209                       (pc)
1210                       (label_ref (match_operand 0 "" ""))))]
1211   ""
1212   "*
1213 {
1214   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1215       && (GET_CODE (operands[1]) == GT
1216           || GET_CODE (operands[1]) == GE
1217           || GET_CODE (operands[1]) == LE
1218           || GET_CODE (operands[1]) == LT))
1219     return 0;
1220   if (get_attr_length (insn) == 2)
1221     return \"b%B1 %l0\";
1222   else
1223     return \"b%b1 .+6 ; jr %l0\";
1224 }"
1225  [(set (attr "length")
1226     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1227                       (const_int 256))
1228                   (const_int 2)
1229                   (const_int 6)))
1230   (set_attr "cc" "none")])
1231
1232 ;; Unconditional and other jump instructions.
1233
1234 (define_insn "jump"
1235   [(set (pc)
1236         (label_ref (match_operand 0 "" "")))]
1237   ""
1238   "*
1239 {
1240   if (get_attr_length (insn) == 2)
1241     return \"br %0\";
1242   else
1243     return \"jr %0\";
1244 }"
1245  [(set (attr "length")
1246     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1247                       (const_int 256))
1248                   (const_int 2)
1249                   (const_int 4)))
1250   (set_attr "cc" "none")])
1251
1252 (define_insn "indirect_jump"
1253   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1254   ""
1255   "jmp %0"
1256   [(set_attr "length" "2")
1257    (set_attr "cc" "none")])
1258
1259 (define_insn "tablejump"
1260   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1261    (use (label_ref (match_operand 1 "" "")))]
1262   ""
1263   "jmp  %0"
1264   [(set_attr "length" "2")
1265    (set_attr "cc" "none")])
1266
1267 (define_insn "switch"
1268   [(set (pc)
1269         (plus:SI
1270          (sign_extend:SI
1271           (mem:HI
1272            (plus:SI (ashift:SI (match_operand:SI 0 "register_operand" "r")
1273                                (const_int 1))
1274                     (label_ref (match_operand 1 "" "")))))
1275          (label_ref (match_dup 1))))]
1276   "TARGET_V850E"
1277   "switch %0"
1278   [(set_attr "length" "2")
1279    (set_attr "cc" "none")])
1280
1281 (define_expand "casesi"
1282   [(match_operand:SI 0 "register_operand" "")
1283    (match_operand:SI 1 "register_operand" "")
1284    (match_operand:SI 2 "register_operand" "")
1285    (match_operand 3 "" "") (match_operand 4 "" "")]
1286   ""
1287   "
1288 {
1289   rtx reg = gen_reg_rtx (SImode);
1290   rtx tableaddress = gen_reg_rtx (SImode);
1291   rtx mem;
1292
1293   /* Subtract the lower bound from the index.  */
1294   emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
1295   /* Compare the result against the number of table entries.  */
1296   emit_insn (gen_cmpsi (reg, operands[2]));
1297   /* Branch to the default label if out of range of the table.  */
1298   emit_jump_insn (gen_bgtu (operands[4]));
1299
1300   if (! TARGET_BIG_SWITCH && TARGET_V850E)
1301     {
1302       emit_jump_insn (gen_switch (reg, operands[3]));
1303       DONE;
1304     }
1305
1306   /* Shift index for the table array access.  */
1307   emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
1308   /* Load the table address into a pseudo.  */
1309   emit_insn (gen_movsi (tableaddress,
1310                         gen_rtx_LABEL_REF (Pmode, operands[3])));
1311   /* Add the table address to the index.  */
1312   emit_insn (gen_addsi3 (reg, reg, tableaddress));
1313   /* Load the table entry.  */
1314   mem = gen_rtx_MEM (CASE_VECTOR_MODE, reg);
1315   RTX_UNCHANGING_P (mem) = 1;
1316   if (! TARGET_BIG_SWITCH)
1317     {
1318       rtx reg2 = gen_reg_rtx (HImode);
1319       emit_insn (gen_movhi (reg2, mem));
1320       emit_insn (gen_extendhisi2 (reg, reg2));
1321     }
1322   else
1323     emit_insn (gen_movsi (reg, mem));
1324   /* Add the table address.  */
1325   emit_insn (gen_addsi3 (reg, reg, tableaddress));
1326   /* Branch to the switch label.  */
1327   emit_jump_insn (gen_tablejump (reg, operands[3]));
1328   DONE;
1329 }")
1330
1331 ;; Call subroutine with no return value.
1332
1333 (define_expand "call"
1334   [(call (match_operand:QI 0 "general_operand" "")
1335          (match_operand:SI 1 "general_operand" ""))]
1336   ""
1337   "
1338 {
1339   if (! call_address_operand (XEXP (operands[0], 0), QImode)
1340       || TARGET_LONG_CALLS)
1341     XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1342   if (TARGET_LONG_CALLS)
1343     emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));
1344   else
1345     emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
1346   
1347   DONE;
1348 }")
1349
1350 (define_insn "call_internal_short"
1351   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1352          (match_operand:SI 1 "general_operand" "g,g"))
1353    (clobber (reg:SI 31))]
1354   "! TARGET_LONG_CALLS"
1355   "@
1356   jarl %0,r31
1357   jarl .+4,r31 ; add 4,r31 ; jmp %0"
1358   [(set_attr "length" "4,8")]
1359 )
1360
1361 (define_insn "call_internal_long"
1362   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1363          (match_operand:SI 1 "general_operand" "g,g"))
1364    (clobber (reg:SI 31))]
1365   "TARGET_LONG_CALLS"
1366   "*
1367   {
1368   if (which_alternative == 0)
1369     {
1370       if (GET_CODE (operands[0]) == REG)
1371         return \"jarl %0,r31\";
1372       else
1373         return \"movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11\";
1374     }
1375   else
1376     return \"jarl .+4,r31 ; add 4,r31 ; jmp %0\";
1377   }"
1378   [(set_attr "length" "16,8")]
1379 )
1380
1381 ;; Call subroutine, returning value in operand 0
1382 ;; (which must be a hard register).
1383
1384 (define_expand "call_value"
1385   [(set (match_operand 0 "" "")
1386         (call (match_operand:QI 1 "general_operand" "")
1387               (match_operand:SI 2 "general_operand" "")))]
1388   ""
1389   "
1390 {
1391   if (! call_address_operand (XEXP (operands[1], 0), QImode)
1392       || TARGET_LONG_CALLS)
1393     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1394   if (TARGET_LONG_CALLS)
1395     emit_call_insn (gen_call_value_internal_long (operands[0],
1396                                                   XEXP (operands[1], 0),
1397                                                   operands[2]));
1398   else
1399     emit_call_insn (gen_call_value_internal_short (operands[0],
1400                                                    XEXP (operands[1], 0),
1401                                                    operands[2]));
1402   DONE;
1403 }")
1404
1405 (define_insn "call_value_internal_short"
1406   [(set (match_operand 0 "" "=r,r")
1407         (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1408               (match_operand:SI 2 "general_operand" "g,g")))
1409    (clobber (reg:SI 31))]
1410   "! TARGET_LONG_CALLS"
1411   "@
1412   jarl %1,r31
1413   jarl .+4,r31 ; add 4,r31 ; jmp %1"
1414   [(set_attr "length" "4,8")]
1415 )
1416
1417 (define_insn "call_value_internal_long"
1418   [(set (match_operand 0 "" "=r,r")
1419         (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1420               (match_operand:SI 2 "general_operand" "g,g")))
1421    (clobber (reg:SI 31))]
1422   "TARGET_LONG_CALLS"
1423   "*
1424   {
1425   if (which_alternative == 0)
1426     {
1427       if (GET_CODE (operands[1]) == REG)
1428         return \"jarl %1, r31\";
1429       else
1430       /* Reload can generate this pattern... */
1431         return \"movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11\";
1432     }
1433   else
1434     return \"jarl .+4, r31 ; add 4, r31 ; jmp %1\";
1435   }"
1436   [(set_attr "length" "16,8")]
1437 )
1438
1439 (define_insn "nop"
1440   [(const_int 0)]
1441   ""
1442   "nop"
1443   [(set_attr "length" "2")
1444    (set_attr "cc" "none")])
1445 \f
1446 ;; ----------------------------------------------------------------------
1447 ;; EXTEND INSTRUCTIONS
1448 ;; ----------------------------------------------------------------------
1449
1450 (define_insn ""
1451   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1452         (zero_extend:SI
1453          (match_operand:HI 1 "nonimmediate_operand" "0,r,T,m")))]
1454   "TARGET_V850E"
1455   "@
1456    zxh %0
1457    andi 65535,%1,%0
1458    sld.hu %1,%0
1459    ld.hu %1,%0"
1460   [(set_attr "length" "2,4,2,4")
1461    (set_attr "cc" "none_0hit,set_znv,none_0hit,none_0hit")])
1462
1463 (define_insn "zero_extendhisi2"
1464   [(set (match_operand:SI 0 "register_operand" "=r")
1465         (zero_extend:SI
1466          (match_operand:HI 1 "register_operand" "r")))]
1467   ""
1468   "andi 65535,%1,%0"
1469   [(set_attr "length" "4")
1470    (set_attr "cc" "set_znv")])
1471
1472 (define_insn ""
1473   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1474         (zero_extend:SI
1475          (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m")))]
1476   "TARGET_V850E"
1477   "@
1478    zxb %0
1479    andi 255,%1,%0
1480    sld.bu %1,%0
1481    ld.bu %1,%0"
1482   [(set_attr "length" "2,4,2,4")
1483    (set_attr "cc" "none_0hit,set_znv,none_0hit,none_0hit")])
1484
1485 (define_insn "zero_extendqisi2"
1486   [(set (match_operand:SI 0 "register_operand" "=r")
1487         (zero_extend:SI
1488          (match_operand:QI 1 "register_operand" "r")))]
1489   ""
1490   "andi 255,%1,%0"
1491   [(set_attr "length" "4")
1492    (set_attr "cc" "set_znv")])
1493
1494 ;;- sign extension instructions
1495
1496 ;; ??? The extendhisi2 pattern should not emit shifts for v850e?
1497
1498 (define_insn "*extendhisi_insn"
1499   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1500         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))]
1501   "TARGET_V850E"
1502   "@
1503    sxh %0
1504    sld.h %1,%0
1505    ld.h %1,%0"
1506   [(set_attr "length" "2,2,4")
1507    (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1508
1509 ;; ??? This is missing a sign extend from memory pattern to match the ld.h
1510 ;; instruction.
1511
1512 (define_expand "extendhisi2"
1513   [(set (match_dup 2)
1514         (ashift:SI (match_operand:HI 1 "register_operand" "")
1515                    (const_int 16)))
1516    (set (match_operand:SI 0 "register_operand" "")
1517        (ashiftrt:SI (match_dup 2)
1518                      (const_int 16)))]
1519   ""
1520   "
1521 {
1522   operands[1] = gen_lowpart (SImode, operands[1]);
1523   operands[2] = gen_reg_rtx (SImode);
1524 }")
1525
1526 ;; ??? The extendqisi2 pattern should not emit shifts for v850e?
1527
1528 (define_insn "*extendqisi_insn"
1529   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1530         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))]
1531   "TARGET_V850E"
1532   "@
1533    sxb %0
1534    sld.b %1,%0
1535    ld.b %1,%0"
1536   [(set_attr "length" "2,2,4")
1537    (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1538
1539 ;; ??? This is missing a sign extend from memory pattern to match the ld.b
1540 ;; instruction.
1541
1542 (define_expand "extendqisi2"
1543   [(set (match_dup 2)
1544         (ashift:SI (match_operand:QI 1 "register_operand" "")
1545                    (const_int 24)))
1546    (set (match_operand:SI 0 "register_operand" "")
1547         (ashiftrt:SI (match_dup 2)
1548                      (const_int 24)))]
1549   ""
1550   "
1551 {
1552   operands[1] = gen_lowpart (SImode, operands[1]);
1553   operands[2] = gen_reg_rtx (SImode);
1554 }")
1555 \f
1556 ;; ----------------------------------------------------------------------
1557 ;; SHIFTS
1558 ;; ----------------------------------------------------------------------
1559
1560 (define_insn "ashlsi3"
1561   [(set (match_operand:SI 0 "register_operand" "=r,r")
1562         (ashift:SI
1563          (match_operand:SI 1 "register_operand" "0,0")
1564          (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1565   ""
1566   "@
1567   shl %2,%0
1568   shl %2,%0"
1569   [(set_attr "length" "4,2")
1570    (set_attr "cc" "set_znv")])
1571
1572 (define_insn "lshrsi3"
1573   [(set (match_operand:SI 0 "register_operand" "=r,r")
1574         (lshiftrt:SI
1575          (match_operand:SI 1 "register_operand" "0,0")
1576          (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1577   ""
1578   "@
1579   shr %2,%0
1580   shr %2,%0"
1581   [(set_attr "length" "4,2")
1582    (set_attr "cc" "set_znv")])
1583
1584 (define_insn "ashrsi3"
1585   [(set (match_operand:SI 0 "register_operand" "=r,r")
1586         (ashiftrt:SI
1587          (match_operand:SI 1 "register_operand" "0,0")
1588          (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1589   ""
1590   "@
1591   sar %2,%0
1592   sar %2,%0"
1593   [(set_attr "length" "4,2")
1594    (set_attr "cc" "set_znv")])
1595
1596 ;; ----------------------------------------------------------------------
1597 ;; PROLOGUE/EPILOGUE
1598 ;; ----------------------------------------------------------------------
1599 (define_expand "prologue"
1600   [(const_int 0)]
1601   ""
1602   "expand_prologue (); DONE;")
1603
1604 (define_expand "epilogue"
1605   [(return)]
1606   ""
1607   "
1608 {
1609   /* Try to use the trivial return first.  Else use the
1610      full epilogue.  */
1611   if (0)
1612     emit_jump_insn (gen_return ());
1613   else
1614     expand_epilogue ();
1615   DONE;
1616 }")
1617
1618 (define_insn "return"
1619   [(return)]
1620   "reload_completed && compute_frame_size (get_frame_size (), (long *)0) == 0"
1621   "jmp [r31]"
1622   [(set_attr "length" "2")
1623    (set_attr "cc" "none")])
1624
1625 (define_insn "return_internal"
1626   [(return)
1627    (use (reg:SI 31))]
1628   ""
1629   "jmp [r31]"
1630   [(set_attr "length" "2")
1631    (set_attr "cc" "none")])
1632
1633
1634 \f
1635 ;; ----------------------------------------------------------------------
1636 ;; HELPER INSTRUCTIONS for saving the prologue and epilog registers
1637 ;; ----------------------------------------------------------------------
1638
1639 ;; This pattern will match a stack adjust RTX followed by any number of push
1640 ;; RTXs.  These RTXs will then be turned into a suitable call to a worker
1641 ;; function.
1642
1643 ;;
1644 ;; Actually, convert the RTXs into a PREPARE instruction.
1645 ;;
1646 (define_insn ""
1647  [(match_parallel 0 "pattern_is_ok_for_prepare"
1648    [(set (reg:SI 3)
1649          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1650     (set (mem:SI (plus:SI (reg:SI 3)
1651                           (match_operand:SI 2 "immediate_operand" "i")))
1652          (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
1653  "TARGET_PROLOG_FUNCTION && TARGET_V850E"
1654  "* return construct_prepare_instruction (operands[0]);
1655  "
1656  [(set_attr "length" "4")
1657   (set_attr "cc"     "none")])
1658
1659 (define_insn ""
1660  [(match_parallel 0 "pattern_is_ok_for_prologue"
1661    [(set (reg:SI 3)
1662          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1663     (set (mem:SI (plus:SI (reg:SI 3)
1664                            (match_operand:SI 2 "immediate_operand" "i")))
1665          (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
1666  "TARGET_PROLOG_FUNCTION"
1667  "* return construct_save_jarl (operands[0]);
1668  "
1669  [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
1670                                      (const_string "16")
1671                                      (const_string "4")))
1672   (set_attr "cc"     "clobber")])
1673
1674 ;;
1675 ;; Actually, turn the RTXs into a DISPOSE instruction.
1676 ;;
1677 (define_insn ""
1678  [(match_parallel 0 "pattern_is_ok_for_dispose"
1679    [(return)
1680     (set (reg:SI 3)
1681          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1682     (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
1683          (mem:SI (plus:SI (reg:SI 3)
1684                           (match_operand:SI 3 "immediate_operand" "i"))))])]
1685  "TARGET_PROLOG_FUNCTION && TARGET_V850E"
1686  "* return construct_dispose_instruction (operands[0]);
1687  "
1688  [(set_attr "length" "4")
1689   (set_attr "cc"     "none")])
1690
1691 ;; This pattern will match a return RTX followed by any number of pop RTXs
1692 ;; and possible a stack adjustment as well.  These RTXs will be turned into
1693 ;; a suitable call to a worker function.
1694
1695 (define_insn ""
1696 [(match_parallel 0 "pattern_is_ok_for_epilogue"
1697    [(return)
1698     (set (reg:SI 3)
1699          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1700     (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
1701          (mem:SI (plus:SI (reg:SI 3)
1702                           (match_operand:SI 3 "immediate_operand" "i"))))])]
1703  "TARGET_PROLOG_FUNCTION && TARGET_V850"
1704  "* return construct_restore_jr (operands[0]);
1705  "
1706  [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
1707                                      (const_string "12")
1708                                      (const_string "4")))
1709   (set_attr "cc"     "clobber")])
1710
1711 ;; Initialize an interrupt function.  Do not depend on TARGET_PROLOG_FUNCTION.
1712 (define_insn "callt_save_interrupt"
1713   [(unspec_volatile [(const_int 0)] 2)]
1714     "TARGET_V850E && !TARGET_DISABLE_CALLT"
1715     ;; The CALLT instruction stores the next address of CALLT to CTPC register
1716     ;; without saving its previous value.  So if the interrupt handler
1717     ;; or its caller could possibily execute the CALLT insn, save_interrupt 
1718     ;; MUST NOT be called via CALLT.
1719     "*
1720 {
1721   output_asm_insn (\"addi -24,   sp, sp\", operands);
1722   output_asm_insn (\"st.w r10,   12[sp]\", operands);
1723   output_asm_insn (\"stsr ctpc,  r10\",    operands);
1724   output_asm_insn (\"st.w r10,   16[sp]\", operands);
1725   output_asm_insn (\"stsr ctpsw, r10\",    operands);
1726   output_asm_insn (\"st.w r10,   20[sp]\", operands);
1727   output_asm_insn (\"callt ctoff(__callt_save_interrupt)\", operands);
1728   return \"\";
1729 }"
1730    [(set_attr "length" "26")
1731     (set_attr "cc" "none")])
1732
1733 (define_insn "callt_return_interrupt"
1734   [(unspec_volatile [(const_int 0)] 3)]
1735   "TARGET_V850E && !TARGET_DISABLE_CALLT"
1736   "callt ctoff(__callt_return_interrupt)"
1737   [(set_attr "length" "2")
1738    (set_attr "cc" "clobber")])
1739
1740 (define_insn "save_interrupt"
1741   [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16)))
1742    (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 30))
1743    (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 4))
1744    (set (mem:SI (plus:SI (reg:SI 3) (const_int  -8))) (reg:SI 1))
1745    (set (mem:SI (plus:SI (reg:SI 3) (const_int  -4))) (reg:SI 10))]
1746   ""
1747   "*
1748 {
1749   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1750     return \"add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10\";
1751   else
1752     {
1753       output_asm_insn (\"add   -16, sp\", operands);
1754       output_asm_insn (\"st.w  r10, 12[sp]\", operands);
1755       output_asm_insn (\"st.w  ep, 0[sp]\", operands);
1756       output_asm_insn (\"st.w  gp, 4[sp]\", operands);
1757       output_asm_insn (\"st.w  r1, 8[sp]\", operands);
1758       output_asm_insn (\"movhi hi(__ep), r0, ep\", operands);
1759       output_asm_insn (\"movea lo(__ep), ep, ep\", operands);
1760       output_asm_insn (\"movhi hi(__gp), r0, gp\", operands);
1761       output_asm_insn (\"movea lo(__gp), gp, gp\", operands);
1762       return \"\";
1763     }
1764 }"
1765   [(set (attr "length")
1766         (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1767                        (const_int 10)
1768                        (const_int 34)))
1769    (set_attr "cc" "clobber")])
1770   
1771 ;; Restore r1, r4, r10, and return from the interrupt
1772 (define_insn "return_interrupt"
1773   [(return)
1774    (set (reg:SI 3)  (plus:SI (reg:SI 3) (const_int 16)))
1775    (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
1776    (set (reg:SI 1)  (mem:SI (plus:SI (reg:SI 3) (const_int  8))))
1777    (set (reg:SI 4)  (mem:SI (plus:SI (reg:SI 3) (const_int  4))))
1778    (set (reg:SI 30) (mem:SI (reg:SI 3)))]
1779   ""
1780   "*
1781 {
1782   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1783     return \"jr __return_interrupt\";
1784   else 
1785     {
1786       output_asm_insn (\"ld.w 0[sp],  ep\",   operands);
1787       output_asm_insn (\"ld.w 4[sp],  gp\",   operands);
1788       output_asm_insn (\"ld.w 8[sp],  r1\",   operands);
1789       output_asm_insn (\"ld.w 12[sp], r10\", operands);
1790       output_asm_insn (\"addi 16, sp, sp\",   operands);
1791       output_asm_insn (\"reti\",            operands);
1792       return \"\";
1793     }
1794 }"
1795   [(set (attr "length")
1796         (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1797                        (const_int 4)
1798                        (const_int 24)))
1799    (set_attr "cc" "clobber")])
1800
1801 ;; Save all registers except for the registers saved in save_interrupt when
1802 ;; an interrupt function makes a call.
1803 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1804 ;; all of memory.  This blocks insns from being moved across this point.
1805 ;; This is needed because the rest of the compiler is not ready to handle
1806 ;; insns this complicated.
1807
1808 (define_insn "callt_save_all_interrupt"
1809   [(unspec_volatile [(const_int 0)] 0)]
1810   "TARGET_V850E && !TARGET_DISABLE_CALLT"
1811   "callt ctoff(__callt_save_all_interrupt)"
1812   [(set_attr "length" "2")
1813    (set_attr "cc" "none")])
1814
1815 (define_insn "save_all_interrupt"
1816   [(unspec_volatile [(const_int 0)] 0)]
1817   ""
1818   "*
1819 {
1820   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1821     return \"jarl __save_all_interrupt,r10\";
1822
1823   output_asm_insn (\"addi -120, sp, sp\", operands);
1824   output_asm_insn (\"mov ep, r1\", operands);
1825   output_asm_insn (\"mov sp, ep\", operands);
1826   output_asm_insn (\"sst.w r31, 116[ep]\", operands);
1827   output_asm_insn (\"sst.w r2,  112[ep]\", operands);
1828   output_asm_insn (\"sst.w gp,  108[ep]\", operands);
1829   output_asm_insn (\"sst.w r6,  104[ep]\", operands);
1830   output_asm_insn (\"sst.w r7,  100[ep]\", operands);
1831   output_asm_insn (\"sst.w r8,   96[ep]\", operands);
1832   output_asm_insn (\"sst.w r9,   92[ep]\", operands);
1833   output_asm_insn (\"sst.w r11,  88[ep]\", operands);
1834   output_asm_insn (\"sst.w r12,  84[ep]\", operands);
1835   output_asm_insn (\"sst.w r13,  80[ep]\", operands);
1836   output_asm_insn (\"sst.w r14,  76[ep]\", operands);
1837   output_asm_insn (\"sst.w r15,  72[ep]\", operands);
1838   output_asm_insn (\"sst.w r16,  68[ep]\", operands);
1839   output_asm_insn (\"sst.w r17,  64[ep]\", operands);
1840   output_asm_insn (\"sst.w r18,  60[ep]\", operands);
1841   output_asm_insn (\"sst.w r19,  56[ep]\", operands);
1842   output_asm_insn (\"sst.w r20,  52[ep]\", operands);
1843   output_asm_insn (\"sst.w r21,  48[ep]\", operands);
1844   output_asm_insn (\"sst.w r22,  44[ep]\", operands);
1845   output_asm_insn (\"sst.w r23,  40[ep]\", operands);
1846   output_asm_insn (\"sst.w r24,  36[ep]\", operands);
1847   output_asm_insn (\"sst.w r25,  32[ep]\", operands);
1848   output_asm_insn (\"sst.w r26,  28[ep]\", operands);
1849   output_asm_insn (\"sst.w r27,  24[ep]\", operands);
1850   output_asm_insn (\"sst.w r28,  20[ep]\", operands);
1851   output_asm_insn (\"sst.w r29,  16[ep]\", operands);
1852   output_asm_insn (\"mov   r1,   ep\", operands);
1853   return \"\";
1854 }"
1855   [(set (attr "length")
1856         (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1857                        (const_int 4)
1858                        (const_int 62)
1859         ))
1860    (set_attr "cc" "clobber")])
1861
1862 (define_insn "_save_all_interrupt"
1863   [(unspec_volatile [(const_int 0)] 0)]
1864   "TARGET_V850 && ! TARGET_LONG_CALLS"
1865   "jarl __save_all_interrupt,r10"
1866   [(set_attr "length" "4")
1867    (set_attr "cc" "clobber")])
1868
1869 ;; Restore all registers saved when an interrupt function makes a call.
1870 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1871 ;; all of memory.  This blocks insns from being moved across this point.
1872 ;; This is needed because the rest of the compiler is not ready to handle
1873 ;; insns this complicated.
1874
1875 (define_insn "callt_restore_all_interrupt"
1876   [(unspec_volatile [(const_int 0)] 1)]
1877   "TARGET_V850E && !TARGET_DISABLE_CALLT"
1878   "callt ctoff(__callt_restore_all_interrupt)"
1879   [(set_attr "length" "2")
1880    (set_attr "cc" "none")])
1881
1882 (define_insn "restore_all_interrupt"
1883   [(unspec_volatile [(const_int 0)] 1)]
1884   ""
1885   "*
1886 {
1887   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1888     return \"jarl __restore_all_interrupt,r10\";
1889   else
1890     {
1891       output_asm_insn (\"mov   ep,      r1\", operands);
1892       output_asm_insn (\"mov   sp,      ep\", operands);
1893       output_asm_insn (\"sld.w 116[ep], r31\", operands);
1894       output_asm_insn (\"sld.w 112[ep], r2\", operands);
1895       output_asm_insn (\"sld.w 108[ep], gp\", operands);
1896       output_asm_insn (\"sld.w 104[ep], r6\", operands);
1897       output_asm_insn (\"sld.w 100[ep], r7\", operands);
1898       output_asm_insn (\"sld.w 96[ep],  r8\", operands);
1899       output_asm_insn (\"sld.w 92[ep],  r9\", operands);
1900       output_asm_insn (\"sld.w 88[ep],  r11\", operands);
1901       output_asm_insn (\"sld.w 84[ep],  r12\", operands);
1902       output_asm_insn (\"sld.w 80[ep],  r13\", operands);
1903       output_asm_insn (\"sld.w 76[ep],  r14\", operands);
1904       output_asm_insn (\"sld.w 72[ep],  r15\", operands);
1905       output_asm_insn (\"sld.w 68[ep],  r16\", operands);
1906       output_asm_insn (\"sld.w 64[ep],  r17\", operands);
1907       output_asm_insn (\"sld.w 60[ep],  r18\", operands);
1908       output_asm_insn (\"sld.w 56[ep],  r19\", operands);
1909       output_asm_insn (\"sld.w 52[ep],  r20\", operands);
1910       output_asm_insn (\"sld.w 48[ep],  r21\", operands);
1911       output_asm_insn (\"sld.w 44[ep],  r22\", operands);
1912       output_asm_insn (\"sld.w 40[ep],  r23\", operands);
1913       output_asm_insn (\"sld.w 36[ep],  r24\", operands);
1914       output_asm_insn (\"sld.w 32[ep],  r25\", operands);
1915       output_asm_insn (\"sld.w 28[ep],  r26\", operands);
1916       output_asm_insn (\"sld.w 24[ep],  r27\", operands);
1917       output_asm_insn (\"sld.w 20[ep],  r28\", operands);
1918       output_asm_insn (\"sld.w 16[ep],  r29\", operands);
1919       output_asm_insn (\"mov   r1,      ep\", operands);
1920       output_asm_insn (\"addi  120, sp, sp\", operands);
1921       return \"\";
1922     }
1923 }"
1924   [(set (attr "length")
1925         (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1926                        (const_int 4)
1927                        (const_int 62)
1928         ))
1929    (set_attr "cc" "clobber")])
1930
1931 (define_insn "_restore_all_interrupt"
1932   [(unspec_volatile [(const_int 0)] 1)]
1933   "TARGET_V850 && ! TARGET_LONG_CALLS"
1934   "jarl __restore_all_interrupt,r10"
1935   [(set_attr "length" "4")
1936    (set_attr "cc" "clobber")])
1937
1938 ;; Save r6-r9 for a variable argument function
1939 (define_insn "save_r6_r9_v850e"
1940   [(set (mem:SI (reg:SI 3)) (reg:SI 6))
1941    (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
1942    (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
1943    (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
1944   ]
1945   "TARGET_PROLOG_FUNCTION && TARGET_V850E && !TARGET_DISABLE_CALLT"
1946   "callt ctoff(__callt_save_r6_r9)"
1947   [(set_attr "length" "2")
1948    (set_attr "cc" "none")])
1949
1950 (define_insn "save_r6_r9"
1951   [(set (mem:SI (reg:SI 3)) (reg:SI 6))
1952    (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
1953    (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
1954    (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
1955    (clobber (reg:SI 10))]
1956   "TARGET_PROLOG_FUNCTION && ! TARGET_LONG_CALLS"
1957   "jarl __save_r6_r9,r10"
1958   [(set_attr "length" "4")
1959    (set_attr "cc" "clobber")])
1960