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