1 ;; GCC machine description for NEC V850
2 ;; Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
4 ;; Contributed by Jeff Law (law@cygnus.com).
6 ;; This file is part of GNU CC.
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING. If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
23 ;; The original PO technology requires these to be ordered by speed,
24 ;; so that assigner will pick the fastest.
26 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;; The V851 manual states that the instruction address space is 16M;
29 ;; the various branch/call instructions only have a 22bit offset (4M range).
31 ;; One day we'll probably need to handle calls to targets more than 4M
34 ;; The size of instructions in bytes.
36 (define_attr "length" ""
39 (define_attr "long_calls" "yes,no"
40 (const (if_then_else (symbol_ref "TARGET_LONG_CALLS")
42 (const_string "no"))))
44 ;; Types of instructions (for scheduling purposes).
46 (define_attr "type" "load,mult,other"
47 (const_string "other"))
49 ;; Condition code settings.
50 ;; none - insn does not affect cc
51 ;; none_0hit - insn does not affect cc but it does modify operand 0
52 ;; This attribute is used to keep track of when operand 0 changes.
53 ;; See the description of NOTICE_UPDATE_CC for more info.
54 ;; set_znv - sets z,n,v to usable values; c is unknown.
55 ;; set_zn - sets z,n to usable values; v,c is unknown.
56 ;; compare - compare instruction
57 ;; clobber - value of cc is unknown
58 (define_attr "cc" "none,none_0hit,set_zn,set_znv,compare,clobber"
59 (const_string "clobber"))
61 ;; Function units for the V850. As best as I can tell, there's
62 ;; a traditional memory load/use stall as well as a stall if
63 ;; the result of a multiply is used too early.
65 (define_function_unit "memory" 1 0 (eq_attr "type" "load") 2 0)
66 (define_function_unit "mult" 1 0 (eq_attr "type" "mult") 2 0)
69 ;; ----------------------------------------------------------------------
71 ;; ----------------------------------------------------------------------
75 (define_expand "movqi"
76 [(set (match_operand:QI 0 "general_operand" "")
77 (match_operand:QI 1 "general_operand" ""))]
81 /* One of the ops has to be in a register or 0 */
82 if (!register_operand (operand0, QImode)
83 && !reg_or_0_operand (operand1, QImode))
84 operands[1] = copy_to_mode_reg (QImode, operand1);
87 (define_insn "*movqi_internal"
88 [(set (match_operand:QI 0 "general_operand" "=r,r,r,Q,r,m,m")
89 (match_operand:QI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
90 "register_operand (operands[0], QImode)
91 || reg_or_0_operand (operands[1], QImode)"
92 "* return output_move_single (operands);"
93 [(set_attr "length" "2,4,2,2,4,4,4")
94 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
95 (set_attr "type" "other,other,load,other,load,other,other")])
99 (define_expand "movhi"
100 [(set (match_operand:HI 0 "general_operand" "")
101 (match_operand:HI 1 "general_operand" ""))]
105 /* One of the ops has to be in a register or 0 */
106 if (!register_operand (operand0, HImode)
107 && !reg_or_0_operand (operand1, HImode))
108 operands[1] = copy_to_mode_reg (HImode, operand1);
111 (define_insn "*movhi_internal"
112 [(set (match_operand:HI 0 "general_operand" "=r,r,r,Q,r,m,m")
113 (match_operand:HI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
114 "register_operand (operands[0], HImode)
115 || reg_or_0_operand (operands[1], HImode)"
116 "* return output_move_single (operands);"
117 [(set_attr "length" "2,4,2,2,4,4,4")
118 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
119 (set_attr "type" "other,other,load,other,load,other,other")])
123 (define_insn "*movsi_high"
124 [(set (match_operand:SI 0 "register_operand" "=r")
125 (high:SI (match_operand 1 "" "")))]
128 [(set_attr "length" "4")
129 (set_attr "cc" "none_0hit")
130 (set_attr "type" "other")])
132 (define_insn "*movsi_lo"
133 [(set (match_operand:SI 0 "register_operand" "=r")
134 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
135 (match_operand:SI 2 "immediate_operand" "i")))]
138 [(set_attr "length" "4")
139 (set_attr "cc" "none_0hit")
140 (set_attr "type" "other")])
142 (define_expand "movsi"
143 [(set (match_operand:SI 0 "general_operand" "")
144 (match_operand:SI 1 "general_operand" ""))]
148 /* One of the ops has to be in a register or 0 */
149 if (!register_operand (operand0, SImode)
150 && !reg_or_0_operand (operand1, SImode))
151 operands[1] = copy_to_mode_reg (SImode, operand1);
153 /* Some constants, as well as symbolic operands
154 must be done with HIGH & LO_SUM patterns. */
155 if (CONSTANT_P (operands[1])
156 && GET_CODE (operands[1]) != HIGH
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])))))
166 if (reload_in_progress || reload_completed)
169 temp = gen_reg_rtx (SImode);
171 emit_insn (gen_rtx (SET, SImode, temp,
172 gen_rtx (HIGH, SImode, operand1)));
173 emit_insn (gen_rtx (SET, SImode, operand0,
174 gen_rtx (LO_SUM, SImode, temp, operand1)));
179 (define_insn "*movsi_internal"
180 [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m")
181 (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))]
182 "register_operand (operands[0], SImode)
183 || reg_or_0_operand (operands[1], SImode)"
184 "* return output_move_single (operands);"
185 [(set_attr "length" "2,4,4,2,2,4,4,4,4")
186 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
187 (set_attr "type" "other,other,other,load,other,load,other,other,other")])
191 (define_expand "movdi"
192 [(set (match_operand:DI 0 "general_operand" "")
193 (match_operand:DI 1 "general_operand" ""))]
197 /* One of the ops has to be in a register or 0 */
198 if (!register_operand (operand0, DImode)
199 && !reg_or_0_operand (operand1, DImode))
200 operands[1] = copy_to_mode_reg (DImode, operand1);
203 (define_insn "*movdi_internal"
204 [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,m,r")
205 (match_operand:DI 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
206 "register_operand (operands[0], DImode)
207 || reg_or_0_operand (operands[1], DImode)"
208 "* return output_move_double (operands);"
209 [(set_attr "length" "4,8,8,16,8,8,8,16")
210 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
211 (set_attr "type" "other,other,other,other,load,other,other,other")])
213 (define_expand "movsf"
214 [(set (match_operand:SF 0 "general_operand" "")
215 (match_operand:SF 1 "general_operand" ""))]
219 /* One of the ops has to be in a register or 0 */
220 if (!register_operand (operand0, SFmode)
221 && !reg_or_0_operand (operand1, SFmode))
222 operands[1] = copy_to_mode_reg (SFmode, operand1);
225 (define_insn "*movsf_internal"
226 [(set (match_operand:SF 0 "general_operand" "=r,r,r,r,r,Q,r,m,m,r")
227 (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))]
228 "register_operand (operands[0], SFmode)
229 || reg_or_0_operand (operands[1], SFmode)"
230 "* return output_move_single (operands);"
231 [(set_attr "length" "2,4,4,8,2,2,4,4,4,8")
232 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
233 (set_attr "type" "other,other,other,other,load,other,load,other,other,other")])
235 (define_expand "movdf"
236 [(set (match_operand:DF 0 "general_operand" "")
237 (match_operand:DF 1 "general_operand" ""))]
241 /* One of the ops has to be in a register or 0 */
242 if (!register_operand (operand0, DFmode)
243 && !reg_or_0_operand (operand1, DFmode))
244 operands[1] = copy_to_mode_reg (DFmode, operand1);
247 (define_insn "*movdf_internal"
248 [(set (match_operand:DF 0 "general_operand" "=r,r,r,r,r,m,m,r")
249 (match_operand:DF 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
250 "register_operand (operands[0], DFmode)
251 || reg_or_0_operand (operands[1], DFmode)"
252 "* return output_move_double (operands);"
253 [(set_attr "length" "4,8,8,16,8,8,8,16")
254 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
255 (set_attr "type" "other,other,other,other,load,other,other,other")])
258 ;; ----------------------------------------------------------------------
260 ;; ----------------------------------------------------------------------
262 (define_insn "*v850_tst1"
263 [(set (cc0) (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
265 (match_operand:QI 1 "const_int_operand" "n")))]
268 [(set_attr "length" "4")
269 (set_attr "cc" "clobber")])
271 ;; This replaces ld.b;sar;andi with tst1;setf nz.
273 ;; ??? The zero_extract sets the Z bit to the opposite of what one would
274 ;; expect. This perhaps should be wrapped in a (eq: X (const_int 0)).
277 [(set (match_operand:SI 0 "register_operand" "")
278 (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
280 (match_operand 2 "const_int_operand" "")))]
282 [(set (cc0) (zero_extract:SI (match_dup 1)
285 (set (match_dup 0) (ne:SI (cc0) (const_int 0)))])
288 [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
291 [(set_attr "length" "2")
292 (set_attr "cc" "set_znv")])
296 (compare (match_operand:SI 0 "register_operand" "r,r")
297 (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
302 [(set_attr "length" "2,2")
303 (set_attr "cc" "compare")])
305 ;; ----------------------------------------------------------------------
307 ;; ----------------------------------------------------------------------
309 (define_insn "addsi3"
310 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
311 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
312 (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))]
318 [(set_attr "length" "2,4,4")
319 (set_attr "cc" "set_zn,set_zn,set_zn")])
321 ;; ----------------------------------------------------------------------
322 ;; SUBTRACT INSTRUCTIONS
323 ;; ----------------------------------------------------------------------
325 (define_insn "subsi3"
326 [(set (match_operand:SI 0 "register_operand" "=r,r")
327 (minus:SI (match_operand:SI 1 "register_operand" "0,r")
328 (match_operand:SI 2 "register_operand" "r,0")))]
333 [(set_attr "length" "2,2")
334 (set_attr "cc" "set_zn")])
336 (define_insn "negsi2"
337 [(set (match_operand:SI 0 "register_operand" "=r")
338 (neg:SI (match_operand:SI 1 "register_operand" "0")))]
341 [(set_attr "length" "2")
342 (set_attr "cc" "set_zn")])
344 ;; ----------------------------------------------------------------------
345 ;; MULTIPLY INSTRUCTIONS
346 ;; ----------------------------------------------------------------------
348 (define_expand "mulhisi3"
349 [(set (match_operand:SI 0 "register_operand" "")
351 (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
352 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
356 (define_insn "*mulhisi3_internal1"
357 [(set (match_operand:SI 0 "register_operand" "=r")
359 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
360 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
363 [(set_attr "length" "2")
364 (set_attr "cc" "none_0hit")
365 (set_attr "type" "mult")])
367 ;; ??? Sign extending constants isn't valid. Fix?
369 (define_insn "*mulhisi3_internal2"
370 [(set (match_operand:SI 0 "register_operand" "=r,r")
372 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
373 (sign_extend:SI (match_operand 2 "const_int_operand" "J,K"))))]
378 [(set_attr "length" "2,4")
379 (set_attr "cc" "none_0hit,none_0hit")
380 (set_attr "type" "mult")])
383 ;; ----------------------------------------------------------------------
385 ;; ----------------------------------------------------------------------
387 (define_insn "*v850_clr1_1"
388 [(set (match_operand:QI 0 "memory_operand" "=m")
390 (and:SI (subreg:SI (match_dup 0) 0)
391 (match_operand:QI 1 "not_power_of_two_operand" "")) 0))]
396 xoperands[0] = operands[0];
397 xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
398 output_asm_insn (\"clr1 %M1,%0\", xoperands);
401 [(set_attr "length" "4")
402 (set_attr "cc" "clobber")])
404 (define_insn "*v850_clr1_2"
405 [(set (match_operand:HI 0 "indirect_operand" "=m")
407 (and:SI (subreg:SI (match_dup 0) 0)
408 (match_operand:HI 1 "not_power_of_two_operand" "")) 0))]
412 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
415 xoperands[0] = gen_rtx (MEM, QImode,
416 plus_constant (XEXP (operands[0], 0), log2 / 8));
417 xoperands[1] = GEN_INT (log2 % 8);
418 output_asm_insn (\"clr1 %1,%0\", xoperands);
421 [(set_attr "length" "4")
422 (set_attr "cc" "clobber")])
424 (define_insn "*v850_clr1_3"
425 [(set (match_operand:SI 0 "indirect_operand" "=m")
426 (and:SI (match_dup 0)
427 (match_operand:SI 1 "not_power_of_two_operand" "")))]
431 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
434 xoperands[0] = gen_rtx (MEM, QImode,
435 plus_constant (XEXP (operands[0], 0), log2 / 8));
436 xoperands[1] = GEN_INT (log2 % 8);
437 output_asm_insn (\"clr1 %1,%0\", xoperands);
440 [(set_attr "length" "4")
441 (set_attr "cc" "clobber")])
443 (define_insn "andsi3"
444 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
445 (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
446 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
452 [(set_attr "length" "2,2,4")
453 (set_attr "cc" "set_znv")])
455 ;; ----------------------------------------------------------------------
457 ;; ----------------------------------------------------------------------
459 (define_insn "*v850_set1_1"
460 [(set (match_operand:QI 0 "memory_operand" "=m")
461 (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
462 (match_operand 1 "power_of_two_operand" "")) 0))]
465 [(set_attr "length" "4")
466 (set_attr "cc" "clobber")])
468 (define_insn "*v850_set1_2"
469 [(set (match_operand:HI 0 "indirect_operand" "=m")
470 (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
471 (match_operand 1 "power_of_two_operand" "")) 0))]
475 int log2 = exact_log2 (INTVAL (operands[1]));
478 return \"set1 %M1,%0\";
482 xoperands[0] = gen_rtx (MEM, QImode,
483 plus_constant (XEXP (operands[0], 0), log2 / 8));
484 xoperands[1] = GEN_INT (log2 % 8);
485 output_asm_insn (\"set1 %1,%0\", xoperands);
489 [(set_attr "length" "4")
490 (set_attr "cc" "clobber")])
492 (define_insn "*v850_set1_3"
493 [(set (match_operand:SI 0 "indirect_operand" "=m")
494 (ior:SI (match_dup 0)
495 (match_operand 1 "power_of_two_operand" "")))]
499 int log2 = exact_log2 (INTVAL (operands[1]));
502 return \"set1 %M1,%0\";
506 xoperands[0] = gen_rtx (MEM, QImode,
507 plus_constant (XEXP (operands[0], 0), log2 / 8));
508 xoperands[1] = GEN_INT (log2 % 8);
509 output_asm_insn (\"set1 %1,%0\", xoperands);
513 [(set_attr "length" "4")
514 (set_attr "cc" "clobber")])
516 (define_insn "iorsi3"
517 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
518 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
519 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
525 [(set_attr "length" "2,2,4")
526 (set_attr "cc" "set_znv")])
528 ;; ----------------------------------------------------------------------
530 ;; ----------------------------------------------------------------------
532 (define_insn "*v850_not1_1"
533 [(set (match_operand:QI 0 "memory_operand" "=m")
534 (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0)
535 (match_operand 1 "power_of_two_operand" "")) 0))]
538 [(set_attr "length" "4")
539 (set_attr "cc" "clobber")])
541 (define_insn "*v850_not1_2"
542 [(set (match_operand:HI 0 "indirect_operand" "=m")
543 (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
544 (match_operand 1 "power_of_two_operand" "")) 0))]
548 int log2 = exact_log2 (INTVAL (operands[1]));
551 return \"not1 %M1,%0\";
555 xoperands[0] = gen_rtx (MEM, QImode,
556 plus_constant (XEXP (operands[0], 0), log2 / 8));
557 xoperands[1] = GEN_INT (log2 % 8);
558 output_asm_insn (\"not1 %1,%0\", xoperands);
562 [(set_attr "length" "4")
563 (set_attr "cc" "clobber")])
565 (define_insn "*v850_not1_3"
566 [(set (match_operand:SI 0 "indirect_operand" "=m")
567 (xor:SI (match_dup 0)
568 (match_operand 1 "power_of_two_operand" "")))]
572 int log2 = exact_log2 (INTVAL (operands[1]));
575 return \"not1 %M1,%0\";
579 xoperands[0] = gen_rtx (MEM, QImode,
580 plus_constant (XEXP (operands[0], 0), log2 / 8));
581 xoperands[1] = GEN_INT (log2 % 8);
582 output_asm_insn (\"not1 %1,%0\", xoperands);
586 [(set_attr "length" "4")
587 (set_attr "cc" "clobber")])
589 (define_insn "xorsi3"
590 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
591 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
592 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
598 [(set_attr "length" "2,2,4")
599 (set_attr "cc" "set_znv")])
601 ;; ----------------------------------------------------------------------
603 ;; ----------------------------------------------------------------------
605 (define_insn "one_cmplsi2"
606 [(set (match_operand:SI 0 "register_operand" "=r")
607 (not:SI (match_operand:SI 1 "register_operand" "r")))]
610 [(set_attr "length" "2")
611 (set_attr "cc" "set_znv")])
613 ;; -----------------------------------------------------------------
615 ;; -----------------------------------------------------------------
617 ;; ??? Is it worth defining insv and extv for the V850 series?!?
619 ;; An insv pattern would be useful, but does not get used because
620 ;; store_bit_field never calls insv when storing a constant value into a
621 ;; single-bit bitfield.
623 ;; extv/extzv patterns would be useful, but do not get used because
624 ;; optimize_bitfield_compare in fold-const usually converts single
625 ;; bit extracts into an AND with a mask.
627 ;; -----------------------------------------------------------------
629 ;; -----------------------------------------------------------------
632 [(set (match_operand:SI 0 "register_operand" "=r")
633 (le:SI (cc0) (const_int 0)))]
637 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
640 return \"setf le,%0\";
642 [(set_attr "length" "4")
643 (set_attr "cc" "none_0hit")])
646 [(set (match_operand:SI 0 "register_operand" "=r")
647 (leu:SI (cc0) (const_int 0)))]
650 [(set_attr "length" "4")
651 (set_attr "cc" "none_0hit")])
654 [(set (match_operand:SI 0 "register_operand" "=r")
655 (ge:SI (cc0) (const_int 0)))]
659 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
662 return \"setf ge,%0\";
664 [(set_attr "length" "4")
665 (set_attr "cc" "none_0hit")])
668 [(set (match_operand:SI 0 "register_operand" "=r")
669 (geu:SI (cc0) (const_int 0)))]
672 [(set_attr "length" "4")
673 (set_attr "cc" "none_0hit")])
676 [(set (match_operand:SI 0 "register_operand" "=r")
677 (lt:SI (cc0) (const_int 0)))]
681 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
684 return \"setf lt,%0\";
686 [(set_attr "length" "4")
687 (set_attr "cc" "none_0hit")])
690 [(set (match_operand:SI 0 "register_operand" "=r")
691 (ltu:SI (cc0) (const_int 0)))]
694 [(set_attr "length" "4")
695 (set_attr "cc" "none_0hit")])
698 [(set (match_operand:SI 0 "register_operand" "=r")
699 (gt:SI (cc0) (const_int 0)))]
703 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
706 return \"setf gt,%0\";
708 [(set_attr "length" "4")
709 (set_attr "cc" "none_0hit")])
712 [(set (match_operand:SI 0 "register_operand" "=r")
713 (gtu:SI (cc0) (const_int 0)))]
716 [(set_attr "length" "4")
717 (set_attr "cc" "none_0hit")])
720 [(set (match_operand:SI 0 "register_operand" "=r")
721 (eq:SI (cc0) (const_int 0)))]
724 [(set_attr "length" "4")
725 (set_attr "cc" "none_0hit")])
728 [(set (match_operand:SI 0 "register_operand" "=r")
729 (ne:SI (cc0) (const_int 0)))]
732 [(set_attr "length" "4")
733 (set_attr "cc" "none_0hit")])
736 ;; ----------------------------------------------------------------------
738 ;; ----------------------------------------------------------------------
740 ;; Conditional jump instructions
744 (if_then_else (le (cc0)
746 (label_ref (match_operand 0 "" ""))
751 (define_expand "bleu"
753 (if_then_else (leu (cc0)
755 (label_ref (match_operand 0 "" ""))
762 (if_then_else (ge (cc0)
764 (label_ref (match_operand 0 "" ""))
769 (define_expand "bgeu"
771 (if_then_else (geu (cc0)
773 (label_ref (match_operand 0 "" ""))
780 (if_then_else (lt (cc0)
782 (label_ref (match_operand 0 "" ""))
787 (define_expand "bltu"
789 (if_then_else (ltu (cc0)
791 (label_ref (match_operand 0 "" ""))
798 (if_then_else (gt (cc0)
800 (label_ref (match_operand 0 "" ""))
805 (define_expand "bgtu"
807 (if_then_else (gtu (cc0)
809 (label_ref (match_operand 0 "" ""))
816 (if_then_else (eq (cc0)
818 (label_ref (match_operand 0 "" ""))
825 (if_then_else (ne (cc0)
827 (label_ref (match_operand 0 "" ""))
832 (define_insn "*branch_normal"
834 (if_then_else (match_operator 1 "comparison_operator"
835 [(cc0) (const_int 0)])
836 (label_ref (match_operand 0 "" ""))
841 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
842 && (GET_CODE (operands[1]) == GT
843 || GET_CODE (operands[1]) == GE
844 || GET_CODE (operands[1]) == LE
845 || GET_CODE (operands[1]) == LT))
848 if (get_attr_length (insn) == 2)
851 return \"b%B1 .+6\;jr %l0\";
853 [(set (attr "length")
854 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
858 (set_attr "cc" "none")])
860 (define_insn "*branch_invert"
862 (if_then_else (match_operator 1 "comparison_operator"
863 [(cc0) (const_int 0)])
865 (label_ref (match_operand 0 "" ""))))]
869 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
870 && (GET_CODE (operands[1]) == GT
871 || GET_CODE (operands[1]) == GE
872 || GET_CODE (operands[1]) == LE
873 || GET_CODE (operands[1]) == LT))
875 if (get_attr_length (insn) == 2)
878 return \"b%b1 .+6\;jr %l0\";
880 [(set (attr "length")
881 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
885 (set_attr "cc" "none")])
887 ;; Unconditional and other jump instructions.
891 (label_ref (match_operand 0 "" "")))]
895 if (get_attr_length (insn) == 2)
900 [(set (attr "length")
901 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
905 (set_attr "cc" "none")])
907 (define_insn "indirect_jump"
908 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
911 [(set_attr "length" "2")
912 (set_attr "cc" "none")])
914 (define_insn "tablejump"
915 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
916 (use (label_ref (match_operand 1 "" "")))]
919 [(set_attr "length" "2")
920 (set_attr "cc" "none")])
922 (define_expand "casesi"
923 [(match_operand:SI 0 "register_operand" "")
924 (match_operand:SI 1 "register_operand" "")
925 (match_operand:SI 2 "register_operand" "")
926 (match_operand 3 "" "") (match_operand 4 "" "")]
930 rtx reg = gen_reg_rtx (SImode);
931 rtx tableaddress = gen_reg_rtx (SImode);
934 /* Subtract the lower bound from the index. */
935 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
936 /* Compare the result against the number of table entries. */
937 emit_insn (gen_cmpsi (reg, operands[2]));
938 /* Branch to the default label if out of range of the table. */
939 emit_jump_insn (gen_bgtu (operands[4]));
941 /* Shift index for the table array access. */
942 emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
943 /* Load the table address into a pseudo. */
944 emit_insn (gen_movsi (tableaddress,
945 gen_rtx (LABEL_REF, VOIDmode, operands[3])));
946 /* Add the table address to the index. */
947 emit_insn (gen_addsi3 (reg, reg, tableaddress));
948 /* Load the table entry. */
949 mem = gen_rtx (MEM, CASE_VECTOR_MODE, reg);
950 RTX_UNCHANGING_P (mem);
951 if (! TARGET_BIG_SWITCH)
953 rtx reg2 = gen_reg_rtx (HImode);
954 emit_insn (gen_movhi (reg2, mem));
955 emit_insn (gen_extendhisi2 (reg, reg2));
958 emit_insn (gen_movsi (reg, mem));
959 /* Add the table address. */
960 emit_insn (gen_addsi3 (reg, reg, tableaddress));
961 /* Branch to the switch label. */
962 emit_jump_insn (gen_tablejump (reg, operands[3]));
966 ;; Call subroutine with no return value.
968 (define_expand "call"
969 [(call (match_operand:QI 0 "general_operand" "")
970 (match_operand:SI 1 "general_operand" ""))]
974 if (! call_address_operand (XEXP (operands[0], 0))
975 || TARGET_LONG_CALLS)
976 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
977 if (TARGET_LONG_CALLS)
978 emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));
980 emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
985 (define_insn "call_internal_short"
986 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
987 (match_operand:SI 1 "general_operand" "g,g"))
988 (clobber (reg:SI 31))]
989 "! TARGET_LONG_CALLS"
992 jarl .+4,r31\\;add 4,r31\\;jmp %0"
993 [(set_attr "length" "4,8")]
996 (define_insn "call_internal_long"
997 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
998 (match_operand:SI 1 "general_operand" "g,g"))
999 (clobber (reg:SI 31))]
1003 if (which_alternative == 0)
1005 if (GET_CODE (operands[0]) == REG)
1006 return \"jarl %0,r31\";
1008 return \"movhi hi(%0), r0, r11\\;movea lo(%0), r11, r11\\;jarl .+4,r31\\;add 4, r31\\;jmp r11\";
1011 return \"jarl .+4,r31\\;add 4,r31\\;jmp %0\";
1013 [(set_attr "length" "16,8")]
1016 ;; Call subroutine, returning value in operand 0
1017 ;; (which must be a hard register).
1019 (define_expand "call_value"
1020 [(set (match_operand 0 "" "")
1021 (call (match_operand:QI 1 "general_operand" "")
1022 (match_operand:SI 2 "general_operand" "")))]
1026 if (! call_address_operand (XEXP (operands[1], 0))
1027 || TARGET_LONG_CALLS)
1028 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1029 if (TARGET_LONG_CALLS)
1030 emit_call_insn (gen_call_value_internal_long (operands[0],
1031 XEXP (operands[1], 0),
1034 emit_call_insn (gen_call_value_internal_short (operands[0],
1035 XEXP (operands[1], 0),
1040 (define_insn "call_value_internal_short"
1041 [(set (match_operand 0 "" "=r,r")
1042 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1043 (match_operand:SI 2 "general_operand" "g,g")))
1044 (clobber (reg:SI 31))]
1045 "! TARGET_LONG_CALLS"
1048 jarl .+4,r31\\;add 4,r31\\;jmp %1"
1049 [(set_attr "length" "4,8")]
1052 (define_insn "call_value_internal_long"
1053 [(set (match_operand 0 "" "=r,r")
1054 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1055 (match_operand:SI 2 "general_operand" "g,g")))
1056 (clobber (reg:SI 31))]
1060 if (which_alternative == 0)
1062 if (GET_CODE (operands[1]) == REG)
1063 return \"jarl %1, r31\";
1065 /* Reload can generate this pattern... */
1066 return \"movhi hi(%1), r0, r11\\;movea lo(%1), r11, r11\\;jarl .+4, r31\\;add 4, r31\\;jmp r11\";
1069 return \"jarl .+4, r31\\;add 4, r31\\;jmp %1\";
1071 [(set_attr "length" "16,8")]
1078 [(set_attr "length" "2")
1079 (set_attr "cc" "none")])
1081 ;; ----------------------------------------------------------------------
1082 ;; EXTEND INSTRUCTIONS
1083 ;; ----------------------------------------------------------------------
1086 (define_insn "zero_extendhisi2"
1087 [(set (match_operand:SI 0 "register_operand" "=r")
1089 (match_operand:HI 1 "register_operand" "r")))]
1092 [(set_attr "length" "4")
1093 (set_attr "cc" "set_znv")])
1096 (define_insn "zero_extendqisi2"
1097 [(set (match_operand:SI 0 "register_operand" "=r")
1099 (match_operand:QI 1 "register_operand" "r")))]
1102 [(set_attr "length" "4")
1103 (set_attr "cc" "set_znv")])
1105 ;;- sign extension instructions
1108 ;; ??? This is missing a sign extend from memory pattern to match the ld.h
1111 (define_expand "extendhisi2"
1113 (ashift:SI (match_operand:HI 1 "register_operand" "")
1115 (set (match_operand:SI 0 "register_operand" "")
1116 (ashiftrt:SI (match_dup 2)
1121 operands[1] = gen_lowpart (SImode, operands[1]);
1122 operands[2] = gen_reg_rtx (SImode);
1126 ;; ??? This is missing a sign extend from memory pattern to match the ld.b
1129 (define_expand "extendqisi2"
1131 (ashift:SI (match_operand:QI 1 "register_operand" "")
1133 (set (match_operand:SI 0 "register_operand" "")
1134 (ashiftrt:SI (match_dup 2)
1139 operands[1] = gen_lowpart (SImode, operands[1]);
1140 operands[2] = gen_reg_rtx (SImode);
1143 ;; ----------------------------------------------------------------------
1145 ;; ----------------------------------------------------------------------
1147 (define_insn "ashlsi3"
1148 [(set (match_operand:SI 0 "register_operand" "=r,r")
1150 (match_operand:SI 1 "register_operand" "0,0")
1151 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1156 [(set_attr "length" "4,2")
1157 (set_attr "cc" "set_znv")])
1159 (define_insn "lshrsi3"
1160 [(set (match_operand:SI 0 "register_operand" "=r,r")
1162 (match_operand:SI 1 "register_operand" "0,0")
1163 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1168 [(set_attr "length" "4,2")
1169 (set_attr "cc" "set_znv")])
1171 (define_insn "ashrsi3"
1172 [(set (match_operand:SI 0 "register_operand" "=r,r")
1174 (match_operand:SI 1 "register_operand" "0,0")
1175 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1180 [(set_attr "length" "4,2")
1181 (set_attr "cc" "set_znv")])
1183 ;; ----------------------------------------------------------------------
1184 ;; PROLOGUE/EPILOGUE
1185 ;; ----------------------------------------------------------------------
1186 (define_expand "prologue"
1189 "expand_prologue (); DONE;")
1191 (define_expand "epilogue"
1196 /* Try to use the trivial return first. Else use the
1199 emit_jump_insn (gen_return ());
1205 (define_insn "return"
1207 "reload_completed && compute_frame_size (get_frame_size (), (long *)0) == 0"
1209 [(set_attr "length" "2")
1210 (set_attr "cc" "none")])
1212 (define_insn "return_internal"
1217 [(set_attr "length" "2")
1218 (set_attr "cc" "none")])
1222 ;; ----------------------------------------------------------------------
1223 ;; HELPER INSTRUCTIONS for saving the prologue and epilog registers
1224 ;; ----------------------------------------------------------------------
1226 ;; This pattern will match a stack adjust RTX followed by any number of push
1227 ;; RTXs. These RTXs will then be turned into a suitable call to a worker
1232 [(match_parallel 0 "pattern_is_ok_for_prologue"
1234 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1235 (set (mem:SI (plus:SI (reg:SI 3)
1236 (match_operand:SI 2 "immediate_operand" "i")))
1237 (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
1238 "TARGET_PROLOG_FUNCTION"
1239 "* return construct_save_jarl (operands[0]);
1241 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
1243 (const_string "4")))
1244 (set_attr "cc" "clobber")])
1246 ;; This pattern will match a return RTX followed by any number of pop RTXs
1247 ;; and possible a stack adjustment as well. These RTXs will be turned into
1248 ;; a suitable call to a worker function.
1251 [(match_parallel 0 "pattern_is_ok_for_epilogue"
1254 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1255 (set (match_operand:SI 2 "register_is_ok_for_epilogue" "r")
1256 (mem:SI (plus:SI (reg:SI 3)
1257 (match_operand:SI 3 "immediate_operand" "i"))))])]
1258 "TARGET_PROLOG_FUNCTION && TARGET_V850"
1259 "* return construct_restore_jr (operands[0]);
1261 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
1263 (const_string "4")))
1264 (set_attr "cc" "clobber")])
1266 ;; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION.
1267 (define_insn "save_interrupt"
1268 [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16)))
1269 (set (mem:SI (reg:SI 3)) (reg:SI 30))
1270 (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 10))
1271 (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 4))
1272 (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))]
1273 "TARGET_V850 && ! TARGET_LONG_CALLS"
1274 "add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10"
1275 [(set_attr "length" "12")
1276 (set_attr "cc" "clobber")])
1278 ;; Restore r1, r4, r10, and return from the interrupt
1279 (define_insn "restore_interrupt"
1281 (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 16)))
1282 (set (reg:SI 30) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
1283 (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
1284 (set (reg:SI 4) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))
1285 (set (reg:SI 1) (mem:SI (reg:SI 3)))]
1287 "jr __return_interrupt"
1288 [(set_attr "length" "4")
1289 (set_attr "cc" "clobber")])
1292 ;; Save all registers except for the registers saved in save_interrupt when
1293 ;; an interrupt function makes a call.
1294 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1295 ;; all of memory. This blocks insns from being moved across this point.
1296 ;; This is needed because the rest of the compiler is not ready to handle
1297 ;; insns this complicated.
1299 (define_insn "save_all_interrupt"
1300 [(unspec_volatile [(const_int 0)] 0)]
1301 "TARGET_V850 && ! TARGET_LONG_CALLS"
1302 "jarl __save_all_interrupt,r10"
1303 [(set_attr "length" "4")
1304 (set_attr "cc" "clobber")])
1307 ;; Restore all registers saved when an interrupt function makes a call.
1308 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1309 ;; all of memory. This blocks insns from being moved across this point.
1310 ;; This is needed because the rest of the compiler is not ready to handle
1311 ;; insns this complicated.
1313 (define_insn "restore_all_interrupt"
1314 [(unspec_volatile [(const_int 0)] 1)]
1315 "TARGET_V850 && ! TARGET_LONG_CALLS"
1316 "jarl __restore_all_interrupt,r10"
1317 [(set_attr "length" "4")
1318 (set_attr "cc" "clobber")])
1320 ;; Save r6-r9 for a variable argument function
1321 (define_insn "save_r6_r9"
1322 [(set (mem:SI (reg:SI 3)) (reg:SI 6))
1323 (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
1324 (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
1325 (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
1326 (clobber (reg:SI 10))]
1327 "TARGET_PROLOG_FUNCTION && ! TARGET_LONG_CALLS"
1328 "jarl __save_r6_r9,r10"
1329 [(set_attr "length" "4")
1330 (set_attr "cc" "clobber")])