OSDN Git Service

* config/v850/v850.md (casesi): Generate LABEL_REF
[pf3gnuchains/gcc-fork.git] / gcc / config / v850 / v850.md
1 ;; GCC machine description for NEC V850
2 ;; Copyright (C) 1996, 1997, 1998, 1999 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       && !special_symbolref_operand (operands[1], VOIDmode)
157       && !(GET_CODE (operands[1]) == CONST_INT
158            && (CONST_OK_FOR_J (INTVAL (operands[1]))
159                || CONST_OK_FOR_K (INTVAL (operands[1]))
160                || CONST_OK_FOR_L (INTVAL (operands[1])))))
161     {
162       rtx temp;
163
164       if (reload_in_progress || reload_completed)
165         temp = operands[0];
166       else
167         temp = gen_reg_rtx (SImode);
168
169       emit_insn (gen_rtx_SET (SImode, temp,
170                               gen_rtx_HIGH (SImode, operand1)));
171       emit_insn (gen_rtx_SET (SImode, operand0,
172                               gen_rtx_LO_SUM (SImode, temp, operand1)));
173       DONE;
174     }
175 }")
176
177 (define_insn "*movsi_internal"
178   [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m")
179         (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))]
180   "register_operand (operands[0], SImode)
181    || reg_or_0_operand (operands[1], SImode)"
182   "* return output_move_single (operands);"
183   [(set_attr "length" "2,4,4,2,2,4,4,4,4")
184    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
185    (set_attr "type" "other,other,other,load,other,load,other,other,other")])
186
187
188
189 (define_expand "movdi"
190   [(set (match_operand:DI 0 "general_operand" "")
191         (match_operand:DI 1 "general_operand" ""))]
192   ""
193   "
194 {
195   /* One of the ops has to be in a register or 0 */
196   if (!register_operand (operand0, DImode)
197       && !reg_or_0_operand (operand1, DImode))
198     operands[1] = copy_to_mode_reg (DImode, operand1);
199 }")
200
201 (define_insn "*movdi_internal"
202   [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,m,r")
203         (match_operand:DI 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
204   "register_operand (operands[0], DImode)
205    || reg_or_0_operand (operands[1], DImode)"
206   "* return output_move_double (operands);"
207   [(set_attr "length" "4,8,8,16,8,8,8,16")
208    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
209    (set_attr "type" "other,other,other,other,load,other,other,other")])
210
211 (define_expand "movsf"
212   [(set (match_operand:SF 0 "general_operand" "")
213         (match_operand:SF 1 "general_operand" ""))]
214   ""
215   "
216 {
217   /* One of the ops has to be in a register or 0 */
218   if (!register_operand (operand0, SFmode)
219       && !reg_or_0_operand (operand1, SFmode))
220     operands[1] = copy_to_mode_reg (SFmode, operand1);
221 }")
222
223 (define_insn "*movsf_internal"
224   [(set (match_operand:SF 0 "general_operand" "=r,r,r,r,r,Q,r,m,m,r")
225         (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))]
226   "register_operand (operands[0], SFmode)
227    || reg_or_0_operand (operands[1], SFmode)"
228   "* return output_move_single (operands);"
229   [(set_attr "length" "2,4,4,8,2,2,4,4,4,8")
230    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
231    (set_attr "type" "other,other,other,other,load,other,load,other,other,other")])
232
233 (define_expand "movdf"
234   [(set (match_operand:DF 0 "general_operand" "")
235         (match_operand:DF 1 "general_operand" ""))]
236   ""
237   "
238 {
239   /* One of the ops has to be in a register or 0 */
240   if (!register_operand (operand0, DFmode)
241       && !reg_or_0_operand (operand1, DFmode))
242     operands[1] = copy_to_mode_reg (DFmode, operand1);
243 }")
244
245 (define_insn "*movdf_internal"
246   [(set (match_operand:DF 0 "general_operand" "=r,r,r,r,r,m,m,r")
247         (match_operand:DF 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
248   "register_operand (operands[0], DFmode)
249    || reg_or_0_operand (operands[1], DFmode)"
250   "* return output_move_double (operands);"
251   [(set_attr "length" "4,8,8,16,8,8,8,16")
252    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
253    (set_attr "type" "other,other,other,other,load,other,other,other")])
254
255 \f
256 ;; ----------------------------------------------------------------------
257 ;; TEST INSTRUCTIONS
258 ;; ----------------------------------------------------------------------
259
260 (define_insn "*v850_tst1"
261   [(set (cc0) (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
262                                (const_int 1)
263                                (match_operand:QI 1 "const_int_operand" "n")))]
264   ""
265   "tst1 %1,%0"
266   [(set_attr "length" "4")
267    (set_attr "cc" "clobber")])
268
269 ;; This replaces ld.b;sar;andi with tst1;setf nz.
270
271 ;; ??? The zero_extract sets the Z bit to the opposite of what one would
272 ;; expect.  This perhaps should be wrapped in a (eq: X (const_int 0)).
273
274 (define_split
275   [(set (match_operand:SI 0 "register_operand" "")
276         (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
277                          (const_int 1)
278                          (match_operand 2 "const_int_operand" "")))]
279   ""
280   [(set (cc0) (zero_extract:SI (match_dup 1)
281                                (const_int 1)
282                                (match_dup 2)))
283    (set (match_dup 0) (ne:SI (cc0) (const_int 0)))])
284
285 (define_insn "tstsi"
286   [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
287   ""
288   "cmp %.,%0"
289   [(set_attr "length" "2")
290    (set_attr "cc" "set_znv")])
291
292 (define_insn "cmpsi"
293   [(set (cc0)
294         (compare (match_operand:SI 0 "register_operand" "r,r")
295                  (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
296   ""
297   "@
298   cmp %1,%0
299   cmp %1,%0"
300   [(set_attr "length" "2,2")
301    (set_attr "cc" "compare")])
302 \f
303 ;; ----------------------------------------------------------------------
304 ;; ADD INSTRUCTIONS
305 ;; ----------------------------------------------------------------------
306
307 (define_insn "addsi3"
308   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
309         (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
310                  (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))]
311   ""
312   "@
313    add %2,%0
314    addi %2,%1,%0
315    addi %O2(%P2),%1,%0"
316   [(set_attr "length" "2,4,4")
317    (set_attr "cc" "set_zn,set_zn,set_zn")])
318
319 ;; ----------------------------------------------------------------------
320 ;; SUBTRACT INSTRUCTIONS
321 ;; ----------------------------------------------------------------------
322
323 (define_insn "subsi3"
324   [(set (match_operand:SI 0 "register_operand" "=r,r")
325         (minus:SI (match_operand:SI 1 "register_operand" "0,r")
326                   (match_operand:SI 2 "register_operand" "r,0")))]
327   ""
328   "@
329   sub %2,%0
330   subr %1,%0"
331   [(set_attr "length" "2,2")
332    (set_attr "cc" "set_zn")])
333
334 (define_insn "negsi2"
335   [(set (match_operand:SI 0 "register_operand" "=r")
336         (neg:SI (match_operand:SI 1 "register_operand" "0")))]
337   ""
338   "subr %.,%0"
339   [(set_attr "length" "2")
340    (set_attr "cc" "set_zn")])
341
342 ;; ----------------------------------------------------------------------
343 ;; MULTIPLY INSTRUCTIONS
344 ;; ----------------------------------------------------------------------
345
346 (define_expand "mulhisi3"
347   [(set (match_operand:SI 0 "register_operand" "")
348         (mult:SI
349           (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
350           (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
351   ""
352   "")
353
354 (define_insn "*mulhisi3_internal1"
355   [(set (match_operand:SI 0 "register_operand" "=r")
356         (mult:SI
357           (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
358           (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
359   ""
360   "mulh %2,%0"
361   [(set_attr "length" "2")
362    (set_attr "cc" "none_0hit")
363    (set_attr "type" "mult")])
364
365 ;; ??? Sign extending constants isn't valid.  Fix?
366
367 (define_insn "*mulhisi3_internal2"
368   [(set (match_operand:SI 0 "register_operand" "=r,r")
369         (mult:SI
370           (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
371           (sign_extend:SI (match_operand 2 "const_int_operand" "J,K"))))]
372   ""
373   "@
374    mulh %2,%0
375    mulhi %2,%1,%0"
376   [(set_attr "length" "2,4")
377    (set_attr "cc" "none_0hit,none_0hit")
378    (set_attr "type" "mult")])
379
380 \f
381 ;; ----------------------------------------------------------------------
382 ;; AND INSTRUCTIONS
383 ;; ----------------------------------------------------------------------
384
385 (define_insn "*v850_clr1_1"
386   [(set (match_operand:QI 0 "memory_operand" "=m")
387         (subreg:QI
388           (and:SI (subreg:SI (match_dup 0) 0)
389                   (match_operand:QI 1 "not_power_of_two_operand" "")) 0))]
390   ""
391   "*
392 {
393   rtx xoperands[2];
394   xoperands[0] = operands[0];
395   xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
396   output_asm_insn (\"clr1 %M1,%0\", xoperands);
397   return \"\";
398 }"
399   [(set_attr "length" "4")
400    (set_attr "cc" "clobber")])
401
402 (define_insn "*v850_clr1_2"
403   [(set (match_operand:HI 0 "indirect_operand" "=m")
404         (subreg:HI
405           (and:SI (subreg:SI (match_dup 0) 0)
406                   (match_operand:HI 1 "not_power_of_two_operand" "")) 0))]
407   ""
408   "*
409 {
410   int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
411
412   rtx xoperands[2];
413   xoperands[0] = gen_rtx_MEM (QImode,
414                               plus_constant (XEXP (operands[0], 0), log2 / 8));
415   xoperands[1] = GEN_INT (log2 % 8);
416   output_asm_insn (\"clr1 %1,%0\", xoperands);
417   return \"\";
418 }"
419   [(set_attr "length" "4")
420    (set_attr "cc" "clobber")])
421
422 (define_insn "*v850_clr1_3"
423   [(set (match_operand:SI 0 "indirect_operand" "=m")
424         (and:SI (match_dup 0)
425                 (match_operand:SI 1 "not_power_of_two_operand" "")))]
426   ""
427   "*
428 {
429   int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
430
431   rtx xoperands[2];
432   xoperands[0] = gen_rtx_MEM (QImode,
433                               plus_constant (XEXP (operands[0], 0), log2 / 8));
434   xoperands[1] = GEN_INT (log2 % 8);
435   output_asm_insn (\"clr1 %1,%0\", xoperands);
436   return \"\";
437 }"
438   [(set_attr "length" "4")
439    (set_attr "cc" "clobber")])
440
441 (define_insn "andsi3"
442   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
443         (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
444                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
445   ""
446   "@
447   and %2,%0
448   and %.,%0
449   andi %2,%1,%0"
450   [(set_attr "length" "2,2,4")
451    (set_attr "cc" "set_znv")])
452
453 ;; ----------------------------------------------------------------------
454 ;; OR INSTRUCTIONS
455 ;; ----------------------------------------------------------------------
456
457 (define_insn "*v850_set1_1"
458   [(set (match_operand:QI 0 "memory_operand" "=m")
459         (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
460                            (match_operand 1 "power_of_two_operand" "")) 0))]
461   ""
462   "set1 %M1,%0"
463   [(set_attr "length" "4")
464    (set_attr "cc" "clobber")])
465
466 (define_insn "*v850_set1_2"
467   [(set (match_operand:HI 0 "indirect_operand" "=m")
468         (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
469                            (match_operand 1 "power_of_two_operand" "")) 0))]
470   ""
471   "*
472 {
473   int log2 = exact_log2 (INTVAL (operands[1]));
474
475   if (log2 < 8)
476     return \"set1 %M1,%0\";
477   else
478     {
479       rtx xoperands[2];
480       xoperands[0] = gen_rtx_MEM (QImode,
481                                   plus_constant (XEXP (operands[0], 0),
482                                                  log2 / 8));
483       xoperands[1] = GEN_INT (log2 % 8);
484       output_asm_insn (\"set1 %1,%0\", xoperands);
485     }
486   return \"\";
487 }"
488   [(set_attr "length" "4")
489    (set_attr "cc" "clobber")])
490
491 (define_insn "*v850_set1_3"
492   [(set (match_operand:SI 0 "indirect_operand" "=m")
493         (ior:SI (match_dup 0)
494                 (match_operand 1 "power_of_two_operand" "")))]
495   ""
496   "*
497 {
498   int log2 = exact_log2 (INTVAL (operands[1]));
499
500   if (log2 < 8)
501     return \"set1 %M1,%0\";
502   else
503     {
504       rtx xoperands[2];
505       xoperands[0] = gen_rtx_MEM (QImode,
506                                   plus_constant (XEXP (operands[0], 0),
507                                                  log2 / 8));
508       xoperands[1] = GEN_INT (log2 % 8);
509       output_asm_insn (\"set1 %1,%0\", xoperands);
510     }
511   return \"\";
512 }"
513   [(set_attr "length" "4")
514    (set_attr "cc" "clobber")])
515
516 (define_insn "iorsi3"
517   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
518         (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
519                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
520   ""
521   "@
522   or %2,%0
523   or %.,%0
524   ori %2,%1,%0"
525   [(set_attr "length" "2,2,4")
526    (set_attr "cc" "set_znv")])
527
528 ;; ----------------------------------------------------------------------
529 ;; XOR INSTRUCTIONS
530 ;; ----------------------------------------------------------------------
531
532 (define_insn "*v850_not1_1"
533   [(set (match_operand:QI 0 "memory_operand" "=m")
534         (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0)
535                            (match_operand 1 "power_of_two_operand" "")) 0))]
536   ""
537   "not1 %M1,%0"
538   [(set_attr "length" "4")
539    (set_attr "cc" "clobber")])
540
541 (define_insn "*v850_not1_2"
542   [(set (match_operand:HI 0 "indirect_operand" "=m")
543         (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
544                            (match_operand 1 "power_of_two_operand" "")) 0))]
545   ""
546   "*
547 {
548   int log2 = exact_log2 (INTVAL (operands[1]));
549
550   if (log2 < 8)
551     return \"not1 %M1,%0\";
552   else
553     {
554       rtx xoperands[2];
555       xoperands[0] = gen_rtx_MEM (QImode,
556                                   plus_constant (XEXP (operands[0], 0),
557                                                  log2 / 8));
558       xoperands[1] = GEN_INT (log2 % 8);
559       output_asm_insn (\"not1 %1,%0\", xoperands);
560     }
561   return \"\";
562 }"
563   [(set_attr "length" "4")
564    (set_attr "cc" "clobber")])
565
566 (define_insn "*v850_not1_3"
567   [(set (match_operand:SI 0 "indirect_operand" "=m")
568         (xor:SI (match_dup 0)
569                 (match_operand 1 "power_of_two_operand" "")))]
570   ""
571   "*
572 {
573   int log2 = exact_log2 (INTVAL (operands[1]));
574
575   if (log2 < 8)
576     return \"not1 %M1,%0\";
577   else
578     {
579       rtx xoperands[2];
580       xoperands[0] = gen_rtx_MEM (QImode,
581                                   plus_constant (XEXP (operands[0], 0),
582                                                  log2 / 8));
583       xoperands[1] = GEN_INT (log2 % 8);
584       output_asm_insn (\"not1 %1,%0\", xoperands);
585     }
586   return \"\";
587 }"
588   [(set_attr "length" "4")
589    (set_attr "cc" "clobber")])
590
591 (define_insn "xorsi3"
592   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
593         (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
594                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
595   ""
596   "@
597   xor %2,%0
598   xor %.,%0
599   xori %2,%1,%0"
600   [(set_attr "length" "2,2,4")
601    (set_attr "cc" "set_znv")])
602 \f
603 ;; ----------------------------------------------------------------------
604 ;; NOT INSTRUCTIONS
605 ;; ----------------------------------------------------------------------
606
607 (define_insn "one_cmplsi2"
608   [(set (match_operand:SI 0 "register_operand" "=r")
609         (not:SI (match_operand:SI 1 "register_operand" "r")))]
610   ""
611   "not %1,%0"
612   [(set_attr "length" "2")
613    (set_attr "cc" "set_znv")])
614 \f
615 ;; -----------------------------------------------------------------
616 ;; BIT FIELDS
617 ;; -----------------------------------------------------------------
618
619 ;; ??? Is it worth defining insv and extv for the V850 series?!?
620
621 ;; An insv pattern would be useful, but does not get used because
622 ;; store_bit_field never calls insv when storing a constant value into a
623 ;; single-bit bitfield.
624
625 ;; extv/extzv patterns would be useful, but do not get used because
626 ;; optimize_bitfield_compare in fold-const usually converts single
627 ;; bit extracts into an AND with a mask.
628
629 ;; -----------------------------------------------------------------
630 ;; Scc INSTRUCTIONS
631 ;; -----------------------------------------------------------------
632
633 (define_insn "sle"
634   [(set (match_operand:SI 0 "register_operand" "=r")
635         (le:SI (cc0) (const_int 0)))]
636   ""
637   "*
638 {
639   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
640     return 0;
641
642   return \"setf le,%0\";
643 }"
644   [(set_attr "length" "4")
645    (set_attr "cc" "none_0hit")])
646
647 (define_insn "sleu"
648   [(set (match_operand:SI 0 "register_operand" "=r")
649         (leu:SI (cc0) (const_int 0)))]
650   ""
651   "setf nh,%0"
652   [(set_attr "length" "4")
653    (set_attr "cc" "none_0hit")])
654
655 (define_insn "sge"
656   [(set (match_operand:SI 0 "register_operand" "=r")
657         (ge:SI (cc0) (const_int 0)))]
658   ""
659   "*
660 {
661   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
662     return 0;
663
664   return \"setf ge,%0\";
665 }"
666   [(set_attr "length" "4")
667    (set_attr "cc" "none_0hit")])
668
669 (define_insn "sgeu"
670   [(set (match_operand:SI 0 "register_operand" "=r")
671         (geu:SI (cc0) (const_int 0)))]
672   ""
673   "setf nl,%0"
674   [(set_attr "length" "4")
675    (set_attr "cc" "none_0hit")])
676
677 (define_insn "slt"
678   [(set (match_operand:SI 0 "register_operand" "=r")
679         (lt:SI (cc0) (const_int 0)))]
680   ""
681   "*
682 {
683   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
684     return 0;
685
686   return \"setf lt,%0\";
687 }"
688   [(set_attr "length" "4")
689    (set_attr "cc" "none_0hit")])
690
691 (define_insn "sltu"
692   [(set (match_operand:SI 0 "register_operand" "=r")
693         (ltu:SI (cc0) (const_int 0)))]
694   ""
695   "setf l,%0"
696   [(set_attr "length" "4")
697    (set_attr "cc" "none_0hit")])
698
699 (define_insn "sgt"
700   [(set (match_operand:SI 0 "register_operand" "=r")
701         (gt:SI (cc0) (const_int 0)))]
702   ""
703   "*
704 {
705   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
706     return 0;
707
708   return \"setf gt,%0\";
709 }"
710   [(set_attr "length" "4")
711    (set_attr "cc" "none_0hit")])
712
713 (define_insn "sgtu"
714   [(set (match_operand:SI 0 "register_operand" "=r")
715         (gtu:SI (cc0) (const_int 0)))]
716   ""
717   "setf h,%0"
718   [(set_attr "length" "4")
719    (set_attr "cc" "none_0hit")])
720
721 (define_insn "seq"
722   [(set (match_operand:SI 0 "register_operand" "=r")
723         (eq:SI (cc0) (const_int 0)))]
724   ""
725   "setf z,%0"
726   [(set_attr "length" "4")
727    (set_attr "cc" "none_0hit")])
728
729 (define_insn "sne"
730   [(set (match_operand:SI 0 "register_operand" "=r")
731         (ne:SI (cc0) (const_int 0)))]
732   ""
733   "setf nz,%0"
734   [(set_attr "length" "4")
735    (set_attr "cc" "none_0hit")])
736
737 \f
738 ;; ----------------------------------------------------------------------
739 ;; JUMP INSTRUCTIONS
740 ;; ----------------------------------------------------------------------
741
742 ;; Conditional jump instructions
743
744 (define_expand "ble"
745   [(set (pc)
746         (if_then_else (le (cc0)
747                           (const_int 0))
748                       (label_ref (match_operand 0 "" ""))
749                       (pc)))]
750   ""
751   "")
752
753 (define_expand "bleu"
754   [(set (pc)
755         (if_then_else (leu (cc0)
756                            (const_int 0))
757                       (label_ref (match_operand 0 "" ""))
758                       (pc)))]
759   ""
760   "")
761
762 (define_expand "bge"
763   [(set (pc)
764         (if_then_else (ge (cc0)
765                           (const_int 0))
766                       (label_ref (match_operand 0 "" ""))
767                       (pc)))]
768   ""
769   "")
770
771 (define_expand "bgeu"
772   [(set (pc)
773         (if_then_else (geu (cc0)
774                            (const_int 0))
775                       (label_ref (match_operand 0 "" ""))
776                       (pc)))]
777   ""
778   "")
779
780 (define_expand "blt"
781   [(set (pc)
782         (if_then_else (lt (cc0)
783                           (const_int 0))
784                       (label_ref (match_operand 0 "" ""))
785                       (pc)))]
786   ""
787   "")
788
789 (define_expand "bltu"
790   [(set (pc)
791         (if_then_else (ltu (cc0)
792                            (const_int 0))
793                       (label_ref (match_operand 0 "" ""))
794                       (pc)))]
795   ""
796   "")
797
798 (define_expand "bgt"
799   [(set (pc)
800         (if_then_else (gt (cc0)
801                           (const_int 0))
802                       (label_ref (match_operand 0 "" ""))
803                       (pc)))]
804   ""
805   "")
806
807 (define_expand "bgtu"
808   [(set (pc)
809         (if_then_else (gtu (cc0)
810                            (const_int 0))
811                       (label_ref (match_operand 0 "" ""))
812                       (pc)))]
813   ""
814   "")
815
816 (define_expand "beq"
817   [(set (pc)
818         (if_then_else (eq (cc0)
819                           (const_int 0))
820                       (label_ref (match_operand 0 "" ""))
821                       (pc)))]
822   ""
823   "")
824
825 (define_expand "bne"
826   [(set (pc)
827         (if_then_else (ne (cc0)
828                           (const_int 0))
829                       (label_ref (match_operand 0 "" ""))
830                       (pc)))]
831   ""
832   "")
833
834 (define_insn "*branch_normal"
835   [(set (pc)
836         (if_then_else (match_operator 1 "comparison_operator"
837                                       [(cc0) (const_int 0)])
838                       (label_ref (match_operand 0 "" ""))
839                       (pc)))]
840   ""
841   "*
842 {
843   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
844       && (GET_CODE (operands[1]) == GT
845           || GET_CODE (operands[1]) == GE
846           || GET_CODE (operands[1]) == LE
847           || GET_CODE (operands[1]) == LT))
848     return 0;
849
850   if (get_attr_length (insn) == 2)
851     return \"b%b1 %l0\";
852   else
853     return \"b%B1 .+6 ; jr %l0\";
854 }"
855  [(set (attr "length")
856     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
857                       (const_int 256))
858                   (const_int 2)
859                   (const_int 6)))
860   (set_attr "cc" "none")])
861
862 (define_insn "*branch_invert"
863   [(set (pc)
864         (if_then_else (match_operator 1 "comparison_operator"
865                                       [(cc0) (const_int 0)])
866                       (pc)
867                       (label_ref (match_operand 0 "" ""))))]
868   ""
869   "*
870 {
871   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
872       && (GET_CODE (operands[1]) == GT
873           || GET_CODE (operands[1]) == GE
874           || GET_CODE (operands[1]) == LE
875           || GET_CODE (operands[1]) == LT))
876     return 0;
877   if (get_attr_length (insn) == 2)
878     return \"b%B1 %l0\";
879   else
880     return \"b%b1 .+6 ; jr %l0\";
881 }"
882  [(set (attr "length")
883     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
884                       (const_int 256))
885                   (const_int 2)
886                   (const_int 6)))
887   (set_attr "cc" "none")])
888
889 ;; Unconditional and other jump instructions.
890
891 (define_insn "jump"
892   [(set (pc)
893         (label_ref (match_operand 0 "" "")))]
894   ""
895   "*
896 {
897   if (get_attr_length (insn) == 2)
898     return \"br %0\";
899   else
900     return \"jr %0\";
901 }"
902  [(set (attr "length")
903     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
904                       (const_int 256))
905                   (const_int 2)
906                   (const_int 4)))
907   (set_attr "cc" "none")])
908
909 (define_insn "indirect_jump"
910   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
911   ""
912   "jmp %0"
913   [(set_attr "length" "2")
914    (set_attr "cc" "none")])
915
916 (define_insn "tablejump"
917   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
918    (use (label_ref (match_operand 1 "" "")))]
919   ""
920   "jmp  %0"
921   [(set_attr "length" "2")
922    (set_attr "cc" "none")])
923
924 (define_expand "casesi"
925   [(match_operand:SI 0 "register_operand" "")
926    (match_operand:SI 1 "register_operand" "")
927    (match_operand:SI 2 "register_operand" "")
928    (match_operand 3 "" "") (match_operand 4 "" "")]
929   ""
930   "
931 {
932   rtx reg = gen_reg_rtx (SImode);
933   rtx tableaddress = gen_reg_rtx (SImode);
934   rtx mem;
935
936   /* Subtract the lower bound from the index.  */
937   emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
938   /* Compare the result against the number of table entries.  */
939   emit_insn (gen_cmpsi (reg, operands[2]));
940   /* Branch to the default label if out of range of the table.  */
941   emit_jump_insn (gen_bgtu (operands[4]));
942
943   /* Shift index for the table array access.  */
944   emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
945   /* Load the table address into a pseudo.  */
946   emit_insn (gen_movsi (tableaddress,
947                         gen_rtx_LABEL_REF (Pmode, operands[3])));
948   /* Add the table address to the index.  */
949   emit_insn (gen_addsi3 (reg, reg, tableaddress));
950   /* Load the table entry.  */
951   mem = gen_rtx_MEM (CASE_VECTOR_MODE, reg);
952   RTX_UNCHANGING_P (mem) = 1;
953   if (! TARGET_BIG_SWITCH)
954     {
955       rtx reg2 = gen_reg_rtx (HImode);
956       emit_insn (gen_movhi (reg2, mem));
957       emit_insn (gen_extendhisi2 (reg, reg2));
958     }
959   else
960     emit_insn (gen_movsi (reg, mem));
961   /* Add the table address.  */
962   emit_insn (gen_addsi3 (reg, reg, tableaddress));
963   /* Branch to the switch label.  */
964   emit_jump_insn (gen_tablejump (reg, operands[3]));
965   DONE;
966 }")
967
968 ;; Call subroutine with no return value.
969
970 (define_expand "call"
971   [(call (match_operand:QI 0 "general_operand" "")
972          (match_operand:SI 1 "general_operand" ""))]
973   ""
974   "
975 {
976   if (! call_address_operand (XEXP (operands[0], 0), QImode)
977       || TARGET_LONG_CALLS)
978     XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
979   if (TARGET_LONG_CALLS)
980     emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));
981   else
982     emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
983   
984   DONE;
985 }")
986
987 (define_insn "call_internal_short"
988   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
989          (match_operand:SI 1 "general_operand" "g,g"))
990    (clobber (reg:SI 31))]
991   "! TARGET_LONG_CALLS"
992   "@
993   jarl %0,r31
994   jarl .+4,r31 ; add 4,r31 ; jmp %0"
995   [(set_attr "length" "4,8")]
996 )
997
998 (define_insn "call_internal_long"
999   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1000          (match_operand:SI 1 "general_operand" "g,g"))
1001    (clobber (reg:SI 31))]
1002   "TARGET_LONG_CALLS"
1003   "*
1004   {
1005   if (which_alternative == 0)
1006     {
1007       if (GET_CODE (operands[0]) == REG)
1008         return \"jarl %0,r31\";
1009       else
1010         return \"movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11\";
1011     }
1012   else
1013     return \"jarl .+4,r31 ; add 4,r31 ; jmp %0\";
1014   }"
1015   [(set_attr "length" "16,8")]
1016 )
1017
1018 ;; Call subroutine, returning value in operand 0
1019 ;; (which must be a hard register).
1020
1021 (define_expand "call_value"
1022   [(set (match_operand 0 "" "")
1023         (call (match_operand:QI 1 "general_operand" "")
1024               (match_operand:SI 2 "general_operand" "")))]
1025   ""
1026   "
1027 {
1028   if (! call_address_operand (XEXP (operands[1], 0), QImode)
1029       || TARGET_LONG_CALLS)
1030     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1031   if (TARGET_LONG_CALLS)
1032     emit_call_insn (gen_call_value_internal_long (operands[0],
1033                                                   XEXP (operands[1], 0),
1034                                                   operands[2]));
1035   else
1036     emit_call_insn (gen_call_value_internal_short (operands[0],
1037                                                    XEXP (operands[1], 0),
1038                                                    operands[2]));
1039   DONE;
1040 }")
1041
1042 (define_insn "call_value_internal_short"
1043   [(set (match_operand 0 "" "=r,r")
1044         (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1045               (match_operand:SI 2 "general_operand" "g,g")))
1046    (clobber (reg:SI 31))]
1047   "! TARGET_LONG_CALLS"
1048   "@
1049   jarl %1,r31
1050   jarl .+4,r31 ; add 4,r31 ; jmp %1"
1051   [(set_attr "length" "4,8")]
1052 )
1053
1054 (define_insn "call_value_internal_long"
1055   [(set (match_operand 0 "" "=r,r")
1056         (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1057               (match_operand:SI 2 "general_operand" "g,g")))
1058    (clobber (reg:SI 31))]
1059   "TARGET_LONG_CALLS"
1060   "*
1061   {
1062   if (which_alternative == 0)
1063     {
1064       if (GET_CODE (operands[1]) == REG)
1065         return \"jarl %1, r31\";
1066       else
1067       /* Reload can generate this pattern... */
1068         return \"movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11\";
1069     }
1070   else
1071     return \"jarl .+4, r31 ; add 4, r31 ; jmp %1\";
1072   }"
1073   [(set_attr "length" "16,8")]
1074 )
1075
1076 (define_insn "nop"
1077   [(const_int 0)]
1078   ""
1079   "nop"
1080   [(set_attr "length" "2")
1081    (set_attr "cc" "none")])
1082 \f
1083 ;; ----------------------------------------------------------------------
1084 ;; EXTEND INSTRUCTIONS
1085 ;; ----------------------------------------------------------------------
1086
1087
1088 (define_insn "zero_extendhisi2"
1089   [(set (match_operand:SI 0 "register_operand" "=r")
1090         (zero_extend:SI
1091          (match_operand:HI 1 "register_operand" "r")))]
1092   ""
1093   "andi 65535,%1,%0"
1094   [(set_attr "length" "4")
1095    (set_attr "cc" "set_znv")])
1096
1097
1098 (define_insn "zero_extendqisi2"
1099   [(set (match_operand:SI 0 "register_operand" "=r")
1100         (zero_extend:SI
1101          (match_operand:QI 1 "register_operand" "r")))]
1102   ""
1103   "andi 255,%1,%0"
1104   [(set_attr "length" "4")
1105    (set_attr "cc" "set_znv")])
1106
1107 ;;- sign extension instructions
1108
1109
1110 ;; ??? This is missing a sign extend from memory pattern to match the ld.h
1111 ;; instruction.
1112
1113 (define_expand "extendhisi2"
1114   [(set (match_dup 2)
1115         (ashift:SI (match_operand:HI 1 "register_operand" "")
1116                    (const_int 16)))
1117    (set (match_operand:SI 0 "register_operand" "")
1118        (ashiftrt:SI (match_dup 2)
1119                      (const_int 16)))]
1120   ""
1121   "
1122 {
1123   operands[1] = gen_lowpart (SImode, operands[1]);
1124   operands[2] = gen_reg_rtx (SImode);
1125 }")
1126
1127
1128 ;; ??? This is missing a sign extend from memory pattern to match the ld.b
1129 ;; instruction.
1130
1131 (define_expand "extendqisi2"
1132   [(set (match_dup 2)
1133         (ashift:SI (match_operand:QI 1 "register_operand" "")
1134                    (const_int 24)))
1135    (set (match_operand:SI 0 "register_operand" "")
1136         (ashiftrt:SI (match_dup 2)
1137                      (const_int 24)))]
1138   ""
1139   "
1140 {
1141   operands[1] = gen_lowpart (SImode, operands[1]);
1142   operands[2] = gen_reg_rtx (SImode);
1143 }")
1144 \f
1145 ;; ----------------------------------------------------------------------
1146 ;; SHIFTS
1147 ;; ----------------------------------------------------------------------
1148
1149 (define_insn "ashlsi3"
1150   [(set (match_operand:SI 0 "register_operand" "=r,r")
1151         (ashift:SI
1152          (match_operand:SI 1 "register_operand" "0,0")
1153          (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1154   ""
1155   "@
1156   shl %2,%0
1157   shl %2,%0"
1158   [(set_attr "length" "4,2")
1159    (set_attr "cc" "set_znv")])
1160
1161 (define_insn "lshrsi3"
1162   [(set (match_operand:SI 0 "register_operand" "=r,r")
1163         (lshiftrt:SI
1164          (match_operand:SI 1 "register_operand" "0,0")
1165          (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1166   ""
1167   "@
1168   shr %2,%0
1169   shr %2,%0"
1170   [(set_attr "length" "4,2")
1171    (set_attr "cc" "set_znv")])
1172
1173 (define_insn "ashrsi3"
1174   [(set (match_operand:SI 0 "register_operand" "=r,r")
1175         (ashiftrt:SI
1176          (match_operand:SI 1 "register_operand" "0,0")
1177          (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1178   ""
1179   "@
1180   sar %2,%0
1181   sar %2,%0"
1182   [(set_attr "length" "4,2")
1183    (set_attr "cc" "set_znv")])
1184
1185 ;; ----------------------------------------------------------------------
1186 ;; PROLOGUE/EPILOGUE
1187 ;; ----------------------------------------------------------------------
1188 (define_expand "prologue"
1189   [(const_int 0)]
1190   ""
1191   "expand_prologue (); DONE;")
1192
1193 (define_expand "epilogue"
1194   [(return)]
1195   ""
1196   "
1197 {
1198   /* Try to use the trivial return first.  Else use the
1199      full epilogue.  */
1200   if (0)
1201     emit_jump_insn (gen_return ());
1202   else
1203     expand_epilogue ();
1204   DONE;
1205 }")
1206
1207 (define_insn "return"
1208   [(return)]
1209   "reload_completed && compute_frame_size (get_frame_size (), (long *)0) == 0"
1210   "jmp [r31]"
1211   [(set_attr "length" "2")
1212    (set_attr "cc" "none")])
1213
1214 (define_insn "return_internal"
1215   [(return)
1216    (use (reg:SI 31))]
1217   ""
1218   "jmp [r31]"
1219   [(set_attr "length" "2")
1220    (set_attr "cc" "none")])
1221
1222
1223 \f
1224 ;; ----------------------------------------------------------------------
1225 ;; HELPER INSTRUCTIONS for saving the prologue and epilog registers
1226 ;; ----------------------------------------------------------------------
1227
1228 ;; This pattern will match a stack adjust RTX followed by any number of push
1229 ;; RTXs.  These RTXs will then be turned into a suitable call to a worker
1230 ;; function.
1231
1232
1233 (define_insn ""
1234  [(match_parallel 0 "pattern_is_ok_for_prologue"
1235    [(set (reg:SI 3)
1236          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1237     (set (mem:SI (plus:SI (reg:SI 3)
1238                            (match_operand:SI 2 "immediate_operand" "i")))
1239          (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
1240  "TARGET_PROLOG_FUNCTION"
1241  "* return construct_save_jarl (operands[0]);
1242  "
1243  [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
1244                                      (const_string "16")
1245                                      (const_string "4")))
1246   (set_attr "cc"     "clobber")])
1247
1248 ;; This pattern will match a return RTX followed by any number of pop RTXs
1249 ;; and possible a stack adjustment as well.  These RTXs will be turned into
1250 ;; a suitable call to a worker function.
1251
1252 (define_insn ""
1253 [(match_parallel 0 "pattern_is_ok_for_epilogue"
1254    [(return)
1255     (set (reg:SI 3)
1256          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1257     (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
1258          (mem:SI (plus:SI (reg:SI 3)
1259                           (match_operand:SI 3 "immediate_operand" "i"))))])]
1260  "TARGET_PROLOG_FUNCTION && TARGET_V850"
1261  "* return construct_restore_jr (operands[0]);
1262  "
1263  [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
1264                                      (const_string "12")
1265                                      (const_string "4")))
1266   (set_attr "cc"     "clobber")])
1267
1268 ;; Initialize an interrupt function.  Do not depend on TARGET_PROLOG_FUNCTION.
1269 (define_insn "save_interrupt"
1270   [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16)))
1271    (set (mem:SI (reg:SI 3)) (reg:SI 30))
1272    (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 10))
1273    (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 4))
1274    (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))]
1275   "TARGET_V850 && ! TARGET_LONG_CALLS"
1276   "add -16, sp ; st.w r10, 12[sp] ; jarl __save_interrupt, r10"
1277   [(set_attr "length" "12")
1278    (set_attr "cc" "clobber")])
1279
1280 ;; Restore r1, r4, r10, and return from the interrupt
1281 (define_insn "restore_interrupt"
1282   [(return)
1283    (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 16)))
1284    (set (reg:SI 30) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
1285    (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
1286    (set (reg:SI 4)  (mem:SI (plus:SI (reg:SI 3) (const_int 4))))
1287    (set (reg:SI 1)  (mem:SI (reg:SI 3)))]
1288   ""
1289   "jr __return_interrupt"
1290   [(set_attr "length" "4")
1291    (set_attr "cc" "clobber")])
1292
1293
1294 ;; Save all registers except for the registers saved in save_interrupt when
1295 ;; an interrupt function makes a call.
1296 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1297 ;; all of memory.  This blocks insns from being moved across this point.
1298 ;; This is needed because the rest of the compiler is not ready to handle
1299 ;; insns this complicated.
1300
1301 (define_insn "save_all_interrupt"
1302   [(unspec_volatile [(const_int 0)] 0)]
1303   "TARGET_V850 && ! TARGET_LONG_CALLS"
1304   "jarl __save_all_interrupt,r10"
1305   [(set_attr "length" "4")
1306    (set_attr "cc" "clobber")])
1307
1308
1309 ;; Restore all registers saved when an interrupt function makes a call.
1310 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1311 ;; all of memory.  This blocks insns from being moved across this point.
1312 ;; This is needed because the rest of the compiler is not ready to handle
1313 ;; insns this complicated.
1314
1315 (define_insn "restore_all_interrupt"
1316   [(unspec_volatile [(const_int 0)] 1)]
1317   "TARGET_V850 && ! TARGET_LONG_CALLS"
1318   "jarl __restore_all_interrupt,r10"
1319   [(set_attr "length" "4")
1320    (set_attr "cc" "clobber")])
1321
1322 ;; Save r6-r9 for a variable argument function
1323 (define_insn "save_r6_r9"
1324   [(set (mem:SI (reg:SI 3)) (reg:SI 6))
1325    (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
1326    (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
1327    (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
1328    (clobber (reg:SI 10))]
1329   "TARGET_PROLOG_FUNCTION && ! TARGET_LONG_CALLS"
1330   "jarl __save_r6_r9,r10"
1331   [(set_attr "length" "4")
1332    (set_attr "cc" "clobber")])
1333