1 ;; GCC machine description for NEC V850
2 ;; Copyright (C) 1996, 1997 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 ;; Types of instructions (for scheduling purposes).
41 (define_attr "type" "load,mult,other"
42 (const_string "other"))
44 ;; Condition code settings.
45 ;; none - insn does not affect cc
46 ;; none_0hit - insn does not affect cc but it does modify operand 0
47 ;; This attribute is used to keep track of when operand 0 changes.
48 ;; See the description of NOTICE_UPDATE_CC for more info.
49 ;; set_znv - sets z,n,v to usable values; c is unknown.
50 ;; set_zn - sets z,n to usable values; v,c is unknown.
51 ;; compare - compare instruction
52 ;; clobber - value of cc is unknown
53 (define_attr "cc" "none,none_0hit,set_zn,set_znv,compare,clobber"
54 (const_string "clobber"))
56 ;; Function units for the V850. As best as I can tell, there's
57 ;; a traditional memory load/use stall as well as a stall if
58 ;; the result of a multiply is used too early.
60 (define_function_unit "memory" 1 0 (eq_attr "type" "load") 2 0)
61 (define_function_unit "mult" 1 0 (eq_attr "type" "mult") 2 0)
64 ;; ----------------------------------------------------------------------
66 ;; ----------------------------------------------------------------------
70 (define_expand "movqi"
71 [(set (match_operand:QI 0 "general_operand" "")
72 (match_operand:QI 1 "general_operand" ""))]
76 /* One of the ops has to be in a register or 0 */
77 if (!register_operand (operand0, QImode)
78 && !reg_or_0_operand (operand1, QImode))
79 operands[1] = copy_to_mode_reg (QImode, operand1);
82 (define_insn "*movqi_internal"
83 [(set (match_operand:QI 0 "general_operand" "=r,r,r,Q,r,m,m")
84 (match_operand:QI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
85 "register_operand (operands[0], QImode)
86 || reg_or_0_operand (operands[1], QImode)"
87 "* return output_move_single (operands);"
88 [(set_attr "length" "2,4,2,2,4,4,4")
89 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
90 (set_attr "type" "other,other,load,other,load,other,other")])
94 (define_expand "movhi"
95 [(set (match_operand:HI 0 "general_operand" "")
96 (match_operand:HI 1 "general_operand" ""))]
100 /* One of the ops has to be in a register or 0 */
101 if (!register_operand (operand0, HImode)
102 && !reg_or_0_operand (operand1, HImode))
103 operands[1] = copy_to_mode_reg (HImode, operand1);
106 (define_insn "*movhi_internal"
107 [(set (match_operand:HI 0 "general_operand" "=r,r,r,Q,r,m,m")
108 (match_operand:HI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
109 "register_operand (operands[0], HImode)
110 || reg_or_0_operand (operands[1], HImode)"
111 "* return output_move_single (operands);"
112 [(set_attr "length" "2,4,2,2,4,4,4")
113 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
114 (set_attr "type" "other,other,load,other,load,other,other")])
118 (define_insn "*movsi_high"
119 [(set (match_operand:SI 0 "register_operand" "=r")
120 (high:SI (match_operand 1 "" "")))]
123 [(set_attr "length" "4")
124 (set_attr "cc" "none_0hit")
125 (set_attr "type" "other")])
127 (define_insn "*movsi_lo"
128 [(set (match_operand:SI 0 "register_operand" "=r")
129 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
130 (match_operand:SI 2 "immediate_operand" "i")))]
133 [(set_attr "length" "4")
134 (set_attr "cc" "none_0hit")
135 (set_attr "type" "other")])
137 (define_expand "movsi"
138 [(set (match_operand:SI 0 "general_operand" "")
139 (match_operand:SI 1 "general_operand" ""))]
143 /* One of the ops has to be in a register or 0 */
144 if (!register_operand (operand0, SImode)
145 && !reg_or_0_operand (operand1, SImode))
146 operands[1] = copy_to_mode_reg (SImode, operand1);
148 /* Some constants, as well as symbolic operands
149 must be done with HIGH & LO_SUM patterns. */
150 if (CONSTANT_P (operands[1])
151 && GET_CODE (operands[1]) != HIGH
152 && !special_symbolref_operand (operands[1], VOIDmode)
153 && !(GET_CODE (operands[1]) == CONST_INT
154 && (CONST_OK_FOR_J (INTVAL (operands[1]))
155 || CONST_OK_FOR_K (INTVAL (operands[1]))
156 || CONST_OK_FOR_L (INTVAL (operands[1])))))
161 if (reload_in_progress || reload_completed)
164 temp = gen_reg_rtx (SImode);
166 emit_insn (gen_rtx (SET, SImode, temp,
167 gen_rtx (HIGH, SImode, operand1)));
168 emit_insn (gen_rtx (SET, SImode, operand0,
169 gen_rtx (LO_SUM, SImode, temp, operand1)));
174 (define_insn "*movsi_internal"
175 [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m")
176 (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))]
177 "register_operand (operands[0], SImode)
178 || reg_or_0_operand (operands[1], SImode)"
179 "* return output_move_single (operands);"
180 [(set_attr "length" "2,4,4,2,2,4,4,4,4")
181 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
182 (set_attr "type" "other,other,other,load,other,load,other,other,other")])
186 (define_expand "movdi"
187 [(set (match_operand:DI 0 "general_operand" "")
188 (match_operand:DI 1 "general_operand" ""))]
192 /* One of the ops has to be in a register or 0 */
193 if (!register_operand (operand0, DImode)
194 && !reg_or_0_operand (operand1, DImode))
195 operands[1] = copy_to_mode_reg (DImode, operand1);
198 (define_insn "*movdi_internal"
199 [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,m,r")
200 (match_operand:DI 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
201 "register_operand (operands[0], DImode)
202 || reg_or_0_operand (operands[1], DImode)"
203 "* return output_move_double (operands);"
204 [(set_attr "length" "4,8,8,16,8,8,8,16")
205 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
206 (set_attr "type" "other,other,other,other,load,other,other,other")])
208 (define_expand "movsf"
209 [(set (match_operand:SF 0 "general_operand" "")
210 (match_operand:SF 1 "general_operand" ""))]
214 /* One of the ops has to be in a register or 0 */
215 if (!register_operand (operand0, SFmode)
216 && !reg_or_0_operand (operand1, SFmode))
217 operands[1] = copy_to_mode_reg (SFmode, operand1);
220 (define_insn "*movsf_internal"
221 [(set (match_operand:SF 0 "general_operand" "=r,r,r,r,r,Q,r,m,m,r")
222 (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))]
223 "register_operand (operands[0], SFmode)
224 || reg_or_0_operand (operands[1], SFmode)"
225 "* return output_move_single (operands);"
226 [(set_attr "length" "2,4,4,8,2,2,4,4,4,8")
227 (set_attr "cc" "none_0hit,none_0hit,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,load,other,other,other")])
230 (define_expand "movdf"
231 [(set (match_operand:DF 0 "general_operand" "")
232 (match_operand:DF 1 "general_operand" ""))]
236 /* One of the ops has to be in a register or 0 */
237 if (!register_operand (operand0, DFmode)
238 && !reg_or_0_operand (operand1, DFmode))
239 operands[1] = copy_to_mode_reg (DFmode, operand1);
242 (define_insn "*movdf_internal"
243 [(set (match_operand:DF 0 "general_operand" "=r,r,r,r,r,m,m,r")
244 (match_operand:DF 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
245 "register_operand (operands[0], DFmode)
246 || reg_or_0_operand (operands[1], DFmode)"
247 "* return output_move_double (operands);"
248 [(set_attr "length" "4,8,8,16,8,8,8,16")
249 (set_attr "cc" "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,other,other")])
253 ;; ----------------------------------------------------------------------
255 ;; ----------------------------------------------------------------------
257 (define_insn "*v850_tst1"
258 [(set (cc0) (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
260 (match_operand:QI 1 "const_int_operand" "n")))]
263 [(set_attr "length" "4")
264 (set_attr "cc" "clobber")])
266 ;; This replaces ld.b;sar;andi with tst1;setf nz.
268 ;; ??? The zero_extract sets the Z bit to the opposite of what one would
269 ;; expect. This perhaps should be wrapped in a (eq: X (const_int 0)).
272 [(set (match_operand:SI 0 "register_operand" "")
273 (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
275 (match_operand 2 "const_int_operand" "")))]
277 [(set (cc0) (zero_extract:SI (match_dup 1)
280 (set (match_dup 0) (ne:SI (cc0) (const_int 0)))])
283 [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
286 [(set_attr "length" "2")
287 (set_attr "cc" "set_znv")])
291 (compare (match_operand:SI 0 "register_operand" "r,r")
292 (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
297 [(set_attr "length" "2,2")
298 (set_attr "cc" "compare")])
300 ;; ----------------------------------------------------------------------
302 ;; ----------------------------------------------------------------------
304 (define_insn "addsi3"
305 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
306 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
307 (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))]
313 [(set_attr "length" "2,4,4")
314 (set_attr "cc" "set_zn,set_zn,set_zn")])
316 ;; ----------------------------------------------------------------------
317 ;; SUBTRACT INSTRUCTIONS
318 ;; ----------------------------------------------------------------------
320 (define_insn "subsi3"
321 [(set (match_operand:SI 0 "register_operand" "=r,r")
322 (minus:SI (match_operand:SI 1 "register_operand" "0,r")
323 (match_operand:SI 2 "register_operand" "r,0")))]
328 [(set_attr "length" "2,2")
329 (set_attr "cc" "set_zn")])
331 (define_insn "negsi2"
332 [(set (match_operand:SI 0 "register_operand" "=r")
333 (neg:SI (match_operand:SI 1 "register_operand" "0")))]
336 [(set_attr "length" "2")
337 (set_attr "cc" "set_zn")])
339 ;; ----------------------------------------------------------------------
340 ;; MULTIPLY INSTRUCTIONS
341 ;; ----------------------------------------------------------------------
343 (define_expand "mulhisi3"
344 [(set (match_operand:SI 0 "register_operand" "")
346 (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
347 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
351 (define_insn "*mulhisi3_internal1"
352 [(set (match_operand:SI 0 "register_operand" "=r")
354 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
355 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
358 [(set_attr "length" "2")
359 (set_attr "cc" "none_0hit")
360 (set_attr "type" "mult")])
362 ;; ??? Sign extending constants isn't valid. Fix?
364 (define_insn "*mulhisi3_internal2"
365 [(set (match_operand:SI 0 "register_operand" "=r,r")
367 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
368 (sign_extend:SI (match_operand 2 "const_int_operand" "J,K"))))]
373 [(set_attr "length" "2,4")
374 (set_attr "cc" "none_0hit,none_0hit")
375 (set_attr "type" "mult")])
378 ;; ----------------------------------------------------------------------
380 ;; ----------------------------------------------------------------------
382 (define_insn "*v850_clr1_1"
383 [(set (match_operand:QI 0 "memory_operand" "=m")
385 (and:SI (subreg:SI (match_dup 0) 0)
386 (match_operand:QI 1 "not_power_of_two_operand" "")) 0))]
391 xoperands[0] = operands[0];
392 xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
393 output_asm_insn (\"clr1 %M1,%0\", xoperands);
396 [(set_attr "length" "4")
397 (set_attr "cc" "clobber")])
399 (define_insn "*v850_clr1_2"
400 [(set (match_operand:HI 0 "memory_operand" "=m")
402 (and:SI (subreg:SI (match_dup 0) 0)
403 (match_operand:HI 1 "not_power_of_two_operand" "")) 0))]
407 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
410 xoperands[0] = gen_rtx (MEM, QImode,
411 plus_constant (XEXP (operands[0], 0), log2 / 8));
412 xoperands[1] = GEN_INT (log2 % 8);
413 output_asm_insn (\"clr1 %1,%0\", xoperands);
416 [(set_attr "length" "4")
417 (set_attr "cc" "clobber")])
419 (define_insn "*v850_clr1_3"
420 [(set (match_operand:SI 0 "memory_operand" "=m")
421 (and:SI (match_dup 0)
422 (match_operand:SI 1 "not_power_of_two_operand" "")))]
426 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
429 xoperands[0] = gen_rtx (MEM, QImode,
430 plus_constant (XEXP (operands[0], 0), log2 / 8));
431 xoperands[1] = GEN_INT (log2 % 8);
432 output_asm_insn (\"clr1 %1,%0\", xoperands);
435 [(set_attr "length" "4")
436 (set_attr "cc" "clobber")])
438 (define_insn "andsi3"
439 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
440 (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
441 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
447 [(set_attr "length" "2,2,4")
448 (set_attr "cc" "set_znv")])
450 ;; ----------------------------------------------------------------------
452 ;; ----------------------------------------------------------------------
454 (define_insn "*v850_set1_1"
455 [(set (match_operand:QI 0 "memory_operand" "=m")
456 (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
457 (match_operand 1 "power_of_two_operand" "")) 0))]
460 [(set_attr "length" "4")
461 (set_attr "cc" "clobber")])
463 (define_insn "*v850_set1_2"
464 [(set (match_operand:HI 0 "memory_operand" "=m")
465 (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
466 (match_operand 1 "power_of_two_operand" "")) 0))]
470 int log2 = exact_log2 (INTVAL (operands[1]));
473 return \"set1 %M1,%0\";
477 xoperands[0] = gen_rtx (MEM, QImode,
478 plus_constant (XEXP (operands[0], 0), log2 / 8));
479 xoperands[1] = GEN_INT (log2 % 8);
480 output_asm_insn (\"set1 %1,%0\", xoperands);
484 [(set_attr "length" "4")
485 (set_attr "cc" "clobber")])
487 (define_insn "*v850_set1_3"
488 [(set (match_operand:SI 0 "memory_operand" "=m")
489 (ior:SI (match_dup 0)
490 (match_operand 1 "power_of_two_operand" "")))]
494 int log2 = exact_log2 (INTVAL (operands[1]));
497 return \"set1 %M1,%0\";
501 xoperands[0] = gen_rtx (MEM, QImode,
502 plus_constant (XEXP (operands[0], 0), log2 / 8));
503 xoperands[1] = GEN_INT (log2 % 8);
504 output_asm_insn (\"set1 %1,%0\", xoperands);
508 [(set_attr "length" "4")
509 (set_attr "cc" "clobber")])
511 (define_insn "iorsi3"
512 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
513 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
514 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
520 [(set_attr "length" "2,2,4")
521 (set_attr "cc" "set_znv")])
523 ;; ----------------------------------------------------------------------
525 ;; ----------------------------------------------------------------------
527 (define_insn "*v850_not1_1"
528 [(set (match_operand:QI 0 "memory_operand" "=m")
529 (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0)
530 (match_operand 1 "power_of_two_operand" "")) 0))]
533 [(set_attr "length" "4")
534 (set_attr "cc" "clobber")])
536 (define_insn "*v850_not1_2"
537 [(set (match_operand:HI 0 "memory_operand" "=m")
538 (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
539 (match_operand 1 "power_of_two_operand" "")) 0))]
543 int log2 = exact_log2 (INTVAL (operands[1]));
546 return \"not1 %M1,%0\";
550 xoperands[0] = gen_rtx (MEM, QImode,
551 plus_constant (XEXP (operands[0], 0), log2 / 8));
552 xoperands[1] = GEN_INT (log2 % 8);
553 output_asm_insn (\"not1 %1,%0\", xoperands);
557 [(set_attr "length" "4")
558 (set_attr "cc" "clobber")])
560 (define_insn "*v850_not1_3"
561 [(set (match_operand:SI 0 "memory_operand" "=m")
562 (xor:SI (match_dup 0)
563 (match_operand 1 "power_of_two_operand" "")))]
567 int log2 = exact_log2 (INTVAL (operands[1]));
570 return \"not1 %M1,%0\";
574 xoperands[0] = gen_rtx (MEM, QImode,
575 plus_constant (XEXP (operands[0], 0), log2 / 8));
576 xoperands[1] = GEN_INT (log2 % 8);
577 output_asm_insn (\"not1 %1,%0\", xoperands);
581 [(set_attr "length" "4")
582 (set_attr "cc" "clobber")])
584 (define_insn "xorsi3"
585 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
586 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
587 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
593 [(set_attr "length" "2,2,4")
594 (set_attr "cc" "set_znv")])
596 ;; ----------------------------------------------------------------------
598 ;; ----------------------------------------------------------------------
600 (define_insn "one_cmplsi2"
601 [(set (match_operand:SI 0 "register_operand" "=r")
602 (not:SI (match_operand:SI 1 "register_operand" "r")))]
605 [(set_attr "length" "2")
606 (set_attr "cc" "set_znv")])
608 ;; -----------------------------------------------------------------
610 ;; -----------------------------------------------------------------
612 ;; ??? Is it worth defining insv and extv for the V850 series?!?
614 ;; An insv pattern would be useful, but does not get used because
615 ;; store_bit_field never calls insv when storing a constant value into a
616 ;; single-bit bitfield.
618 ;; extv/extzv patterns would be useful, but do not get used because
619 ;; optimize_bitfield_compare in fold-const usually converts single
620 ;; bit extracts into an AND with a mask.
622 ;; -----------------------------------------------------------------
624 ;; -----------------------------------------------------------------
627 [(set (match_operand:SI 0 "register_operand" "=r")
628 (le:SI (cc0) (const_int 0)))]
632 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
635 return \"setf le,%0\";
637 [(set_attr "length" "4")
638 (set_attr "cc" "none_0hit")])
641 [(set (match_operand:SI 0 "register_operand" "=r")
642 (leu:SI (cc0) (const_int 0)))]
645 [(set_attr "length" "4")
646 (set_attr "cc" "none_0hit")])
649 [(set (match_operand:SI 0 "register_operand" "=r")
650 (ge:SI (cc0) (const_int 0)))]
654 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
657 return \"setf ge,%0\";
659 [(set_attr "length" "4")
660 (set_attr "cc" "none_0hit")])
663 [(set (match_operand:SI 0 "register_operand" "=r")
664 (geu:SI (cc0) (const_int 0)))]
667 [(set_attr "length" "4")
668 (set_attr "cc" "none_0hit")])
671 [(set (match_operand:SI 0 "register_operand" "=r")
672 (lt:SI (cc0) (const_int 0)))]
676 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
679 return \"setf lt,%0\";
681 [(set_attr "length" "4")
682 (set_attr "cc" "none_0hit")])
685 [(set (match_operand:SI 0 "register_operand" "=r")
686 (ltu:SI (cc0) (const_int 0)))]
689 [(set_attr "length" "4")
690 (set_attr "cc" "none_0hit")])
693 [(set (match_operand:SI 0 "register_operand" "=r")
694 (gt:SI (cc0) (const_int 0)))]
698 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
701 return \"setf gt,%0\";
703 [(set_attr "length" "4")
704 (set_attr "cc" "none_0hit")])
707 [(set (match_operand:SI 0 "register_operand" "=r")
708 (gtu:SI (cc0) (const_int 0)))]
711 [(set_attr "length" "4")
712 (set_attr "cc" "none_0hit")])
715 [(set (match_operand:SI 0 "register_operand" "=r")
716 (eq:SI (cc0) (const_int 0)))]
719 [(set_attr "length" "4")
720 (set_attr "cc" "none_0hit")])
723 [(set (match_operand:SI 0 "register_operand" "=r")
724 (ne:SI (cc0) (const_int 0)))]
727 [(set_attr "length" "4")
728 (set_attr "cc" "none_0hit")])
731 ;; ----------------------------------------------------------------------
733 ;; ----------------------------------------------------------------------
735 ;; Conditional jump instructions
739 (if_then_else (le (cc0)
741 (label_ref (match_operand 0 "" ""))
746 (define_expand "bleu"
748 (if_then_else (leu (cc0)
750 (label_ref (match_operand 0 "" ""))
757 (if_then_else (ge (cc0)
759 (label_ref (match_operand 0 "" ""))
764 (define_expand "bgeu"
766 (if_then_else (geu (cc0)
768 (label_ref (match_operand 0 "" ""))
775 (if_then_else (lt (cc0)
777 (label_ref (match_operand 0 "" ""))
782 (define_expand "bltu"
784 (if_then_else (ltu (cc0)
786 (label_ref (match_operand 0 "" ""))
793 (if_then_else (gt (cc0)
795 (label_ref (match_operand 0 "" ""))
800 (define_expand "bgtu"
802 (if_then_else (gtu (cc0)
804 (label_ref (match_operand 0 "" ""))
811 (if_then_else (eq (cc0)
813 (label_ref (match_operand 0 "" ""))
820 (if_then_else (ne (cc0)
822 (label_ref (match_operand 0 "" ""))
827 (define_insn "*branch_normal"
829 (if_then_else (match_operator 1 "comparison_operator"
830 [(cc0) (const_int 0)])
831 (label_ref (match_operand 0 "" ""))
836 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
837 && (GET_CODE (operands[1]) == GT
838 || GET_CODE (operands[1]) == GE
839 || GET_CODE (operands[1]) == LE
840 || GET_CODE (operands[1]) == LT))
843 if (get_attr_length (insn) == 2)
846 return \"b%B1 .+6\;jr %l0\";
848 [(set (attr "length")
849 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
853 (set_attr "cc" "none")])
855 (define_insn "*branch_invert"
857 (if_then_else (match_operator 1 "comparison_operator"
858 [(cc0) (const_int 0)])
860 (label_ref (match_operand 0 "" ""))))]
864 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
865 && (GET_CODE (operands[1]) == GT
866 || GET_CODE (operands[1]) == GE
867 || GET_CODE (operands[1]) == LE
868 || GET_CODE (operands[1]) == LT))
870 if (get_attr_length (insn) == 2)
873 return \"b%b1 .+6\;jr %l0\";
875 [(set (attr "length")
876 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
880 (set_attr "cc" "none")])
882 ;; Unconditional and other jump instructions.
886 (label_ref (match_operand 0 "" "")))]
890 if (get_attr_length (insn) == 2)
895 [(set (attr "length")
896 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
900 (set_attr "cc" "none")])
902 (define_insn "indirect_jump"
903 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
906 [(set_attr "length" "2")
907 (set_attr "cc" "none")])
909 (define_insn "tablejump"
910 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
911 (use (label_ref (match_operand 1 "" "")))]
914 [(set_attr "length" "2")
915 (set_attr "cc" "none")])
917 (define_expand "casesi"
918 [(match_operand:SI 0 "register_operand" "")
919 (match_operand:SI 1 "register_operand" "")
920 (match_operand:SI 2 "register_operand" "")
921 (match_operand 3 "" "") (match_operand 4 "" "")]
925 rtx reg = gen_reg_rtx (SImode);
926 rtx tableaddress = gen_reg_rtx (SImode);
929 /* Subtract the lower bound from the index. */
930 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
931 /* Compare the result against the number of table entries. */
932 emit_insn (gen_cmpsi (reg, operands[2]));
933 /* Branch to the default label if out of range of the table. */
934 emit_jump_insn (gen_bgtu (operands[4]));
936 /* Shift index for the table array access. */
937 emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
938 /* Load the table address into a pseudo. */
939 emit_insn (gen_movsi (tableaddress,
940 gen_rtx (LABEL_REF, VOIDmode, operands[3])));
941 /* Add the table address to the index. */
942 emit_insn (gen_addsi3 (reg, reg, tableaddress));
943 /* Load the table entry. */
944 mem = gen_rtx (MEM, CASE_VECTOR_MODE, reg);
945 RTX_UNCHANGING_P (mem);
946 if (! TARGET_BIG_SWITCH)
948 rtx reg2 = gen_reg_rtx (HImode);
949 emit_insn (gen_movhi (reg2, mem));
950 emit_insn (gen_extendhisi2 (reg, reg2));
953 emit_insn (gen_movsi (reg, mem));
954 /* Add the table address. */
955 emit_insn (gen_addsi3 (reg, reg, tableaddress));
956 /* Branch to the switch label. */
957 emit_jump_insn (gen_tablejump (reg, operands[3]));
961 ;; Call subroutine with no return value.
963 (define_expand "call"
964 [(call (match_operand:QI 0 "general_operand" "")
965 (match_operand:SI 1 "general_operand" ""))]
969 if (! call_address_operand (XEXP (operands[0], 0))
970 || TARGET_LONG_CALLS)
971 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
972 emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
976 (define_insn "call_internal"
977 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
978 (match_operand:SI 1 "general_operand" "g,g"))
979 (clobber (reg:SI 31))]
983 jarl .+4,r31\\n\\tadd 4,r31\\n\\tjmp %0"
984 [(set_attr "length" "4,8")])
986 ;; Call subroutine, returning value in operand 0
987 ;; (which must be a hard register).
989 (define_expand "call_value"
990 [(set (match_operand 0 "" "")
991 (call (match_operand:QI 1 "general_operand" "")
992 (match_operand:SI 2 "general_operand" "")))]
996 if (! call_address_operand (XEXP (operands[1], 0))
997 || TARGET_LONG_CALLS)
998 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
999 emit_call_insn (gen_call_value_internal (operands[0],
1000 XEXP (operands[1], 0),
1005 (define_insn "call_value_internal"
1006 [(set (match_operand 0 "" "=r,r")
1007 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1008 (match_operand:SI 2 "general_operand" "g,g")))
1009 (clobber (reg:SI 31))]
1013 jarl .+4,r31\\n\\tadd 4,r31\\n\\tjmp %1"
1014 [(set_attr "length" "4,8")])
1020 [(set_attr "length" "2")
1021 (set_attr "cc" "none")])
1023 ;; ----------------------------------------------------------------------
1024 ;; EXTEND INSTRUCTIONS
1025 ;; ----------------------------------------------------------------------
1028 (define_insn "zero_extendhisi2"
1029 [(set (match_operand:SI 0 "register_operand" "=r")
1031 (match_operand:HI 1 "register_operand" "r")))]
1034 [(set_attr "length" "4")
1035 (set_attr "cc" "set_znv")])
1038 (define_insn "zero_extendqisi2"
1039 [(set (match_operand:SI 0 "register_operand" "=r")
1041 (match_operand:QI 1 "register_operand" "r")))]
1044 [(set_attr "length" "4")
1045 (set_attr "cc" "set_znv")])
1047 ;;- sign extension instructions
1050 ;; ??? This is missing a sign extend from memory pattern to match the ld.h
1053 (define_expand "extendhisi2"
1055 (ashift:SI (match_operand:HI 1 "register_operand" "")
1057 (set (match_operand:SI 0 "register_operand" "")
1058 (ashiftrt:SI (match_dup 2)
1063 operands[1] = gen_lowpart (SImode, operands[1]);
1064 operands[2] = gen_reg_rtx (SImode);
1068 ;; ??? This is missing a sign extend from memory pattern to match the ld.b
1071 (define_expand "extendqisi2"
1073 (ashift:SI (match_operand:QI 1 "register_operand" "")
1075 (set (match_operand:SI 0 "register_operand" "")
1076 (ashiftrt:SI (match_dup 2)
1081 operands[1] = gen_lowpart (SImode, operands[1]);
1082 operands[2] = gen_reg_rtx (SImode);
1085 ;; ----------------------------------------------------------------------
1087 ;; ----------------------------------------------------------------------
1089 (define_insn "ashlsi3"
1090 [(set (match_operand:SI 0 "register_operand" "=r,r")
1092 (match_operand:SI 1 "register_operand" "0,0")
1093 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1098 [(set_attr "length" "4,2")
1099 (set_attr "cc" "set_znv")])
1101 (define_insn "lshrsi3"
1102 [(set (match_operand:SI 0 "register_operand" "=r,r")
1104 (match_operand:SI 1 "register_operand" "0,0")
1105 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1110 [(set_attr "length" "4,2")
1111 (set_attr "cc" "set_znv")])
1113 (define_insn "ashrsi3"
1114 [(set (match_operand:SI 0 "register_operand" "=r,r")
1116 (match_operand:SI 1 "register_operand" "0,0")
1117 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1122 [(set_attr "length" "4,2")
1123 (set_attr "cc" "set_znv")])
1125 ;; ----------------------------------------------------------------------
1126 ;; PROLOGUE/EPILOGUE
1127 ;; ----------------------------------------------------------------------
1128 (define_expand "prologue"
1131 "expand_prologue (); DONE;")
1133 (define_expand "epilogue"
1138 /* Try to use the trivial return first. Else use the
1141 emit_jump_insn (gen_return ());
1147 (define_insn "return"
1149 "reload_completed && compute_frame_size (get_frame_size (), (long *)0) == 0"
1151 [(set_attr "length" "2")
1152 (set_attr "cc" "none")])
1154 (define_insn "return_internal"
1159 [(set_attr "length" "2")
1160 (set_attr "cc" "none")])
1164 ;; ----------------------------------------------------------------------
1165 ;; HELPER INSTRUCTIONS for saving the prologue and epilog registers
1166 ;; ----------------------------------------------------------------------
1168 ;; This pattern will match a stack adjust RTX followed by any number of push
1169 ;; RTXs. These RTXs will then be turned into a suitable call to a worker
1174 [(match_parallel 0 "pattern_is_ok_for_prologue"
1176 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1177 (set (mem:SI (plus:SI (reg:SI 3)
1178 (match_operand:SI 2 "immediate_operand" "i")))
1179 (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
1180 "TARGET_PROLOG_FUNCTION"
1181 "* return construct_save_jarl (operands[0]);
1183 [(set_attr "length" "4")
1184 (set_attr "cc" "clobber")])
1187 ;; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION.
1188 (define_insn "save_interrupt"
1189 [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16)))
1190 (set (mem:SI (reg:SI 3)) (reg:SI 30))
1191 (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 10))
1192 (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 4))
1193 (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))]
1195 "add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10"
1196 [(set_attr "length" "12")
1197 (set_attr "cc" "clobber")])
1200 ;; Save all registers except for the registers saved in save_interrupt when
1201 ;; an interrupt function makes a call.
1202 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1203 ;; all of memory. This blocks insns from being moved across this point.
1204 ;; This is needed because the rest of the compiler is not ready to handle
1205 ;; insns this complicated.
1207 (define_insn "save_all_interrupt"
1208 [(unspec_volatile [(const_int 0)] 0)]
1210 "jarl __save_all_interrupt,r10"
1211 [(set_attr "length" "4")
1212 (set_attr "cc" "clobber")])
1217 ;; This pattern will match a return RTX followed by any number of pop RTXs
1218 ;; and possible a stack adjustment as well. These RTXs will be turned into
1219 ;; a suitable call to a worker function.
1223 [(match_parallel 0 "pattern_is_ok_for_epilogue"
1226 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1227 (set (match_operand:SI 2 "register_is_ok_for_epilogue" "r")
1228 (mem:SI (plus:SI (reg:SI 3)
1229 (match_operand:SI 3 "immediate_operand" "i"))))])]
1230 "TARGET_PROLOG_FUNCTION && TARGET_V850"
1231 "* return construct_restore_jr (operands[0]);
1233 [(set_attr "length" "4")
1234 (set_attr "cc" "clobber")])
1236 ;; Restore r1, r4, r10, and return from the interrupt
1237 (define_insn "restore_interrupt"
1239 (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 16)))
1240 (set (reg:SI 30) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
1241 (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
1242 (set (reg:SI 4) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))
1243 (set (reg:SI 1) (mem:SI (reg:SI 3)))]
1245 "jr __return_interrupt"
1246 [(set_attr "length" "4")
1247 (set_attr "cc" "clobber")])
1249 ;; Restore all registers saved when an interrupt function makes a call.
1250 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1251 ;; all of memory. This blocks insns from being moved across this point.
1252 ;; This is needed because the rest of the compiler is not ready to handle
1253 ;; insns this complicated.
1255 (define_insn "restore_all_interrupt"
1256 [(unspec_volatile [(const_int 0)] 1)]
1258 "jarl __restore_all_interrupt,r10"
1259 [(set_attr "length" "4")
1260 (set_attr "cc" "clobber")])
1262 ;; Save r6-r9 for a variable argument function
1263 (define_insn "save_r6_r9"
1264 [(set (mem:SI (reg:SI 3)) (reg:SI 6))
1265 (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
1266 (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
1267 (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
1268 (clobber (reg:SI 10))]
1269 "TARGET_PROLOG_FUNCTION"
1270 "jarl __save_r6_r9,r10"
1271 [(set_attr "length" "4")
1272 (set_attr "cc" "clobber")])