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