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