1 ;; GCC machine description for NEC V850
2 ;; Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
3 ;; Contributed by Jeff Law (law@cygnus.com).
5 ;; This file is part of GNU CC.
7 ;; GNU CC 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)
12 ;; GNU CC 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.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU CC; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
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).
30 ;; One day we'll probably need to handle calls to targets more than 4M
33 ;; The size of instructions in bytes.
35 (define_attr "length" ""
38 (define_attr "long_calls" "yes,no"
39 (const (if_then_else (symbol_ref "TARGET_LONG_CALLS")
41 (const_string "no"))))
43 ;; Types of instructions (for scheduling purposes).
45 (define_attr "type" "load,mult,other"
46 (const_string "other"))
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"))
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.
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)
68 ;; ----------------------------------------------------------------------
70 ;; ----------------------------------------------------------------------
74 (define_expand "movqi"
75 [(set (match_operand:QI 0 "general_operand" "")
76 (match_operand:QI 1 "general_operand" ""))]
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);
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")])
98 (define_expand "movhi"
99 [(set (match_operand:HI 0 "general_operand" "")
100 (match_operand:HI 1 "general_operand" ""))]
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);
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")])
122 (define_insn "*movsi_high"
123 [(set (match_operand:SI 0 "register_operand" "=r")
124 (high:SI (match_operand 1 "" "")))]
127 [(set_attr "length" "4")
128 (set_attr "cc" "none_0hit")
129 (set_attr "type" "other")])
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")))]
137 [(set_attr "length" "4")
138 (set_attr "cc" "none_0hit")
139 (set_attr "type" "other")])
141 (define_expand "movsi"
142 [(set (match_operand:SI 0 "general_operand" "")
143 (match_operand:SI 1 "general_operand" ""))]
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);
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 && !special_symbolref_operand (operands[1], VOIDmode)
157 && !(GET_CODE (operands[1]) == CONST_INT
158 && (CONST_OK_FOR_J (INTVAL (operands[1]))
159 || CONST_OK_FOR_K (INTVAL (operands[1]))
160 || CONST_OK_FOR_L (INTVAL (operands[1])))))
164 if (reload_in_progress || reload_completed)
167 temp = gen_reg_rtx (SImode);
169 emit_insn (gen_rtx_SET (SImode, temp,
170 gen_rtx_HIGH (SImode, operand1)));
171 emit_insn (gen_rtx_SET (SImode, operand0,
172 gen_rtx_LO_SUM (SImode, temp, operand1)));
177 (define_insn "*movsi_internal"
178 [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m")
179 (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))]
180 "register_operand (operands[0], SImode)
181 || reg_or_0_operand (operands[1], SImode)"
182 "* return output_move_single (operands);"
183 [(set_attr "length" "2,4,4,2,2,4,4,4,4")
184 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
185 (set_attr "type" "other,other,other,load,other,load,other,other,other")])
189 (define_expand "movdi"
190 [(set (match_operand:DI 0 "general_operand" "")
191 (match_operand:DI 1 "general_operand" ""))]
195 /* One of the ops has to be in a register or 0 */
196 if (!register_operand (operand0, DImode)
197 && !reg_or_0_operand (operand1, DImode))
198 operands[1] = copy_to_mode_reg (DImode, operand1);
201 (define_insn "*movdi_internal"
202 [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,m,r")
203 (match_operand:DI 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
204 "register_operand (operands[0], DImode)
205 || reg_or_0_operand (operands[1], DImode)"
206 "* return output_move_double (operands);"
207 [(set_attr "length" "4,8,8,16,8,8,8,16")
208 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
209 (set_attr "type" "other,other,other,other,load,other,other,other")])
211 (define_expand "movsf"
212 [(set (match_operand:SF 0 "general_operand" "")
213 (match_operand:SF 1 "general_operand" ""))]
217 /* One of the ops has to be in a register or 0 */
218 if (!register_operand (operand0, SFmode)
219 && !reg_or_0_operand (operand1, SFmode))
220 operands[1] = copy_to_mode_reg (SFmode, operand1);
223 (define_insn "*movsf_internal"
224 [(set (match_operand:SF 0 "general_operand" "=r,r,r,r,r,Q,r,m,m,r")
225 (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))]
226 "register_operand (operands[0], SFmode)
227 || reg_or_0_operand (operands[1], SFmode)"
228 "* return output_move_single (operands);"
229 [(set_attr "length" "2,4,4,8,2,2,4,4,4,8")
230 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
231 (set_attr "type" "other,other,other,other,load,other,load,other,other,other")])
233 (define_expand "movdf"
234 [(set (match_operand:DF 0 "general_operand" "")
235 (match_operand:DF 1 "general_operand" ""))]
239 /* One of the ops has to be in a register or 0 */
240 if (!register_operand (operand0, DFmode)
241 && !reg_or_0_operand (operand1, DFmode))
242 operands[1] = copy_to_mode_reg (DFmode, operand1);
245 (define_insn "*movdf_internal"
246 [(set (match_operand:DF 0 "general_operand" "=r,r,r,r,r,m,m,r")
247 (match_operand:DF 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
248 "register_operand (operands[0], DFmode)
249 || reg_or_0_operand (operands[1], DFmode)"
250 "* return output_move_double (operands);"
251 [(set_attr "length" "4,8,8,16,8,8,8,16")
252 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
253 (set_attr "type" "other,other,other,other,load,other,other,other")])
256 ;; ----------------------------------------------------------------------
258 ;; ----------------------------------------------------------------------
260 (define_insn "*v850_tst1"
261 [(set (cc0) (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
263 (match_operand:QI 1 "const_int_operand" "n")))]
266 [(set_attr "length" "4")
267 (set_attr "cc" "clobber")])
269 ;; This replaces ld.b;sar;andi with tst1;setf nz.
271 ;; ??? The zero_extract sets the Z bit to the opposite of what one would
272 ;; expect. This perhaps should be wrapped in a (eq: X (const_int 0)).
275 [(set (match_operand:SI 0 "register_operand" "")
276 (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
278 (match_operand 2 "const_int_operand" "")))]
280 [(set (cc0) (zero_extract:SI (match_dup 1)
283 (set (match_dup 0) (ne:SI (cc0) (const_int 0)))])
286 [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
289 [(set_attr "length" "2")
290 (set_attr "cc" "set_znv")])
294 (compare (match_operand:SI 0 "register_operand" "r,r")
295 (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
300 [(set_attr "length" "2,2")
301 (set_attr "cc" "compare")])
303 ;; ----------------------------------------------------------------------
305 ;; ----------------------------------------------------------------------
307 (define_insn "addsi3"
308 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
309 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
310 (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))]
316 [(set_attr "length" "2,4,4")
317 (set_attr "cc" "set_zn,set_zn,set_zn")])
319 ;; ----------------------------------------------------------------------
320 ;; SUBTRACT INSTRUCTIONS
321 ;; ----------------------------------------------------------------------
323 (define_insn "subsi3"
324 [(set (match_operand:SI 0 "register_operand" "=r,r")
325 (minus:SI (match_operand:SI 1 "register_operand" "0,r")
326 (match_operand:SI 2 "register_operand" "r,0")))]
331 [(set_attr "length" "2,2")
332 (set_attr "cc" "set_zn")])
334 (define_insn "negsi2"
335 [(set (match_operand:SI 0 "register_operand" "=r")
336 (neg:SI (match_operand:SI 1 "register_operand" "0")))]
339 [(set_attr "length" "2")
340 (set_attr "cc" "set_zn")])
342 ;; ----------------------------------------------------------------------
343 ;; MULTIPLY INSTRUCTIONS
344 ;; ----------------------------------------------------------------------
346 (define_expand "mulhisi3"
347 [(set (match_operand:SI 0 "register_operand" "")
349 (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
350 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
354 (define_insn "*mulhisi3_internal1"
355 [(set (match_operand:SI 0 "register_operand" "=r")
357 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
358 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
361 [(set_attr "length" "2")
362 (set_attr "cc" "none_0hit")
363 (set_attr "type" "mult")])
365 ;; ??? Sign extending constants isn't valid. Fix?
367 (define_insn "*mulhisi3_internal2"
368 [(set (match_operand:SI 0 "register_operand" "=r,r")
370 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
371 (sign_extend:SI (match_operand 2 "const_int_operand" "J,K"))))]
376 [(set_attr "length" "2,4")
377 (set_attr "cc" "none_0hit,none_0hit")
378 (set_attr "type" "mult")])
381 ;; ----------------------------------------------------------------------
383 ;; ----------------------------------------------------------------------
385 (define_insn "*v850_clr1_1"
386 [(set (match_operand:QI 0 "memory_operand" "=m")
388 (and:SI (subreg:SI (match_dup 0) 0)
389 (match_operand:QI 1 "not_power_of_two_operand" "")) 0))]
394 xoperands[0] = operands[0];
395 xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
396 output_asm_insn (\"clr1 %M1,%0\", xoperands);
399 [(set_attr "length" "4")
400 (set_attr "cc" "clobber")])
402 (define_insn "*v850_clr1_2"
403 [(set (match_operand:HI 0 "indirect_operand" "=m")
405 (and:SI (subreg:SI (match_dup 0) 0)
406 (match_operand:HI 1 "not_power_of_two_operand" "")) 0))]
410 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
413 xoperands[0] = gen_rtx_MEM (QImode,
414 plus_constant (XEXP (operands[0], 0), log2 / 8));
415 xoperands[1] = GEN_INT (log2 % 8);
416 output_asm_insn (\"clr1 %1,%0\", xoperands);
419 [(set_attr "length" "4")
420 (set_attr "cc" "clobber")])
422 (define_insn "*v850_clr1_3"
423 [(set (match_operand:SI 0 "indirect_operand" "=m")
424 (and:SI (match_dup 0)
425 (match_operand:SI 1 "not_power_of_two_operand" "")))]
429 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
432 xoperands[0] = gen_rtx_MEM (QImode,
433 plus_constant (XEXP (operands[0], 0), log2 / 8));
434 xoperands[1] = GEN_INT (log2 % 8);
435 output_asm_insn (\"clr1 %1,%0\", xoperands);
438 [(set_attr "length" "4")
439 (set_attr "cc" "clobber")])
441 (define_insn "andsi3"
442 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
443 (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
444 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
450 [(set_attr "length" "2,2,4")
451 (set_attr "cc" "set_znv")])
453 ;; ----------------------------------------------------------------------
455 ;; ----------------------------------------------------------------------
457 (define_insn "*v850_set1_1"
458 [(set (match_operand:QI 0 "memory_operand" "=m")
459 (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
460 (match_operand 1 "power_of_two_operand" "")) 0))]
463 [(set_attr "length" "4")
464 (set_attr "cc" "clobber")])
466 (define_insn "*v850_set1_2"
467 [(set (match_operand:HI 0 "indirect_operand" "=m")
468 (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
469 (match_operand 1 "power_of_two_operand" "")) 0))]
473 int log2 = exact_log2 (INTVAL (operands[1]));
476 return \"set1 %M1,%0\";
480 xoperands[0] = gen_rtx_MEM (QImode,
481 plus_constant (XEXP (operands[0], 0),
483 xoperands[1] = GEN_INT (log2 % 8);
484 output_asm_insn (\"set1 %1,%0\", xoperands);
488 [(set_attr "length" "4")
489 (set_attr "cc" "clobber")])
491 (define_insn "*v850_set1_3"
492 [(set (match_operand:SI 0 "indirect_operand" "=m")
493 (ior:SI (match_dup 0)
494 (match_operand 1 "power_of_two_operand" "")))]
498 int log2 = exact_log2 (INTVAL (operands[1]));
501 return \"set1 %M1,%0\";
505 xoperands[0] = gen_rtx_MEM (QImode,
506 plus_constant (XEXP (operands[0], 0),
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),
558 xoperands[1] = GEN_INT (log2 % 8);
559 output_asm_insn (\"not1 %1,%0\", xoperands);
563 [(set_attr "length" "4")
564 (set_attr "cc" "clobber")])
566 (define_insn "*v850_not1_3"
567 [(set (match_operand:SI 0 "indirect_operand" "=m")
568 (xor:SI (match_dup 0)
569 (match_operand 1 "power_of_two_operand" "")))]
573 int log2 = exact_log2 (INTVAL (operands[1]));
576 return \"not1 %M1,%0\";
580 xoperands[0] = gen_rtx_MEM (QImode,
581 plus_constant (XEXP (operands[0], 0),
583 xoperands[1] = GEN_INT (log2 % 8);
584 output_asm_insn (\"not1 %1,%0\", xoperands);
588 [(set_attr "length" "4")
589 (set_attr "cc" "clobber")])
591 (define_insn "xorsi3"
592 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
593 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
594 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
600 [(set_attr "length" "2,2,4")
601 (set_attr "cc" "set_znv")])
603 ;; ----------------------------------------------------------------------
605 ;; ----------------------------------------------------------------------
607 (define_insn "one_cmplsi2"
608 [(set (match_operand:SI 0 "register_operand" "=r")
609 (not:SI (match_operand:SI 1 "register_operand" "r")))]
612 [(set_attr "length" "2")
613 (set_attr "cc" "set_znv")])
615 ;; -----------------------------------------------------------------
617 ;; -----------------------------------------------------------------
619 ;; ??? Is it worth defining insv and extv for the V850 series?!?
621 ;; An insv pattern would be useful, but does not get used because
622 ;; store_bit_field never calls insv when storing a constant value into a
623 ;; single-bit bitfield.
625 ;; extv/extzv patterns would be useful, but do not get used because
626 ;; optimize_bitfield_compare in fold-const usually converts single
627 ;; bit extracts into an AND with a mask.
629 ;; -----------------------------------------------------------------
631 ;; -----------------------------------------------------------------
634 [(set (match_operand:SI 0 "register_operand" "=r")
635 (le:SI (cc0) (const_int 0)))]
639 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
642 return \"setf le,%0\";
644 [(set_attr "length" "4")
645 (set_attr "cc" "none_0hit")])
648 [(set (match_operand:SI 0 "register_operand" "=r")
649 (leu:SI (cc0) (const_int 0)))]
652 [(set_attr "length" "4")
653 (set_attr "cc" "none_0hit")])
656 [(set (match_operand:SI 0 "register_operand" "=r")
657 (ge:SI (cc0) (const_int 0)))]
661 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
664 return \"setf ge,%0\";
666 [(set_attr "length" "4")
667 (set_attr "cc" "none_0hit")])
670 [(set (match_operand:SI 0 "register_operand" "=r")
671 (geu:SI (cc0) (const_int 0)))]
674 [(set_attr "length" "4")
675 (set_attr "cc" "none_0hit")])
678 [(set (match_operand:SI 0 "register_operand" "=r")
679 (lt:SI (cc0) (const_int 0)))]
683 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
686 return \"setf lt,%0\";
688 [(set_attr "length" "4")
689 (set_attr "cc" "none_0hit")])
692 [(set (match_operand:SI 0 "register_operand" "=r")
693 (ltu:SI (cc0) (const_int 0)))]
696 [(set_attr "length" "4")
697 (set_attr "cc" "none_0hit")])
700 [(set (match_operand:SI 0 "register_operand" "=r")
701 (gt:SI (cc0) (const_int 0)))]
705 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
708 return \"setf gt,%0\";
710 [(set_attr "length" "4")
711 (set_attr "cc" "none_0hit")])
714 [(set (match_operand:SI 0 "register_operand" "=r")
715 (gtu:SI (cc0) (const_int 0)))]
718 [(set_attr "length" "4")
719 (set_attr "cc" "none_0hit")])
722 [(set (match_operand:SI 0 "register_operand" "=r")
723 (eq:SI (cc0) (const_int 0)))]
726 [(set_attr "length" "4")
727 (set_attr "cc" "none_0hit")])
730 [(set (match_operand:SI 0 "register_operand" "=r")
731 (ne:SI (cc0) (const_int 0)))]
734 [(set_attr "length" "4")
735 (set_attr "cc" "none_0hit")])
738 ;; ----------------------------------------------------------------------
740 ;; ----------------------------------------------------------------------
742 ;; Conditional jump instructions
746 (if_then_else (le (cc0)
748 (label_ref (match_operand 0 "" ""))
753 (define_expand "bleu"
755 (if_then_else (leu (cc0)
757 (label_ref (match_operand 0 "" ""))
764 (if_then_else (ge (cc0)
766 (label_ref (match_operand 0 "" ""))
771 (define_expand "bgeu"
773 (if_then_else (geu (cc0)
775 (label_ref (match_operand 0 "" ""))
782 (if_then_else (lt (cc0)
784 (label_ref (match_operand 0 "" ""))
789 (define_expand "bltu"
791 (if_then_else (ltu (cc0)
793 (label_ref (match_operand 0 "" ""))
800 (if_then_else (gt (cc0)
802 (label_ref (match_operand 0 "" ""))
807 (define_expand "bgtu"
809 (if_then_else (gtu (cc0)
811 (label_ref (match_operand 0 "" ""))
818 (if_then_else (eq (cc0)
820 (label_ref (match_operand 0 "" ""))
827 (if_then_else (ne (cc0)
829 (label_ref (match_operand 0 "" ""))
834 (define_insn "*branch_normal"
836 (if_then_else (match_operator 1 "comparison_operator"
837 [(cc0) (const_int 0)])
838 (label_ref (match_operand 0 "" ""))
843 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
844 && (GET_CODE (operands[1]) == GT
845 || GET_CODE (operands[1]) == GE
846 || GET_CODE (operands[1]) == LE
847 || GET_CODE (operands[1]) == LT))
850 if (get_attr_length (insn) == 2)
853 return \"b%B1 .+6 ; jr %l0\";
855 [(set (attr "length")
856 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
860 (set_attr "cc" "none")])
862 (define_insn "*branch_invert"
864 (if_then_else (match_operator 1 "comparison_operator"
865 [(cc0) (const_int 0)])
867 (label_ref (match_operand 0 "" ""))))]
871 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
872 && (GET_CODE (operands[1]) == GT
873 || GET_CODE (operands[1]) == GE
874 || GET_CODE (operands[1]) == LE
875 || GET_CODE (operands[1]) == LT))
877 if (get_attr_length (insn) == 2)
880 return \"b%b1 .+6 ; jr %l0\";
882 [(set (attr "length")
883 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
887 (set_attr "cc" "none")])
889 ;; Unconditional and other jump instructions.
893 (label_ref (match_operand 0 "" "")))]
897 if (get_attr_length (insn) == 2)
902 [(set (attr "length")
903 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
907 (set_attr "cc" "none")])
909 (define_insn "indirect_jump"
910 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
913 [(set_attr "length" "2")
914 (set_attr "cc" "none")])
916 (define_insn "tablejump"
917 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
918 (use (label_ref (match_operand 1 "" "")))]
921 [(set_attr "length" "2")
922 (set_attr "cc" "none")])
924 (define_expand "casesi"
925 [(match_operand:SI 0 "register_operand" "")
926 (match_operand:SI 1 "register_operand" "")
927 (match_operand:SI 2 "register_operand" "")
928 (match_operand 3 "" "") (match_operand 4 "" "")]
932 rtx reg = gen_reg_rtx (SImode);
933 rtx tableaddress = gen_reg_rtx (SImode);
936 /* Subtract the lower bound from the index. */
937 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
938 /* Compare the result against the number of table entries. */
939 emit_insn (gen_cmpsi (reg, operands[2]));
940 /* Branch to the default label if out of range of the table. */
941 emit_jump_insn (gen_bgtu (operands[4]));
943 /* Shift index for the table array access. */
944 emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
945 /* Load the table address into a pseudo. */
946 emit_insn (gen_movsi (tableaddress,
947 gen_rtx_LABEL_REF (Pmode, operands[3])));
948 /* Add the table address to the index. */
949 emit_insn (gen_addsi3 (reg, reg, tableaddress));
950 /* Load the table entry. */
951 mem = gen_rtx_MEM (CASE_VECTOR_MODE, reg);
952 RTX_UNCHANGING_P (mem) = 1;
953 if (! TARGET_BIG_SWITCH)
955 rtx reg2 = gen_reg_rtx (HImode);
956 emit_insn (gen_movhi (reg2, mem));
957 emit_insn (gen_extendhisi2 (reg, reg2));
960 emit_insn (gen_movsi (reg, mem));
961 /* Add the table address. */
962 emit_insn (gen_addsi3 (reg, reg, tableaddress));
963 /* Branch to the switch label. */
964 emit_jump_insn (gen_tablejump (reg, operands[3]));
968 ;; Call subroutine with no return value.
970 (define_expand "call"
971 [(call (match_operand:QI 0 "general_operand" "")
972 (match_operand:SI 1 "general_operand" ""))]
976 if (! call_address_operand (XEXP (operands[0], 0), QImode)
977 || TARGET_LONG_CALLS)
978 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
979 if (TARGET_LONG_CALLS)
980 emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));
982 emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
987 (define_insn "call_internal_short"
988 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
989 (match_operand:SI 1 "general_operand" "g,g"))
990 (clobber (reg:SI 31))]
991 "! TARGET_LONG_CALLS"
994 jarl .+4,r31 ; add 4,r31 ; jmp %0"
995 [(set_attr "length" "4,8")]
998 (define_insn "call_internal_long"
999 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1000 (match_operand:SI 1 "general_operand" "g,g"))
1001 (clobber (reg:SI 31))]
1005 if (which_alternative == 0)
1007 if (GET_CODE (operands[0]) == REG)
1008 return \"jarl %0,r31\";
1010 return \"movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11\";
1013 return \"jarl .+4,r31 ; add 4,r31 ; jmp %0\";
1015 [(set_attr "length" "16,8")]
1018 ;; Call subroutine, returning value in operand 0
1019 ;; (which must be a hard register).
1021 (define_expand "call_value"
1022 [(set (match_operand 0 "" "")
1023 (call (match_operand:QI 1 "general_operand" "")
1024 (match_operand:SI 2 "general_operand" "")))]
1028 if (! call_address_operand (XEXP (operands[1], 0), QImode)
1029 || TARGET_LONG_CALLS)
1030 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1031 if (TARGET_LONG_CALLS)
1032 emit_call_insn (gen_call_value_internal_long (operands[0],
1033 XEXP (operands[1], 0),
1036 emit_call_insn (gen_call_value_internal_short (operands[0],
1037 XEXP (operands[1], 0),
1042 (define_insn "call_value_internal_short"
1043 [(set (match_operand 0 "" "=r,r")
1044 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1045 (match_operand:SI 2 "general_operand" "g,g")))
1046 (clobber (reg:SI 31))]
1047 "! TARGET_LONG_CALLS"
1050 jarl .+4,r31 ; add 4,r31 ; jmp %1"
1051 [(set_attr "length" "4,8")]
1054 (define_insn "call_value_internal_long"
1055 [(set (match_operand 0 "" "=r,r")
1056 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1057 (match_operand:SI 2 "general_operand" "g,g")))
1058 (clobber (reg:SI 31))]
1062 if (which_alternative == 0)
1064 if (GET_CODE (operands[1]) == REG)
1065 return \"jarl %1, r31\";
1067 /* Reload can generate this pattern... */
1068 return \"movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11\";
1071 return \"jarl .+4, r31 ; add 4, r31 ; jmp %1\";
1073 [(set_attr "length" "16,8")]
1080 [(set_attr "length" "2")
1081 (set_attr "cc" "none")])
1083 ;; ----------------------------------------------------------------------
1084 ;; EXTEND INSTRUCTIONS
1085 ;; ----------------------------------------------------------------------
1088 (define_insn "zero_extendhisi2"
1089 [(set (match_operand:SI 0 "register_operand" "=r")
1091 (match_operand:HI 1 "register_operand" "r")))]
1094 [(set_attr "length" "4")
1095 (set_attr "cc" "set_znv")])
1098 (define_insn "zero_extendqisi2"
1099 [(set (match_operand:SI 0 "register_operand" "=r")
1101 (match_operand:QI 1 "register_operand" "r")))]
1104 [(set_attr "length" "4")
1105 (set_attr "cc" "set_znv")])
1107 ;;- sign extension instructions
1110 ;; ??? This is missing a sign extend from memory pattern to match the ld.h
1113 (define_expand "extendhisi2"
1115 (ashift:SI (match_operand:HI 1 "register_operand" "")
1117 (set (match_operand:SI 0 "register_operand" "")
1118 (ashiftrt:SI (match_dup 2)
1123 operands[1] = gen_lowpart (SImode, operands[1]);
1124 operands[2] = gen_reg_rtx (SImode);
1128 ;; ??? This is missing a sign extend from memory pattern to match the ld.b
1131 (define_expand "extendqisi2"
1133 (ashift:SI (match_operand:QI 1 "register_operand" "")
1135 (set (match_operand:SI 0 "register_operand" "")
1136 (ashiftrt:SI (match_dup 2)
1141 operands[1] = gen_lowpart (SImode, operands[1]);
1142 operands[2] = gen_reg_rtx (SImode);
1145 ;; ----------------------------------------------------------------------
1147 ;; ----------------------------------------------------------------------
1149 (define_insn "ashlsi3"
1150 [(set (match_operand:SI 0 "register_operand" "=r,r")
1152 (match_operand:SI 1 "register_operand" "0,0")
1153 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1158 [(set_attr "length" "4,2")
1159 (set_attr "cc" "set_znv")])
1161 (define_insn "lshrsi3"
1162 [(set (match_operand:SI 0 "register_operand" "=r,r")
1164 (match_operand:SI 1 "register_operand" "0,0")
1165 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1170 [(set_attr "length" "4,2")
1171 (set_attr "cc" "set_znv")])
1173 (define_insn "ashrsi3"
1174 [(set (match_operand:SI 0 "register_operand" "=r,r")
1176 (match_operand:SI 1 "register_operand" "0,0")
1177 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1182 [(set_attr "length" "4,2")
1183 (set_attr "cc" "set_znv")])
1185 ;; ----------------------------------------------------------------------
1186 ;; PROLOGUE/EPILOGUE
1187 ;; ----------------------------------------------------------------------
1188 (define_expand "prologue"
1191 "expand_prologue (); DONE;")
1193 (define_expand "epilogue"
1198 /* Try to use the trivial return first. Else use the
1201 emit_jump_insn (gen_return ());
1207 (define_insn "return"
1209 "reload_completed && compute_frame_size (get_frame_size (), (long *)0) == 0"
1211 [(set_attr "length" "2")
1212 (set_attr "cc" "none")])
1214 (define_insn "return_internal"
1219 [(set_attr "length" "2")
1220 (set_attr "cc" "none")])
1224 ;; ----------------------------------------------------------------------
1225 ;; HELPER INSTRUCTIONS for saving the prologue and epilog registers
1226 ;; ----------------------------------------------------------------------
1228 ;; This pattern will match a stack adjust RTX followed by any number of push
1229 ;; RTXs. These RTXs will then be turned into a suitable call to a worker
1234 [(match_parallel 0 "pattern_is_ok_for_prologue"
1236 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1237 (set (mem:SI (plus:SI (reg:SI 3)
1238 (match_operand:SI 2 "immediate_operand" "i")))
1239 (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
1240 "TARGET_PROLOG_FUNCTION"
1241 "* return construct_save_jarl (operands[0]);
1243 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
1245 (const_string "4")))
1246 (set_attr "cc" "clobber")])
1248 ;; This pattern will match a return RTX followed by any number of pop RTXs
1249 ;; and possible a stack adjustment as well. These RTXs will be turned into
1250 ;; a suitable call to a worker function.
1253 [(match_parallel 0 "pattern_is_ok_for_epilogue"
1256 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1257 (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
1258 (mem:SI (plus:SI (reg:SI 3)
1259 (match_operand:SI 3 "immediate_operand" "i"))))])]
1260 "TARGET_PROLOG_FUNCTION && TARGET_V850"
1261 "* return construct_restore_jr (operands[0]);
1263 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
1265 (const_string "4")))
1266 (set_attr "cc" "clobber")])
1268 ;; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION.
1269 (define_insn "save_interrupt"
1270 [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16)))
1271 (set (mem:SI (reg:SI 3)) (reg:SI 30))
1272 (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 10))
1273 (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 4))
1274 (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))]
1275 "TARGET_V850 && ! TARGET_LONG_CALLS"
1276 "add -16, sp ; st.w r10, 12[sp] ; jarl __save_interrupt, r10"
1277 [(set_attr "length" "12")
1278 (set_attr "cc" "clobber")])
1280 ;; Restore r1, r4, r10, and return from the interrupt
1281 (define_insn "restore_interrupt"
1283 (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 16)))
1284 (set (reg:SI 30) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
1285 (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
1286 (set (reg:SI 4) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))
1287 (set (reg:SI 1) (mem:SI (reg:SI 3)))]
1289 "jr __return_interrupt"
1290 [(set_attr "length" "4")
1291 (set_attr "cc" "clobber")])
1294 ;; Save all registers except for the registers saved in save_interrupt when
1295 ;; an interrupt function makes a call.
1296 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1297 ;; all of memory. This blocks insns from being moved across this point.
1298 ;; This is needed because the rest of the compiler is not ready to handle
1299 ;; insns this complicated.
1301 (define_insn "save_all_interrupt"
1302 [(unspec_volatile [(const_int 0)] 0)]
1303 "TARGET_V850 && ! TARGET_LONG_CALLS"
1304 "jarl __save_all_interrupt,r10"
1305 [(set_attr "length" "4")
1306 (set_attr "cc" "clobber")])
1309 ;; Restore all registers saved when an interrupt function makes a call.
1310 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1311 ;; all of memory. This blocks insns from being moved across this point.
1312 ;; This is needed because the rest of the compiler is not ready to handle
1313 ;; insns this complicated.
1315 (define_insn "restore_all_interrupt"
1316 [(unspec_volatile [(const_int 0)] 1)]
1317 "TARGET_V850 && ! TARGET_LONG_CALLS"
1318 "jarl __restore_all_interrupt,r10"
1319 [(set_attr "length" "4")
1320 (set_attr "cc" "clobber")])
1322 ;; Save r6-r9 for a variable argument function
1323 (define_insn "save_r6_r9"
1324 [(set (mem:SI (reg:SI 3)) (reg:SI 6))
1325 (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
1326 (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
1327 (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
1328 (clobber (reg:SI 10))]
1329 "TARGET_PROLOG_FUNCTION && ! TARGET_LONG_CALLS"
1330 "jarl __save_r6_r9,r10"
1331 [(set_attr "length" "4")
1332 (set_attr "cc" "clobber")])