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