2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / gcc / config / v850 / v850.md
blobb359c7230020b72798186c3bf9722d287852a562
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).
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; any later version.
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING.  If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
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).
30 ;; One day we'll probably need to handle calls to targets more than 4M
31 ;; away.
33 ;; The size of instructions in bytes.
35 (define_attr "length" ""
36   (const_int 4))
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).
45 (define_attr "type" "load,mult,other"
46   (const_string "other"))
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"))
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.
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)
68 ;; ----------------------------------------------------------------------
69 ;; MOVE INSTRUCTIONS
70 ;; ----------------------------------------------------------------------
72 ;; movqi
74 (define_expand "movqi"
75   [(set (match_operand:QI 0 "general_operand" "")
76         (match_operand:QI 1 "general_operand" ""))]
77   ""
78   "
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 }")
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")])
96 ;; movhi
98 (define_expand "movhi"
99   [(set (match_operand:HI 0 "general_operand" "")
100         (match_operand:HI 1 "general_operand" ""))]
101   ""
102   "
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);
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")])
120 ;; movsi and helpers
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")])
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")])
141 (define_expand "movsi"
142   [(set (match_operand:SI 0 "general_operand" "")
143         (match_operand:SI 1 "general_operand" ""))]
144   ""
145   "
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);
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;
165       if (reload_in_progress || reload_completed)
166         temp = operands[0];
167       else
168         temp = gen_reg_rtx (SImode);
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     }
178 ;; This is the same as the following pattern, except that it includes
179 ;; support for arbitrary 32 bit immediates.
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.
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")])
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")])
208 (define_expand "movdi"
209   [(set (match_operand:DI 0 "general_operand" "")
210         (match_operand:DI 1 "general_operand" ""))]
211   ""
212   "
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);
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")])
230 (define_expand "movsf"
231   [(set (match_operand:SF 0 "general_operand" "")
232         (match_operand:SF 1 "general_operand" ""))]
233   ""
234   "
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);
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")])
252 (define_expand "movdf"
253   [(set (match_operand:DF 0 "general_operand" "")
254         (match_operand:DF 1 "general_operand" ""))]
255   ""
256   "
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);
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")])
275 ;; ----------------------------------------------------------------------
276 ;; TEST INSTRUCTIONS
277 ;; ----------------------------------------------------------------------
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")])
288 ;; This replaces ld.b;sar;andi with tst1;setf nz.
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)).
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)))])
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")])
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")])
322 ;; ----------------------------------------------------------------------
323 ;; ADD INSTRUCTIONS
324 ;; ----------------------------------------------------------------------
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")])
338 ;; ----------------------------------------------------------------------
339 ;; SUBTRACT INSTRUCTIONS
340 ;; ----------------------------------------------------------------------
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")])
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")])
361 ;; ----------------------------------------------------------------------
362 ;; MULTIPLY INSTRUCTIONS
363 ;; ----------------------------------------------------------------------
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   "if (GET_CODE (operands[2]) == CONST_INT)
372      {
373        emit_insn (gen_mulhisi3_internal2 (operands[0], operands[1], operands[2]));
374        DONE;
375      }")
377 (define_insn "*mulhisi3_internal1"
378   [(set (match_operand:SI 0 "register_operand" "=r")
379         (mult:SI
380           (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
381           (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
382   ""
383   "mulh %2,%0"
384   [(set_attr "length" "2")
385    (set_attr "cc" "none_0hit")
386    (set_attr "type" "mult")])
388 (define_insn "mulhisi3_internal2"
389   [(set (match_operand:SI 0 "register_operand" "=r,r")
390         (mult:SI
391           (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
392           (match_operand:HI 2 "const_int_operand" "J,K")))]
393   ""
394   "@
395    mulh %2,%0
396    mulhi %2,%1,%0"
397   [(set_attr "length" "2,4")
398    (set_attr "cc" "none_0hit,none_0hit")
399    (set_attr "type" "mult")])
401 ;; ??? The scheduling info is probably wrong.
403 ;; ??? This instruction can also generate the 32 bit highpart, but using it
404 ;; may increase code size counter to the desired result.
406 ;; ??? This instructions can also give a DImode result.
408 ;; ??? There is unsigned version, but it matters only for the DImode/highpart
409 ;; results.
411 (define_insn "mulsi3"
412   [(set (match_operand:SI 0 "register_operand" "=r")
413         (mult:SI (match_operand:SI 1 "register_operand" "%0")
414                  (match_operand:SI 2 "reg_or_int9_operand" "rO")))]
415   "TARGET_V850E"
416   "mul %2,%1,%."
417   [(set_attr "length" "4")
418    (set_attr "cc" "none_0hit")
419    (set_attr "type" "mult")])
421 ;; ----------------------------------------------------------------------
422 ;; DIVIDE INSTRUCTIONS
423 ;; ----------------------------------------------------------------------
425 ;; ??? These insns do set the Z/N condition codes, except that they are based
426 ;; on only one of the two results, so it doesn't seem to make sense to use
427 ;; them.
429 ;; ??? The scheduling info is probably wrong.
431 (define_insn "divmodsi4"
432   [(set (match_operand:SI 0 "register_operand" "=r")
433         (div:SI (match_operand:SI 1 "register_operand" "0")
434                 (match_operand:SI 2 "register_operand" "r")))
435    (set (match_operand:SI 3 "register_operand" "=r")
436         (mod:SI (match_dup 1)
437                 (match_dup 2)))]
438   "TARGET_V850E"
439   "div %2,%0,%3"
440   [(set_attr "length" "4")
441    (set_attr "cc" "clobber")
442    (set_attr "type" "other")])
443         
444 (define_insn "udivmodsi4"
445   [(set (match_operand:SI 0 "register_operand" "=r")
446         (udiv:SI (match_operand:SI 1 "register_operand" "0")
447                  (match_operand:SI 2 "register_operand" "r")))
448    (set (match_operand:SI 3 "register_operand" "=r")
449         (umod:SI (match_dup 1)
450                  (match_dup 2)))]
451   "TARGET_V850E"
452   "divu %2,%0,%3"
453   [(set_attr "length" "4")
454    (set_attr "cc" "clobber")
455    (set_attr "type" "other")])
456         
457 ;; ??? There is a 2 byte instruction for generating only the quotient.
458 ;; However, it isn't clear how to compute the length field correctly.
460 (define_insn "divmodhi4"
461   [(set (match_operand:HI 0 "register_operand" "=r")
462         (div:HI (match_operand:HI 1 "register_operand" "0")
463                 (match_operand:HI 2 "register_operand" "r")))
464    (set (match_operand:HI 3 "register_operand" "=r")
465         (mod:HI (match_dup 1)
466                 (match_dup 2)))]
467   "TARGET_V850E"
468   "divh %2,%0,%3"
469   [(set_attr "length" "4")
470    (set_attr "cc" "clobber")
471    (set_attr "type" "other")])
473 ;; Half-words are sign-extended by default, so we must zero extend to a word
474 ;; here before doing the divide.
476 (define_insn "udivmodhi4"
477   [(set (match_operand:HI 0 "register_operand" "=r")
478         (udiv:HI (match_operand:HI 1 "register_operand" "0")
479                  (match_operand:HI 2 "register_operand" "r")))
480    (set (match_operand:HI 3 "register_operand" "=r")
481         (umod:HI (match_dup 1)
482                  (match_dup 2)))]
483   "TARGET_V850E"
484   "zxh %0 ; divhu %2,%0,%3"
485   [(set_attr "length" "4")
486    (set_attr "cc" "clobber")
487    (set_attr "type" "other")])
489 ;; ----------------------------------------------------------------------
490 ;; AND INSTRUCTIONS
491 ;; ----------------------------------------------------------------------
493 (define_insn "*v850_clr1_1"
494   [(set (match_operand:QI 0 "memory_operand" "=m")
495         (subreg:QI
496           (and:SI (subreg:SI (match_dup 0) 0)
497                   (match_operand:QI 1 "not_power_of_two_operand" "")) 0))]
498   ""
499   "*
501   rtx xoperands[2];
502   xoperands[0] = operands[0];
503   xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
504   output_asm_insn (\"clr1 %M1,%0\", xoperands);
505   return \"\";
507   [(set_attr "length" "4")
508    (set_attr "cc" "clobber")])
510 (define_insn "*v850_clr1_2"
511   [(set (match_operand:HI 0 "indirect_operand" "=m")
512         (subreg:HI
513           (and:SI (subreg:SI (match_dup 0) 0)
514                   (match_operand:HI 1 "not_power_of_two_operand" "")) 0))]
515   ""
516   "*
518   int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
520   rtx xoperands[2];
521   xoperands[0] = gen_rtx_MEM (QImode,
522                               plus_constant (XEXP (operands[0], 0), log2 / 8));
523   xoperands[1] = GEN_INT (log2 % 8);
524   output_asm_insn (\"clr1 %1,%0\", xoperands);
525   return \"\";
527   [(set_attr "length" "4")
528    (set_attr "cc" "clobber")])
530 (define_insn "*v850_clr1_3"
531   [(set (match_operand:SI 0 "indirect_operand" "=m")
532         (and:SI (match_dup 0)
533                 (match_operand:SI 1 "not_power_of_two_operand" "")))]
534   ""
535   "*
537   int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
539   rtx xoperands[2];
540   xoperands[0] = gen_rtx_MEM (QImode,
541                               plus_constant (XEXP (operands[0], 0), log2 / 8));
542   xoperands[1] = GEN_INT (log2 % 8);
543   output_asm_insn (\"clr1 %1,%0\", xoperands);
544   return \"\";
546   [(set_attr "length" "4")
547    (set_attr "cc" "clobber")])
549 (define_insn "andsi3"
550   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
551         (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
552                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
553   ""
554   "@
555   and %2,%0
556   and %.,%0
557   andi %2,%1,%0"
558   [(set_attr "length" "2,2,4")
559    (set_attr "cc" "set_znv")])
561 ;; ----------------------------------------------------------------------
562 ;; OR INSTRUCTIONS
563 ;; ----------------------------------------------------------------------
565 (define_insn "*v850_set1_1"
566   [(set (match_operand:QI 0 "memory_operand" "=m")
567         (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
568                            (match_operand 1 "power_of_two_operand" "")) 0))]
569   ""
570   "set1 %M1,%0"
571   [(set_attr "length" "4")
572    (set_attr "cc" "clobber")])
574 (define_insn "*v850_set1_2"
575   [(set (match_operand:HI 0 "indirect_operand" "=m")
576         (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
577                            (match_operand 1 "power_of_two_operand" "")) 0))]
578   ""
579   "*
581   int log2 = exact_log2 (INTVAL (operands[1]));
583   if (log2 < 8)
584     return \"set1 %M1,%0\";
585   else
586     {
587       rtx xoperands[2];
588       xoperands[0] = gen_rtx_MEM (QImode,
589                                   plus_constant (XEXP (operands[0], 0),
590                                                  log2 / 8));
591       xoperands[1] = GEN_INT (log2 % 8);
592       output_asm_insn (\"set1 %1,%0\", xoperands);
593     }
594   return \"\";
596   [(set_attr "length" "4")
597    (set_attr "cc" "clobber")])
599 (define_insn "*v850_set1_3"
600   [(set (match_operand:SI 0 "indirect_operand" "=m")
601         (ior:SI (match_dup 0)
602                 (match_operand 1 "power_of_two_operand" "")))]
603   ""
604   "*
606   int log2 = exact_log2 (INTVAL (operands[1]));
608   if (log2 < 8)
609     return \"set1 %M1,%0\";
610   else
611     {
612       rtx xoperands[2];
613       xoperands[0] = gen_rtx_MEM (QImode,
614                                   plus_constant (XEXP (operands[0], 0),
615                                                  log2 / 8));
616       xoperands[1] = GEN_INT (log2 % 8);
617       output_asm_insn (\"set1 %1,%0\", xoperands);
618     }
619   return \"\";
621   [(set_attr "length" "4")
622    (set_attr "cc" "clobber")])
624 (define_insn "iorsi3"
625   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
626         (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
627                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
628   ""
629   "@
630   or %2,%0
631   or %.,%0
632   ori %2,%1,%0"
633   [(set_attr "length" "2,2,4")
634    (set_attr "cc" "set_znv")])
636 ;; ----------------------------------------------------------------------
637 ;; XOR INSTRUCTIONS
638 ;; ----------------------------------------------------------------------
640 (define_insn "*v850_not1_1"
641   [(set (match_operand:QI 0 "memory_operand" "=m")
642         (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0)
643                            (match_operand 1 "power_of_two_operand" "")) 0))]
644   ""
645   "not1 %M1,%0"
646   [(set_attr "length" "4")
647    (set_attr "cc" "clobber")])
649 (define_insn "*v850_not1_2"
650   [(set (match_operand:HI 0 "indirect_operand" "=m")
651         (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
652                            (match_operand 1 "power_of_two_operand" "")) 0))]
653   ""
654   "*
656   int log2 = exact_log2 (INTVAL (operands[1]));
658   if (log2 < 8)
659     return \"not1 %M1,%0\";
660   else
661     {
662       rtx xoperands[2];
663       xoperands[0] = gen_rtx_MEM (QImode,
664                                   plus_constant (XEXP (operands[0], 0),
665                                                  log2 / 8));
666       xoperands[1] = GEN_INT (log2 % 8);
667       output_asm_insn (\"not1 %1,%0\", xoperands);
668     }
669   return \"\";
671   [(set_attr "length" "4")
672    (set_attr "cc" "clobber")])
674 (define_insn "*v850_not1_3"
675   [(set (match_operand:SI 0 "indirect_operand" "=m")
676         (xor:SI (match_dup 0)
677                 (match_operand 1 "power_of_two_operand" "")))]
678   ""
679   "*
681   int log2 = exact_log2 (INTVAL (operands[1]));
683   if (log2 < 8)
684     return \"not1 %M1,%0\";
685   else
686     {
687       rtx xoperands[2];
688       xoperands[0] = gen_rtx_MEM (QImode,
689                                   plus_constant (XEXP (operands[0], 0),
690                                                  log2 / 8));
691       xoperands[1] = GEN_INT (log2 % 8);
692       output_asm_insn (\"not1 %1,%0\", xoperands);
693     }
694   return \"\";
696   [(set_attr "length" "4")
697    (set_attr "cc" "clobber")])
699 (define_insn "xorsi3"
700   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
701         (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
702                 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
703   ""
704   "@
705   xor %2,%0
706   xor %.,%0
707   xori %2,%1,%0"
708   [(set_attr "length" "2,2,4")
709    (set_attr "cc" "set_znv")])
711 ;; ----------------------------------------------------------------------
712 ;; NOT INSTRUCTIONS
713 ;; ----------------------------------------------------------------------
715 (define_insn "one_cmplsi2"
716   [(set (match_operand:SI 0 "register_operand" "=r")
717         (not:SI (match_operand:SI 1 "register_operand" "r")))]
718   ""
719   "not %1,%0"
720   [(set_attr "length" "2")
721    (set_attr "cc" "set_znv")])
723 ;; -----------------------------------------------------------------
724 ;; BIT FIELDS
725 ;; -----------------------------------------------------------------
727 ;; ??? Is it worth defining insv and extv for the V850 series?!?
729 ;; An insv pattern would be useful, but does not get used because
730 ;; store_bit_field never calls insv when storing a constant value into a
731 ;; single-bit bitfield.
733 ;; extv/extzv patterns would be useful, but do not get used because
734 ;; optimize_bitfield_compare in fold-const usually converts single
735 ;; bit extracts into an AND with a mask.
737 ;; -----------------------------------------------------------------
738 ;; Scc INSTRUCTIONS
739 ;; -----------------------------------------------------------------
741 (define_insn "sle"
742   [(set (match_operand:SI 0 "register_operand" "=r")
743         (le:SI (cc0) (const_int 0)))]
744   ""
745   "*
747   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
748     return 0;
750   return \"setf le,%0\";
752   [(set_attr "length" "4")
753    (set_attr "cc" "none_0hit")])
755 (define_insn "sleu"
756   [(set (match_operand:SI 0 "register_operand" "=r")
757         (leu:SI (cc0) (const_int 0)))]
758   ""
759   "setf nh,%0"
760   [(set_attr "length" "4")
761    (set_attr "cc" "none_0hit")])
763 (define_insn "sge"
764   [(set (match_operand:SI 0 "register_operand" "=r")
765         (ge:SI (cc0) (const_int 0)))]
766   ""
767   "*
769   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
770     return 0;
772   return \"setf ge,%0\";
774   [(set_attr "length" "4")
775    (set_attr "cc" "none_0hit")])
777 (define_insn "sgeu"
778   [(set (match_operand:SI 0 "register_operand" "=r")
779         (geu:SI (cc0) (const_int 0)))]
780   ""
781   "setf nl,%0"
782   [(set_attr "length" "4")
783    (set_attr "cc" "none_0hit")])
785 (define_insn "slt"
786   [(set (match_operand:SI 0 "register_operand" "=r")
787         (lt:SI (cc0) (const_int 0)))]
788   ""
789   "*
791   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
792     return 0;
794   return \"setf lt,%0\";
796   [(set_attr "length" "4")
797    (set_attr "cc" "none_0hit")])
799 (define_insn "sltu"
800   [(set (match_operand:SI 0 "register_operand" "=r")
801         (ltu:SI (cc0) (const_int 0)))]
802   ""
803   "setf l,%0"
804   [(set_attr "length" "4")
805    (set_attr "cc" "none_0hit")])
807 (define_insn "sgt"
808   [(set (match_operand:SI 0 "register_operand" "=r")
809         (gt:SI (cc0) (const_int 0)))]
810   ""
811   "*
813   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
814     return 0;
816   return \"setf gt,%0\";
818   [(set_attr "length" "4")
819    (set_attr "cc" "none_0hit")])
821 (define_insn "sgtu"
822   [(set (match_operand:SI 0 "register_operand" "=r")
823         (gtu:SI (cc0) (const_int 0)))]
824   ""
825   "setf h,%0"
826   [(set_attr "length" "4")
827    (set_attr "cc" "none_0hit")])
829 (define_insn "seq"
830   [(set (match_operand:SI 0 "register_operand" "=r")
831         (eq:SI (cc0) (const_int 0)))]
832   ""
833   "setf z,%0"
834   [(set_attr "length" "4")
835    (set_attr "cc" "none_0hit")])
837 (define_insn "sne"
838   [(set (match_operand:SI 0 "register_operand" "=r")
839         (ne:SI (cc0) (const_int 0)))]
840   ""
841   "setf nz,%0"
842   [(set_attr "length" "4")
843    (set_attr "cc" "none_0hit")])
845 ;; ----------------------------------------------------------------------
846 ;; CONDITIONAL MOVE INSTRUCTIONS
847 ;; ----------------------------------------------------------------------
849 ;; Instructions using cc0 aren't allowed to have input reloads, so we must
850 ;; hide the fact that this instruction uses cc0.  We do so by including the
851 ;; compare instruction inside it.
853 ;; ??? This is very ugly.  The right way to do this is to modify cmpsi so
854 ;; that it doesn't emit RTL, and then modify the bcc/scc patterns so that
855 ;; they emit RTL for the compare instruction.  Unfortunately, this requires
856 ;; lots of changes that will be hard to sanitize.  So for now, cmpsi still
857 ;; emits RTL, and I get the compare operands here from the previous insn.
859 (define_expand "movsicc"
860   [(set (match_operand:SI 0 "register_operand" "=r")
861         (if_then_else:SI
862          (match_operator 1 "comparison_operator"
863                          [(match_dup 4) (match_dup 5)])
864          (match_operand:SI 2 "reg_or_const_operand" "rJ")
865          (match_operand:SI 3 "reg_or_const_operand" "rI")))]
866   "TARGET_V850E"
867   "
869   rtx insn = get_last_insn_anywhere ();
871   if (   (GET_CODE (operands[2]) == CONST_INT
872        && GET_CODE (operands[3]) == CONST_INT))
873     {
874       int o2 = INTVAL (operands[2]);
875       int o3 = INTVAL (operands[3]);
877       if (o2 == 1 && o3 == 0)
878         FAIL;   /* setf */
879       if (o3 == 1 && o2 == 0)
880         FAIL;   /* setf */
881       if (o2 == 0 && (o3 < -16 || o3 > 15) && exact_log2 (o3) >= 0)
882         FAIL;   /* setf + shift */
883       if (o3 == 0 && (o2 < -16 || o2 > 15) && exact_log2 (o2) >=0)
884         FAIL;   /* setf + shift */
885       if (o2 != 0)
886         operands[2] = copy_to_mode_reg (SImode, operands[2]);
887       if (o3 !=0 )
888         operands[3] = copy_to_mode_reg (SImode, operands[3]);
889     }
890   else
891     {
892       if (GET_CODE (operands[2]) != REG)
893         operands[2] = copy_to_mode_reg (SImode,operands[2]);
894       if (GET_CODE (operands[3]) != REG)
895         operands[3] = copy_to_mode_reg (SImode, operands[3]);
896     }
897   if (GET_CODE (insn) == INSN
898       && GET_CODE (PATTERN (insn)) == SET
899       && SET_DEST (PATTERN (insn)) == cc0_rtx)
900     {
901       rtx src = SET_SRC (PATTERN (insn));
903       if (GET_CODE (src) == COMPARE)
904         {
905           operands[4] = XEXP (src, 0);
906           operands[5] = XEXP (src, 1);
907         }
908       else if (GET_CODE (src) == REG
909                || GET_CODE (src) == SUBREG)
910         {
911           operands[4] = src;
912           operands[5] = const0_rtx;
913         }
914       else
915         abort ();
916     }
917   else
918     abort ();
921 ;; ??? Clobbering the condition codes is overkill.
923 ;; ??? We sometimes emit an unnecessary compare instruction because the
924 ;; condition codes may have already been set by an earlier instruction,
925 ;; but we have no code here to avoid the compare if it is unnecessary.
927 (define_insn "*movsicc_normal"
928   [(set (match_operand:SI 0 "register_operand" "=r")
929         (if_then_else:SI
930          (match_operator 1 "comparison_operator"
931                          [(match_operand:SI 4 "register_operand" "r")
932                           (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
933          (match_operand:SI 2 "reg_or_int5_operand" "rJ")
934          (match_operand:SI 3 "reg_or_0_operand" "rI")))]
935   "TARGET_V850E"
936   "cmp %5,%4 ; cmov %c1,%2,%z3,%0"
937   [(set_attr "length" "6")
938    (set_attr "cc" "clobber")])
940 (define_insn "*movsicc_reversed"
941   [(set (match_operand:SI 0 "register_operand" "=r")
942         (if_then_else:SI
943          (match_operator 1 "comparison_operator"
944                          [(match_operand:SI 4 "register_operand" "r")
945                           (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
946          (match_operand:SI 2 "reg_or_0_operand" "rI")
947          (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
948   "TARGET_V850E"
949   "cmp %5,%4 ; cmov %C1,%3,%z2,%0"
950   [(set_attr "length" "6")
951    (set_attr "cc" "clobber")])
953 (define_insn "*movsicc_tst1"
954   [(set (match_operand:SI 0 "register_operand" "=r")
955         (if_then_else:SI
956          (match_operator 1 "comparison_operator"
957                          [(zero_extract:SI
958                            (match_operand:QI 2 "memory_operand" "m")
959                            (const_int 1)
960                            (match_operand 3 "const_int_operand" "n"))
961                           (const_int 0)])
962          (match_operand:SI 4 "reg_or_int5_operand" "rJ")
963          (match_operand:SI 5 "reg_or_0_operand" "rI")))]
964   "TARGET_V850E"
965   "tst1 %3,%2 ; cmov %c1,%4,%z5,%0"
966   [(set_attr "length" "8")
967    (set_attr "cc" "clobber")])
969 (define_insn "*movsicc_tst1_reversed"
970   [(set (match_operand:SI 0 "register_operand" "=r")
971         (if_then_else:SI
972          (match_operator 1 "comparison_operator"
973                          [(zero_extract:SI
974                            (match_operand:QI 2 "memory_operand" "m")
975                            (const_int 1)
976                            (match_operand 3 "const_int_operand" "n"))
977                           (const_int 0)])
978          (match_operand:SI 4 "reg_or_0_operand" "rI")
979          (match_operand:SI 5 "reg_or_int5_operand" "rJ")))]
980   "TARGET_V850E"
981   "tst1 %3,%2 ; cmov %C1,%5,%z4,%0"
982   [(set_attr "length" "8")
983    (set_attr "cc" "clobber")])
985 ;; Matching for sasf requires combining 4 instructions, so we provide a
986 ;; dummy pattern to match the first 3, which will always be turned into the
987 ;; second pattern by subsequent combining.  As above, we must include the
988 ;; comparison to avoid input reloads in an insn using cc0.
990 (define_insn "*sasf_1"
991   [(set (match_operand:SI 0 "register_operand" "")
992         (ior:SI (match_operator 1 "comparison_operator" [(cc0) (const_int 0)])
993                 (ashift:SI (match_operand:SI 2 "register_operand" "")
994                            (const_int 1))))]
995   "TARGET_V850E"
996   "* abort ();")
998 (define_insn "*sasf_2"
999   [(set (match_operand:SI 0 "register_operand" "=r")
1000         (ior:SI
1001          (match_operator 1 "comparison_operator"
1002                          [(match_operand:SI 3 "register_operand" "r")
1003                           (match_operand:SI 4 "reg_or_int5_operand" "rJ")])
1004          (ashift:SI (match_operand:SI 2 "register_operand" "0")
1005                     (const_int 1))))]
1006   "TARGET_V850E"
1007   "cmp %4,%3 ; sasf %c1,%0"
1008   [(set_attr "length" "6")
1009    (set_attr "cc" "clobber")])
1011 (define_split
1012   [(set (match_operand:SI 0 "register_operand" "")
1013         (if_then_else:SI
1014          (match_operator 1 "comparison_operator"
1015                          [(match_operand:SI 4 "register_operand" "")
1016                           (match_operand:SI 5 "reg_or_int5_operand" "")])
1017          (match_operand:SI 2 "const_int_operand" "")
1018          (match_operand:SI 3 "const_int_operand" "")))]
1019   "TARGET_V850E
1020    && ((INTVAL (operands[2]) ^ INTVAL (operands[3])) == 1)
1021    && ((INTVAL (operands[2]) + INTVAL (operands[3])) != 1)
1022    && (GET_CODE (operands[5]) == CONST_INT
1023       || REGNO (operands[0]) != REGNO (operands[5]))
1024    && REGNO (operands[0]) != REGNO (operands[4])"
1025   [(set (match_dup 0) (match_dup 6))
1026    (set (match_dup 0)
1027         (ior:SI (match_op_dup 7 [(match_dup 4) (match_dup 5)])
1028                 (ashift:SI (match_dup 0) (const_int 1))))]
1029   "
1031   operands[6] = GEN_INT (INTVAL (operands[2]) >> 1);
1032   if (INTVAL (operands[2]) & 0x1)
1033     operands[7] = operands[1];
1034   else
1035     operands[7] = gen_rtx (reverse_condition (GET_CODE (operands[1])),
1036                            GET_MODE (operands[1]), XEXP (operands[1], 0),
1037                            XEXP (operands[1], 1));
1039 ;; ---------------------------------------------------------------------
1040 ;; BYTE SWAP INSTRUCTIONS
1041 ;; ---------------------------------------------------------------------
1043 (define_expand "rotlhi3"
1044   [(set (match_operand:HI 0 "register_operand" "")
1045         (rotate:HI (match_operand:HI 1 "register_operand" "")
1046                    (match_operand:HI 2 "const_int_operand" "")))]
1047   "TARGET_V850E"
1048   "
1050   if (INTVAL (operands[2]) != 8)
1051     FAIL;
1054 (define_insn "*rotlhi3_8"
1055   [(set (match_operand:HI 0 "register_operand" "=r")
1056         (rotate:HI (match_operand:HI 1 "register_operand" "r")
1057                    (const_int 8)))]
1058   "TARGET_V850E"
1059   "bsh %1,%0"
1060   [(set_attr "length" "4")
1061    (set_attr "cc" "clobber")])
1063 (define_expand "rotlsi3"
1064   [(set (match_operand:SI 0 "register_operand" "")
1065         (rotate:SI (match_operand:SI 1 "register_operand" "")
1066                    (match_operand:SI 2 "const_int_operand" "")))]
1067   "TARGET_V850E"
1068   "
1070   if (INTVAL (operands[2]) != 16)
1071     FAIL;
1074 (define_insn "*rotlsi3_16"
1075   [(set (match_operand:SI 0 "register_operand" "=r")
1076         (rotate:SI (match_operand:SI 1 "register_operand" "r")
1077                    (const_int 16)))]
1078   "TARGET_V850E"
1079   "hsw %1,%0"
1080   [(set_attr "length" "4")
1081    (set_attr "cc" "clobber")])
1083 ;; ----------------------------------------------------------------------
1084 ;; JUMP INSTRUCTIONS
1085 ;; ----------------------------------------------------------------------
1087 ;; Conditional jump instructions
1089 (define_expand "ble"
1090   [(set (pc)
1091         (if_then_else (le (cc0)
1092                           (const_int 0))
1093                       (label_ref (match_operand 0 "" ""))
1094                       (pc)))]
1095   ""
1096   "")
1098 (define_expand "bleu"
1099   [(set (pc)
1100         (if_then_else (leu (cc0)
1101                            (const_int 0))
1102                       (label_ref (match_operand 0 "" ""))
1103                       (pc)))]
1104   ""
1105   "")
1107 (define_expand "bge"
1108   [(set (pc)
1109         (if_then_else (ge (cc0)
1110                           (const_int 0))
1111                       (label_ref (match_operand 0 "" ""))
1112                       (pc)))]
1113   ""
1114   "")
1116 (define_expand "bgeu"
1117   [(set (pc)
1118         (if_then_else (geu (cc0)
1119                            (const_int 0))
1120                       (label_ref (match_operand 0 "" ""))
1121                       (pc)))]
1122   ""
1123   "")
1125 (define_expand "blt"
1126   [(set (pc)
1127         (if_then_else (lt (cc0)
1128                           (const_int 0))
1129                       (label_ref (match_operand 0 "" ""))
1130                       (pc)))]
1131   ""
1132   "")
1134 (define_expand "bltu"
1135   [(set (pc)
1136         (if_then_else (ltu (cc0)
1137                            (const_int 0))
1138                       (label_ref (match_operand 0 "" ""))
1139                       (pc)))]
1140   ""
1141   "")
1143 (define_expand "bgt"
1144   [(set (pc)
1145         (if_then_else (gt (cc0)
1146                           (const_int 0))
1147                       (label_ref (match_operand 0 "" ""))
1148                       (pc)))]
1149   ""
1150   "")
1152 (define_expand "bgtu"
1153   [(set (pc)
1154         (if_then_else (gtu (cc0)
1155                            (const_int 0))
1156                       (label_ref (match_operand 0 "" ""))
1157                       (pc)))]
1158   ""
1159   "")
1161 (define_expand "beq"
1162   [(set (pc)
1163         (if_then_else (eq (cc0)
1164                           (const_int 0))
1165                       (label_ref (match_operand 0 "" ""))
1166                       (pc)))]
1167   ""
1168   "")
1170 (define_expand "bne"
1171   [(set (pc)
1172         (if_then_else (ne (cc0)
1173                           (const_int 0))
1174                       (label_ref (match_operand 0 "" ""))
1175                       (pc)))]
1176   ""
1177   "")
1179 (define_insn "*branch_normal"
1180   [(set (pc)
1181         (if_then_else (match_operator 1 "comparison_operator"
1182                                       [(cc0) (const_int 0)])
1183                       (label_ref (match_operand 0 "" ""))
1184                       (pc)))]
1185   ""
1186   "*
1188   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1189       && (GET_CODE (operands[1]) == GT
1190           || GET_CODE (operands[1]) == GE
1191           || GET_CODE (operands[1]) == LE
1192           || GET_CODE (operands[1]) == LT))
1193     return 0;
1195   if (get_attr_length (insn) == 2)
1196     return \"b%b1 %l0\";
1197   else
1198     return \"b%B1 .+6 ; jr %l0\";
1200  [(set (attr "length")
1201     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1202                       (const_int 256))
1203                   (const_int 2)
1204                   (const_int 6)))
1205   (set_attr "cc" "none")])
1207 (define_insn "*branch_invert"
1208   [(set (pc)
1209         (if_then_else (match_operator 1 "comparison_operator"
1210                                       [(cc0) (const_int 0)])
1211                       (pc)
1212                       (label_ref (match_operand 0 "" ""))))]
1213   ""
1214   "*
1216   if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1217       && (GET_CODE (operands[1]) == GT
1218           || GET_CODE (operands[1]) == GE
1219           || GET_CODE (operands[1]) == LE
1220           || GET_CODE (operands[1]) == LT))
1221     return 0;
1222   if (get_attr_length (insn) == 2)
1223     return \"b%B1 %l0\";
1224   else
1225     return \"b%b1 .+6 ; jr %l0\";
1227  [(set (attr "length")
1228     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1229                       (const_int 256))
1230                   (const_int 2)
1231                   (const_int 6)))
1232   (set_attr "cc" "none")])
1234 ;; Unconditional and other jump instructions.
1236 (define_insn "jump"
1237   [(set (pc)
1238         (label_ref (match_operand 0 "" "")))]
1239   ""
1240   "*
1242   if (get_attr_length (insn) == 2)
1243     return \"br %0\";
1244   else
1245     return \"jr %0\";
1247  [(set (attr "length")
1248     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1249                       (const_int 256))
1250                   (const_int 2)
1251                   (const_int 4)))
1252   (set_attr "cc" "none")])
1254 (define_insn "indirect_jump"
1255   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1256   ""
1257   "jmp %0"
1258   [(set_attr "length" "2")
1259    (set_attr "cc" "none")])
1261 (define_insn "tablejump"
1262   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1263    (use (label_ref (match_operand 1 "" "")))]
1264   ""
1265   "jmp  %0"
1266   [(set_attr "length" "2")
1267    (set_attr "cc" "none")])
1269 (define_insn "switch"
1270   [(set (pc)
1271         (plus:SI
1272          (sign_extend:SI
1273           (mem:HI
1274            (plus:SI (ashift:SI (match_operand:SI 0 "register_operand" "r")
1275                                (const_int 1))
1276                     (label_ref (match_operand 1 "" "")))))
1277          (label_ref (match_dup 1))))]
1278   "TARGET_V850E"
1279   "switch %0"
1280   [(set_attr "length" "2")
1281    (set_attr "cc" "none")])
1283 (define_expand "casesi"
1284   [(match_operand:SI 0 "register_operand" "")
1285    (match_operand:SI 1 "register_operand" "")
1286    (match_operand:SI 2 "register_operand" "")
1287    (match_operand 3 "" "") (match_operand 4 "" "")]
1288   ""
1289   "
1291   rtx reg = gen_reg_rtx (SImode);
1292   rtx tableaddress = gen_reg_rtx (SImode);
1293   rtx mem;
1295   /* Subtract the lower bound from the index.  */
1296   emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
1297   /* Compare the result against the number of table entries.  */
1298   emit_insn (gen_cmpsi (reg, operands[2]));
1299   /* Branch to the default label if out of range of the table.  */
1300   emit_jump_insn (gen_bgtu (operands[4]));
1302   if (! TARGET_BIG_SWITCH && TARGET_V850E)
1303     {
1304       emit_jump_insn (gen_switch (reg, operands[3]));
1305       DONE;
1306     }
1308   /* Shift index for the table array access.  */
1309   emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
1310   /* Load the table address into a pseudo.  */
1311   emit_insn (gen_movsi (tableaddress,
1312                         gen_rtx_LABEL_REF (Pmode, operands[3])));
1313   /* Add the table address to the index.  */
1314   emit_insn (gen_addsi3 (reg, reg, tableaddress));
1315   /* Load the table entry.  */
1316   mem = gen_rtx_MEM (CASE_VECTOR_MODE, reg);
1317   RTX_UNCHANGING_P (mem) = 1;
1318   if (! TARGET_BIG_SWITCH)
1319     {
1320       rtx reg2 = gen_reg_rtx (HImode);
1321       emit_insn (gen_movhi (reg2, mem));
1322       emit_insn (gen_extendhisi2 (reg, reg2));
1323     }
1324   else
1325     emit_insn (gen_movsi (reg, mem));
1326   /* Add the table address.  */
1327   emit_insn (gen_addsi3 (reg, reg, tableaddress));
1328   /* Branch to the switch label.  */
1329   emit_jump_insn (gen_tablejump (reg, operands[3]));
1330   DONE;
1333 ;; Call subroutine with no return value.
1335 (define_expand "call"
1336   [(call (match_operand:QI 0 "general_operand" "")
1337          (match_operand:SI 1 "general_operand" ""))]
1338   ""
1339   "
1341   if (! call_address_operand (XEXP (operands[0], 0), QImode)
1342       || TARGET_LONG_CALLS)
1343     XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1344   if (TARGET_LONG_CALLS)
1345     emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));
1346   else
1347     emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
1348   
1349   DONE;
1352 (define_insn "call_internal_short"
1353   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1354          (match_operand:SI 1 "general_operand" "g,g"))
1355    (clobber (reg:SI 31))]
1356   "! TARGET_LONG_CALLS"
1357   "@
1358   jarl %0,r31
1359   jarl .+4,r31 ; add 4,r31 ; jmp %0"
1360   [(set_attr "length" "4,8")]
1363 (define_insn "call_internal_long"
1364   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1365          (match_operand:SI 1 "general_operand" "g,g"))
1366    (clobber (reg:SI 31))]
1367   "TARGET_LONG_CALLS"
1368   "*
1369   {
1370   if (which_alternative == 0)
1371     {
1372       if (GET_CODE (operands[0]) == REG)
1373         return \"jarl %0,r31\";
1374       else
1375         return \"movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11\";
1376     }
1377   else
1378     return \"jarl .+4,r31 ; add 4,r31 ; jmp %0\";
1379   }"
1380   [(set_attr "length" "16,8")]
1383 ;; Call subroutine, returning value in operand 0
1384 ;; (which must be a hard register).
1386 (define_expand "call_value"
1387   [(set (match_operand 0 "" "")
1388         (call (match_operand:QI 1 "general_operand" "")
1389               (match_operand:SI 2 "general_operand" "")))]
1390   ""
1391   "
1393   if (! call_address_operand (XEXP (operands[1], 0), QImode)
1394       || TARGET_LONG_CALLS)
1395     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1396   if (TARGET_LONG_CALLS)
1397     emit_call_insn (gen_call_value_internal_long (operands[0],
1398                                                   XEXP (operands[1], 0),
1399                                                   operands[2]));
1400   else
1401     emit_call_insn (gen_call_value_internal_short (operands[0],
1402                                                    XEXP (operands[1], 0),
1403                                                    operands[2]));
1404   DONE;
1407 (define_insn "call_value_internal_short"
1408   [(set (match_operand 0 "" "=r,r")
1409         (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1410               (match_operand:SI 2 "general_operand" "g,g")))
1411    (clobber (reg:SI 31))]
1412   "! TARGET_LONG_CALLS"
1413   "@
1414   jarl %1,r31
1415   jarl .+4,r31 ; add 4,r31 ; jmp %1"
1416   [(set_attr "length" "4,8")]
1419 (define_insn "call_value_internal_long"
1420   [(set (match_operand 0 "" "=r,r")
1421         (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1422               (match_operand:SI 2 "general_operand" "g,g")))
1423    (clobber (reg:SI 31))]
1424   "TARGET_LONG_CALLS"
1425   "*
1426   {
1427   if (which_alternative == 0)
1428     {
1429       if (GET_CODE (operands[1]) == REG)
1430         return \"jarl %1, r31\";
1431       else
1432       /* Reload can generate this pattern... */
1433         return \"movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11\";
1434     }
1435   else
1436     return \"jarl .+4, r31 ; add 4, r31 ; jmp %1\";
1437   }"
1438   [(set_attr "length" "16,8")]
1441 (define_insn "nop"
1442   [(const_int 0)]
1443   ""
1444   "nop"
1445   [(set_attr "length" "2")
1446    (set_attr "cc" "none")])
1448 ;; ----------------------------------------------------------------------
1449 ;; EXTEND INSTRUCTIONS
1450 ;; ----------------------------------------------------------------------
1452 (define_insn ""
1453   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1454         (zero_extend:SI
1455          (match_operand:HI 1 "nonimmediate_operand" "0,r,T,m")))]
1456   "TARGET_V850E"
1457   "@
1458    zxh %0
1459    andi 65535,%1,%0
1460    sld.hu %1,%0
1461    ld.hu %1,%0"
1462   [(set_attr "length" "2,4,2,4")
1463    (set_attr "cc" "none_0hit,set_znv,none_0hit,none_0hit")])
1465 (define_insn "zero_extendhisi2"
1466   [(set (match_operand:SI 0 "register_operand" "=r")
1467         (zero_extend:SI
1468          (match_operand:HI 1 "register_operand" "r")))]
1469   ""
1470   "andi 65535,%1,%0"
1471   [(set_attr "length" "4")
1472    (set_attr "cc" "set_znv")])
1474 (define_insn ""
1475   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1476         (zero_extend:SI
1477          (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m")))]
1478   "TARGET_V850E"
1479   "@
1480    zxb %0
1481    andi 255,%1,%0
1482    sld.bu %1,%0
1483    ld.bu %1,%0"
1484   [(set_attr "length" "2,4,2,4")
1485    (set_attr "cc" "none_0hit,set_znv,none_0hit,none_0hit")])
1487 (define_insn "zero_extendqisi2"
1488   [(set (match_operand:SI 0 "register_operand" "=r")
1489         (zero_extend:SI
1490          (match_operand:QI 1 "register_operand" "r")))]
1491   ""
1492   "andi 255,%1,%0"
1493   [(set_attr "length" "4")
1494    (set_attr "cc" "set_znv")])
1496 ;;- sign extension instructions
1498 ;; ??? The extendhisi2 pattern should not emit shifts for v850e?
1500 (define_insn "*extendhisi_insn"
1501   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1502         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))]
1503   "TARGET_V850E"
1504   "@
1505    sxh %0
1506    sld.h %1,%0
1507    ld.h %1,%0"
1508   [(set_attr "length" "2,2,4")
1509    (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1511 ;; ??? This is missing a sign extend from memory pattern to match the ld.h
1512 ;; instruction.
1514 (define_expand "extendhisi2"
1515   [(set (match_dup 2)
1516         (ashift:SI (match_operand:HI 1 "register_operand" "")
1517                    (const_int 16)))
1518    (set (match_operand:SI 0 "register_operand" "")
1519        (ashiftrt:SI (match_dup 2)
1520                      (const_int 16)))]
1521   ""
1522   "
1524   operands[1] = gen_lowpart (SImode, operands[1]);
1525   operands[2] = gen_reg_rtx (SImode);
1528 ;; ??? The extendqisi2 pattern should not emit shifts for v850e?
1530 (define_insn "*extendqisi_insn"
1531   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1532         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))]
1533   "TARGET_V850E"
1534   "@
1535    sxb %0
1536    sld.b %1,%0
1537    ld.b %1,%0"
1538   [(set_attr "length" "2,2,4")
1539    (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1541 ;; ??? This is missing a sign extend from memory pattern to match the ld.b
1542 ;; instruction.
1544 (define_expand "extendqisi2"
1545   [(set (match_dup 2)
1546         (ashift:SI (match_operand:QI 1 "register_operand" "")
1547                    (const_int 24)))
1548    (set (match_operand:SI 0 "register_operand" "")
1549         (ashiftrt:SI (match_dup 2)
1550                      (const_int 24)))]
1551   ""
1552   "
1554   operands[1] = gen_lowpart (SImode, operands[1]);
1555   operands[2] = gen_reg_rtx (SImode);
1558 ;; ----------------------------------------------------------------------
1559 ;; SHIFTS
1560 ;; ----------------------------------------------------------------------
1562 (define_insn "ashlsi3"
1563   [(set (match_operand:SI 0 "register_operand" "=r,r")
1564         (ashift:SI
1565          (match_operand:SI 1 "register_operand" "0,0")
1566          (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1567   ""
1568   "@
1569   shl %2,%0
1570   shl %2,%0"
1571   [(set_attr "length" "4,2")
1572    (set_attr "cc" "set_znv")])
1574 (define_insn "lshrsi3"
1575   [(set (match_operand:SI 0 "register_operand" "=r,r")
1576         (lshiftrt:SI
1577          (match_operand:SI 1 "register_operand" "0,0")
1578          (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1579   ""
1580   "@
1581   shr %2,%0
1582   shr %2,%0"
1583   [(set_attr "length" "4,2")
1584    (set_attr "cc" "set_znv")])
1586 (define_insn "ashrsi3"
1587   [(set (match_operand:SI 0 "register_operand" "=r,r")
1588         (ashiftrt:SI
1589          (match_operand:SI 1 "register_operand" "0,0")
1590          (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1591   ""
1592   "@
1593   sar %2,%0
1594   sar %2,%0"
1595   [(set_attr "length" "4,2")
1596    (set_attr "cc" "set_znv")])
1598 ;; ----------------------------------------------------------------------
1599 ;; PROLOGUE/EPILOGUE
1600 ;; ----------------------------------------------------------------------
1601 (define_expand "prologue"
1602   [(const_int 0)]
1603   ""
1604   "expand_prologue (); DONE;")
1606 (define_expand "epilogue"
1607   [(return)]
1608   ""
1609   "
1611   /* Try to use the trivial return first.  Else use the
1612      full epilogue.  */
1613   if (0)
1614     emit_jump_insn (gen_return ());
1615   else
1616     expand_epilogue ();
1617   DONE;
1620 (define_insn "return"
1621   [(return)]
1622   "reload_completed && compute_frame_size (get_frame_size (), (long *)0) == 0"
1623   "jmp [r31]"
1624   [(set_attr "length" "2")
1625    (set_attr "cc" "none")])
1627 (define_insn "return_internal"
1628   [(return)
1629    (use (reg:SI 31))]
1630   ""
1631   "jmp [r31]"
1632   [(set_attr "length" "2")
1633    (set_attr "cc" "none")])
1637 ;; ----------------------------------------------------------------------
1638 ;; HELPER INSTRUCTIONS for saving the prologue and epilog registers
1639 ;; ----------------------------------------------------------------------
1641 ;; This pattern will match a stack adjust RTX followed by any number of push
1642 ;; RTXs.  These RTXs will then be turned into a suitable call to a worker
1643 ;; function.
1646 ;; Actually, convert the RTXs into a PREPARE instruction.
1648 (define_insn ""
1649  [(match_parallel 0 "pattern_is_ok_for_prepare"
1650    [(set (reg:SI 3)
1651          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1652     (set (mem:SI (plus:SI (reg:SI 3)
1653                           (match_operand:SI 2 "immediate_operand" "i")))
1654          (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
1655  "TARGET_PROLOG_FUNCTION && TARGET_V850E"
1656  "* return construct_prepare_instruction (operands[0]);
1658  [(set_attr "length" "4")
1659   (set_attr "cc"     "none")])
1661 (define_insn ""
1662  [(match_parallel 0 "pattern_is_ok_for_prologue"
1663    [(set (reg:SI 3)
1664          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1665     (set (mem:SI (plus:SI (reg:SI 3)
1666                            (match_operand:SI 2 "immediate_operand" "i")))
1667          (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
1668  "TARGET_PROLOG_FUNCTION && TARGET_V850"
1669  "* return construct_save_jarl (operands[0]);
1671  [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
1672                                      (const_string "16")
1673                                      (const_string "4")))
1674   (set_attr "cc"     "clobber")])
1677 ;; Actually, turn the RTXs into a DISPOSE instruction.
1679 (define_insn ""
1680  [(match_parallel 0 "pattern_is_ok_for_dispose"
1681    [(return)
1682     (set (reg:SI 3)
1683          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1684     (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
1685          (mem:SI (plus:SI (reg:SI 3)
1686                           (match_operand:SI 3 "immediate_operand" "i"))))])]
1687  "TARGET_PROLOG_FUNCTION && TARGET_V850E"
1688  "* return construct_dispose_instruction (operands[0]);
1690  [(set_attr "length" "4")
1691   (set_attr "cc"     "none")])
1693 ;; This pattern will match a return RTX followed by any number of pop RTXs
1694 ;; and possible a stack adjustment as well.  These RTXs will be turned into
1695 ;; a suitable call to a worker function.
1697 (define_insn ""
1698 [(match_parallel 0 "pattern_is_ok_for_epilogue"
1699    [(return)
1700     (set (reg:SI 3)
1701          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1702     (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
1703          (mem:SI (plus:SI (reg:SI 3)
1704                           (match_operand:SI 3 "immediate_operand" "i"))))])]
1705  "TARGET_PROLOG_FUNCTION && TARGET_V850"
1706  "* return construct_restore_jr (operands[0]);
1708  [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
1709                                      (const_string "12")
1710                                      (const_string "4")))
1711   (set_attr "cc"     "clobber")])
1713 ;; Initialize an interrupt function.  Do not depend on TARGET_PROLOG_FUNCTION.
1714 (define_insn "callt_save_interrupt"
1715   [(unspec_volatile [(const_int 0)] 2)]
1716     "TARGET_V850E && !TARGET_DISABLE_CALLT"
1717     ;; The CALLT instruction stores the next address of CALLT to CTPC register
1718     ;; without saving its previous value.  So if the interrupt handler
1719     ;; or its caller could possibly execute the CALLT insn, save_interrupt 
1720     ;; MUST NOT be called via CALLT.
1721     "*
1723   output_asm_insn (\"addi -24,   sp, sp\", operands);
1724   output_asm_insn (\"st.w r10,   12[sp]\", operands);
1725   output_asm_insn (\"stsr ctpc,  r10\",    operands);
1726   output_asm_insn (\"st.w r10,   16[sp]\", operands);
1727   output_asm_insn (\"stsr ctpsw, r10\",    operands);
1728   output_asm_insn (\"st.w r10,   20[sp]\", operands);
1729   output_asm_insn (\"callt ctoff(__callt_save_interrupt)\", operands);
1730   return \"\";
1732    [(set_attr "length" "26")
1733     (set_attr "cc" "none")])
1735 (define_insn "callt_return_interrupt"
1736   [(unspec_volatile [(const_int 0)] 3)]
1737   "TARGET_V850E && !TARGET_DISABLE_CALLT"
1738   "callt ctoff(__callt_return_interrupt)"
1739   [(set_attr "length" "2")
1740    (set_attr "cc" "clobber")])
1742 (define_insn "save_interrupt"
1743   [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16)))
1744    (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 30))
1745    (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 4))
1746    (set (mem:SI (plus:SI (reg:SI 3) (const_int  -8))) (reg:SI 1))
1747    (set (mem:SI (plus:SI (reg:SI 3) (const_int  -4))) (reg:SI 10))]
1748   ""
1749   "*
1751   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1752     return \"add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10\";
1753   else
1754     {
1755       output_asm_insn (\"add   -16, sp\", operands);
1756       output_asm_insn (\"st.w  r10, 12[sp]\", operands);
1757       output_asm_insn (\"st.w  ep, 0[sp]\", operands);
1758       output_asm_insn (\"st.w  gp, 4[sp]\", operands);
1759       output_asm_insn (\"st.w  r1, 8[sp]\", operands);
1760       output_asm_insn (\"movhi hi(__ep), r0, ep\", operands);
1761       output_asm_insn (\"movea lo(__ep), ep, ep\", operands);
1762       output_asm_insn (\"movhi hi(__gp), r0, gp\", operands);
1763       output_asm_insn (\"movea lo(__gp), gp, gp\", operands);
1764       return \"\";
1765     }
1767   [(set (attr "length")
1768         (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1769                        (const_int 10)
1770                        (const_int 34)))
1771    (set_attr "cc" "clobber")])
1772   
1773 ;; Restore r1, r4, r10, and return from the interrupt
1774 (define_insn "return_interrupt"
1775   [(return)
1776    (set (reg:SI 3)  (plus:SI (reg:SI 3) (const_int 16)))
1777    (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
1778    (set (reg:SI 1)  (mem:SI (plus:SI (reg:SI 3) (const_int  8))))
1779    (set (reg:SI 4)  (mem:SI (plus:SI (reg:SI 3) (const_int  4))))
1780    (set (reg:SI 30) (mem:SI (reg:SI 3)))]
1781   ""
1782   "*
1784   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1785     return \"jr __return_interrupt\";
1786   else 
1787     {
1788       output_asm_insn (\"ld.w 0[sp],  ep\",   operands);
1789       output_asm_insn (\"ld.w 4[sp],  gp\",   operands);
1790       output_asm_insn (\"ld.w 8[sp],  r1\",   operands);
1791       output_asm_insn (\"ld.w 12[sp], r10\", operands);
1792       output_asm_insn (\"addi 16, sp, sp\",   operands);
1793       output_asm_insn (\"reti\",            operands);
1794       return \"\";
1795     }
1797   [(set (attr "length")
1798         (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1799                        (const_int 4)
1800                        (const_int 24)))
1801    (set_attr "cc" "clobber")])
1803 ;; Save all registers except for the registers saved in save_interrupt when
1804 ;; an interrupt function makes a call.
1805 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1806 ;; all of memory.  This blocks insns from being moved across this point.
1807 ;; This is needed because the rest of the compiler is not ready to handle
1808 ;; insns this complicated.
1810 (define_insn "callt_save_all_interrupt"
1811   [(unspec_volatile [(const_int 0)] 0)]
1812   "TARGET_V850E && !TARGET_DISABLE_CALLT"
1813   "callt ctoff(__callt_save_all_interrupt)"
1814   [(set_attr "length" "2")
1815    (set_attr "cc" "none")])
1817 (define_insn "save_all_interrupt"
1818   [(unspec_volatile [(const_int 0)] 0)]
1819   ""
1820   "*
1822   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1823     return \"jarl __save_all_interrupt,r10\";
1825   output_asm_insn (\"addi -120, sp, sp\", operands);
1826   output_asm_insn (\"mov ep, r1\", operands);
1827   output_asm_insn (\"mov sp, ep\", operands);
1828   output_asm_insn (\"sst.w r31, 116[ep]\", operands);
1829   output_asm_insn (\"sst.w r2,  112[ep]\", operands);
1830   output_asm_insn (\"sst.w gp,  108[ep]\", operands);
1831   output_asm_insn (\"sst.w r6,  104[ep]\", operands);
1832   output_asm_insn (\"sst.w r7,  100[ep]\", operands);
1833   output_asm_insn (\"sst.w r8,   96[ep]\", operands);
1834   output_asm_insn (\"sst.w r9,   92[ep]\", operands);
1835   output_asm_insn (\"sst.w r11,  88[ep]\", operands);
1836   output_asm_insn (\"sst.w r12,  84[ep]\", operands);
1837   output_asm_insn (\"sst.w r13,  80[ep]\", operands);
1838   output_asm_insn (\"sst.w r14,  76[ep]\", operands);
1839   output_asm_insn (\"sst.w r15,  72[ep]\", operands);
1840   output_asm_insn (\"sst.w r16,  68[ep]\", operands);
1841   output_asm_insn (\"sst.w r17,  64[ep]\", operands);
1842   output_asm_insn (\"sst.w r18,  60[ep]\", operands);
1843   output_asm_insn (\"sst.w r19,  56[ep]\", operands);
1844   output_asm_insn (\"sst.w r20,  52[ep]\", operands);
1845   output_asm_insn (\"sst.w r21,  48[ep]\", operands);
1846   output_asm_insn (\"sst.w r22,  44[ep]\", operands);
1847   output_asm_insn (\"sst.w r23,  40[ep]\", operands);
1848   output_asm_insn (\"sst.w r24,  36[ep]\", operands);
1849   output_asm_insn (\"sst.w r25,  32[ep]\", operands);
1850   output_asm_insn (\"sst.w r26,  28[ep]\", operands);
1851   output_asm_insn (\"sst.w r27,  24[ep]\", operands);
1852   output_asm_insn (\"sst.w r28,  20[ep]\", operands);
1853   output_asm_insn (\"sst.w r29,  16[ep]\", operands);
1854   output_asm_insn (\"mov   r1,   ep\", operands);
1855   return \"\";
1857   [(set (attr "length")
1858         (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1859                        (const_int 4)
1860                        (const_int 62)
1861         ))
1862    (set_attr "cc" "clobber")])
1864 (define_insn "_save_all_interrupt"
1865   [(unspec_volatile [(const_int 0)] 0)]
1866   "TARGET_V850 && ! TARGET_LONG_CALLS"
1867   "jarl __save_all_interrupt,r10"
1868   [(set_attr "length" "4")
1869    (set_attr "cc" "clobber")])
1871 ;; Restore all registers saved when an interrupt function makes a call.
1872 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1873 ;; all of memory.  This blocks insns from being moved across this point.
1874 ;; This is needed because the rest of the compiler is not ready to handle
1875 ;; insns this complicated.
1877 (define_insn "callt_restore_all_interrupt"
1878   [(unspec_volatile [(const_int 0)] 1)]
1879   "TARGET_V850E && !TARGET_DISABLE_CALLT"
1880   "callt ctoff(__callt_restore_all_interrupt)"
1881   [(set_attr "length" "2")
1882    (set_attr "cc" "none")])
1884 (define_insn "restore_all_interrupt"
1885   [(unspec_volatile [(const_int 0)] 1)]
1886   ""
1887   "*
1889   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1890     return \"jarl __restore_all_interrupt,r10\";
1891   else
1892     {
1893       output_asm_insn (\"mov   ep,      r1\", operands);
1894       output_asm_insn (\"mov   sp,      ep\", operands);
1895       output_asm_insn (\"sld.w 116[ep], r31\", operands);
1896       output_asm_insn (\"sld.w 112[ep], r2\", operands);
1897       output_asm_insn (\"sld.w 108[ep], gp\", operands);
1898       output_asm_insn (\"sld.w 104[ep], r6\", operands);
1899       output_asm_insn (\"sld.w 100[ep], r7\", operands);
1900       output_asm_insn (\"sld.w 96[ep],  r8\", operands);
1901       output_asm_insn (\"sld.w 92[ep],  r9\", operands);
1902       output_asm_insn (\"sld.w 88[ep],  r11\", operands);
1903       output_asm_insn (\"sld.w 84[ep],  r12\", operands);
1904       output_asm_insn (\"sld.w 80[ep],  r13\", operands);
1905       output_asm_insn (\"sld.w 76[ep],  r14\", operands);
1906       output_asm_insn (\"sld.w 72[ep],  r15\", operands);
1907       output_asm_insn (\"sld.w 68[ep],  r16\", operands);
1908       output_asm_insn (\"sld.w 64[ep],  r17\", operands);
1909       output_asm_insn (\"sld.w 60[ep],  r18\", operands);
1910       output_asm_insn (\"sld.w 56[ep],  r19\", operands);
1911       output_asm_insn (\"sld.w 52[ep],  r20\", operands);
1912       output_asm_insn (\"sld.w 48[ep],  r21\", operands);
1913       output_asm_insn (\"sld.w 44[ep],  r22\", operands);
1914       output_asm_insn (\"sld.w 40[ep],  r23\", operands);
1915       output_asm_insn (\"sld.w 36[ep],  r24\", operands);
1916       output_asm_insn (\"sld.w 32[ep],  r25\", operands);
1917       output_asm_insn (\"sld.w 28[ep],  r26\", operands);
1918       output_asm_insn (\"sld.w 24[ep],  r27\", operands);
1919       output_asm_insn (\"sld.w 20[ep],  r28\", operands);
1920       output_asm_insn (\"sld.w 16[ep],  r29\", operands);
1921       output_asm_insn (\"mov   r1,      ep\", operands);
1922       output_asm_insn (\"addi  120, sp, sp\", operands);
1923       return \"\";
1924     }
1926   [(set (attr "length")
1927         (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1928                        (const_int 4)
1929                        (const_int 62)
1930         ))
1931    (set_attr "cc" "clobber")])
1933 (define_insn "_restore_all_interrupt"
1934   [(unspec_volatile [(const_int 0)] 1)]
1935   "TARGET_V850 && ! TARGET_LONG_CALLS"
1936   "jarl __restore_all_interrupt,r10"
1937   [(set_attr "length" "4")
1938    (set_attr "cc" "clobber")])
1940 ;; Save r6-r9 for a variable argument function
1941 (define_insn "save_r6_r9_v850e"
1942   [(set (mem:SI (reg:SI 3)) (reg:SI 6))
1943    (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
1944    (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
1945    (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
1946   ]
1947   "TARGET_PROLOG_FUNCTION && TARGET_V850E && !TARGET_DISABLE_CALLT"
1948   "callt ctoff(__callt_save_r6_r9)"
1949   [(set_attr "length" "2")
1950    (set_attr "cc" "none")])
1952 (define_insn "save_r6_r9"
1953   [(set (mem:SI (reg:SI 3)) (reg:SI 6))
1954    (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
1955    (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
1956    (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
1957    (clobber (reg:SI 10))]
1958   "TARGET_PROLOG_FUNCTION && ! TARGET_LONG_CALLS"
1959   "jarl __save_r6_r9,r10"
1960   [(set_attr "length" "4")
1961    (set_attr "cc" "clobber")])