1 ;; GCC machine description for NEC V850
2 ;; Copyright (C) 1996-2018 Free Software Foundation, Inc.
3 ;; Contributed by Jeff Law (law@cygnus.com).
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;; The original PO technology requires these to be ordered by speed,
22 ;; so that assigner will pick the fastest.
24 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;; The V851 manual states that the instruction address space is 16M;
27 ;; the various branch/call instructions only have a 22bit offset (4M range).
29 ;; One day we'll probably need to handle calls to targets more than 4M
32 ;; The size of instructions in bytes.
34 ;;---------------------------------------------------------------------------
39 [(ZERO_REGNUM 0) ; constant zero
40 (SP_REGNUM 3) ; Stack Pointer
41 (GP_REGNUM 4) ; GP Pointer
42 (RV_REGNUM 10) ; Return value register
43 (EP_REGNUM 30) ; EP pointer
44 (LP_REGNUM 31) ; Return address register
45 (CC_REGNUM 32) ; Condition code pseudo register
46 (FCC_REGNUM 33) ; Floating Condition code pseudo register
50 (define_c_enum "unspec" [
56 (define_attr "length" ""
59 (define_attr "long_calls" "yes,no"
60 (const (if_then_else (symbol_ref "TARGET_LONG_CALLS")
62 (const_string "no"))))
64 ;; Types of instructions (for scheduling purposes).
66 (define_attr "type" "load,store,bit1,mult,macc,div,fpu,single,other"
67 (const_string "other"))
69 (define_attr "cpu" "none,v850,v850e,v850e1,v850e2,v850e2v3,v850e3v5"
70 (cond [(match_test "TARGET_V850")
72 (match_test "TARGET_V850E")
73 (const_string "v850e")
74 (match_test "TARGET_V850E1")
75 (const_string "v850e1")
76 (match_test "TARGET_V850E2")
77 (const_string "v850e2")
78 (match_test "TARGET_V850E2V3")
79 (const_string "v850e2v3")
80 (match_test "TARGET_V850E3V5")
81 (const_string "v850e3v5")]
82 (const_string "none")))
85 ;; Function units for the V850. As best as I can tell, there's
86 ;; a traditional memory load/use stall as well as a stall if
87 ;; the result of a multiply is used too early.
89 (define_insn_reservation "v850_other" 1
90 (eq_attr "type" "other")
92 (define_insn_reservation "v850_mult" 2
93 (eq_attr "type" "mult")
95 (define_insn_reservation "v850_memory" 2
96 (eq_attr "type" "load")
99 (include "predicates.md")
100 (include "constraints.md")
102 ;; ----------------------------------------------------------------------
104 ;; ----------------------------------------------------------------------
105 (define_insn "sign23byte_load"
106 [(set (match_operand:SI 0 "register_operand" "=r")
108 (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
109 (match_operand 2 "disp23_operand" "W")))))]
112 [(set_attr "length" "4")])
114 (define_insn "unsign23byte_load"
115 [(set (match_operand:SI 0 "register_operand" "=r")
117 (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
118 (match_operand 2 "disp23_operand" "W")))))]
121 [(set_attr "length" "4")])
123 (define_insn "sign23hword_load"
124 [(set (match_operand:SI 0 "register_operand" "=r")
126 (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
127 (match_operand 2 "disp23_operand" "W")))))]
130 [(set_attr "length" "4")])
132 (define_insn "unsign23hword_load"
133 [(set (match_operand:SI 0 "register_operand" "=r")
135 (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
136 (match_operand 2 "disp23_operand" "W")))))]
139 [(set_attr "length" "4")])
141 (define_insn "23word_load"
142 [(set (match_operand:SI 0 "register_operand" "=r")
143 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
144 (match_operand 2 "disp23_operand" "W"))))]
147 [(set_attr "length" "4")])
149 (define_insn "23byte_store"
150 [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "r")
151 (match_operand 1 "disp23_operand" "W")))
152 (match_operand:QI 2 "register_operand" "r"))]
155 [(set_attr "length" "4")])
157 (define_insn "23hword_store"
158 [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "r")
159 (match_operand 1 "disp23_operand" "W")))
160 (match_operand:HI 2 "register_operand" "r"))]
163 [(set_attr "length" "4")])
165 (define_insn "23word_store"
166 [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
167 (match_operand 1 "disp23_operand" "W")))
168 (match_operand:SI 2 "register_operand" "r"))]
171 [(set_attr "length" "4")])
175 (define_expand "movdi"
176 [(set (match_operand:DI 0 "general_operand")
177 (match_operand:DI 1 "general_operand"))]
180 /* One of the ops has to be in a register or 0. */
181 if (!register_operand (operand0, DImode)
182 && !register_operand (operand1, DImode))
183 operands[1] = copy_to_mode_reg (DImode, operand1);
185 if (register_operand (operand0, DImode)
186 && (CONST_INT_P (operands[1]) || CONST_DOUBLE_P (operands[1])))
190 for (i = 0; i < UNITS_PER_WORD * 2; i += UNITS_PER_WORD)
191 emit_move_insn (simplify_gen_subreg (SImode, operands[0], DImode, i),
192 simplify_gen_subreg (SImode, operands[1], DImode, i));
198 (define_insn "*movdi_internal"
199 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,e!r,m")
200 (match_operand:DI 1 "nonimmediate_operand" "r,m,e!r"))]
202 || (register_operand (operands[0], DImode) && register_operand (operands[1], DImode))"
203 { return v850_gen_movdi (operands); }
204 [(set_attr "length" "4,12,12")
205 (set_attr "type" "other,load,store")])
209 (define_expand "movqi"
210 [(set (match_operand:QI 0 "general_operand" "")
211 (match_operand:QI 1 "general_operand" ""))]
214 /* One of the ops has to be in a register or 0 */
215 if (!register_operand (operand0, QImode)
216 && !reg_or_0_operand (operand1, QImode))
217 operands[1] = copy_to_mode_reg (QImode, operand1);
220 (define_insn "*movqi_internal"
221 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,Q,r,m,m")
222 (match_operand:QI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
223 "register_operand (operands[0], QImode)
224 || reg_or_0_operand (operands[1], QImode)"
226 return output_move_single (operands);
228 [(set_attr "length" "2,4,2,2,4,4,4")
229 (set_attr "type" "other,other,load,other,load,store,store")])
233 (define_expand "movhi"
234 [(set (match_operand:HI 0 "general_operand" "")
235 (match_operand:HI 1 "general_operand" ""))]
238 /* One of the ops has to be in a register or 0 */
239 if (!register_operand (operand0, HImode)
240 && !reg_or_0_operand (operand1, HImode))
241 operands[1] = copy_to_mode_reg (HImode, operand1);
244 (define_insn "*movhi_internal"
245 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,Q,r,m,m")
246 (match_operand:HI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
247 "register_operand (operands[0], HImode)
248 || reg_or_0_operand (operands[1], HImode)"
250 return output_move_single (operands);
252 [(set_attr "length" "2,4,2,2,4,4,4")
253 (set_attr "type" "other,other,load,other,load,store,store")])
257 (define_insn "*movsi_high"
258 [(set (match_operand:SI 0 "register_operand" "=r")
259 (high:SI (match_operand 1 "immediate_operand" "i")))]
262 [(set_attr "length" "4")
263 (set_attr "type" "other")])
265 (define_insn "*movsi_lo"
266 [(set (match_operand:SI 0 "register_operand" "=r")
267 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
268 (match_operand:SI 2 "immediate_operand" "i")))]
271 [(set_attr "length" "4")
272 (set_attr "type" "other")])
274 (define_expand "movsi"
275 [(set (match_operand:SI 0 "general_operand" "")
276 (match_operand:SI 1 "general_operand" ""))]
279 /* One of the ops has to be in a register or 0 */
280 if (!register_operand (operand0, SImode)
281 && !reg_or_0_operand (operand1, SImode))
282 operands[1] = copy_to_mode_reg (SImode, operand1);
284 /* Some constants, as well as symbolic operands
285 must be done with HIGH & LO_SUM patterns. */
286 if (CONSTANT_P (operands[1])
287 && GET_CODE (operands[1]) != HIGH
288 && ! (TARGET_V850E_UP)
289 && !special_symbolref_operand (operands[1], VOIDmode)
290 && !(GET_CODE (operands[1]) == CONST_INT
291 && (CONST_OK_FOR_J (INTVAL (operands[1]))
292 || CONST_OK_FOR_K (INTVAL (operands[1]))
293 || CONST_OK_FOR_L (INTVAL (operands[1])))))
297 if (reload_in_progress || reload_completed)
300 temp = gen_reg_rtx (SImode);
302 emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (SImode, operand1)));
303 emit_insn (gen_rtx_SET (operand0,
304 gen_rtx_LO_SUM (SImode, temp, operand1)));
309 ;; This is the same as the following pattern, except that it includes
310 ;; support for arbitrary 32-bit immediates.
312 ;; ??? This always loads addresses using hilo. If the only use of this address
313 ;; was in a load/store, then we would get smaller code if we only loaded the
314 ;; upper part with hi, and then put the lower part in the load/store insn.
316 (define_insn "*movsi_internal_v850e"
317 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,Q,r,r,m,m,r")
318 (match_operand:SI 1 "general_operand" "Jr,K,L,Q,Ir,m,R,r,I,i"))]
320 && (register_operand (operands[0], SImode)
321 || reg_or_0_operand (operands[1], SImode))"
323 return output_move_single (operands);
325 [(set_attr "length" "2,4,4,2,2,4,4,4,4,6")
326 (set_attr "type" "other,other,other,load,other,load,other,store,store,other")])
328 (define_insn "*movsi_internal"
329 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,Q,r,r,m,m")
330 (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))]
331 "register_operand (operands[0], SImode)
332 || reg_or_0_operand (operands[1], SImode)"
334 return output_move_single (operands);
336 [(set_attr "length" "2,4,4,2,2,4,4,4,4")
337 (set_attr "type" "other,other,other,load,other,load,store,store,other")])
339 (define_insn "*movsf_internal"
340 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,Q,r,m,m,r")
341 (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))]
342 "register_operand (operands[0], SFmode)
343 || reg_or_0_operand (operands[1], SFmode)"
345 return output_move_single (operands);
347 [(set_attr "length" "2,4,4,8,2,2,4,4,4,8")
348 (set_attr "type" "other,other,other,other,load,other,load,store,store,other")])
350 ;; ----------------------------------------------------------------------
352 ;; ----------------------------------------------------------------------
354 (define_insn "*v850_tst1"
356 (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
358 (match_operand:QI 1 "const_int_operand" "n"))
362 [(set_attr "length" "4")])
364 ;; This replaces ld.b;sar;andi with tst1;setf nz.
367 [(set (match_operand:SI 0 "register_operand" "")
368 (compare (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
370 (match_operand 2 "const_int_operand" ""))
373 [(set (cc0) (compare (zero_extract:SI (match_dup 1)
377 (set (match_dup 0) (ne:SI (cc0) (const_int 0)))])
379 (define_expand "cbranchsi4"
381 (compare (match_operand:SI 1 "register_operand" "")
382 (match_operand:SI 2 "reg_or_int5_operand" "")))
385 (match_operator 0 "ordered_comparison_operator" [(cc0)
387 (label_ref (match_operand 3 "" ""))
391 (define_expand "cstoresi4"
393 (compare (match_operand:SI 2 "register_operand" "")
394 (match_operand:SI 3 "reg_or_int5_operand" "")))
395 (set (match_operand:SI 0 "register_operand")
396 (match_operator:SI 1 "ordered_comparison_operator" [(cc0)
400 (define_expand "cmpsi"
402 (compare (match_operand:SI 0 "register_operand" "r,r")
403 (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
406 v850_compare_op0 = operands[0];
407 v850_compare_op1 = operands[1];
411 (define_insn "cmpsi_insn"
413 (compare (match_operand:SI 0 "register_operand" "r,r")
414 (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
419 [(set_attr "length" "2,2")])
421 (define_expand "cbranchsf4"
423 (if_then_else (match_operator 0 "ordered_comparison_operator"
424 [(match_operand:SF 1 "register_operand")
425 (match_operand:SF 2 "register_operand")])
426 (label_ref (match_operand 3 ""))
431 enum rtx_code cond = GET_CODE (operands[0]);
437 v850_compare_op0 = operands[1];
438 v850_compare_op1 = operands[2];
440 if (GET_MODE_CLASS (GET_MODE (v850_compare_op0)) != MODE_FLOAT)
443 mode = v850_gen_float_compare (cond, VOIDmode, v850_compare_op0, v850_compare_op1);
444 fcc_reg = gen_rtx_REG (mode, FCC_REGNUM);
445 cc_reg = gen_rtx_REG (mode, CC_REGNUM);
446 emit_insn (gen_rtx_SET (cc_reg, fcc_reg));
447 tmp = gen_rtx_fmt_ee (cond, mode, cc_reg, const0_rtx);
448 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
449 gen_rtx_LABEL_REF (VOIDmode, operands[3]), pc_rtx);
450 emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
454 (define_insn "cstoresf4"
455 [(set (match_operand:SI 0 "register_operand" "=r")
456 (match_operator:SI 1 "ordered_comparison_operator"
457 [(match_operand:SF 2 "register_operand" "r")
458 (match_operand:SF 3 "register_operand" "r")]))]
461 if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
462 return "cmpf.s %c1, %z2, %z3 ; trfsr ; setf nz, %0";
463 if (GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE)
464 return "cmpf.s %c1, %z2, %z3 ; trfsr ; setf z, %0";
465 if (GET_CODE (operands[1]) == EQ)
466 return "cmpf.s eq, %z2, %z3 ; trfsr ; setf z, %0";
467 if (GET_CODE (operands[1]) == NE)
468 return "cmpf.s neq, %z2, %z3 ; trfsr ; setf nz, %0";
471 [(set_attr "length" "12")
472 (set_attr "type" "fpu")])
474 (define_expand "cbranchdf4"
476 (if_then_else (match_operator 0 "ordered_comparison_operator"
477 [(match_operand:DF 1 "even_reg_operand")
478 (match_operand:DF 2 "even_reg_operand")])
479 (label_ref (match_operand 3 ""))
484 enum rtx_code cond = GET_CODE (operands[0]);
490 v850_compare_op0 = operands[1];
491 v850_compare_op1 = operands[2];
493 if (GET_MODE_CLASS (GET_MODE (v850_compare_op0)) != MODE_FLOAT)
496 mode = v850_gen_float_compare (cond, VOIDmode, v850_compare_op0, v850_compare_op1);
497 fcc_reg = gen_rtx_REG (mode, FCC_REGNUM);
498 cc_reg = gen_rtx_REG (mode, CC_REGNUM);
499 emit_insn (gen_rtx_SET (cc_reg, fcc_reg));
500 tmp = gen_rtx_fmt_ee (cond, mode, cc_reg, const0_rtx);
501 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
502 gen_rtx_LABEL_REF (VOIDmode, operands[3]), pc_rtx);
503 emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
507 (define_insn "cstoredf4"
508 [(set (match_operand:SI 0 "register_operand" "=r")
509 (match_operator:SI 1 "ordered_comparison_operator"
510 [(match_operand:DF 2 "even_reg_operand" "r")
511 (match_operand:DF 3 "even_reg_operand" "r")]))]
514 if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
515 return "cmpf.d %c1, %z2, %z3 ; trfsr ; setf nz, %0";
516 if (GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE)
517 return "cmpf.d %c1, %z2, %z3 ; trfsr ; setf z, %0";
518 if (GET_CODE (operands[1]) == EQ)
519 return "cmpf.d eq, %z2, %z3 ; trfsr ; setf z ,%0";
520 if (GET_CODE (operands[1]) == NE)
521 return "cmpf.d neq, %z2, %z3 ; trfsr ; setf nz, %0";
524 [(set_attr "length" "12")
525 (set_attr "type" "fpu")])
527 (define_expand "cmpsf"
528 [(set (reg:CC CC_REGNUM)
529 (compare (match_operand:SF 0 "register_operand" "r")
530 (match_operand:SF 1 "register_operand" "r")))]
533 v850_compare_op0 = operands[0];
534 v850_compare_op1 = operands[1];
538 (define_expand "cmpdf"
539 [(set (reg:CC CC_REGNUM)
540 (compare (match_operand:DF 0 "even_reg_operand" "r")
541 (match_operand:DF 1 "even_reg_operand" "r")))]
544 v850_compare_op0 = operands[0];
545 v850_compare_op1 = operands[1];
549 ;; ----------------------------------------------------------------------
551 ;; ----------------------------------------------------------------------
553 (define_insn "addsi3"
554 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
555 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
556 (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))
557 (clobber (reg:CC CC_REGNUM))]
564 [(set_attr "length" "2,4,4")])
566 ;; ----------------------------------------------------------------------
567 ;; SUBTRACT INSTRUCTIONS
568 ;; ----------------------------------------------------------------------
570 (define_insn "subsi3"
571 [(set (match_operand:SI 0 "register_operand" "=r,r")
572 (minus:SI (match_operand:SI 1 "register_operand" "0,r")
573 (match_operand:SI 2 "register_operand" "r,0")))
574 (clobber (reg:CC CC_REGNUM))]
579 [(set_attr "length" "2,2")])
581 (define_insn "negsi2"
582 [(set (match_operand:SI 0 "register_operand" "=r")
583 (neg:SI (match_operand:SI 1 "register_operand" "0")))
584 (clobber (reg:CC CC_REGNUM))]
587 [(set_attr "length" "2")])
589 ;; ----------------------------------------------------------------------
590 ;; MULTIPLY INSTRUCTIONS
591 ;; ----------------------------------------------------------------------
593 (define_expand "mulhisi3"
594 [(set (match_operand:SI 0 "register_operand" "")
596 (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
597 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
600 if (GET_CODE (operands[2]) == CONST_INT)
602 emit_insn (gen_mulhisi3_internal2 (operands[0], operands[1], operands[2]));
607 (define_insn "*mulhisi3_internal1"
608 [(set (match_operand:SI 0 "register_operand" "=r")
610 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
611 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
614 [(set_attr "length" "2")
615 (set_attr "type" "mult")])
617 (define_insn "mulhisi3_internal2"
618 [(set (match_operand:SI 0 "register_operand" "=r,r")
620 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
621 (match_operand:HI 2 "const_int_operand" "J,K")))]
626 [(set_attr "length" "2,4")
627 (set_attr "type" "mult")])
629 ;; ??? The scheduling info is probably wrong.
631 ;; ??? This instruction can also generate the 32-bit highpart, but using it
632 ;; may increase code size counter to the desired result.
634 ;; ??? This instructions can also give a DImode result.
636 ;; ??? There is unsigned version, but it matters only for the DImode/highpart
639 (define_insn "mulsi3"
640 [(set (match_operand:SI 0 "register_operand" "=r")
641 (mult:SI (match_operand:SI 1 "register_operand" "%0")
642 (match_operand:SI 2 "reg_or_int9_operand" "rO")))]
645 [(set_attr "length" "4")
646 (set_attr "type" "mult")])
648 ;; ----------------------------------------------------------------------
649 ;; DIVIDE INSTRUCTIONS
650 ;; ----------------------------------------------------------------------
652 ;; ??? These insns do set the Z/N condition codes, except that they are based
653 ;; on only one of the two results, so it doesn't seem to make sense to use
656 ;; ??? The scheduling info is probably wrong.
658 (define_insn "divmodsi4"
659 [(set (match_operand:SI 0 "register_operand" "=r")
660 (div:SI (match_operand:SI 1 "register_operand" "0")
661 (match_operand:SI 2 "register_operand" "r")))
662 (set (match_operand:SI 3 "register_operand" "=r")
663 (mod:SI (match_dup 1)
665 (clobber (reg:CC CC_REGNUM))]
668 if (TARGET_V850E2_UP)
669 return "divq %2,%0,%3";
671 return "div %2,%0,%3";
673 [(set_attr "length" "4")
674 (set_attr "type" "div")])
676 (define_insn "udivmodsi4"
677 [(set (match_operand:SI 0 "register_operand" "=r")
678 (udiv:SI (match_operand:SI 1 "register_operand" "0")
679 (match_operand:SI 2 "register_operand" "r")))
680 (set (match_operand:SI 3 "register_operand" "=r")
681 (umod:SI (match_dup 1)
683 (clobber (reg:CC CC_REGNUM))]
686 if (TARGET_V850E2_UP)
687 return "divqu %2,%0,%3";
689 return "divu %2,%0,%3";
691 [(set_attr "length" "4")
692 (set_attr "type" "div")])
694 ;; ??? There is a 2 byte instruction for generating only the quotient.
695 ;; However, it isn't clear how to compute the length field correctly.
697 (define_insn "divmodhi4"
698 [(set (match_operand:HI 0 "register_operand" "=r")
699 (div:HI (match_operand:HI 1 "register_operand" "0")
700 (match_operand:HI 2 "register_operand" "r")))
701 (set (match_operand:HI 3 "register_operand" "=r")
702 (mod:HI (match_dup 1)
704 (clobber (reg:CC CC_REGNUM))]
706 "sxh %0\n\tdivh %2,%0,%3"
707 [(set_attr "length" "6")
708 (set_attr "type" "div")])
710 ;; The half word needs to be zero/sign extended to 32 bits before doing
711 ;; the division/modulo operation.
713 (define_insn "udivmodhi4"
714 [(set (match_operand:HI 0 "register_operand" "=r")
715 (udiv:HI (match_operand:HI 1 "register_operand" "0")
716 (match_operand:HI 2 "register_operand" "r")))
717 (set (match_operand:HI 3 "register_operand" "=r")
718 (umod:HI (match_dup 1)
720 (clobber (reg:CC CC_REGNUM))]
722 "zxh %0\n\tdivhu %2,%0,%3"
723 [(set_attr "length" "6")
724 (set_attr "type" "div")])
726 ;; ----------------------------------------------------------------------
728 ;; ----------------------------------------------------------------------
730 (define_insn "*v850_clr1_1"
731 [(set (match_operand:QI 0 "memory_operand" "=m")
733 (and:SI (subreg:SI (match_dup 0) 0)
734 (match_operand:QI 1 "not_power_of_two_operand" "")) 0))
735 (clobber (reg:CC CC_REGNUM))]
739 xoperands[0] = operands[0];
740 xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
741 output_asm_insn ("clr1 %M1,%0", xoperands);
744 [(set_attr "length" "4")
745 (set_attr "type" "bit1")])
747 (define_insn "*v850_clr1_2"
748 [(set (match_operand:HI 0 "indirect_operand" "=m")
750 (and:SI (subreg:SI (match_dup 0) 0)
751 (match_operand:HI 1 "not_power_of_two_operand" "")) 0))
752 (clobber (reg:CC CC_REGNUM))]
755 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
758 xoperands[0] = gen_rtx_MEM (QImode,
759 plus_constant (Pmode, XEXP (operands[0], 0),
761 xoperands[1] = GEN_INT (log2 % 8);
762 output_asm_insn ("clr1 %1,%0", xoperands);
765 [(set_attr "length" "4")
766 (set_attr "type" "bit1")])
768 (define_insn "*v850_clr1_3"
769 [(set (match_operand:SI 0 "indirect_operand" "=m")
770 (and:SI (match_dup 0)
771 (match_operand:SI 1 "not_power_of_two_operand" "")))
772 (clobber (reg:CC CC_REGNUM))]
775 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
778 xoperands[0] = gen_rtx_MEM (QImode,
779 plus_constant (Pmode, XEXP (operands[0], 0),
781 xoperands[1] = GEN_INT (log2 % 8);
782 output_asm_insn ("clr1 %1,%0", xoperands);
785 [(set_attr "length" "4")
786 (set_attr "type" "bit1")])
788 (define_insn "andsi3"
789 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
790 (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
791 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
792 (clobber (reg:CC CC_REGNUM))]
798 [(set_attr "length" "2,2,4")])
800 ;; ----------------------------------------------------------------------
802 ;; ----------------------------------------------------------------------
804 (define_insn "*v850_set1_1"
805 [(set (match_operand:QI 0 "memory_operand" "=m")
806 (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
807 (match_operand 1 "power_of_two_operand" "")) 0))
808 (clobber (reg:CC CC_REGNUM))]
811 [(set_attr "length" "4")
812 (set_attr "type" "bit1")])
814 (define_insn "*v850_set1_2"
815 [(set (match_operand:HI 0 "indirect_operand" "=m")
816 (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
817 (match_operand 1 "power_of_two_operand" "")) 0))]
820 int log2 = exact_log2 (INTVAL (operands[1]));
823 return "set1 %M1,%0";
827 xoperands[0] = gen_rtx_MEM (QImode,
828 plus_constant (Pmode, XEXP (operands[0], 0),
830 xoperands[1] = GEN_INT (log2 % 8);
831 output_asm_insn ("set1 %1,%0", xoperands);
835 [(set_attr "length" "4")
836 (set_attr "type" "bit1")])
838 (define_insn "*v850_set1_3"
839 [(set (match_operand:SI 0 "indirect_operand" "=m")
840 (ior:SI (match_dup 0)
841 (match_operand 1 "power_of_two_operand" "")))
842 (clobber (reg:CC CC_REGNUM))]
845 int log2 = exact_log2 (INTVAL (operands[1]));
848 return "set1 %M1,%0";
852 xoperands[0] = gen_rtx_MEM (QImode,
853 plus_constant (Pmode, XEXP (operands[0], 0),
855 xoperands[1] = GEN_INT (log2 % 8);
856 output_asm_insn ("set1 %1,%0", xoperands);
860 [(set_attr "length" "4")
861 (set_attr "type" "bit1")])
863 (define_insn "iorsi3"
864 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
865 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
866 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
867 (clobber (reg:CC CC_REGNUM))]
873 [(set_attr "length" "2,2,4")])
875 ;; ----------------------------------------------------------------------
877 ;; ----------------------------------------------------------------------
879 (define_insn "*v850_not1_1"
880 [(set (match_operand:QI 0 "memory_operand" "=m")
881 (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0)
882 (match_operand 1 "power_of_two_operand" "")) 0))
883 (clobber (reg:CC CC_REGNUM))]
886 [(set_attr "length" "4")
887 (set_attr "type" "bit1")])
889 (define_insn "*v850_not1_2"
890 [(set (match_operand:HI 0 "indirect_operand" "=m")
891 (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
892 (match_operand 1 "power_of_two_operand" "")) 0))]
895 int log2 = exact_log2 (INTVAL (operands[1]));
898 return "not1 %M1,%0";
902 xoperands[0] = gen_rtx_MEM (QImode,
903 plus_constant (Pmode, XEXP (operands[0], 0),
905 xoperands[1] = GEN_INT (log2 % 8);
906 output_asm_insn ("not1 %1,%0", xoperands);
910 [(set_attr "length" "4")
911 (set_attr "type" "bit1")])
913 (define_insn "*v850_not1_3"
914 [(set (match_operand:SI 0 "indirect_operand" "=m")
915 (xor:SI (match_dup 0)
916 (match_operand 1 "power_of_two_operand" "")))
917 (clobber (reg:CC CC_REGNUM))]
920 int log2 = exact_log2 (INTVAL (operands[1]));
923 return "not1 %M1,%0";
927 xoperands[0] = gen_rtx_MEM (QImode,
928 plus_constant (Pmode, XEXP (operands[0], 0),
930 xoperands[1] = GEN_INT (log2 % 8);
931 output_asm_insn ("not1 %1,%0", xoperands);
935 [(set_attr "length" "4")
936 (set_attr "type" "bit1")])
938 (define_insn "xorsi3"
939 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
940 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
941 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
942 (clobber (reg:CC CC_REGNUM))]
948 [(set_attr "length" "2,2,4")])
950 ;; ----------------------------------------------------------------------
952 ;; ----------------------------------------------------------------------
954 (define_insn "one_cmplsi2"
955 [(set (match_operand:SI 0 "register_operand" "=r")
956 (not:SI (match_operand:SI 1 "register_operand" "r")))
957 (clobber (reg:CC CC_REGNUM))]
960 [(set_attr "length" "2")])
962 ;; -----------------------------------------------------------------
964 ;; -----------------------------------------------------------------
966 ;; ??? Is it worth defining insv and extv for the V850 series?!?
968 ;; An insv pattern would be useful, but does not get used because
969 ;; store_bit_field never calls insv when storing a constant value into a
970 ;; single-bit bitfield.
972 ;; extv/extzv patterns would be useful, but do not get used because
973 ;; optimize_bitfield_compare in fold-const usually converts single
974 ;; bit extracts into an AND with a mask.
977 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
978 (match_operand:SI 1 "immediate_operand" "n")
979 (match_operand:SI 2 "immediate_operand" "n"))
980 (match_operand:SI 3 "register_operand" "r"))]
982 "bins %3, %2, %1, %0"
983 [(set_attr "length" "4")])
985 ;; -----------------------------------------------------------------
987 ;; -----------------------------------------------------------------
989 (define_insn "*setcc"
990 [(set (match_operand:SI 0 "register_operand" "=r")
991 (match_operator:SI 1 "comparison_operator"
992 [(cc0) (const_int 0)]))]
995 [(set_attr "length" "4")])
997 (define_insn "setf_insn"
998 [(set (match_operand:SI 0 "register_operand" "=r")
999 (match_operator:SI 1 "comparison_operator"
1000 [(reg:CC CC_REGNUM) (const_int 0)]))]
1003 [(set_attr "length" "4")])
1005 (define_insn "set_z_insn"
1006 [(set (match_operand:SI 0 "register_operand" "=r")
1007 (match_operand 1 "v850_float_z_comparison_operator" ""))]
1008 "TARGET_V850E2V3_UP"
1010 [(set_attr "length" "4")])
1012 (define_insn "set_nz_insn"
1013 [(set (match_operand:SI 0 "register_operand" "=r")
1014 (match_operand 1 "v850_float_nz_comparison_operator" ""))]
1015 "TARGET_V850E2V3_UP"
1017 [(set_attr "length" "4")])
1019 ;; ----------------------------------------------------------------------
1020 ;; CONDITIONAL MOVE INSTRUCTIONS
1021 ;; ----------------------------------------------------------------------
1023 ;; Instructions using cc0 aren't allowed to have input reloads, so we must
1024 ;; hide the fact that this instruction uses cc0. We do so by including the
1025 ;; compare instruction inside it.
1027 (define_expand "movsicc"
1028 [(set (match_operand:SI 0 "register_operand" "=r")
1030 (match_operand 1 "comparison_operator")
1031 (match_operand:SI 2 "reg_or_const_operand" "rJ")
1032 (match_operand:SI 3 "reg_or_const_operand" "rI")))]
1035 /* Make sure that we have an integer comparison... */
1036 if (GET_MODE (XEXP (operands[1], 0)) != CCmode
1037 && GET_MODE (XEXP (operands[1], 0)) != SImode)
1040 if ((GET_CODE (operands[2]) == CONST_INT
1041 && GET_CODE (operands[3]) == CONST_INT))
1043 int o2 = INTVAL (operands[2]);
1044 int o3 = INTVAL (operands[3]);
1046 if (o2 == 1 && o3 == 0)
1048 if (o3 == 1 && o2 == 0)
1050 if (o2 == 0 && (o3 < -16 || o3 > 15) && exact_log2 (o3) >= 0)
1051 FAIL; /* setf + shift */
1052 if (o3 == 0 && (o2 < -16 || o2 > 15) && exact_log2 (o2) >=0)
1053 FAIL; /* setf + shift */
1055 operands[2] = copy_to_mode_reg (SImode, operands[2]);
1057 operands[3] = copy_to_mode_reg (SImode, operands[3]);
1061 if (GET_CODE (operands[2]) != REG)
1062 operands[2] = copy_to_mode_reg (SImode,operands[2]);
1063 if (GET_CODE (operands[3]) != REG)
1064 operands[3] = copy_to_mode_reg (SImode, operands[3]);
1068 ;; ??? Clobbering the condition codes is overkill.
1070 ;; ??? We sometimes emit an unnecessary compare instruction because the
1071 ;; condition codes may have already been set by an earlier instruction,
1072 ;; but we have no code here to avoid the compare if it is unnecessary.
1074 (define_insn "movsicc_normal_cc"
1075 [(set (match_operand:SI 0 "register_operand" "=r")
1077 (match_operator 1 "comparison_operator"
1078 [(reg:CC CC_REGNUM) (const_int 0)])
1079 (match_operand:SI 2 "reg_or_int5_operand" "rJ")
1080 (match_operand:SI 3 "reg_or_0_operand" "rI")))]
1082 "cmov %c1,%2,%z3,%0";
1083 [(set_attr "length" "6")])
1085 (define_insn "movsicc_reversed_cc"
1086 [(set (match_operand:SI 0 "register_operand" "=r")
1088 (match_operator 1 "comparison_operator"
1089 [(reg:CC CC_REGNUM) (const_int 0)])
1090 (match_operand:SI 2 "reg_or_0_operand" "rI")
1091 (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
1093 "cmov %C1,%3,%z2,%0"
1094 [(set_attr "length" "6")])
1096 (define_insn "*movsicc_normal"
1097 [(set (match_operand:SI 0 "register_operand" "=r")
1099 (match_operator 1 "comparison_operator"
1100 [(match_operand:SI 4 "register_operand" "r")
1101 (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
1102 (match_operand:SI 2 "reg_or_int5_operand" "rJ")
1103 (match_operand:SI 3 "reg_or_0_operand" "rI")))]
1105 "cmp %5,%4 ; cmov %c1,%2,%z3,%0"
1106 [(set_attr "length" "6")])
1108 (define_insn "*movsicc_reversed"
1109 [(set (match_operand:SI 0 "register_operand" "=r")
1111 (match_operator 1 "comparison_operator"
1112 [(match_operand:SI 4 "register_operand" "r")
1113 (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
1114 (match_operand:SI 2 "reg_or_0_operand" "rI")
1115 (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
1117 "cmp %5,%4 ; cmov %C1,%3,%z2,%0"
1118 [(set_attr "length" "6")])
1120 (define_insn "*movsicc_tst1"
1121 [(set (match_operand:SI 0 "register_operand" "=r")
1123 (match_operator 1 "comparison_operator"
1125 (match_operand:QI 2 "memory_operand" "m")
1127 (match_operand 3 "const_int_operand" "n"))
1129 (match_operand:SI 4 "reg_or_int5_operand" "rJ")
1130 (match_operand:SI 5 "reg_or_0_operand" "rI")))]
1132 "tst1 %3,%2 ; cmov %c1,%4,%z5,%0"
1133 [(set_attr "length" "8")])
1135 (define_insn "*movsicc_tst1_reversed"
1136 [(set (match_operand:SI 0 "register_operand" "=r")
1138 (match_operator 1 "comparison_operator"
1140 (match_operand:QI 2 "memory_operand" "m")
1142 (match_operand 3 "const_int_operand" "n"))
1144 (match_operand:SI 4 "reg_or_0_operand" "rI")
1145 (match_operand:SI 5 "reg_or_int5_operand" "rJ")))]
1147 "tst1 %3,%2 ; cmov %C1,%5,%z4,%0"
1148 [(set_attr "length" "8")])
1150 ;; Matching for sasf requires combining 4 instructions, so we provide a
1151 ;; dummy pattern to match the first 3, which will always be turned into the
1152 ;; second pattern by subsequent combining. As above, we must include the
1153 ;; comparison to avoid input reloads in an insn using cc0.
1155 (define_insn "*sasf"
1156 [(set (match_operand:SI 0 "register_operand" "=r")
1158 (match_operator 1 "comparison_operator"
1159 [(match_operand:SI 3 "register_operand" "r")
1160 (match_operand:SI 4 "reg_or_int5_operand" "rJ")])
1161 (ashift:SI (match_operand:SI 2 "register_operand" "0")
1163 (clobber (reg:CC CC_REGNUM))]
1165 "cmp %4,%3 ; sasf %c1,%0"
1166 [(set_attr "length" "6")])
1169 [(set (match_operand:SI 0 "register_operand" "")
1171 (match_operator 1 "comparison_operator"
1172 [(match_operand:SI 4 "register_operand" "")
1173 (match_operand:SI 5 "reg_or_int5_operand" "")])
1174 (match_operand:SI 2 "const_int_operand" "")
1175 (match_operand:SI 3 "const_int_operand" "")))
1176 (clobber (reg:CC CC_REGNUM))]
1178 && ((INTVAL (operands[2]) ^ INTVAL (operands[3])) == 1)
1179 && ((INTVAL (operands[2]) + INTVAL (operands[3])) != 1)
1180 && (GET_CODE (operands[5]) == CONST_INT
1181 || REGNO (operands[0]) != REGNO (operands[5]))
1182 && REGNO (operands[0]) != REGNO (operands[4])"
1183 [(set (match_dup 0) (match_dup 6))
1184 (parallel [(set (match_dup 0)
1185 (ior:SI (match_op_dup 7 [(match_dup 4) (match_dup 5)])
1186 (ashift:SI (match_dup 0) (const_int 1))))
1187 (clobber (reg:CC CC_REGNUM))])]
1189 operands[6] = GEN_INT (INTVAL (operands[2]) >> 1);
1190 if (INTVAL (operands[2]) & 0x1)
1191 operands[7] = operands[1];
1193 operands[7] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
1194 GET_MODE (operands[1]),
1195 XEXP (operands[1], 0), XEXP (operands[1], 1));
1198 ;; ---------------------------------------------------------------------
1199 ;; BYTE SWAP INSTRUCTIONS
1200 ;; ---------------------------------------------------------------------
1201 (define_expand "rotlhi3"
1202 [(parallel [(set (match_operand:HI 0 "register_operand" "")
1203 (rotate:HI (match_operand:HI 1 "register_operand" "")
1204 (match_operand:HI 2 "const_int_operand" "")))
1205 (clobber (reg:CC CC_REGNUM))])]
1208 if (INTVAL (operands[2]) != 8)
1212 (define_insn "*rotlhi3_8"
1213 [(set (match_operand:HI 0 "register_operand" "=r")
1214 (rotate:HI (match_operand:HI 1 "register_operand" "r")
1216 (clobber (reg:CC CC_REGNUM))]
1219 [(set_attr "length" "4")])
1221 (define_expand "rotlsi3"
1222 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1223 (rotate:SI (match_operand:SI 1 "register_operand" "")
1224 (match_operand:SI 2 "const_int_operand" "")))
1225 (clobber (reg:CC CC_REGNUM))])]
1228 if (INTVAL (operands[2]) != 16)
1232 (define_insn "rotlsi3_a"
1233 [(set (match_operand:SI 0 "register_operand" "=r")
1234 (match_operator:SI 4 "ior_operator"
1235 [(ashift:SI (match_operand:SI 1 "register_operand" "r")
1236 (match_operand:SI 2 "const_int_operand" "n"))
1237 (lshiftrt:SI (match_dup 1)
1238 (match_operand:SI 3 "const_int_operand" "n"))]))]
1239 "TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)"
1241 [(set_attr "length" "4")])
1243 (define_insn "rotlsi3_b"
1244 [(set (match_operand:SI 0 "register_operand" "=r")
1245 (match_operator:SI 4 "ior_operator"
1246 [(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1247 (match_operand:SI 3 "const_int_operand" "n"))
1248 (ashift:SI (match_dup 1)
1249 (match_operand:SI 2 "const_int_operand" "n"))]))]
1250 "TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)"
1252 [(set_attr "length" "4")])
1254 (define_insn "rotlsi3_v850e3v5"
1255 [(set (match_operand:SI 0 "register_operand" "=r")
1256 (rotate:SI (match_operand:SI 1 "register_operand" "r")
1257 (match_operand:SI 2 "e3v5_shift_operand" "rn")))
1258 (clobber (reg:CC CC_REGNUM))]
1259 "TARGET_V850E3V5_UP"
1261 [(set_attr "length" "4")])
1263 (define_insn "*rotlsi3_16"
1264 [(set (match_operand:SI 0 "register_operand" "=r")
1265 (rotate:SI (match_operand:SI 1 "register_operand" "r")
1267 (clobber (reg:CC CC_REGNUM))]
1270 [(set_attr "length" "4")])
1272 ;; ----------------------------------------------------------------------
1273 ;; JUMP INSTRUCTIONS
1274 ;; ----------------------------------------------------------------------
1278 (define_expand "doloop_begin"
1279 [(use (match_operand 0 "" "")) ; loop pseudo
1280 (use (match_operand 1 "" ""))] ; doloop_end pattern
1281 "TARGET_V850E3V5_UP && TARGET_LOOP"
1283 rtx loop_cnt = operands[0];
1284 gcc_assert (GET_MODE (loop_cnt) == SImode);
1285 emit_insn (gen_fix_loop_counter (loop_cnt));
1290 (define_insn "fix_loop_counter"
1291 [(unspec:SI [(match_operand:SI 0 "register_operand" "+r,!m")
1292 (clobber (match_scratch:SI 1 "=X,r"))] UNSPEC_LOOP)]
1293 "TARGET_V850E3V5_UP && TARGET_LOOP"
1295 switch (which_alternative)
1297 case 0: return "add 1, %0 # LOOP_BEGIN";
1298 case 1: return "ld.w %0, %1; add 1, %1; st.w %1, %0 # LOOP_BEGIN";
1299 default: gcc_unreachable ();
1302 [(set_attr "length" "2,6")])
1304 (define_expand "doloop_end"
1305 [(use (match_operand 0 "" "")) ; loop pseudo
1306 (use (match_operand 1 "" ""))] ; label
1307 "TARGET_V850E3V5_UP && TARGET_LOOP"
1309 rtx loop_cnt = operands[0];
1310 rtx label = operands[1];
1312 if (GET_MODE (loop_cnt) != SImode)
1315 emit_jump_insn (gen_doloop_end_internal_loop (label, loop_cnt));
1320 (define_insn "doloop_end_internal_loop"
1322 (if_then_else (ne (match_operand:SI 1 "register_operand" "+r,!m")
1324 (label_ref (match_operand 0 "" ""))
1326 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))
1327 (clobber (match_scratch:SI 2 "=X,r"))
1328 (clobber (reg:CC CC_REGNUM))]
1329 "TARGET_V850E3V5_UP && TARGET_LOOP"
1331 switch (which_alternative)
1334 if (get_attr_length (insn) == 4)
1335 return "loop %1, %0 # LOOP.1.0";
1337 return "add -1, %1; bne %l0 # LOOP.1.1";
1339 return "ld.w %1, %2; add -1, %2; st.w %2, %1; bne %l0 # LOOP.2.1";
1344 [(set (attr "length")
1345 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1350 ;; Conditional jump instructions
1352 (define_insn "*branch_normal"
1354 (if_then_else (match_operator 1 "comparison_operator"
1355 [(cc0) (const_int 0)])
1356 (label_ref (match_operand 0 "" ""))
1360 if (get_attr_length (insn) == 2)
1362 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1364 return "b%B1 .+6 ; jr %l0";
1366 [(set (attr "length")
1367 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1370 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1375 (define_insn "*branch_invert"
1377 (if_then_else (match_operator 1 "comparison_operator"
1378 [(cc0) (const_int 0)])
1380 (label_ref (match_operand 0 "" ""))))]
1383 if (get_attr_length (insn) == 2)
1386 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1389 return "b%b1 .+6 ; jr %l0";
1391 [(set (attr "length")
1392 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1395 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1400 (define_insn "branch_z_normal"
1402 (if_then_else (match_operand 1 "v850_float_z_comparison_operator" "")
1403 (label_ref (match_operand 0 "" ""))
1405 "TARGET_V850E2V3_UP"
1407 if (get_attr_length (insn) == 2)
1410 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1413 return "bnz 1f ; jr %l0 ; 1:";
1415 [(set (attr "length")
1416 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1419 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1424 (define_insn "*branch_z_invert"
1426 (if_then_else (match_operand 1 "v850_float_z_comparison_operator" "")
1428 (label_ref (match_operand 0 "" ""))))]
1429 "TARGET_V850E2V3_UP"
1431 if (get_attr_length (insn) == 2)
1434 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1437 return "bz 1f ; jr %l0 ; 1:";
1439 [(set (attr "length")
1440 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1443 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1448 (define_insn "branch_nz_normal"
1450 (if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "")
1451 (label_ref (match_operand 0 "" ""))
1453 "TARGET_V850E2V3_UP"
1455 if (get_attr_length (insn) == 2)
1458 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1461 return "bz 1f ; jr %l0 ; 1:";
1463 [(set (attr "length")
1464 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1467 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1472 (define_insn "*branch_nz_invert"
1474 (if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "")
1476 (label_ref (match_operand 0 "" ""))))]
1477 "TARGET_V850E2V3_UP"
1479 if (get_attr_length (insn) == 2)
1482 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1485 return "bnz 1f ; jr %l0 ; 1:";
1487 [(set (attr "length")
1488 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1491 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1496 ;; Unconditional and other jump instructions.
1500 (label_ref (match_operand 0 "" "")))]
1503 if (get_attr_length (insn) == 2)
1508 [(set (attr "length")
1509 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1514 (define_insn "indirect_jump"
1515 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1518 [(set_attr "length" "2")])
1520 (define_insn "tablejump"
1521 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1522 (use (label_ref (match_operand 1 "" "")))]
1525 [(set_attr "length" "2")])
1527 (define_insn "switch"
1532 (plus:SI (ashift:SI (match_operand:SI 0 "register_operand" "r")
1534 (label_ref (match_operand 1 "" "")))))
1535 (label_ref (match_dup 1))))]
1538 [(set_attr "length" "2")])
1540 (define_expand "casesi"
1541 [(match_operand:SI 0 "register_operand" "")
1542 (match_operand:SI 1 "register_operand" "")
1543 (match_operand:SI 2 "register_operand" "")
1544 (match_operand 3 "" "") (match_operand 4 "" "")]
1547 rtx reg = gen_reg_rtx (SImode);
1548 rtx tableaddress = gen_reg_rtx (SImode);
1552 /* Subtract the lower bound from the index. */
1553 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
1555 /* Compare the result against the number of table entries;
1556 branch to the default label if out of range of the table. */
1557 test = gen_rtx_fmt_ee (GTU, VOIDmode, reg, operands[2]);
1558 emit_jump_insn (gen_cbranchsi4 (test, reg, operands[2], operands[4]));
1560 /* Shift index for the table array access. */
1561 emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
1562 /* Load the table address into a pseudo. */
1563 emit_insn (gen_movsi (tableaddress,
1564 gen_rtx_LABEL_REF (Pmode, operands[3])));
1565 /* Add the table address to the index. */
1566 emit_insn (gen_addsi3 (reg, reg, tableaddress));
1567 /* Load the table entry. */
1568 mem = gen_const_mem (CASE_VECTOR_MODE, reg);
1569 if (! TARGET_BIG_SWITCH)
1571 rtx reg2 = gen_reg_rtx (HImode);
1572 emit_insn (gen_movhi (reg2, mem));
1573 emit_insn (gen_extendhisi2 (reg, reg2));
1576 emit_insn (gen_movsi (reg, mem));
1577 /* Add the table address. */
1578 emit_insn (gen_addsi3 (reg, reg, tableaddress));
1579 /* Branch to the switch label. */
1580 emit_jump_insn (gen_tablejump (reg, operands[3]));
1584 ;; Call subroutine with no return value.
1586 (define_expand "call"
1587 [(call (match_operand:QI 0 "general_operand" "")
1588 (match_operand:SI 1 "general_operand" ""))]
1591 if (! call_address_operand (XEXP (operands[0], 0), QImode)
1592 || TARGET_LONG_CALLS)
1593 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1594 if (TARGET_LONG_CALLS)
1595 emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));
1597 emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
1602 (define_insn "call_internal_short"
1603 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1604 (match_operand:SI 1 "general_operand" "g,g"))
1605 (clobber (reg:SI 31))]
1606 "! TARGET_LONG_CALLS"
1608 if (which_alternative == 1)
1610 if (TARGET_V850E3V5_UP)
1611 return "jarl [%0], r31";
1613 return "jarl .+4, r31 ; add 4, r31 ; jmp %0";
1616 return "jarl %0, r31";
1618 [(set_attr "length" "4,8")])
1620 (define_insn "call_internal_long"
1621 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1622 (match_operand:SI 1 "general_operand" "g,g"))
1623 (clobber (reg:SI 31))]
1626 if (which_alternative == 0)
1628 if (GET_CODE (operands[0]) == REG)
1629 return "jarl %0,r31";
1631 if (TARGET_V850E3V5_UP)
1632 return "mov hilo(%0), r11 ; jarl [r11], r31";
1634 return "movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11";
1637 if (TARGET_V850E3V5_UP)
1638 return "jarl [%0], r31";
1640 return "jarl .+4,r31 ; add 4,r31 ; jmp %0";
1642 [(set_attr "length" "16,8")])
1644 ;; Call subroutine, returning value in operand 0
1645 ;; (which must be a hard register).
1647 (define_expand "call_value"
1648 [(set (match_operand 0 "" "")
1649 (call (match_operand:QI 1 "general_operand" "")
1650 (match_operand:SI 2 "general_operand" "")))]
1653 if (! call_address_operand (XEXP (operands[1], 0), QImode)
1654 || TARGET_LONG_CALLS)
1655 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1656 if (TARGET_LONG_CALLS)
1657 emit_call_insn (gen_call_value_internal_long (operands[0],
1658 XEXP (operands[1], 0),
1661 emit_call_insn (gen_call_value_internal_short (operands[0],
1662 XEXP (operands[1], 0),
1667 (define_insn "call_value_internal_short"
1668 [(set (match_operand 0 "" "=r,r")
1669 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1670 (match_operand:SI 2 "general_operand" "g,g")))
1671 (clobber (reg:SI 31))]
1672 "! TARGET_LONG_CALLS"
1674 if (which_alternative == 1)
1676 if (TARGET_V850E3V5_UP)
1677 return "jarl [%1], r31";
1679 return "jarl .+4, r31 ; add 4, r31 ; jmp %1";
1682 return "jarl %1, r31";
1684 [(set_attr "length" "4,8")])
1686 (define_insn "call_value_internal_long"
1687 [(set (match_operand 0 "" "=r,r")
1688 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1689 (match_operand:SI 2 "general_operand" "g,g")))
1690 (clobber (reg:SI 31))]
1693 if (which_alternative == 0)
1695 if (GET_CODE (operands[1]) == REG)
1696 return "jarl %1, r31";
1698 /* Reload can generate this pattern.... */
1699 if (TARGET_V850E3V5_UP)
1700 return "mov hilo(%1), r11 ; jarl [r11], r31";
1702 return "movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11";
1705 if (TARGET_V850E3V5_UP)
1706 return "jarl [%1], r31";
1708 return "jarl .+4, r31 ; add 4, r31 ; jmp %1";
1710 [(set_attr "length" "16,8")])
1716 [(set_attr "length" "2")])
1718 ;; ----------------------------------------------------------------------
1719 ;; EXTEND INSTRUCTIONS
1720 ;; ----------------------------------------------------------------------
1722 (define_insn "*zero_extendhisi2_v850e"
1723 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1725 (match_operand:HI 1 "nonimmediate_operand" "0,r,T,m")))
1726 (clobber (reg:CC CC_REGNUM))]
1733 [(set_attr "length" "2,4,2,4")])
1735 (define_insn "*zero_extendhisi2_v850"
1736 [(set (match_operand:SI 0 "register_operand" "=r")
1738 (match_operand:HI 1 "register_operand" "r")))
1739 (clobber (reg:CC CC_REGNUM))] ;; A lie, but we have to match the expander
1742 [(set_attr "length" "4")])
1744 (define_expand "zero_extendhisi2"
1745 [(parallel [(set (match_operand:SI 0 "register_operand")
1747 (match_operand:HI 1 "nonimmediate_operand")))
1748 (clobber (reg:CC CC_REGNUM))])]
1751 if (! (TARGET_V850E_UP))
1752 operands[1] = force_reg (HImode, operands[1]);
1755 (define_insn "*zero_extendqisi2_v850e"
1756 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1758 (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m")))
1759 (clobber (reg:CC CC_REGNUM))]
1766 [(set_attr "length" "2,4,2,4")])
1768 (define_insn "*zero_extendqisi2_v850"
1769 [(set (match_operand:SI 0 "register_operand" "=r")
1771 (match_operand:QI 1 "register_operand" "r")))
1772 (clobber (reg:CC CC_REGNUM))] ;; A lie, but we have to match the expander
1775 [(set_attr "length" "4")])
1777 (define_expand "zero_extendqisi2"
1778 [(parallel [(set (match_operand:SI 0 "register_operand")
1780 (match_operand:QI 1 "nonimmediate_operand")))
1781 (clobber (reg:CC CC_REGNUM))])]
1784 if (! (TARGET_V850E_UP))
1785 operands[1] = force_reg (QImode, operands[1]);
1788 ;;- sign extension instructions
1790 ;; ??? The extendhisi2 pattern should not emit shifts for v850e?
1792 (define_insn "*extendhisi_insn"
1793 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1794 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))
1795 (clobber (reg:CC CC_REGNUM))]
1801 [(set_attr "length" "2,2,4")])
1803 ;; ??? This is missing a sign extend from memory pattern to match the ld.h
1806 (define_expand "extendhisi2"
1807 [(parallel [(set (match_dup 2)
1808 (ashift:SI (match_operand:HI 1 "register_operand" "")
1810 (clobber (reg:CC CC_REGNUM))])
1811 (parallel [(set (match_operand:SI 0 "register_operand" "")
1812 (ashiftrt:SI (match_dup 2)
1814 (clobber (reg:CC CC_REGNUM))])]
1817 operands[1] = gen_lowpart (SImode, operands[1]);
1818 operands[2] = gen_reg_rtx (SImode);
1821 ;; ??? The extendqisi2 pattern should not emit shifts for v850e?
1823 (define_insn "*extendqisi_insn"
1824 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1825 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))
1826 (clobber (reg:CC CC_REGNUM))]
1832 [(set_attr "length" "2,2,4")])
1834 ;; ??? This is missing a sign extend from memory pattern to match the ld.b
1837 (define_expand "extendqisi2"
1838 [(parallel [(set (match_dup 2)
1839 (ashift:SI (match_operand:QI 1 "register_operand" "")
1841 (clobber (reg:CC CC_REGNUM))])
1842 (parallel [(set (match_operand:SI 0 "register_operand" "")
1843 (ashiftrt:SI (match_dup 2)
1845 (clobber (reg:CC CC_REGNUM))])]
1848 operands[1] = gen_lowpart (SImode, operands[1]);
1849 operands[2] = gen_reg_rtx (SImode);
1852 ;; ----------------------------------------------------------------------
1854 ;; ----------------------------------------------------------------------
1856 (define_insn "ashlsi3"
1857 [(set (match_operand:SI 0 "register_operand" "=r,r")
1859 (match_operand:SI 1 "register_operand" "0,0")
1860 (match_operand:SI 2 "nonmemory_operand" "r,N")))
1861 (clobber (reg:CC CC_REGNUM))]
1866 [(set_attr "length" "4,2")])
1868 (define_insn "ashlsi3_v850e2"
1869 [(set (match_operand:SI 0 "register_operand" "=r")
1871 (match_operand:SI 1 "register_operand" "r")
1872 (match_operand:SI 2 "nonmemory_operand" "r")))
1873 (clobber (reg:CC CC_REGNUM))]
1876 [(set_attr "length" "4")])
1878 (define_insn "lshrsi3"
1879 [(set (match_operand:SI 0 "register_operand" "=r,r")
1881 (match_operand:SI 1 "register_operand" "0,0")
1882 (match_operand:SI 2 "nonmemory_operand" "r,N")))
1883 (clobber (reg:CC CC_REGNUM))]
1888 [(set_attr "length" "4,2")])
1890 (define_insn "lshrsi3_v850e2"
1891 [(set (match_operand:SI 0 "register_operand" "=r")
1893 (match_operand:SI 1 "register_operand" "r")
1894 (match_operand:SI 2 "nonmemory_operand" "r")))
1895 (clobber (reg:CC CC_REGNUM))]
1898 [(set_attr "length" "4")])
1900 (define_insn "ashrsi3"
1901 [(set (match_operand:SI 0 "register_operand" "=r,r")
1903 (match_operand:SI 1 "register_operand" "0,0")
1904 (match_operand:SI 2 "nonmemory_operand" "r,N")))
1905 (clobber (reg:CC CC_REGNUM))]
1910 [(set_attr "length" "4,2")])
1912 (define_insn "ashrsi3_v850e2"
1913 [(set (match_operand:SI 0 "register_operand" "=r")
1915 (match_operand:SI 1 "register_operand" "r")
1916 (match_operand:SI 2 "nonmemory_operand" "r")))
1917 (clobber (reg:CC CC_REGNUM))]
1920 [(set_attr "length" "4")])
1922 ;; ----------------------------------------------------------------------
1923 ;; FIND FIRST BIT INSTRUCTION
1924 ;; ----------------------------------------------------------------------
1926 (define_insn "ffssi2"
1927 [(set (match_operand:SI 0 "register_operand" "=r")
1928 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
1929 (clobber (reg:CC CC_REGNUM))]
1932 [(set_attr "length" "4")])
1934 ;; ----------------------------------------------------------------------
1935 ;; PROLOGUE/EPILOGUE
1936 ;; ----------------------------------------------------------------------
1937 (define_expand "prologue"
1945 (define_expand "epilogue"
1953 (define_insn "return_simple"
1957 [(set_attr "length" "2")])
1959 (define_insn "return_internal"
1964 [(set_attr "length" "2")])
1966 ;; ----------------------------------------------------------------------
1967 ;; v850e2V3 floating-point hardware support
1968 ;; ----------------------------------------------------------------------
1971 (define_insn "addsf3"
1972 [(set (match_operand:SF 0 "register_operand" "=r")
1973 (plus:SF (match_operand:SF 1 "register_operand" "r")
1974 (match_operand:SF 2 "register_operand" "r")))]
1977 [(set_attr "length" "4")
1978 (set_attr "type" "fpu")])
1980 (define_insn "adddf3"
1981 [(set (match_operand:DF 0 "even_reg_operand" "=r")
1982 (plus:DF (match_operand:DF 1 "even_reg_operand" "r")
1983 (match_operand:DF 2 "even_reg_operand" "r")))]
1986 [(set_attr "length" "4")
1987 (set_attr "type" "fpu")])
1989 (define_insn "subsf3"
1990 [(set (match_operand:SF 0 "register_operand" "=r")
1991 (minus:SF (match_operand:SF 1 "register_operand" "r")
1992 (match_operand:SF 2 "register_operand" "r")))]
1995 [(set_attr "length" "4")
1996 (set_attr "type" "fpu")])
1998 (define_insn "subdf3"
1999 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2000 (minus:DF (match_operand:DF 1 "even_reg_operand" "r")
2001 (match_operand:DF 2 "even_reg_operand" "r")))]
2004 [(set_attr "length" "4")
2005 (set_attr "type" "fpu")])
2007 (define_insn "mulsf3"
2008 [(set (match_operand:SF 0 "register_operand" "=r")
2009 (mult:SF (match_operand:SF 1 "register_operand" "r")
2010 (match_operand:SF 2 "register_operand" "r")))]
2013 [(set_attr "length" "4")
2014 (set_attr "type" "fpu")])
2016 (define_insn "muldf3"
2017 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2018 (mult:DF (match_operand:DF 1 "even_reg_operand" "r")
2019 (match_operand:DF 2 "even_reg_operand" "r")))]
2022 [(set_attr "length" "4")
2023 (set_attr "type" "fpu")])
2025 (define_insn "divsf3"
2026 [(set (match_operand:SF 0 "register_operand" "=r")
2027 (div:SF (match_operand:SF 1 "register_operand" "r")
2028 (match_operand:SF 2 "register_operand" "r")))]
2031 [(set_attr "length" "4")
2032 (set_attr "type" "fpu")])
2034 (define_insn "divdf3"
2035 [(set (match_operand:DF 0 "register_operand" "=r")
2036 (div:DF (match_operand:DF 1 "even_reg_operand" "r")
2037 (match_operand:DF 2 "even_reg_operand" "r")))]
2040 [(set_attr "length" "4")
2041 (set_attr "type" "fpu")])
2043 (define_insn "minsf3"
2044 [(set (match_operand:SF 0 "register_operand" "=r")
2045 (smin:SF (match_operand:SF 1 "reg_or_0_operand" "r")
2046 (match_operand:SF 2 "reg_or_0_operand" "r")))]
2049 [(set_attr "length" "4")
2050 (set_attr "type" "fpu")])
2052 (define_insn "mindf3"
2053 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2054 (smin:DF (match_operand:DF 1 "even_reg_operand" "r")
2055 (match_operand:DF 2 "even_reg_operand" "r")))]
2058 [(set_attr "length" "4")
2059 (set_attr "type" "fpu")])
2061 (define_insn "maxsf3"
2062 [(set (match_operand:SF 0 "register_operand" "=r")
2063 (smax:SF (match_operand:SF 1 "reg_or_0_operand" "r")
2064 (match_operand:SF 2 "reg_or_0_operand" "r")))]
2067 [(set_attr "length" "4")
2068 (set_attr "type" "fpu")])
2070 (define_insn "maxdf3"
2071 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2072 (smax:DF (match_operand:DF 1 "even_reg_operand" "r")
2073 (match_operand:DF 2 "even_reg_operand" "r")))]
2076 [(set_attr "length" "4")
2077 (set_attr "type" "fpu")])
2079 (define_insn "abssf2"
2080 [(set (match_operand:SF 0 "register_operand" "=r")
2081 (abs:SF (match_operand:SF 1 "register_operand" "r")))]
2084 [(set_attr "length" "4")
2085 (set_attr "type" "fpu")])
2087 (define_insn "absdf2"
2088 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2089 (abs:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2092 [(set_attr "length" "4")
2093 (set_attr "type" "fpu")])
2095 (define_insn "negsf2"
2096 [(set (match_operand:SF 0 "register_operand" "=r")
2097 (neg:SF (match_operand:SF 1 "register_operand" "r")))]
2100 [(set_attr "length" "4")
2101 (set_attr "type" "fpu")])
2103 (define_insn "negdf2"
2104 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2105 (neg:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2108 [(set_attr "length" "4")
2109 (set_attr "type" "fpu")])
2112 (define_insn "sqrtsf2"
2113 [(set (match_operand:SF 0 "register_operand" "=r")
2114 (sqrt:SF (match_operand:SF 1 "register_operand" "r")))]
2117 [(set_attr "length" "4")
2118 (set_attr "type" "fpu")])
2120 (define_insn "sqrtdf2"
2121 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2122 (sqrt:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2125 [(set_attr "length" "4")
2126 (set_attr "type" "fpu")])
2129 (define_insn "fix_truncsfsi2"
2130 [(set (match_operand:SI 0 "register_operand" "=r")
2131 (fix:SI (match_operand:SF 1 "register_operand" "r")))]
2134 [(set_attr "length" "4")
2135 (set_attr "type" "fpu")])
2137 (define_insn "fixuns_truncsfsi2"
2138 [(set (match_operand:SI 0 "register_operand" "=r")
2139 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "r")))]
2142 [(set_attr "length" "4")
2143 (set_attr "type" "fpu")])
2145 (define_insn "fix_truncdfsi2"
2146 [(set (match_operand:SI 0 "register_operand" "=r")
2147 (fix:SI (match_operand:DF 1 "even_reg_operand" "r")))]
2150 [(set_attr "length" "4")
2151 (set_attr "type" "fpu")])
2153 (define_insn "fixuns_truncdfsi2"
2154 [(set (match_operand:SI 0 "register_operand" "=r")
2155 (unsigned_fix:SI (match_operand:DF 1 "even_reg_operand" "r")))]
2158 [(set_attr "length" "4")
2159 (set_attr "type" "fpu")])
2161 (define_insn "fix_truncsfdi2"
2162 [(set (match_operand:DI 0 "register_operand" "=r")
2163 (fix:DI (match_operand:SF 1 "register_operand" "r")))]
2166 [(set_attr "length" "4")
2167 (set_attr "type" "fpu")])
2169 (define_insn "fixuns_truncsfdi2"
2170 [(set (match_operand:DI 0 "register_operand" "=r")
2171 (unsigned_fix:DI (match_operand:SF 1 "register_operand" "r")))]
2174 [(set_attr "length" "4")
2175 (set_attr "type" "fpu")])
2177 (define_insn "fix_truncdfdi2"
2178 [(set (match_operand:DI 0 "register_operand" "=r")
2179 (fix:DI (match_operand:DF 1 "even_reg_operand" "r")))]
2182 [(set_attr "length" "4")
2183 (set_attr "type" "fpu")])
2185 (define_insn "fixuns_truncdfdi2"
2186 [(set (match_operand:DI 0 "register_operand" "=r")
2187 (unsigned_fix:DI (match_operand:DF 1 "even_reg_operand" "r")))]
2190 [(set_attr "length" "4")
2191 (set_attr "type" "fpu")])
2194 (define_insn "floatsisf2"
2195 [(set (match_operand:SF 0 "register_operand" "=r")
2196 (float:SF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2199 [(set_attr "length" "4")
2200 (set_attr "type" "fpu")])
2202 (define_insn "unsfloatsisf2"
2203 [(set (match_operand:SF 0 "register_operand" "=r")
2204 (unsigned_float:SF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2207 [(set_attr "length" "4")
2208 (set_attr "type" "fpu")])
2210 (define_insn "floatsidf2"
2211 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2212 (float:DF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2215 [(set_attr "length" "4")
2216 (set_attr "type" "fpu")])
2218 (define_insn "unsfloatsidf2"
2219 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2220 (unsigned_float:DF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2223 [(set_attr "length" "4")
2224 (set_attr "type" "fpu")])
2226 (define_insn "floatdisf2"
2227 [(set (match_operand:SF 0 "even_reg_operand" "=r")
2228 (float:SF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2231 [(set_attr "length" "4")
2232 (set_attr "type" "fpu")])
2234 (define_insn "unsfloatdisf2"
2235 [(set (match_operand:SF 0 "even_reg_operand" "=r")
2236 (unsigned_float:SF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2239 [(set_attr "length" "4")
2240 (set_attr "type" "fpu")])
2242 (define_insn "floatdidf2"
2243 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2244 (float:DF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2247 [(set_attr "length" "4")
2248 (set_attr "type" "fpu")])
2250 (define_insn "unsfloatdidf2"
2251 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2252 (unsigned_float:DF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2255 [(set_attr "length" "4")
2256 (set_attr "type" "fpu")])
2258 ;; single-float -> double-float
2259 (define_insn "extendsfdf2"
2260 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2262 (match_operand:SF 1 "reg_or_0_operand" "rI")))]
2265 [(set_attr "length" "4")
2266 (set_attr "type" "fpu")])
2268 ;; double-float -> single-float
2269 (define_insn "truncdfsf2"
2270 [(set (match_operand:SF 0 "register_operand" "=r")
2272 (match_operand:DF 1 "even_reg_operand" "r")))]
2275 [(set_attr "length" "4")
2276 (set_attr "type" "fpu")])
2279 ;; ---------------- special insns
2282 ;; Generic code demands that the recip and rsqrt named patterns
2283 ;; have precisely one operand. So that's what we expose in the
2284 ;; expander via the strange UNSPEC. However, those expanders
2285 ;; generate normal looking recip and rsqrt patterns.
2287 (define_expand "recipsf2"
2288 [(set (match_operand:SF 0 "register_operand" "")
2289 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
2293 emit_insn (gen_recipsf2_insn (operands[0], CONST1_RTX (SFmode), operands[1]));
2297 (define_insn "recipsf2_insn"
2298 [(set (match_operand:SF 0 "register_operand" "=r")
2299 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2300 (match_operand:SF 2 "register_operand" "r")))]
2303 [(set_attr "length" "4")
2304 (set_attr "type" "fpu")])
2306 (define_expand "recipdf2"
2307 [(set (match_operand:DF 0 "even_reg_operand" "")
2308 (unspec:DF [(match_operand:SF 1 "even_reg_operand" "")]
2312 emit_insn (gen_recipdf2_insn (operands[0], CONST1_RTX (DFmode), operands[1]));
2316 (define_insn "recipdf2_insn"
2317 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2318 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2319 (match_operand:DF 2 "even_reg_operand" "r")))]
2322 [(set_attr "length" "4")
2323 (set_attr "type" "fpu")])
2325 ;;; reciprocal of square-root
2326 (define_expand "rsqrtsf2"
2327 [(set (match_operand:SF 0 "register_operand" "=")
2328 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
2332 emit_insn (gen_rsqrtsf2_insn (operands[0], CONST1_RTX (SFmode), operands[1]));
2336 (define_insn "rsqrtsf2_insn"
2337 [(set (match_operand:SF 0 "register_operand" "=r")
2338 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2339 (sqrt:SF (match_operand:SF 2 "register_operand" "r"))))]
2342 [(set_attr "length" "4")
2343 (set_attr "type" "fpu")])
2345 (define_expand "rsqrtdf2"
2346 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2347 (unspec:DF [(match_operand:DF 1 "even_reg_operand" "r")]
2351 emit_insn (gen_rsqrtdf2_insn (operands[0], CONST1_RTX (DFmode), operands[1]));
2355 (define_insn "rsqrtdf2_insn"
2356 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2357 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2358 (sqrt:DF (match_operand:DF 2 "even_reg_operand" "r"))))]
2361 [(set_attr "length" "4")
2362 (set_attr "type" "fpu")])
2364 ;; Note: The FPU-2.0 (ie pre e3v5) versions of these routines do not actually
2365 ;; need operand 4 to be the same as operand 0. But the FPU-2.0 versions are
2366 ;; also deprecated so the loss of flexibility is unimportant.
2369 (define_insn "fmasf4"
2370 [(set (match_operand:SF 0 "register_operand" "=r")
2371 (fma:SF (match_operand:SF 1 "register_operand" "r")
2372 (match_operand:SF 2 "register_operand" "r")
2373 (match_operand:SF 3 "register_operand" "0")))]
2375 { return TARGET_V850E3V5_UP ? "fmaf.s %1, %2, %0" : "maddf.s %2, %1, %3, %0"; }
2376 [(set_attr "length" "4")
2377 (set_attr "type" "fpu")])
2379 ;;; multiply-subtract
2380 (define_insn "fmssf4"
2381 [(set (match_operand:SF 0 "register_operand" "=r")
2382 (fma:SF (match_operand:SF 1 "register_operand" "r")
2383 (match_operand:SF 2 "register_operand" "r")
2384 (neg:SF (match_operand:SF 3 "register_operand" "0"))))]
2386 { return TARGET_V850E3V5_UP ? "fmsf.s %1, %2, %0" : "msubf.s %2, %1, %3, %0"; }
2387 [(set_attr "length" "4")
2388 (set_attr "type" "fpu")])
2390 ;;; negative-multiply-add
2391 (define_insn "fnmasf4"
2392 [(set (match_operand:SF 0 "register_operand" "=r")
2393 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "r")
2394 (match_operand:SF 2 "register_operand" "r")
2395 (match_operand:SF 3 "register_operand" "0"))))]
2397 { return TARGET_V850E3V5_UP ? "fnmaf.s %1, %2, %0" : "nmaddf.s %2, %1, %3, %0"; }
2398 [(set_attr "length" "4")
2399 (set_attr "type" "fpu")])
2401 ;; negative-multiply-subtract
2402 (define_insn "fnmssf4"
2403 [(set (match_operand:SF 0 "register_operand" "=r")
2404 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "r")
2405 (match_operand:SF 2 "register_operand" "r")
2406 (neg:SF (match_operand:SF 3 "register_operand" "0")))))]
2408 { return TARGET_V850E3V5_UP ? "fnmsf.s %1, %2, %0" : "nmsubf.s %2, %1, %3, %0"; }
2409 [(set_attr "length" "4")
2410 (set_attr "type" "fpu")])
2412 ; ---------------- comparison/conditionals
2416 (define_insn "cmpsf_le_insn"
2417 [(set (reg:CC_FPU_LE FCC_REGNUM)
2418 (compare:CC_FPU_LE (match_operand:SF 0 "register_operand" "r")
2419 (match_operand:SF 1 "register_operand" "r")))]
2421 "cmpf.s le, %z0, %z1"
2422 [(set_attr "length" "4")
2423 (set_attr "type" "fpu")])
2425 (define_insn "cmpsf_lt_insn"
2426 [(set (reg:CC_FPU_LT FCC_REGNUM)
2427 (compare:CC_FPU_LT (match_operand:SF 0 "register_operand" "r")
2428 (match_operand:SF 1 "register_operand" "r")))]
2430 "cmpf.s lt, %z0, %z1"
2431 [(set_attr "length" "4")
2432 (set_attr "type" "fpu")])
2434 (define_insn "cmpsf_ge_insn"
2435 [(set (reg:CC_FPU_GE FCC_REGNUM)
2436 (compare:CC_FPU_GE (match_operand:SF 0 "register_operand" "r")
2437 (match_operand:SF 1 "register_operand" "r")))]
2439 "cmpf.s le, %z1, %z0"
2440 [(set_attr "length" "4")
2441 (set_attr "type" "fpu")])
2443 (define_insn "cmpsf_gt_insn"
2444 [(set (reg:CC_FPU_GT FCC_REGNUM)
2445 (compare:CC_FPU_GT (match_operand:SF 0 "register_operand" "r")
2446 (match_operand:SF 1 "register_operand" "r")))]
2448 "cmpf.s lt, %z1, %z0"
2449 [(set_attr "length" "4")
2450 (set_attr "type" "fpu")])
2452 (define_insn "cmpsf_eq_insn"
2453 [(set (reg:CC_FPU_EQ FCC_REGNUM)
2454 (compare:CC_FPU_EQ (match_operand:SF 0 "register_operand" "r")
2455 (match_operand:SF 1 "register_operand" "r")))]
2457 "cmpf.s eq, %z0, %z1"
2458 [(set_attr "length" "4")
2459 (set_attr "type" "fpu")])
2463 (define_insn "cmpdf_le_insn"
2464 [(set (reg:CC_FPU_LE FCC_REGNUM)
2465 (compare:CC_FPU_LE (match_operand:DF 0 "even_reg_operand" "r")
2466 (match_operand:DF 1 "even_reg_operand" "r")))]
2468 "cmpf.d le, %z0, %z1"
2469 [(set_attr "length" "4")
2470 (set_attr "type" "fpu")])
2472 (define_insn "cmpdf_lt_insn"
2473 [(set (reg:CC_FPU_LT FCC_REGNUM)
2474 (compare:CC_FPU_LT (match_operand:DF 0 "even_reg_operand" "r")
2475 (match_operand:DF 1 "even_reg_operand" "r")))]
2477 "cmpf.d lt, %z0, %z1"
2478 [(set_attr "length" "4")
2479 (set_attr "type" "fpu")])
2481 (define_insn "cmpdf_ge_insn"
2482 [(set (reg:CC_FPU_GE FCC_REGNUM)
2483 (compare:CC_FPU_GE (match_operand:DF 0 "even_reg_operand" "r")
2484 (match_operand:DF 1 "even_reg_operand" "r")))]
2486 "cmpf.d le, %z1, %z0"
2487 [(set_attr "length" "4")
2488 (set_attr "type" "fpu")])
2490 (define_insn "cmpdf_gt_insn"
2491 [(set (reg:CC_FPU_GT FCC_REGNUM)
2492 (compare:CC_FPU_GT (match_operand:DF 0 "even_reg_operand" "r")
2493 (match_operand:DF 1 "even_reg_operand" "r")))]
2495 "cmpf.d lt, %z1, %z0"
2496 [(set_attr "length" "4")
2497 (set_attr "type" "fpu")])
2499 (define_insn "cmpdf_eq_insn"
2500 [(set (reg:CC_FPU_EQ FCC_REGNUM)
2501 (compare:CC_FPU_EQ (match_operand:DF 0 "even_reg_operand" "r")
2502 (match_operand:DF 1 "even_reg_operand" "r")))]
2504 "cmpf.d eq, %z0, %z1"
2505 [(set_attr "length" "4")
2506 (set_attr "type" "fpu")])
2509 ;; Transfer a v850e2v3 fcc to the Z bit of CC0 (this is necessary to do a
2510 ;; conditional branch based on a floating-point compare)
2513 (define_insn "trfsr"
2514 [(set (match_operand 0 "" "") (match_operand 1 "" ""))]
2516 && GET_MODE(operands[0]) == GET_MODE(operands[1])
2517 && GET_CODE(operands[0]) == REG && REGNO (operands[0]) == CC_REGNUM
2518 && GET_CODE(operands[1]) == REG && REGNO (operands[1]) == FCC_REGNUM
2519 && (GET_MODE(operands[0]) == CC_FPU_LEmode
2520 || GET_MODE(operands[0]) == CC_FPU_GEmode
2521 || GET_MODE(operands[0]) == CC_FPU_LTmode
2522 || GET_MODE(operands[0]) == CC_FPU_GTmode
2523 || GET_MODE(operands[0]) == CC_FPU_EQmode
2524 || GET_MODE(operands[0]) == CC_FPU_NEmode)"
2526 [(set_attr "length" "4")
2527 (set_attr "type" "fpu")])
2530 ;; Floating-point conditional moves for the v850e2v3.
2533 ;; The actual v850e2v3 conditional move instructions
2535 (define_insn "movsfcc_z_insn"
2536 [(set (match_operand:SF 0 "register_operand" "=r")
2538 (match_operand 3 "v850_float_z_comparison_operator" "")
2539 (match_operand:SF 1 "reg_or_0_operand" "rIG")
2540 (match_operand:SF 2 "reg_or_0_operand" "rIG")))]
2542 "cmovf.s 0,%z1,%z2,%0")
2544 (define_insn "movsfcc_nz_insn"
2545 [(set (match_operand:SF 0 "register_operand" "=r")
2547 (match_operand 3 "v850_float_nz_comparison_operator" "")
2548 (match_operand:SF 1 "reg_or_0_operand" "rIG")
2549 (match_operand:SF 2 "reg_or_0_operand" "rIG")))]
2551 "cmovf.s 0,%z2,%z1,%0")
2553 (define_insn "movdfcc_z_insn"
2554 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2556 (match_operand 3 "v850_float_z_comparison_operator" "")
2557 (match_operand:DF 1 "even_reg_operand" "r")
2558 (match_operand:DF 2 "even_reg_operand" "r")))]
2560 "cmovf.d 0,%z1,%z2,%0")
2562 (define_insn "movdfcc_nz_insn"
2563 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2565 (match_operand 3 "v850_float_nz_comparison_operator" "")
2566 (match_operand:DF 1 "even_reg_operand" "r")
2567 (match_operand:DF 2 "even_reg_operand" "r")))]
2569 "cmovf.d 0,%z2,%z1,%0")
2571 (define_insn "movedfcc_z_zero"
2572 [(set (match_operand:DF 0 "register_operand" "=r")
2574 (match_operand 3 "v850_float_z_comparison_operator" "")
2575 (match_operand:DF 1 "reg_or_0_operand" "rIG")
2576 (match_operand:DF 2 "reg_or_0_operand" "rIG")))]
2578 "cmovf.s 0,%z1,%z2,%0 ; cmovf.s 0,%Z1,%Z2,%R0"
2579 [(set_attr "length" "8")])
2581 (define_insn "movedfcc_nz_zero"
2582 [(set (match_operand:DF 0 "register_operand" "=r")
2584 (match_operand 3 "v850_float_nz_comparison_operator" "")
2585 (match_operand:DF 1 "reg_or_0_operand" "rIG")
2586 (match_operand:DF 2 "reg_or_0_operand" "rIG")))]
2588 "cmovf.s 0,%z2,%z1,%0 ; cmovf.s 0,%Z2,%Z1,%R0"
2589 [(set_attr "length" "8")])
2592 ;; ----------------------------------------------------------------------
2593 ;; HELPER INSTRUCTIONS for saving the prologue and epilogue registers
2594 ;; ----------------------------------------------------------------------
2596 ;; This pattern will match a stack adjust RTX followed by any number of push
2597 ;; RTXs. These RTXs will then be turned into a suitable call to a worker
2601 ;; Actually, convert the RTXs into a PREPARE instruction.
2605 [(match_parallel 0 "pattern_is_ok_for_prepare"
2607 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2608 (set (mem:SI (plus:SI (reg:SI 3)
2609 (match_operand:SI 2 "immediate_operand" "i")))
2610 (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
2611 "TARGET_PROLOG_FUNCTION && (TARGET_V850E_UP)"
2613 return construct_prepare_instruction (operands[0]);
2615 [(set_attr "length" "4")])
2618 [(match_parallel 0 "pattern_is_ok_for_prologue"
2620 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2621 (set (mem:SI (plus:SI (reg:SI 3)
2622 (match_operand:SI 2 "immediate_operand" "i")))
2623 (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
2624 "TARGET_PROLOG_FUNCTION"
2626 return construct_save_jarl (operands[0]);
2628 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
2630 (const_string "4")))])
2633 ;; Actually, turn the RTXs into a DISPOSE instruction.
2636 [(match_parallel 0 "pattern_is_ok_for_dispose"
2639 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2640 (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
2641 (mem:SI (plus:SI (reg:SI 3)
2642 (match_operand:SI 3 "immediate_operand" "i"))))])]
2643 "TARGET_PROLOG_FUNCTION && (TARGET_V850E_UP)"
2645 return construct_dispose_instruction (operands[0]);
2647 [(set_attr "length" "4")])
2649 ;; This pattern will match a return RTX followed by any number of pop RTXs
2650 ;; and possible a stack adjustment as well. These RTXs will be turned into
2651 ;; a suitable call to a worker function.
2654 [(match_parallel 0 "pattern_is_ok_for_epilogue"
2657 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2658 (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
2659 (mem:SI (plus:SI (reg:SI 3)
2660 (match_operand:SI 3 "immediate_operand" "i"))))])]
2661 "TARGET_PROLOG_FUNCTION"
2663 return construct_restore_jr (operands[0]);
2665 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
2667 (const_string "4")))])
2669 ;; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION.
2670 (define_insn "callt_save_interrupt"
2671 [(unspec_volatile [(const_int 0)] 2)]
2672 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2673 ;; The CALLT instruction stores the next address of CALLT to CTPC register
2674 ;; without saving its previous value. So if the interrupt handler
2675 ;; or its caller could possibly execute the CALLT insn, save_interrupt
2676 ;; MUST NOT be called via CALLT.
2678 output_asm_insn ("addi -28, sp, sp", operands);
2679 output_asm_insn ("st.w r1, 24[sp]", operands);
2680 output_asm_insn ("st.w r10, 12[sp]", operands);
2681 output_asm_insn ("st.w r11, 16[sp]", operands);
2682 output_asm_insn ("stsr ctpc, r10", operands);
2683 output_asm_insn ("st.w r10, 20[sp]", operands);
2684 output_asm_insn ("stsr ctpsw, r10", operands);
2685 output_asm_insn ("st.w r10, 24[sp]", operands);
2686 output_asm_insn ("callt ctoff(__callt_save_interrupt)", operands);
2689 [(set_attr "length" "26")])
2691 (define_insn "callt_return_interrupt"
2692 [(unspec_volatile [(const_int 0)] 3)]
2693 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2694 "callt ctoff(__callt_return_interrupt)"
2695 [(set_attr "length" "2")])
2697 (define_insn "save_interrupt"
2698 [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -20)))
2699 (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 30))
2700 (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 4))
2701 (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))
2702 (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 10))
2703 (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 11))]
2706 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2707 return "addi -20,sp,sp \; st.w r11,16[sp] \; st.w r10,12[sp] \; jarl __save_interrupt,r10";
2710 output_asm_insn ("addi -20, sp, sp", operands);
2711 output_asm_insn ("st.w r11, 16[sp]", operands);
2712 output_asm_insn ("st.w r10, 12[sp]", operands);
2713 output_asm_insn ("st.w ep, 0[sp]", operands);
2714 output_asm_insn ("st.w gp, 4[sp]", operands);
2715 output_asm_insn ("st.w r1, 8[sp]", operands);
2716 output_asm_insn ("movhi hi(__ep), r0, ep", operands);
2717 output_asm_insn ("movea lo(__ep), ep, ep", operands);
2718 output_asm_insn ("movhi hi(__gp), r0, gp", operands);
2719 output_asm_insn ("movea lo(__gp), gp, gp", operands);
2723 [(set (attr "length")
2724 (if_then_else (match_test "TARGET_LONG_CALLS")
2728 ;; Restore r1, r4, r10, and return from the interrupt
2729 (define_insn "return_interrupt"
2731 (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 20)))
2732 (set (reg:SI 11) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))
2733 (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
2734 (set (reg:SI 1) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
2735 (set (reg:SI 4) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))
2736 (set (reg:SI 30) (mem:SI (reg:SI 3)))]
2739 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2740 return "jr __return_interrupt";
2743 output_asm_insn ("ld.w 0[sp], ep", operands);
2744 output_asm_insn ("ld.w 4[sp], gp", operands);
2745 output_asm_insn ("ld.w 8[sp], r1", operands);
2746 output_asm_insn ("ld.w 12[sp], r10", operands);
2747 output_asm_insn ("ld.w 16[sp], r11", operands);
2748 output_asm_insn ("addi 20, sp, sp", operands);
2749 output_asm_insn ("reti", operands);
2753 [(set (attr "length")
2754 (if_then_else (match_test "TARGET_LONG_CALLS")
2758 ;; Save all registers except for the registers saved in save_interrupt when
2759 ;; an interrupt function makes a call.
2760 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2761 ;; all of memory. This blocks insns from being moved across this point.
2762 ;; This is needed because the rest of the compiler is not ready to handle
2763 ;; insns this complicated.
2765 (define_insn "callt_save_all_interrupt"
2766 [(unspec_volatile [(const_int 0)] 0)]
2767 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2768 "callt ctoff(__callt_save_all_interrupt)"
2769 [(set_attr "length" "2")])
2771 (define_insn "save_all_interrupt"
2772 [(unspec_volatile [(const_int 0)] 0)]
2775 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2776 return "jarl __save_all_interrupt,r10";
2778 output_asm_insn ("addi -120, sp, sp", operands);
2782 output_asm_insn ("mov ep, r1", operands);
2783 output_asm_insn ("mov sp, ep", operands);
2784 output_asm_insn ("sst.w r31, 116[ep]", operands);
2785 output_asm_insn ("sst.w r2, 112[ep]", operands);
2786 output_asm_insn ("sst.w gp, 108[ep]", operands);
2787 output_asm_insn ("sst.w r6, 104[ep]", operands);
2788 output_asm_insn ("sst.w r7, 100[ep]", operands);
2789 output_asm_insn ("sst.w r8, 96[ep]", operands);
2790 output_asm_insn ("sst.w r9, 92[ep]", operands);
2791 output_asm_insn ("sst.w r11, 88[ep]", operands);
2792 output_asm_insn ("sst.w r12, 84[ep]", operands);
2793 output_asm_insn ("sst.w r13, 80[ep]", operands);
2794 output_asm_insn ("sst.w r14, 76[ep]", operands);
2795 output_asm_insn ("sst.w r15, 72[ep]", operands);
2796 output_asm_insn ("sst.w r16, 68[ep]", operands);
2797 output_asm_insn ("sst.w r17, 64[ep]", operands);
2798 output_asm_insn ("sst.w r18, 60[ep]", operands);
2799 output_asm_insn ("sst.w r19, 56[ep]", operands);
2800 output_asm_insn ("sst.w r20, 52[ep]", operands);
2801 output_asm_insn ("sst.w r21, 48[ep]", operands);
2802 output_asm_insn ("sst.w r22, 44[ep]", operands);
2803 output_asm_insn ("sst.w r23, 40[ep]", operands);
2804 output_asm_insn ("sst.w r24, 36[ep]", operands);
2805 output_asm_insn ("sst.w r25, 32[ep]", operands);
2806 output_asm_insn ("sst.w r26, 28[ep]", operands);
2807 output_asm_insn ("sst.w r27, 24[ep]", operands);
2808 output_asm_insn ("sst.w r28, 20[ep]", operands);
2809 output_asm_insn ("sst.w r29, 16[ep]", operands);
2810 output_asm_insn ("mov r1, ep", operands);
2814 output_asm_insn ("st.w r31, 116[sp]", operands);
2815 output_asm_insn ("st.w r2, 112[sp]", operands);
2816 output_asm_insn ("st.w gp, 108[sp]", operands);
2817 output_asm_insn ("st.w r6, 104[sp]", operands);
2818 output_asm_insn ("st.w r7, 100[sp]", operands);
2819 output_asm_insn ("st.w r8, 96[sp]", operands);
2820 output_asm_insn ("st.w r9, 92[sp]", operands);
2821 output_asm_insn ("st.w r11, 88[sp]", operands);
2822 output_asm_insn ("st.w r12, 84[sp]", operands);
2823 output_asm_insn ("st.w r13, 80[sp]", operands);
2824 output_asm_insn ("st.w r14, 76[sp]", operands);
2825 output_asm_insn ("st.w r15, 72[sp]", operands);
2826 output_asm_insn ("st.w r16, 68[sp]", operands);
2827 output_asm_insn ("st.w r17, 64[sp]", operands);
2828 output_asm_insn ("st.w r18, 60[sp]", operands);
2829 output_asm_insn ("st.w r19, 56[sp]", operands);
2830 output_asm_insn ("st.w r20, 52[sp]", operands);
2831 output_asm_insn ("st.w r21, 48[sp]", operands);
2832 output_asm_insn ("st.w r22, 44[sp]", operands);
2833 output_asm_insn ("st.w r23, 40[sp]", operands);
2834 output_asm_insn ("st.w r24, 36[sp]", operands);
2835 output_asm_insn ("st.w r25, 32[sp]", operands);
2836 output_asm_insn ("st.w r26, 28[sp]", operands);
2837 output_asm_insn ("st.w r27, 24[sp]", operands);
2838 output_asm_insn ("st.w r28, 20[sp]", operands);
2839 output_asm_insn ("st.w r29, 16[sp]", operands);
2844 [(set (attr "length")
2845 (if_then_else (match_test "TARGET_LONG_CALLS")
2849 (define_insn "_save_all_interrupt"
2850 [(unspec_volatile [(const_int 0)] 0)]
2851 "TARGET_V850 && ! TARGET_LONG_CALLS"
2852 "jarl __save_all_interrupt,r10"
2853 [(set_attr "length" "4")])
2855 ;; Restore all registers saved when an interrupt function makes a call.
2856 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2857 ;; all of memory. This blocks insns from being moved across this point.
2858 ;; This is needed because the rest of the compiler is not ready to handle
2859 ;; insns this complicated.
2861 (define_insn "callt_restore_all_interrupt"
2862 [(unspec_volatile [(const_int 0)] 1)]
2863 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2864 "callt ctoff(__callt_restore_all_interrupt)"
2865 [(set_attr "length" "2")])
2867 (define_insn "restore_all_interrupt"
2868 [(unspec_volatile [(const_int 0)] 1)]
2871 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2872 return "jarl __restore_all_interrupt,r10";
2876 output_asm_insn ("mov ep, r1", operands);
2877 output_asm_insn ("mov sp, ep", operands);
2878 output_asm_insn ("sld.w 116[ep], r31", operands);
2879 output_asm_insn ("sld.w 112[ep], r2", operands);
2880 output_asm_insn ("sld.w 108[ep], gp", operands);
2881 output_asm_insn ("sld.w 104[ep], r6", operands);
2882 output_asm_insn ("sld.w 100[ep], r7", operands);
2883 output_asm_insn ("sld.w 96[ep], r8", operands);
2884 output_asm_insn ("sld.w 92[ep], r9", operands);
2885 output_asm_insn ("sld.w 88[ep], r11", operands);
2886 output_asm_insn ("sld.w 84[ep], r12", operands);
2887 output_asm_insn ("sld.w 80[ep], r13", operands);
2888 output_asm_insn ("sld.w 76[ep], r14", operands);
2889 output_asm_insn ("sld.w 72[ep], r15", operands);
2890 output_asm_insn ("sld.w 68[ep], r16", operands);
2891 output_asm_insn ("sld.w 64[ep], r17", operands);
2892 output_asm_insn ("sld.w 60[ep], r18", operands);
2893 output_asm_insn ("sld.w 56[ep], r19", operands);
2894 output_asm_insn ("sld.w 52[ep], r20", operands);
2895 output_asm_insn ("sld.w 48[ep], r21", operands);
2896 output_asm_insn ("sld.w 44[ep], r22", operands);
2897 output_asm_insn ("sld.w 40[ep], r23", operands);
2898 output_asm_insn ("sld.w 36[ep], r24", operands);
2899 output_asm_insn ("sld.w 32[ep], r25", operands);
2900 output_asm_insn ("sld.w 28[ep], r26", operands);
2901 output_asm_insn ("sld.w 24[ep], r27", operands);
2902 output_asm_insn ("sld.w 20[ep], r28", operands);
2903 output_asm_insn ("sld.w 16[ep], r29", operands);
2904 output_asm_insn ("mov r1, ep", operands);
2908 output_asm_insn ("ld.w 116[sp], r31", operands);
2909 output_asm_insn ("ld.w 112[sp], r2", operands);
2910 output_asm_insn ("ld.w 108[sp], gp", operands);
2911 output_asm_insn ("ld.w 104[sp], r6", operands);
2912 output_asm_insn ("ld.w 100[sp], r7", operands);
2913 output_asm_insn ("ld.w 96[sp], r8", operands);
2914 output_asm_insn ("ld.w 92[sp], r9", operands);
2915 output_asm_insn ("ld.w 88[sp], r11", operands);
2916 output_asm_insn ("ld.w 84[sp], r12", operands);
2917 output_asm_insn ("ld.w 80[sp], r13", operands);
2918 output_asm_insn ("ld.w 76[sp], r14", operands);
2919 output_asm_insn ("ld.w 72[sp], r15", operands);
2920 output_asm_insn ("ld.w 68[sp], r16", operands);
2921 output_asm_insn ("ld.w 64[sp], r17", operands);
2922 output_asm_insn ("ld.w 60[sp], r18", operands);
2923 output_asm_insn ("ld.w 56[sp], r19", operands);
2924 output_asm_insn ("ld.w 52[sp], r20", operands);
2925 output_asm_insn ("ld.w 48[sp], r21", operands);
2926 output_asm_insn ("ld.w 44[sp], r22", operands);
2927 output_asm_insn ("ld.w 40[sp], r23", operands);
2928 output_asm_insn ("ld.w 36[sp], r24", operands);
2929 output_asm_insn ("ld.w 32[sp], r25", operands);
2930 output_asm_insn ("ld.w 28[sp], r26", operands);
2931 output_asm_insn ("ld.w 24[sp], r27", operands);
2932 output_asm_insn ("ld.w 20[sp], r28", operands);
2933 output_asm_insn ("ld.w 16[sp], r29", operands);
2935 output_asm_insn ("addi 120, sp, sp", operands);
2938 [(set (attr "length")
2939 (if_then_else (match_test "TARGET_LONG_CALLS")
2944 (define_insn "_restore_all_interrupt"
2945 [(unspec_volatile [(const_int 0)] 1)]
2946 "TARGET_V850 && ! TARGET_LONG_CALLS"
2947 "jarl __restore_all_interrupt,r10"
2948 [(set_attr "length" "4")])