Merged revisions 143552,143554,143557,143560,143562,143564-143567,143570-143573,14357...
[official-gcc.git] / gcc / config / v850 / v850.md
blob901075921769adefca10e71fbf9a1ce49b9ec4e4
1 ;; GCC machine description for NEC V850
2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2002, 2004, 2005, 2007, 2008
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   /* Shift index for the table array access.  */
1254   emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
1255   /* Load the table address into a pseudo.  */
1256   emit_insn (gen_movsi (tableaddress,
1257                         gen_rtx_LABEL_REF (Pmode, operands[3])));
1258   /* Add the table address to the index.  */
1259   emit_insn (gen_addsi3 (reg, reg, tableaddress));
1260   /* Load the table entry.  */
1261   mem = gen_const_mem (CASE_VECTOR_MODE, reg);
1262   if (! TARGET_BIG_SWITCH)
1263     {
1264       rtx reg2 = gen_reg_rtx (HImode);
1265       emit_insn (gen_movhi (reg2, mem));
1266       emit_insn (gen_extendhisi2 (reg, reg2));
1267     }
1268   else
1269     emit_insn (gen_movsi (reg, mem));
1270   /* Add the table address.  */
1271   emit_insn (gen_addsi3 (reg, reg, tableaddress));
1272   /* Branch to the switch label.  */
1273   emit_jump_insn (gen_tablejump (reg, operands[3]));
1274   DONE;
1277 ;; Call subroutine with no return value.
1279 (define_expand "call"
1280   [(call (match_operand:QI 0 "general_operand" "")
1281          (match_operand:SI 1 "general_operand" ""))]
1282   ""
1283   "
1285   if (! call_address_operand (XEXP (operands[0], 0), QImode)
1286       || TARGET_LONG_CALLS)
1287     XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1288   if (TARGET_LONG_CALLS)
1289     emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));
1290   else
1291     emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
1292   
1293   DONE;
1296 (define_insn "call_internal_short"
1297   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1298          (match_operand:SI 1 "general_operand" "g,g"))
1299    (clobber (reg:SI 31))]
1300   "! TARGET_LONG_CALLS"
1301   "@
1302   jarl %0,r31
1303   jarl .+4,r31 ; add 4,r31 ; jmp %0"
1304   [(set_attr "length" "4,8")]
1307 (define_insn "call_internal_long"
1308   [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1309          (match_operand:SI 1 "general_operand" "g,g"))
1310    (clobber (reg:SI 31))]
1311   "TARGET_LONG_CALLS"
1312   "*
1313   {
1314   if (which_alternative == 0)
1315     {
1316       if (GET_CODE (operands[0]) == REG)
1317         return \"jarl %0,r31\";
1318       else
1319         return \"movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11\";
1320     }
1321   else
1322     return \"jarl .+4,r31 ; add 4,r31 ; jmp %0\";
1323   }"
1324   [(set_attr "length" "16,8")]
1327 ;; Call subroutine, returning value in operand 0
1328 ;; (which must be a hard register).
1330 (define_expand "call_value"
1331   [(set (match_operand 0 "" "")
1332         (call (match_operand:QI 1 "general_operand" "")
1333               (match_operand:SI 2 "general_operand" "")))]
1334   ""
1335   "
1337   if (! call_address_operand (XEXP (operands[1], 0), QImode)
1338       || TARGET_LONG_CALLS)
1339     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1340   if (TARGET_LONG_CALLS)
1341     emit_call_insn (gen_call_value_internal_long (operands[0],
1342                                                   XEXP (operands[1], 0),
1343                                                   operands[2]));
1344   else
1345     emit_call_insn (gen_call_value_internal_short (operands[0],
1346                                                    XEXP (operands[1], 0),
1347                                                    operands[2]));
1348   DONE;
1351 (define_insn "call_value_internal_short"
1352   [(set (match_operand 0 "" "=r,r")
1353         (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1354               (match_operand:SI 2 "general_operand" "g,g")))
1355    (clobber (reg:SI 31))]
1356   "! TARGET_LONG_CALLS"
1357   "@
1358   jarl %1,r31
1359   jarl .+4,r31 ; add 4,r31 ; jmp %1"
1360   [(set_attr "length" "4,8")]
1363 (define_insn "call_value_internal_long"
1364   [(set (match_operand 0 "" "=r,r")
1365         (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1366               (match_operand:SI 2 "general_operand" "g,g")))
1367    (clobber (reg:SI 31))]
1368   "TARGET_LONG_CALLS"
1369   "*
1370   {
1371   if (which_alternative == 0)
1372     {
1373       if (GET_CODE (operands[1]) == REG)
1374         return \"jarl %1, r31\";
1375       else
1376       /* Reload can generate this pattern....  */
1377         return \"movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11\";
1378     }
1379   else
1380     return \"jarl .+4, r31 ; add 4, r31 ; jmp %1\";
1381   }"
1382   [(set_attr "length" "16,8")]
1385 (define_insn "nop"
1386   [(const_int 0)]
1387   ""
1388   "nop"
1389   [(set_attr "length" "2")
1390    (set_attr "cc" "none")])
1392 ;; ----------------------------------------------------------------------
1393 ;; EXTEND INSTRUCTIONS
1394 ;; ----------------------------------------------------------------------
1396 (define_insn ""
1397   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1398         (zero_extend:SI
1399          (match_operand:HI 1 "nonimmediate_operand" "0,r,T,m")))]
1400   "TARGET_V850E"
1401   "@
1402    zxh %0
1403    andi 65535,%1,%0
1404    sld.hu %1,%0
1405    ld.hu %1,%0"
1406   [(set_attr "length" "2,4,2,4")
1407    (set_attr "cc" "none_0hit,set_znv,none_0hit,none_0hit")])
1409 (define_insn "zero_extendhisi2"
1410   [(set (match_operand:SI 0 "register_operand" "=r")
1411         (zero_extend:SI
1412          (match_operand:HI 1 "register_operand" "r")))]
1413   ""
1414   "andi 65535,%1,%0"
1415   [(set_attr "length" "4")
1416    (set_attr "cc" "set_znv")])
1418 (define_insn ""
1419   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1420         (zero_extend:SI
1421          (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m")))]
1422   "TARGET_V850E"
1423   "@
1424    zxb %0
1425    andi 255,%1,%0
1426    sld.bu %1,%0
1427    ld.bu %1,%0"
1428   [(set_attr "length" "2,4,2,4")
1429    (set_attr "cc" "none_0hit,set_znv,none_0hit,none_0hit")])
1431 (define_insn "zero_extendqisi2"
1432   [(set (match_operand:SI 0 "register_operand" "=r")
1433         (zero_extend:SI
1434          (match_operand:QI 1 "register_operand" "r")))]
1435   ""
1436   "andi 255,%1,%0"
1437   [(set_attr "length" "4")
1438    (set_attr "cc" "set_znv")])
1440 ;;- sign extension instructions
1442 ;; ??? The extendhisi2 pattern should not emit shifts for v850e?
1444 (define_insn "*extendhisi_insn"
1445   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1446         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))]
1447   "TARGET_V850E"
1448   "@
1449    sxh %0
1450    sld.h %1,%0
1451    ld.h %1,%0"
1452   [(set_attr "length" "2,2,4")
1453    (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1455 ;; ??? This is missing a sign extend from memory pattern to match the ld.h
1456 ;; instruction.
1458 (define_expand "extendhisi2"
1459   [(set (match_dup 2)
1460         (ashift:SI (match_operand:HI 1 "register_operand" "")
1461                    (const_int 16)))
1462    (set (match_operand:SI 0 "register_operand" "")
1463        (ashiftrt:SI (match_dup 2)
1464                      (const_int 16)))]
1465   ""
1466   "
1468   operands[1] = gen_lowpart (SImode, operands[1]);
1469   operands[2] = gen_reg_rtx (SImode);
1472 ;; ??? The extendqisi2 pattern should not emit shifts for v850e?
1474 (define_insn "*extendqisi_insn"
1475   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1476         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))]
1477   "TARGET_V850E"
1478   "@
1479    sxb %0
1480    sld.b %1,%0
1481    ld.b %1,%0"
1482   [(set_attr "length" "2,2,4")
1483    (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1485 ;; ??? This is missing a sign extend from memory pattern to match the ld.b
1486 ;; instruction.
1488 (define_expand "extendqisi2"
1489   [(set (match_dup 2)
1490         (ashift:SI (match_operand:QI 1 "register_operand" "")
1491                    (const_int 24)))
1492    (set (match_operand:SI 0 "register_operand" "")
1493         (ashiftrt:SI (match_dup 2)
1494                      (const_int 24)))]
1495   ""
1496   "
1498   operands[1] = gen_lowpart (SImode, operands[1]);
1499   operands[2] = gen_reg_rtx (SImode);
1502 ;; ----------------------------------------------------------------------
1503 ;; SHIFTS
1504 ;; ----------------------------------------------------------------------
1506 (define_insn "ashlsi3"
1507   [(set (match_operand:SI 0 "register_operand" "=r,r")
1508         (ashift:SI
1509          (match_operand:SI 1 "register_operand" "0,0")
1510          (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1511   ""
1512   "@
1513   shl %2,%0
1514   shl %2,%0"
1515   [(set_attr "length" "4,2")
1516    (set_attr "cc" "set_znv")])
1518 (define_insn "lshrsi3"
1519   [(set (match_operand:SI 0 "register_operand" "=r,r")
1520         (lshiftrt:SI
1521          (match_operand:SI 1 "register_operand" "0,0")
1522          (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1523   ""
1524   "@
1525   shr %2,%0
1526   shr %2,%0"
1527   [(set_attr "length" "4,2")
1528    (set_attr "cc" "set_znv")])
1530 (define_insn "ashrsi3"
1531   [(set (match_operand:SI 0 "register_operand" "=r,r")
1532         (ashiftrt:SI
1533          (match_operand:SI 1 "register_operand" "0,0")
1534          (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1535   ""
1536   "@
1537   sar %2,%0
1538   sar %2,%0"
1539   [(set_attr "length" "4,2")
1540    (set_attr "cc" "set_znv")])
1542 ;; ----------------------------------------------------------------------
1543 ;; PROLOGUE/EPILOGUE
1544 ;; ----------------------------------------------------------------------
1545 (define_expand "prologue"
1546   [(const_int 0)]
1547   ""
1548   "expand_prologue (); DONE;")
1550 (define_expand "epilogue"
1551   [(return)]
1552   ""
1553   "
1555   /* Try to use the trivial return first.  Else use the
1556      full epilogue.  */
1557   if (0)
1558     emit_jump_insn (gen_return ());
1559   else
1560     expand_epilogue ();
1561   DONE;
1564 (define_insn "return"
1565   [(return)]
1566   "reload_completed && compute_frame_size (get_frame_size (), (long *)0) == 0"
1567   "jmp [r31]"
1568   [(set_attr "length" "2")
1569    (set_attr "cc" "none")])
1571 (define_insn "return_internal"
1572   [(return)
1573    (use (reg:SI 31))]
1574   ""
1575   "jmp [r31]"
1576   [(set_attr "length" "2")
1577    (set_attr "cc" "none")])
1581 ;; ----------------------------------------------------------------------
1582 ;; HELPER INSTRUCTIONS for saving the prologue and epilogue registers
1583 ;; ----------------------------------------------------------------------
1585 ;; This pattern will match a stack adjust RTX followed by any number of push
1586 ;; RTXs.  These RTXs will then be turned into a suitable call to a worker
1587 ;; function.
1590 ;; Actually, convert the RTXs into a PREPARE instruction.
1592 (define_insn ""
1593  [(match_parallel 0 "pattern_is_ok_for_prepare"
1594    [(set (reg:SI 3)
1595          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1596     (set (mem:SI (plus:SI (reg:SI 3)
1597                           (match_operand:SI 2 "immediate_operand" "i")))
1598          (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
1599  "TARGET_PROLOG_FUNCTION && TARGET_V850E"
1600  "* return construct_prepare_instruction (operands[0]);
1602  [(set_attr "length" "4")
1603   (set_attr "cc"     "none")])
1605 (define_insn ""
1606  [(match_parallel 0 "pattern_is_ok_for_prologue"
1607    [(set (reg:SI 3)
1608          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1609     (set (mem:SI (plus:SI (reg:SI 3)
1610                            (match_operand:SI 2 "immediate_operand" "i")))
1611          (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
1612  "TARGET_PROLOG_FUNCTION && TARGET_V850"
1613  "* return construct_save_jarl (operands[0]);
1615  [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
1616                                      (const_string "16")
1617                                      (const_string "4")))
1618   (set_attr "cc"     "clobber")])
1621 ;; Actually, turn the RTXs into a DISPOSE instruction.
1623 (define_insn ""
1624  [(match_parallel 0 "pattern_is_ok_for_dispose"
1625    [(return)
1626     (set (reg:SI 3)
1627          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1628     (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
1629          (mem:SI (plus:SI (reg:SI 3)
1630                           (match_operand:SI 3 "immediate_operand" "i"))))])]
1631  "TARGET_PROLOG_FUNCTION && TARGET_V850E"
1632  "* return construct_dispose_instruction (operands[0]);
1634  [(set_attr "length" "4")
1635   (set_attr "cc"     "none")])
1637 ;; This pattern will match a return RTX followed by any number of pop RTXs
1638 ;; and possible a stack adjustment as well.  These RTXs will be turned into
1639 ;; a suitable call to a worker function.
1641 (define_insn ""
1642 [(match_parallel 0 "pattern_is_ok_for_epilogue"
1643    [(return)
1644     (set (reg:SI 3)
1645          (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1646     (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
1647          (mem:SI (plus:SI (reg:SI 3)
1648                           (match_operand:SI 3 "immediate_operand" "i"))))])]
1649  "TARGET_PROLOG_FUNCTION && TARGET_V850"
1650  "* return construct_restore_jr (operands[0]);
1652  [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
1653                                      (const_string "12")
1654                                      (const_string "4")))
1655   (set_attr "cc"     "clobber")])
1657 ;; Initialize an interrupt function.  Do not depend on TARGET_PROLOG_FUNCTION.
1658 (define_insn "callt_save_interrupt"
1659   [(unspec_volatile [(const_int 0)] 2)]
1660     "TARGET_V850E && !TARGET_DISABLE_CALLT"
1661     ;; The CALLT instruction stores the next address of CALLT to CTPC register
1662     ;; without saving its previous value.  So if the interrupt handler
1663     ;; or its caller could possibly execute the CALLT insn, save_interrupt 
1664     ;; MUST NOT be called via CALLT.
1665     "*
1667   output_asm_insn (\"addi -24,   sp, sp\", operands);
1668   output_asm_insn (\"st.w r10,   12[sp]\", operands);
1669   output_asm_insn (\"stsr ctpc,  r10\",    operands);
1670   output_asm_insn (\"st.w r10,   16[sp]\", operands);
1671   output_asm_insn (\"stsr ctpsw, r10\",    operands);
1672   output_asm_insn (\"st.w r10,   20[sp]\", operands);
1673   output_asm_insn (\"callt ctoff(__callt_save_interrupt)\", operands);
1674   return \"\";
1676    [(set_attr "length" "26")
1677     (set_attr "cc" "none")])
1679 (define_insn "callt_return_interrupt"
1680   [(unspec_volatile [(const_int 0)] 3)]
1681   "TARGET_V850E && !TARGET_DISABLE_CALLT"
1682   "callt ctoff(__callt_return_interrupt)"
1683   [(set_attr "length" "2")
1684    (set_attr "cc" "clobber")])
1686 (define_insn "save_interrupt"
1687   [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16)))
1688    (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 30))
1689    (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 4))
1690    (set (mem:SI (plus:SI (reg:SI 3) (const_int  -8))) (reg:SI 1))
1691    (set (mem:SI (plus:SI (reg:SI 3) (const_int  -4))) (reg:SI 10))]
1692   ""
1693   "*
1695   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1696     return \"add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10\";
1697   else
1698     {
1699       output_asm_insn (\"add   -16, sp\", operands);
1700       output_asm_insn (\"st.w  r10, 12[sp]\", operands);
1701       output_asm_insn (\"st.w  ep, 0[sp]\", operands);
1702       output_asm_insn (\"st.w  gp, 4[sp]\", operands);
1703       output_asm_insn (\"st.w  r1, 8[sp]\", operands);
1704       output_asm_insn (\"movhi hi(__ep), r0, ep\", operands);
1705       output_asm_insn (\"movea lo(__ep), ep, ep\", operands);
1706       output_asm_insn (\"movhi hi(__gp), r0, gp\", operands);
1707       output_asm_insn (\"movea lo(__gp), gp, gp\", operands);
1708       return \"\";
1709     }
1711   [(set (attr "length")
1712         (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1713                        (const_int 10)
1714                        (const_int 34)))
1715    (set_attr "cc" "clobber")])
1716   
1717 ;; Restore r1, r4, r10, and return from the interrupt
1718 (define_insn "return_interrupt"
1719   [(return)
1720    (set (reg:SI 3)  (plus:SI (reg:SI 3) (const_int 16)))
1721    (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
1722    (set (reg:SI 1)  (mem:SI (plus:SI (reg:SI 3) (const_int  8))))
1723    (set (reg:SI 4)  (mem:SI (plus:SI (reg:SI 3) (const_int  4))))
1724    (set (reg:SI 30) (mem:SI (reg:SI 3)))]
1725   ""
1726   "*
1728   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1729     return \"jr __return_interrupt\";
1730   else 
1731     {
1732       output_asm_insn (\"ld.w 0[sp],  ep\",   operands);
1733       output_asm_insn (\"ld.w 4[sp],  gp\",   operands);
1734       output_asm_insn (\"ld.w 8[sp],  r1\",   operands);
1735       output_asm_insn (\"ld.w 12[sp], r10\", operands);
1736       output_asm_insn (\"addi 16, sp, sp\",   operands);
1737       output_asm_insn (\"reti\",            operands);
1738       return \"\";
1739     }
1741   [(set (attr "length")
1742         (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1743                        (const_int 4)
1744                        (const_int 24)))
1745    (set_attr "cc" "clobber")])
1747 ;; Save all registers except for the registers saved in save_interrupt when
1748 ;; an interrupt function makes a call.
1749 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1750 ;; all of memory.  This blocks insns from being moved across this point.
1751 ;; This is needed because the rest of the compiler is not ready to handle
1752 ;; insns this complicated.
1754 (define_insn "callt_save_all_interrupt"
1755   [(unspec_volatile [(const_int 0)] 0)]
1756   "TARGET_V850E && !TARGET_DISABLE_CALLT"
1757   "callt ctoff(__callt_save_all_interrupt)"
1758   [(set_attr "length" "2")
1759    (set_attr "cc" "none")])
1761 (define_insn "save_all_interrupt"
1762   [(unspec_volatile [(const_int 0)] 0)]
1763   ""
1764   "*
1766   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1767     return \"jarl __save_all_interrupt,r10\";
1769   output_asm_insn (\"addi -120, sp, sp\", operands);
1771   if (TARGET_EP)
1772     {
1773       output_asm_insn (\"mov ep, r1\", operands);
1774       output_asm_insn (\"mov sp, ep\", operands);
1775       output_asm_insn (\"sst.w r31, 116[ep]\", operands);
1776       output_asm_insn (\"sst.w r2,  112[ep]\", operands);
1777       output_asm_insn (\"sst.w gp,  108[ep]\", operands);
1778       output_asm_insn (\"sst.w r6,  104[ep]\", operands);
1779       output_asm_insn (\"sst.w r7,  100[ep]\", operands);
1780       output_asm_insn (\"sst.w r8,   96[ep]\", operands);
1781       output_asm_insn (\"sst.w r9,   92[ep]\", operands);
1782       output_asm_insn (\"sst.w r11,  88[ep]\", operands);
1783       output_asm_insn (\"sst.w r12,  84[ep]\", operands);
1784       output_asm_insn (\"sst.w r13,  80[ep]\", operands);
1785       output_asm_insn (\"sst.w r14,  76[ep]\", operands);
1786       output_asm_insn (\"sst.w r15,  72[ep]\", operands);
1787       output_asm_insn (\"sst.w r16,  68[ep]\", operands);
1788       output_asm_insn (\"sst.w r17,  64[ep]\", operands);
1789       output_asm_insn (\"sst.w r18,  60[ep]\", operands);
1790       output_asm_insn (\"sst.w r19,  56[ep]\", operands);
1791       output_asm_insn (\"sst.w r20,  52[ep]\", operands);
1792       output_asm_insn (\"sst.w r21,  48[ep]\", operands);
1793       output_asm_insn (\"sst.w r22,  44[ep]\", operands);
1794       output_asm_insn (\"sst.w r23,  40[ep]\", operands);
1795       output_asm_insn (\"sst.w r24,  36[ep]\", operands);
1796       output_asm_insn (\"sst.w r25,  32[ep]\", operands);
1797       output_asm_insn (\"sst.w r26,  28[ep]\", operands);
1798       output_asm_insn (\"sst.w r27,  24[ep]\", operands);
1799       output_asm_insn (\"sst.w r28,  20[ep]\", operands);
1800       output_asm_insn (\"sst.w r29,  16[ep]\", operands);
1801       output_asm_insn (\"mov   r1,   ep\", operands);
1802     }
1803   else
1804     {
1805       output_asm_insn (\"st.w r31, 116[sp]\", operands);
1806       output_asm_insn (\"st.w r2,  112[sp]\", operands);
1807       output_asm_insn (\"st.w gp,  108[sp]\", operands);
1808       output_asm_insn (\"st.w r6,  104[sp]\", operands);
1809       output_asm_insn (\"st.w r7,  100[sp]\", operands);
1810       output_asm_insn (\"st.w r8,   96[sp]\", operands);
1811       output_asm_insn (\"st.w r9,   92[sp]\", operands);
1812       output_asm_insn (\"st.w r11,  88[sp]\", operands);
1813       output_asm_insn (\"st.w r12,  84[sp]\", operands);
1814       output_asm_insn (\"st.w r13,  80[sp]\", operands);
1815       output_asm_insn (\"st.w r14,  76[sp]\", operands);
1816       output_asm_insn (\"st.w r15,  72[sp]\", operands);
1817       output_asm_insn (\"st.w r16,  68[sp]\", operands);
1818       output_asm_insn (\"st.w r17,  64[sp]\", operands);
1819       output_asm_insn (\"st.w r18,  60[sp]\", operands);
1820       output_asm_insn (\"st.w r19,  56[sp]\", operands);
1821       output_asm_insn (\"st.w r20,  52[sp]\", operands);
1822       output_asm_insn (\"st.w r21,  48[sp]\", operands);
1823       output_asm_insn (\"st.w r22,  44[sp]\", operands);
1824       output_asm_insn (\"st.w r23,  40[sp]\", operands);
1825       output_asm_insn (\"st.w r24,  36[sp]\", operands);
1826       output_asm_insn (\"st.w r25,  32[sp]\", operands);
1827       output_asm_insn (\"st.w r26,  28[sp]\", operands);
1828       output_asm_insn (\"st.w r27,  24[sp]\", operands);
1829       output_asm_insn (\"st.w r28,  20[sp]\", operands);
1830       output_asm_insn (\"st.w r29,  16[sp]\", operands);
1831     }
1832     
1833   return \"\";
1835   [(set (attr "length")
1836         (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1837                        (const_int 4)
1838                        (const_int 62)
1839         ))
1840    (set_attr "cc" "clobber")])
1842 (define_insn "_save_all_interrupt"
1843   [(unspec_volatile [(const_int 0)] 0)]
1844   "TARGET_V850 && ! TARGET_LONG_CALLS"
1845   "jarl __save_all_interrupt,r10"
1846   [(set_attr "length" "4")
1847    (set_attr "cc" "clobber")])
1849 ;; Restore all registers saved when an interrupt function makes a call.
1850 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1851 ;; all of memory.  This blocks insns from being moved across this point.
1852 ;; This is needed because the rest of the compiler is not ready to handle
1853 ;; insns this complicated.
1855 (define_insn "callt_restore_all_interrupt"
1856   [(unspec_volatile [(const_int 0)] 1)]
1857   "TARGET_V850E && !TARGET_DISABLE_CALLT"
1858   "callt ctoff(__callt_restore_all_interrupt)"
1859   [(set_attr "length" "2")
1860    (set_attr "cc" "none")])
1862 (define_insn "restore_all_interrupt"
1863   [(unspec_volatile [(const_int 0)] 1)]
1864   ""
1865   "*
1867   if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1868     return \"jarl __restore_all_interrupt,r10\";
1870   if (TARGET_EP)
1871     {
1872       output_asm_insn (\"mov   ep,      r1\", operands);
1873       output_asm_insn (\"mov   sp,      ep\", operands);
1874       output_asm_insn (\"sld.w 116[ep], r31\", operands);
1875       output_asm_insn (\"sld.w 112[ep], r2\", operands);
1876       output_asm_insn (\"sld.w 108[ep], gp\", operands);
1877       output_asm_insn (\"sld.w 104[ep], r6\", operands);
1878       output_asm_insn (\"sld.w 100[ep], r7\", operands);
1879       output_asm_insn (\"sld.w 96[ep],  r8\", operands);
1880       output_asm_insn (\"sld.w 92[ep],  r9\", operands);
1881       output_asm_insn (\"sld.w 88[ep],  r11\", operands);
1882       output_asm_insn (\"sld.w 84[ep],  r12\", operands);
1883       output_asm_insn (\"sld.w 80[ep],  r13\", operands);
1884       output_asm_insn (\"sld.w 76[ep],  r14\", operands);
1885       output_asm_insn (\"sld.w 72[ep],  r15\", operands);
1886       output_asm_insn (\"sld.w 68[ep],  r16\", operands);
1887       output_asm_insn (\"sld.w 64[ep],  r17\", operands);
1888       output_asm_insn (\"sld.w 60[ep],  r18\", operands);
1889       output_asm_insn (\"sld.w 56[ep],  r19\", operands);
1890       output_asm_insn (\"sld.w 52[ep],  r20\", operands);
1891       output_asm_insn (\"sld.w 48[ep],  r21\", operands);
1892       output_asm_insn (\"sld.w 44[ep],  r22\", operands);
1893       output_asm_insn (\"sld.w 40[ep],  r23\", operands);
1894       output_asm_insn (\"sld.w 36[ep],  r24\", operands);
1895       output_asm_insn (\"sld.w 32[ep],  r25\", operands);
1896       output_asm_insn (\"sld.w 28[ep],  r26\", operands);
1897       output_asm_insn (\"sld.w 24[ep],  r27\", operands);
1898       output_asm_insn (\"sld.w 20[ep],  r28\", operands);
1899       output_asm_insn (\"sld.w 16[ep],  r29\", operands);
1900       output_asm_insn (\"mov   r1,      ep\", operands);
1901     }
1902   else
1903     {
1904       output_asm_insn (\"ld.w 116[sp], r31\", operands);
1905       output_asm_insn (\"ld.w 112[sp], r2\", operands);
1906       output_asm_insn (\"ld.w 108[sp], gp\", operands);
1907       output_asm_insn (\"ld.w 104[sp], r6\", operands);
1908       output_asm_insn (\"ld.w 100[sp], r7\", operands);
1909       output_asm_insn (\"ld.w 96[sp],  r8\", operands);
1910       output_asm_insn (\"ld.w 92[sp],  r9\", operands);
1911       output_asm_insn (\"ld.w 88[sp],  r11\", operands);
1912       output_asm_insn (\"ld.w 84[sp],  r12\", operands);
1913       output_asm_insn (\"ld.w 80[sp],  r13\", operands);
1914       output_asm_insn (\"ld.w 76[sp],  r14\", operands);
1915       output_asm_insn (\"ld.w 72[sp],  r15\", operands);
1916       output_asm_insn (\"ld.w 68[sp],  r16\", operands);
1917       output_asm_insn (\"ld.w 64[sp],  r17\", operands);
1918       output_asm_insn (\"ld.w 60[sp],  r18\", operands);
1919       output_asm_insn (\"ld.w 56[sp],  r19\", operands);
1920       output_asm_insn (\"ld.w 52[sp],  r20\", operands);
1921       output_asm_insn (\"ld.w 48[sp],  r21\", operands);
1922       output_asm_insn (\"ld.w 44[sp],  r22\", operands);
1923       output_asm_insn (\"ld.w 40[sp],  r23\", operands);
1924       output_asm_insn (\"ld.w 36[sp],  r24\", operands);
1925       output_asm_insn (\"ld.w 32[sp],  r25\", operands);
1926       output_asm_insn (\"ld.w 28[sp],  r26\", operands);
1927       output_asm_insn (\"ld.w 24[sp],  r27\", operands);
1928       output_asm_insn (\"ld.w 20[sp],  r28\", operands);
1929       output_asm_insn (\"ld.w 16[sp],  r29\", operands);
1930     }
1931   output_asm_insn (\"addi  120, sp, sp\", operands);
1932   return \"\";
1934   [(set (attr "length")
1935         (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1936                        (const_int 4)
1937                        (const_int 62)
1938         ))
1939    (set_attr "cc" "clobber")])
1941 (define_insn "_restore_all_interrupt"
1942   [(unspec_volatile [(const_int 0)] 1)]
1943   "TARGET_V850 && ! TARGET_LONG_CALLS"
1944   "jarl __restore_all_interrupt,r10"
1945   [(set_attr "length" "4")
1946    (set_attr "cc" "clobber")])
1948 ;; Save r6-r9 for a variable argument function
1949 (define_insn "save_r6_r9_v850e"
1950   [(set (mem:SI (reg:SI 3)) (reg:SI 6))
1951    (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
1952    (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
1953    (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
1954   ]
1955   "TARGET_PROLOG_FUNCTION && TARGET_V850E && !TARGET_DISABLE_CALLT"
1956   "callt ctoff(__callt_save_r6_r9)"
1957   [(set_attr "length" "2")
1958    (set_attr "cc" "none")])
1960 (define_insn "save_r6_r9"
1961   [(set (mem:SI (reg:SI 3)) (reg:SI 6))
1962    (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
1963    (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
1964    (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
1965    (clobber (reg:SI 10))]
1966   "TARGET_PROLOG_FUNCTION && ! TARGET_LONG_CALLS"
1967   "jarl __save_r6_r9,r10"
1968   [(set_attr "length" "4")
1969    (set_attr "cc" "clobber")])