1 ;; GCC machine description for NEC V850
2 ;; Copyright (C) 1996-2017 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
47 (UNSPEC_LOOP 200) ; loop counter
51 (define_attr "length" ""
54 (define_attr "long_calls" "yes,no"
55 (const (if_then_else (symbol_ref "TARGET_LONG_CALLS")
57 (const_string "no"))))
59 ;; Types of instructions (for scheduling purposes).
61 (define_attr "type" "load,store,bit1,mult,macc,div,fpu,single,other"
62 (const_string "other"))
64 (define_attr "cpu" "none,v850,v850e,v850e1,v850e2,v850e2v3,v850e3v5"
65 (cond [(match_test "TARGET_V850")
67 (match_test "TARGET_V850E")
68 (const_string "v850e")
69 (match_test "TARGET_V850E1")
70 (const_string "v850e1")
71 (match_test "TARGET_V850E2")
72 (const_string "v850e2")
73 (match_test "TARGET_V850E2V3")
74 (const_string "v850e2v3")
75 (match_test "TARGET_V850E3V5")
76 (const_string "v850e3v5")]
77 (const_string "none")))
79 ;; Condition code settings.
80 ;; none - insn does not affect cc
81 ;; none_0hit - insn does not affect cc but it does modify operand 0
82 ;; This attribute is used to keep track of when operand 0 changes.
83 ;; See the description of NOTICE_UPDATE_CC for more info.
84 ;; set_znv - sets z,n,v to usable values; c is unknown.
85 ;; set_zn - sets z,n to usable values; v,c is unknown.
86 ;; compare - compare instruction
87 ;; clobber - value of cc is unknown
88 (define_attr "cc" "none,none_0hit,set_z,set_zn,set_znv,compare,clobber"
89 (const_string "clobber"))
91 ;; Function units for the V850. As best as I can tell, there's
92 ;; a traditional memory load/use stall as well as a stall if
93 ;; the result of a multiply is used too early.
95 (define_insn_reservation "v850_other" 1
96 (eq_attr "type" "other")
98 (define_insn_reservation "v850_mult" 2
99 (eq_attr "type" "mult")
101 (define_insn_reservation "v850_memory" 2
102 (eq_attr "type" "load")
105 (include "predicates.md")
106 (include "constraints.md")
108 ;; ----------------------------------------------------------------------
110 ;; ----------------------------------------------------------------------
111 (define_insn "sign23byte_load"
112 [(set (match_operand:SI 0 "register_operand" "=r")
114 (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
115 (match_operand 2 "disp23_operand" "W")))))]
118 [(set_attr "length" "4")
119 (set_attr "cc" "none_0hit")])
121 (define_insn "unsign23byte_load"
122 [(set (match_operand:SI 0 "register_operand" "=r")
124 (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
125 (match_operand 2 "disp23_operand" "W")))))]
128 [(set_attr "length" "4")
129 (set_attr "cc" "none_0hit")])
131 (define_insn "sign23hword_load"
132 [(set (match_operand:SI 0 "register_operand" "=r")
134 (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
135 (match_operand 2 "disp23_operand" "W")))))]
138 [(set_attr "length" "4")
139 (set_attr "cc" "none_0hit")])
141 (define_insn "unsign23hword_load"
142 [(set (match_operand:SI 0 "register_operand" "=r")
144 (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
145 (match_operand 2 "disp23_operand" "W")))))]
148 [(set_attr "length" "4")
149 (set_attr "cc" "none_0hit")])
151 (define_insn "23word_load"
152 [(set (match_operand:SI 0 "register_operand" "=r")
153 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
154 (match_operand 2 "disp23_operand" "W"))))]
157 [(set_attr "length" "4")
158 (set_attr "cc" "none_0hit")])
160 (define_insn "23byte_store"
161 [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "r")
162 (match_operand 1 "disp23_operand" "W")))
163 (match_operand:QI 2 "register_operand" "r"))]
166 [(set_attr "length" "4")
167 (set_attr "cc" "none_0hit")])
169 (define_insn "23hword_store"
170 [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "r")
171 (match_operand 1 "disp23_operand" "W")))
172 (match_operand:HI 2 "register_operand" "r"))]
175 [(set_attr "length" "4")
176 (set_attr "cc" "none_0hit")])
178 (define_insn "23word_store"
179 [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
180 (match_operand 1 "disp23_operand" "W")))
181 (match_operand:SI 2 "register_operand" "r"))]
184 [(set_attr "length" "4")
185 (set_attr "cc" "none_0hit")])
189 (define_expand "movdi"
190 [(set (match_operand:DI 0 "general_operand")
191 (match_operand:DI 1 "general_operand"))]
194 /* One of the ops has to be in a register or 0. */
195 if (!register_operand (operand0, DImode)
196 && !register_operand (operand1, DImode))
197 operands[1] = copy_to_mode_reg (DImode, operand1);
199 if (register_operand (operand0, DImode)
200 && (CONST_INT_P (operands[1]) || CONST_DOUBLE_P (operands[1])))
204 for (i = 0; i < UNITS_PER_WORD * 2; i += UNITS_PER_WORD)
205 emit_move_insn (simplify_gen_subreg (SImode, operands[0], DImode, i),
206 simplify_gen_subreg (SImode, operands[1], DImode, i));
212 (define_insn "*movdi_internal"
213 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,e!r,m")
214 (match_operand:DI 1 "nonimmediate_operand" "r,m,e!r"))]
216 || (register_operand (operands[0], DImode) && register_operand (operands[1], DImode))"
217 { return v850_gen_movdi (operands); }
218 [(set_attr "length" "4,12,12")
219 (set_attr "cc" "none_0hit")
220 (set_attr "type" "other,load,store")]
225 (define_expand "movqi"
226 [(set (match_operand:QI 0 "general_operand" "")
227 (match_operand:QI 1 "general_operand" ""))]
230 /* One of the ops has to be in a register or 0 */
231 if (!register_operand (operand0, QImode)
232 && !reg_or_0_operand (operand1, QImode))
233 operands[1] = copy_to_mode_reg (QImode, operand1);
236 (define_insn "*movqi_internal"
237 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,Q,r,m,m")
238 (match_operand:QI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
239 "register_operand (operands[0], QImode)
240 || reg_or_0_operand (operands[1], QImode)"
242 return output_move_single (operands);
244 [(set_attr "length" "2,4,2,2,4,4,4")
245 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
246 (set_attr "type" "other,other,load,other,load,store,store")])
250 (define_expand "movhi"
251 [(set (match_operand:HI 0 "general_operand" "")
252 (match_operand:HI 1 "general_operand" ""))]
255 /* One of the ops has to be in a register or 0 */
256 if (!register_operand (operand0, HImode)
257 && !reg_or_0_operand (operand1, HImode))
258 operands[1] = copy_to_mode_reg (HImode, operand1);
261 (define_insn "*movhi_internal"
262 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,Q,r,m,m")
263 (match_operand:HI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
264 "register_operand (operands[0], HImode)
265 || reg_or_0_operand (operands[1], HImode)"
267 return output_move_single (operands);
269 [(set_attr "length" "2,4,2,2,4,4,4")
270 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
271 (set_attr "type" "other,other,load,other,load,store,store")])
275 (define_insn "*movsi_high"
276 [(set (match_operand:SI 0 "register_operand" "=r")
277 (high:SI (match_operand 1 "immediate_operand" "i")))]
280 [(set_attr "length" "4")
281 (set_attr "cc" "none_0hit")
282 (set_attr "type" "other")])
284 (define_insn "*movsi_lo"
285 [(set (match_operand:SI 0 "register_operand" "=r")
286 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
287 (match_operand:SI 2 "immediate_operand" "i")))]
290 [(set_attr "length" "4")
291 (set_attr "cc" "none_0hit")
292 (set_attr "type" "other")])
294 (define_expand "movsi"
295 [(set (match_operand:SI 0 "general_operand" "")
296 (match_operand:SI 1 "general_operand" ""))]
299 /* One of the ops has to be in a register or 0 */
300 if (!register_operand (operand0, SImode)
301 && !reg_or_0_operand (operand1, SImode))
302 operands[1] = copy_to_mode_reg (SImode, operand1);
304 /* Some constants, as well as symbolic operands
305 must be done with HIGH & LO_SUM patterns. */
306 if (CONSTANT_P (operands[1])
307 && GET_CODE (operands[1]) != HIGH
308 && ! (TARGET_V850E_UP)
309 && !special_symbolref_operand (operands[1], VOIDmode)
310 && !(GET_CODE (operands[1]) == CONST_INT
311 && (CONST_OK_FOR_J (INTVAL (operands[1]))
312 || CONST_OK_FOR_K (INTVAL (operands[1]))
313 || CONST_OK_FOR_L (INTVAL (operands[1])))))
317 if (reload_in_progress || reload_completed)
320 temp = gen_reg_rtx (SImode);
322 emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (SImode, operand1)));
323 emit_insn (gen_rtx_SET (operand0,
324 gen_rtx_LO_SUM (SImode, temp, operand1)));
329 ;; This is the same as the following pattern, except that it includes
330 ;; support for arbitrary 32-bit immediates.
332 ;; ??? This always loads addresses using hilo. If the only use of this address
333 ;; was in a load/store, then we would get smaller code if we only loaded the
334 ;; upper part with hi, and then put the lower part in the load/store insn.
336 (define_insn "*movsi_internal_v850e"
337 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,Q,r,r,m,m,r")
338 (match_operand:SI 1 "general_operand" "Jr,K,L,Q,Ir,m,R,r,I,i"))]
340 && (register_operand (operands[0], SImode)
341 || reg_or_0_operand (operands[1], SImode))"
343 return output_move_single (operands);
345 [(set_attr "length" "2,4,4,2,2,4,4,4,4,6")
346 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
347 (set_attr "type" "other,other,other,load,other,load,other,store,store,other")])
349 (define_insn "*movsi_internal"
350 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,Q,r,r,m,m")
351 (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))]
352 "register_operand (operands[0], SImode)
353 || reg_or_0_operand (operands[1], SImode)"
355 return output_move_single (operands);
357 [(set_attr "length" "2,4,4,2,2,4,4,4,4")
358 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
359 (set_attr "type" "other,other,other,load,other,load,store,store,other")])
361 (define_insn "*movsf_internal"
362 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,Q,r,m,m,r")
363 (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))]
364 "register_operand (operands[0], SFmode)
365 || reg_or_0_operand (operands[1], SFmode)"
367 return output_move_single (operands);
369 [(set_attr "length" "2,4,4,8,2,2,4,4,4,8")
370 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
371 (set_attr "type" "other,other,other,other,load,other,load,store,store,other")])
373 ;; ----------------------------------------------------------------------
375 ;; ----------------------------------------------------------------------
377 (define_insn "*v850_tst1"
379 (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
381 (match_operand:QI 1 "const_int_operand" "n"))
385 [(set_attr "length" "4")
386 (set_attr "cc" "clobber")])
388 ;; This replaces ld.b;sar;andi with tst1;setf nz.
391 [(set (match_operand:SI 0 "register_operand" "")
392 (compare (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
394 (match_operand 2 "const_int_operand" ""))
397 [(set (cc0) (compare (zero_extract:SI (match_dup 1)
401 (set (match_dup 0) (ne:SI (cc0) (const_int 0)))])
403 (define_expand "cbranchsi4"
405 (compare (match_operand:SI 1 "register_operand" "")
406 (match_operand:SI 2 "reg_or_int5_operand" "")))
409 (match_operator 0 "ordered_comparison_operator" [(cc0)
411 (label_ref (match_operand 3 "" ""))
415 (define_expand "cstoresi4"
417 (compare (match_operand:SI 2 "register_operand" "")
418 (match_operand:SI 3 "reg_or_int5_operand" "")))
419 (set (match_operand:SI 0 "register_operand")
420 (match_operator:SI 1 "ordered_comparison_operator" [(cc0)
424 (define_expand "cmpsi"
426 (compare (match_operand:SI 0 "register_operand" "r,r")
427 (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
430 v850_compare_op0 = operands[0];
431 v850_compare_op1 = operands[1];
435 (define_insn "cmpsi_insn"
437 (compare (match_operand:SI 0 "register_operand" "r,r")
438 (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
443 [(set_attr "length" "2,2")
444 (set_attr "cc" "compare")])
446 (define_expand "cbranchsf4"
448 (if_then_else (match_operator 0 "ordered_comparison_operator"
449 [(match_operand:SF 1 "register_operand")
450 (match_operand:SF 2 "register_operand")])
451 (label_ref (match_operand 3 ""))
456 enum rtx_code cond = GET_CODE (operands[0]);
462 v850_compare_op0 = operands[1];
463 v850_compare_op1 = operands[2];
465 if (GET_MODE_CLASS (GET_MODE (v850_compare_op0)) != MODE_FLOAT)
468 mode = v850_gen_float_compare (cond, VOIDmode, v850_compare_op0, v850_compare_op1);
469 fcc_reg = gen_rtx_REG (mode, FCC_REGNUM);
470 cc_reg = gen_rtx_REG (mode, CC_REGNUM);
471 emit_insn (gen_rtx_SET (cc_reg, fcc_reg));
472 tmp = gen_rtx_fmt_ee (cond, mode, cc_reg, const0_rtx);
473 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
474 gen_rtx_LABEL_REF (VOIDmode, operands[3]), pc_rtx);
475 emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
479 (define_insn "cstoresf4"
480 [(set (match_operand:SI 0 "register_operand" "=r")
481 (match_operator:SI 1 "ordered_comparison_operator"
482 [(match_operand:SF 2 "register_operand" "r")
483 (match_operand:SF 3 "register_operand" "r")]))]
486 if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
487 return "cmpf.s %c1, %z2, %z3 ; trfsr ; setf nz, %0";
488 if (GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE)
489 return "cmpf.s %c1, %z2, %z3 ; trfsr ; setf z, %0";
490 if (GET_CODE (operands[1]) == EQ)
491 return "cmpf.s eq, %z2, %z3 ; trfsr ; setf z, %0";
492 if (GET_CODE (operands[1]) == NE)
493 return "cmpf.s neq, %z2, %z3 ; trfsr ; setf nz, %0";
496 [(set_attr "length" "12")
497 (set_attr "type" "fpu")]
500 (define_expand "cbranchdf4"
502 (if_then_else (match_operator 0 "ordered_comparison_operator"
503 [(match_operand:DF 1 "even_reg_operand")
504 (match_operand:DF 2 "even_reg_operand")])
505 (label_ref (match_operand 3 ""))
510 enum rtx_code cond = GET_CODE (operands[0]);
516 v850_compare_op0 = operands[1];
517 v850_compare_op1 = operands[2];
519 if (GET_MODE_CLASS (GET_MODE (v850_compare_op0)) != MODE_FLOAT)
522 mode = v850_gen_float_compare (cond, VOIDmode, v850_compare_op0, v850_compare_op1);
523 fcc_reg = gen_rtx_REG (mode, FCC_REGNUM);
524 cc_reg = gen_rtx_REG (mode, CC_REGNUM);
525 emit_insn (gen_rtx_SET (cc_reg, fcc_reg));
526 tmp = gen_rtx_fmt_ee (cond, mode, cc_reg, const0_rtx);
527 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
528 gen_rtx_LABEL_REF (VOIDmode, operands[3]), pc_rtx);
529 emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
533 (define_insn "cstoredf4"
534 [(set (match_operand:SI 0 "register_operand" "=r")
535 (match_operator:SI 1 "ordered_comparison_operator"
536 [(match_operand:DF 2 "even_reg_operand" "r")
537 (match_operand:DF 3 "even_reg_operand" "r")]))]
540 if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
541 return "cmpf.d %c1, %z2, %z3 ; trfsr ; setf nz, %0";
542 if (GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE)
543 return "cmpf.d %c1, %z2, %z3 ; trfsr ; setf z, %0";
544 if (GET_CODE (operands[1]) == EQ)
545 return "cmpf.d eq, %z2, %z3 ; trfsr ; setf z ,%0";
546 if (GET_CODE (operands[1]) == NE)
547 return "cmpf.d neq, %z2, %z3 ; trfsr ; setf nz, %0";
550 [(set_attr "length" "12")
551 (set_attr "type" "fpu")]
554 (define_expand "cmpsf"
555 [(set (reg:CC CC_REGNUM)
556 (compare (match_operand:SF 0 "register_operand" "r")
557 (match_operand:SF 1 "register_operand" "r")))]
560 v850_compare_op0 = operands[0];
561 v850_compare_op1 = operands[1];
565 (define_expand "cmpdf"
566 [(set (reg:CC CC_REGNUM)
567 (compare (match_operand:DF 0 "even_reg_operand" "r")
568 (match_operand:DF 1 "even_reg_operand" "r")))]
571 v850_compare_op0 = operands[0];
572 v850_compare_op1 = operands[1];
576 ;; ----------------------------------------------------------------------
578 ;; ----------------------------------------------------------------------
580 (define_insn "addsi3"
581 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
582 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
583 (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))
584 (clobber (reg:CC CC_REGNUM))]
591 [(set_attr "length" "2,4,4")
592 (set_attr "cc" "set_zn,set_zn,set_zn")])
594 ;; ----------------------------------------------------------------------
595 ;; SUBTRACT INSTRUCTIONS
596 ;; ----------------------------------------------------------------------
598 (define_insn "subsi3"
599 [(set (match_operand:SI 0 "register_operand" "=r,r")
600 (minus:SI (match_operand:SI 1 "register_operand" "0,r")
601 (match_operand:SI 2 "register_operand" "r,0")))
602 (clobber (reg:CC CC_REGNUM))]
607 [(set_attr "length" "2,2")
608 (set_attr "cc" "set_zn,set_zn")])
610 (define_insn "negsi2"
611 [(set (match_operand:SI 0 "register_operand" "=r")
612 (neg:SI (match_operand:SI 1 "register_operand" "0")))
613 (clobber (reg:CC CC_REGNUM))]
616 [(set_attr "length" "2")
617 (set_attr "cc" "set_zn")])
619 ;; ----------------------------------------------------------------------
620 ;; MULTIPLY INSTRUCTIONS
621 ;; ----------------------------------------------------------------------
623 (define_expand "mulhisi3"
624 [(set (match_operand:SI 0 "register_operand" "")
626 (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
627 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
630 if (GET_CODE (operands[2]) == CONST_INT)
632 emit_insn (gen_mulhisi3_internal2 (operands[0], operands[1], operands[2]));
637 (define_insn "*mulhisi3_internal1"
638 [(set (match_operand:SI 0 "register_operand" "=r")
640 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
641 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
644 [(set_attr "length" "2")
645 (set_attr "cc" "none_0hit")
646 (set_attr "type" "mult")])
648 (define_insn "mulhisi3_internal2"
649 [(set (match_operand:SI 0 "register_operand" "=r,r")
651 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
652 (match_operand:HI 2 "const_int_operand" "J,K")))]
657 [(set_attr "length" "2,4")
658 (set_attr "cc" "none_0hit,none_0hit")
659 (set_attr "type" "mult")])
661 ;; ??? The scheduling info is probably wrong.
663 ;; ??? This instruction can also generate the 32-bit highpart, but using it
664 ;; may increase code size counter to the desired result.
666 ;; ??? This instructions can also give a DImode result.
668 ;; ??? There is unsigned version, but it matters only for the DImode/highpart
671 (define_insn "mulsi3"
672 [(set (match_operand:SI 0 "register_operand" "=r")
673 (mult:SI (match_operand:SI 1 "register_operand" "%0")
674 (match_operand:SI 2 "reg_or_int9_operand" "rO")))]
677 [(set_attr "length" "4")
678 (set_attr "cc" "none_0hit")
679 (set_attr "type" "mult")])
681 ;; ----------------------------------------------------------------------
682 ;; DIVIDE INSTRUCTIONS
683 ;; ----------------------------------------------------------------------
685 ;; ??? These insns do set the Z/N condition codes, except that they are based
686 ;; on only one of the two results, so it doesn't seem to make sense to use
689 ;; ??? The scheduling info is probably wrong.
691 (define_insn "divmodsi4"
692 [(set (match_operand:SI 0 "register_operand" "=r")
693 (div:SI (match_operand:SI 1 "register_operand" "0")
694 (match_operand:SI 2 "register_operand" "r")))
695 (set (match_operand:SI 3 "register_operand" "=r")
696 (mod:SI (match_dup 1)
698 (clobber (reg:CC CC_REGNUM))]
701 if (TARGET_V850E2_UP)
702 return "divq %2,%0,%3";
704 return "div %2,%0,%3";
706 [(set_attr "length" "4")
707 (set_attr "cc" "clobber")
708 (set_attr "type" "div")])
710 (define_insn "udivmodsi4"
711 [(set (match_operand:SI 0 "register_operand" "=r")
712 (udiv:SI (match_operand:SI 1 "register_operand" "0")
713 (match_operand:SI 2 "register_operand" "r")))
714 (set (match_operand:SI 3 "register_operand" "=r")
715 (umod:SI (match_dup 1)
717 (clobber (reg:CC CC_REGNUM))]
720 if (TARGET_V850E2_UP)
721 return "divqu %2,%0,%3";
723 return "divu %2,%0,%3";
725 [(set_attr "length" "4")
726 (set_attr "cc" "clobber")
727 (set_attr "type" "div")])
729 ;; ??? There is a 2 byte instruction for generating only the quotient.
730 ;; However, it isn't clear how to compute the length field correctly.
732 (define_insn "divmodhi4"
733 [(set (match_operand:HI 0 "register_operand" "=r")
734 (div:HI (match_operand:HI 1 "register_operand" "0")
735 (match_operand:HI 2 "register_operand" "r")))
736 (set (match_operand:HI 3 "register_operand" "=r")
737 (mod:HI (match_dup 1)
739 (clobber (reg:CC CC_REGNUM))]
742 [(set_attr "length" "4")
743 (set_attr "cc" "clobber")
744 (set_attr "type" "div")])
746 ;; Half-words are sign-extended by default, so we must zero extend to a word
747 ;; here before doing the divide.
749 (define_insn "udivmodhi4"
750 [(set (match_operand:HI 0 "register_operand" "=r")
751 (udiv:HI (match_operand:HI 1 "register_operand" "0")
752 (match_operand:HI 2 "register_operand" "r")))
753 (set (match_operand:HI 3 "register_operand" "=r")
754 (umod:HI (match_dup 1)
756 (clobber (reg:CC CC_REGNUM))]
758 "zxh %0 ; divhu %2,%0,%3"
759 [(set_attr "length" "4")
760 (set_attr "cc" "clobber")
761 (set_attr "type" "div")])
763 ;; ----------------------------------------------------------------------
765 ;; ----------------------------------------------------------------------
767 (define_insn "*v850_clr1_1"
768 [(set (match_operand:QI 0 "memory_operand" "=m")
770 (and:SI (subreg:SI (match_dup 0) 0)
771 (match_operand:QI 1 "not_power_of_two_operand" "")) 0))
772 (clobber (reg:CC CC_REGNUM))]
776 xoperands[0] = operands[0];
777 xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
778 output_asm_insn ("clr1 %M1,%0", xoperands);
781 [(set_attr "length" "4")
782 (set_attr "cc" "clobber")
783 (set_attr "type" "bit1")])
785 (define_insn "*v850_clr1_2"
786 [(set (match_operand:HI 0 "indirect_operand" "=m")
788 (and:SI (subreg:SI (match_dup 0) 0)
789 (match_operand:HI 1 "not_power_of_two_operand" "")) 0))
790 (clobber (reg:CC CC_REGNUM))]
793 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
796 xoperands[0] = gen_rtx_MEM (QImode,
797 plus_constant (Pmode, XEXP (operands[0], 0),
799 xoperands[1] = GEN_INT (log2 % 8);
800 output_asm_insn ("clr1 %1,%0", xoperands);
803 [(set_attr "length" "4")
804 (set_attr "cc" "clobber")
805 (set_attr "type" "bit1")])
807 (define_insn "*v850_clr1_3"
808 [(set (match_operand:SI 0 "indirect_operand" "=m")
809 (and:SI (match_dup 0)
810 (match_operand:SI 1 "not_power_of_two_operand" "")))
811 (clobber (reg:CC CC_REGNUM))]
814 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
817 xoperands[0] = gen_rtx_MEM (QImode,
818 plus_constant (Pmode, XEXP (operands[0], 0),
820 xoperands[1] = GEN_INT (log2 % 8);
821 output_asm_insn ("clr1 %1,%0", xoperands);
824 [(set_attr "length" "4")
825 (set_attr "cc" "clobber")
826 (set_attr "type" "bit1")])
828 (define_insn "andsi3"
829 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
830 (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
831 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
832 (clobber (reg:CC CC_REGNUM))]
838 [(set_attr "length" "2,2,4")
839 (set_attr "cc" "set_zn")])
841 ;; ----------------------------------------------------------------------
843 ;; ----------------------------------------------------------------------
845 (define_insn "*v850_set1_1"
846 [(set (match_operand:QI 0 "memory_operand" "=m")
847 (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
848 (match_operand 1 "power_of_two_operand" "")) 0))
849 (clobber (reg:CC CC_REGNUM))]
852 [(set_attr "length" "4")
853 (set_attr "cc" "clobber")
854 (set_attr "type" "bit1")])
856 (define_insn "*v850_set1_2"
857 [(set (match_operand:HI 0 "indirect_operand" "=m")
858 (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
859 (match_operand 1 "power_of_two_operand" "")) 0))]
862 int log2 = exact_log2 (INTVAL (operands[1]));
865 return "set1 %M1,%0";
869 xoperands[0] = gen_rtx_MEM (QImode,
870 plus_constant (Pmode, XEXP (operands[0], 0),
872 xoperands[1] = GEN_INT (log2 % 8);
873 output_asm_insn ("set1 %1,%0", xoperands);
877 [(set_attr "length" "4")
878 (set_attr "cc" "clobber")
879 (set_attr "type" "bit1")])
881 (define_insn "*v850_set1_3"
882 [(set (match_operand:SI 0 "indirect_operand" "=m")
883 (ior:SI (match_dup 0)
884 (match_operand 1 "power_of_two_operand" "")))
885 (clobber (reg:CC CC_REGNUM))]
888 int log2 = exact_log2 (INTVAL (operands[1]));
891 return "set1 %M1,%0";
895 xoperands[0] = gen_rtx_MEM (QImode,
896 plus_constant (Pmode, XEXP (operands[0], 0),
898 xoperands[1] = GEN_INT (log2 % 8);
899 output_asm_insn ("set1 %1,%0", xoperands);
903 [(set_attr "length" "4")
904 (set_attr "cc" "clobber")
905 (set_attr "type" "bit1")])
907 (define_insn "iorsi3"
908 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
909 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
910 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
911 (clobber (reg:CC CC_REGNUM))]
917 [(set_attr "length" "2,2,4")
918 (set_attr "cc" "set_zn")])
920 ;; ----------------------------------------------------------------------
922 ;; ----------------------------------------------------------------------
924 (define_insn "*v850_not1_1"
925 [(set (match_operand:QI 0 "memory_operand" "=m")
926 (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0)
927 (match_operand 1 "power_of_two_operand" "")) 0))
928 (clobber (reg:CC CC_REGNUM))]
931 [(set_attr "length" "4")
932 (set_attr "cc" "clobber")
933 (set_attr "type" "bit1")])
935 (define_insn "*v850_not1_2"
936 [(set (match_operand:HI 0 "indirect_operand" "=m")
937 (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
938 (match_operand 1 "power_of_two_operand" "")) 0))]
941 int log2 = exact_log2 (INTVAL (operands[1]));
944 return "not1 %M1,%0";
948 xoperands[0] = gen_rtx_MEM (QImode,
949 plus_constant (Pmode, XEXP (operands[0], 0),
951 xoperands[1] = GEN_INT (log2 % 8);
952 output_asm_insn ("not1 %1,%0", xoperands);
956 [(set_attr "length" "4")
957 (set_attr "cc" "clobber")
958 (set_attr "type" "bit1")])
960 (define_insn "*v850_not1_3"
961 [(set (match_operand:SI 0 "indirect_operand" "=m")
962 (xor:SI (match_dup 0)
963 (match_operand 1 "power_of_two_operand" "")))
964 (clobber (reg:CC CC_REGNUM))]
967 int log2 = exact_log2 (INTVAL (operands[1]));
970 return "not1 %M1,%0";
974 xoperands[0] = gen_rtx_MEM (QImode,
975 plus_constant (Pmode, XEXP (operands[0], 0),
977 xoperands[1] = GEN_INT (log2 % 8);
978 output_asm_insn ("not1 %1,%0", xoperands);
982 [(set_attr "length" "4")
983 (set_attr "cc" "clobber")
984 (set_attr "type" "bit1")])
986 (define_insn "xorsi3"
987 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
988 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
989 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
990 (clobber (reg:CC CC_REGNUM))]
996 [(set_attr "length" "2,2,4")
997 (set_attr "cc" "set_zn")])
999 ;; ----------------------------------------------------------------------
1001 ;; ----------------------------------------------------------------------
1003 (define_insn "one_cmplsi2"
1004 [(set (match_operand:SI 0 "register_operand" "=r")
1005 (not:SI (match_operand:SI 1 "register_operand" "r")))
1006 (clobber (reg:CC CC_REGNUM))]
1009 [(set_attr "length" "2")
1010 (set_attr "cc" "set_zn")])
1012 ;; -----------------------------------------------------------------
1014 ;; -----------------------------------------------------------------
1016 ;; ??? Is it worth defining insv and extv for the V850 series?!?
1018 ;; An insv pattern would be useful, but does not get used because
1019 ;; store_bit_field never calls insv when storing a constant value into a
1020 ;; single-bit bitfield.
1022 ;; extv/extzv patterns would be useful, but do not get used because
1023 ;; optimize_bitfield_compare in fold-const usually converts single
1024 ;; bit extracts into an AND with a mask.
1027 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1028 (match_operand:SI 1 "immediate_operand" "n")
1029 (match_operand:SI 2 "immediate_operand" "n"))
1030 (match_operand:SI 3 "register_operand" "r"))]
1031 "TARGET_V850E3V5_UP"
1032 "bins %3, %2, %1, %0"
1033 [(set_attr "length" "4")
1034 (set_attr "cc" "set_zn")]
1037 ;; -----------------------------------------------------------------
1039 ;; -----------------------------------------------------------------
1041 (define_insn "*setcc"
1042 [(set (match_operand:SI 0 "register_operand" "=r")
1043 (match_operator:SI 1 "comparison_operator"
1044 [(cc0) (const_int 0)]))]
1047 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1048 && (GET_CODE (operands[1]) == GT
1049 || GET_CODE (operands[1]) == GE
1050 || GET_CODE (operands[1]) == LE
1051 || GET_CODE (operands[1]) == LT))
1054 return "setf %c1,%0";
1056 [(set_attr "length" "4")
1057 (set_attr "cc" "none_0hit")])
1059 (define_insn "setf_insn"
1060 [(set (match_operand:SI 0 "register_operand" "=r")
1061 (match_operator:SI 1 "comparison_operator"
1062 [(reg:CC CC_REGNUM) (const_int 0)]))]
1065 [(set_attr "length" "4")
1066 (set_attr "cc" "none_0hit")])
1068 (define_insn "set_z_insn"
1069 [(set (match_operand:SI 0 "register_operand" "=r")
1070 (match_operand 1 "v850_float_z_comparison_operator" ""))]
1071 "TARGET_V850E2V3_UP"
1073 [(set_attr "length" "4")
1074 (set_attr "cc" "none_0hit")])
1076 (define_insn "set_nz_insn"
1077 [(set (match_operand:SI 0 "register_operand" "=r")
1078 (match_operand 1 "v850_float_nz_comparison_operator" ""))]
1079 "TARGET_V850E2V3_UP"
1081 [(set_attr "length" "4")
1082 (set_attr "cc" "none_0hit")])
1084 ;; ----------------------------------------------------------------------
1085 ;; CONDITIONAL MOVE INSTRUCTIONS
1086 ;; ----------------------------------------------------------------------
1088 ;; Instructions using cc0 aren't allowed to have input reloads, so we must
1089 ;; hide the fact that this instruction uses cc0. We do so by including the
1090 ;; compare instruction inside it.
1092 (define_expand "movsicc"
1093 [(set (match_operand:SI 0 "register_operand" "=r")
1095 (match_operand 1 "comparison_operator")
1096 (match_operand:SI 2 "reg_or_const_operand" "rJ")
1097 (match_operand:SI 3 "reg_or_const_operand" "rI")))]
1100 /* Make sure that we have an integer comparison... */
1101 if (GET_MODE (XEXP (operands[1], 0)) != CCmode
1102 && GET_MODE (XEXP (operands[1], 0)) != SImode)
1105 if ((GET_CODE (operands[2]) == CONST_INT
1106 && GET_CODE (operands[3]) == CONST_INT))
1108 int o2 = INTVAL (operands[2]);
1109 int o3 = INTVAL (operands[3]);
1111 if (o2 == 1 && o3 == 0)
1113 if (o3 == 1 && o2 == 0)
1115 if (o2 == 0 && (o3 < -16 || o3 > 15) && exact_log2 (o3) >= 0)
1116 FAIL; /* setf + shift */
1117 if (o3 == 0 && (o2 < -16 || o2 > 15) && exact_log2 (o2) >=0)
1118 FAIL; /* setf + shift */
1120 operands[2] = copy_to_mode_reg (SImode, operands[2]);
1122 operands[3] = copy_to_mode_reg (SImode, operands[3]);
1126 if (GET_CODE (operands[2]) != REG)
1127 operands[2] = copy_to_mode_reg (SImode,operands[2]);
1128 if (GET_CODE (operands[3]) != REG)
1129 operands[3] = copy_to_mode_reg (SImode, operands[3]);
1133 ;; ??? Clobbering the condition codes is overkill.
1135 ;; ??? We sometimes emit an unnecessary compare instruction because the
1136 ;; condition codes may have already been set by an earlier instruction,
1137 ;; but we have no code here to avoid the compare if it is unnecessary.
1139 (define_insn "movsicc_normal_cc"
1140 [(set (match_operand:SI 0 "register_operand" "=r")
1142 (match_operator 1 "comparison_operator"
1143 [(reg:CC CC_REGNUM) (const_int 0)])
1144 (match_operand:SI 2 "reg_or_int5_operand" "rJ")
1145 (match_operand:SI 3 "reg_or_0_operand" "rI")))]
1147 "cmov %c1,%2,%z3,%0";
1148 [(set_attr "length" "6")
1149 (set_attr "cc" "compare")])
1151 (define_insn "movsicc_reversed_cc"
1152 [(set (match_operand:SI 0 "register_operand" "=r")
1154 (match_operator 1 "comparison_operator"
1155 [(reg:CC CC_REGNUM) (const_int 0)])
1156 (match_operand:SI 2 "reg_or_0_operand" "rI")
1157 (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
1159 "cmov %C1,%3,%z2,%0"
1160 [(set_attr "length" "6")
1161 (set_attr "cc" "compare")])
1163 (define_insn "*movsicc_normal"
1164 [(set (match_operand:SI 0 "register_operand" "=r")
1166 (match_operator 1 "comparison_operator"
1167 [(match_operand:SI 4 "register_operand" "r")
1168 (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
1169 (match_operand:SI 2 "reg_or_int5_operand" "rJ")
1170 (match_operand:SI 3 "reg_or_0_operand" "rI")))]
1172 "cmp %5,%4 ; cmov %c1,%2,%z3,%0"
1173 [(set_attr "length" "6")
1174 (set_attr "cc" "clobber")])
1176 (define_insn "*movsicc_reversed"
1177 [(set (match_operand:SI 0 "register_operand" "=r")
1179 (match_operator 1 "comparison_operator"
1180 [(match_operand:SI 4 "register_operand" "r")
1181 (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
1182 (match_operand:SI 2 "reg_or_0_operand" "rI")
1183 (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
1185 "cmp %5,%4 ; cmov %C1,%3,%z2,%0"
1186 [(set_attr "length" "6")
1187 (set_attr "cc" "clobber")])
1189 (define_insn "*movsicc_tst1"
1190 [(set (match_operand:SI 0 "register_operand" "=r")
1192 (match_operator 1 "comparison_operator"
1194 (match_operand:QI 2 "memory_operand" "m")
1196 (match_operand 3 "const_int_operand" "n"))
1198 (match_operand:SI 4 "reg_or_int5_operand" "rJ")
1199 (match_operand:SI 5 "reg_or_0_operand" "rI")))]
1201 "tst1 %3,%2 ; cmov %c1,%4,%z5,%0"
1202 [(set_attr "length" "8")
1203 (set_attr "cc" "clobber")])
1205 (define_insn "*movsicc_tst1_reversed"
1206 [(set (match_operand:SI 0 "register_operand" "=r")
1208 (match_operator 1 "comparison_operator"
1210 (match_operand:QI 2 "memory_operand" "m")
1212 (match_operand 3 "const_int_operand" "n"))
1214 (match_operand:SI 4 "reg_or_0_operand" "rI")
1215 (match_operand:SI 5 "reg_or_int5_operand" "rJ")))]
1217 "tst1 %3,%2 ; cmov %C1,%5,%z4,%0"
1218 [(set_attr "length" "8")
1219 (set_attr "cc" "clobber")])
1221 ;; Matching for sasf requires combining 4 instructions, so we provide a
1222 ;; dummy pattern to match the first 3, which will always be turned into the
1223 ;; second pattern by subsequent combining. As above, we must include the
1224 ;; comparison to avoid input reloads in an insn using cc0.
1226 (define_insn "*sasf"
1227 [(set (match_operand:SI 0 "register_operand" "=r")
1229 (match_operator 1 "comparison_operator"
1230 [(match_operand:SI 3 "register_operand" "r")
1231 (match_operand:SI 4 "reg_or_int5_operand" "rJ")])
1232 (ashift:SI (match_operand:SI 2 "register_operand" "0")
1234 (clobber (reg:CC CC_REGNUM))]
1236 "cmp %4,%3 ; sasf %c1,%0"
1237 [(set_attr "length" "6")
1238 (set_attr "cc" "clobber")])
1241 [(set (match_operand:SI 0 "register_operand" "")
1243 (match_operator 1 "comparison_operator"
1244 [(match_operand:SI 4 "register_operand" "")
1245 (match_operand:SI 5 "reg_or_int5_operand" "")])
1246 (match_operand:SI 2 "const_int_operand" "")
1247 (match_operand:SI 3 "const_int_operand" "")))
1248 (clobber (reg:CC CC_REGNUM))]
1250 && ((INTVAL (operands[2]) ^ INTVAL (operands[3])) == 1)
1251 && ((INTVAL (operands[2]) + INTVAL (operands[3])) != 1)
1252 && (GET_CODE (operands[5]) == CONST_INT
1253 || REGNO (operands[0]) != REGNO (operands[5]))
1254 && REGNO (operands[0]) != REGNO (operands[4])"
1255 [(set (match_dup 0) (match_dup 6))
1256 (parallel [(set (match_dup 0)
1257 (ior:SI (match_op_dup 7 [(match_dup 4) (match_dup 5)])
1258 (ashift:SI (match_dup 0) (const_int 1))))
1259 (clobber (reg:CC CC_REGNUM))])]
1261 operands[6] = GEN_INT (INTVAL (operands[2]) >> 1);
1262 if (INTVAL (operands[2]) & 0x1)
1263 operands[7] = operands[1];
1265 operands[7] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
1266 GET_MODE (operands[1]),
1267 XEXP (operands[1], 0), XEXP (operands[1], 1));
1270 ;; ---------------------------------------------------------------------
1271 ;; BYTE SWAP INSTRUCTIONS
1272 ;; ---------------------------------------------------------------------
1273 (define_expand "rotlhi3"
1274 [(parallel [(set (match_operand:HI 0 "register_operand" "")
1275 (rotate:HI (match_operand:HI 1 "register_operand" "")
1276 (match_operand:HI 2 "const_int_operand" "")))
1277 (clobber (reg:CC CC_REGNUM))])]
1280 if (INTVAL (operands[2]) != 8)
1284 (define_insn "*rotlhi3_8"
1285 [(set (match_operand:HI 0 "register_operand" "=r")
1286 (rotate:HI (match_operand:HI 1 "register_operand" "r")
1288 (clobber (reg:CC CC_REGNUM))]
1291 [(set_attr "length" "4")
1292 (set_attr "cc" "clobber")])
1294 (define_expand "rotlsi3"
1295 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1296 (rotate:SI (match_operand:SI 1 "register_operand" "")
1297 (match_operand:SI 2 "const_int_operand" "")))
1298 (clobber (reg:CC CC_REGNUM))])]
1301 if (INTVAL (operands[2]) != 16)
1305 (define_insn "rotlsi3_a"
1306 [(set (match_operand:SI 0 "register_operand" "=r")
1307 (match_operator:SI 4 "ior_operator"
1308 [(ashift:SI (match_operand:SI 1 "register_operand" "r")
1309 (match_operand:SI 2 "const_int_operand" "n"))
1310 (lshiftrt:SI (match_dup 1)
1311 (match_operand:SI 3 "const_int_operand" "n"))]))]
1312 "TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)"
1314 [(set_attr "length" "4")
1315 (set_attr "cc" "set_zn")]
1318 (define_insn "rotlsi3_b"
1319 [(set (match_operand:SI 0 "register_operand" "=r")
1320 (match_operator:SI 4 "ior_operator"
1321 [(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1322 (match_operand:SI 3 "const_int_operand" "n"))
1323 (ashift:SI (match_dup 1)
1324 (match_operand:SI 2 "const_int_operand" "n"))]))]
1325 "TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)"
1327 [(set_attr "length" "4")
1328 (set_attr "cc" "set_zn")]
1331 (define_insn "rotlsi3_v850e3v5"
1332 [(set (match_operand:SI 0 "register_operand" "=r")
1333 (rotate:SI (match_operand:SI 1 "register_operand" "r")
1334 (match_operand:SI 2 "e3v5_shift_operand" "rn")))
1335 (clobber (reg:CC CC_REGNUM))]
1336 "TARGET_V850E3V5_UP"
1338 [(set_attr "length" "4")
1339 (set_attr "cc" "set_zn")]
1342 (define_insn "*rotlsi3_16"
1343 [(set (match_operand:SI 0 "register_operand" "=r")
1344 (rotate:SI (match_operand:SI 1 "register_operand" "r")
1346 (clobber (reg:CC CC_REGNUM))]
1349 [(set_attr "length" "4")
1350 (set_attr "cc" "clobber")])
1352 ;; ----------------------------------------------------------------------
1353 ;; JUMP INSTRUCTIONS
1354 ;; ----------------------------------------------------------------------
1358 (define_expand "doloop_begin"
1359 [(use (match_operand 0 "" "")) ; loop pseudo
1360 (use (match_operand 1 "" ""))] ; doloop_end pattern
1361 "TARGET_V850E3V5_UP && TARGET_LOOP"
1363 rtx loop_cnt = operands[0];
1364 gcc_assert (GET_MODE (loop_cnt) == SImode);
1365 emit_insn (gen_fix_loop_counter (loop_cnt));
1370 (define_insn "fix_loop_counter"
1371 [(unspec:SI [(match_operand:SI 0 "register_operand" "+r,!m")
1372 (clobber (match_scratch:SI 1 "=X,r"))] UNSPEC_LOOP)]
1373 "TARGET_V850E3V5_UP && TARGET_LOOP"
1375 switch (which_alternative)
1377 case 0: return "add 1, %0 # LOOP_BEGIN";
1378 case 1: return "ld.w %0, %1; add 1, %1; st.w %1, %0 # LOOP_BEGIN";
1379 default: gcc_unreachable ();
1382 [(set_attr "length" "2,6")
1383 (set_attr "cc" "none")]
1386 (define_expand "doloop_end"
1387 [(use (match_operand 0 "" "")) ; loop pseudo
1388 (use (match_operand 1 "" ""))] ; label
1389 "TARGET_V850E3V5_UP && TARGET_LOOP"
1391 rtx loop_cnt = operands[0];
1392 rtx label = operands[1];
1394 if (GET_MODE (loop_cnt) != SImode)
1397 emit_jump_insn (gen_doloop_end_internal_loop (label, loop_cnt));
1402 (define_insn "doloop_end_internal_loop"
1404 (if_then_else (ne (match_operand:SI 1 "register_operand" "+r,!m")
1406 (label_ref (match_operand 0 "" ""))
1408 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))
1409 (clobber (match_scratch:SI 2 "=X,r"))
1410 (clobber (reg:CC CC_REGNUM))]
1411 "TARGET_V850E3V5_UP && TARGET_LOOP"
1413 switch (which_alternative)
1416 if (get_attr_length (insn) == 4)
1417 return "loop %1, %0 # LOOP.1.0";
1419 return "add -1, %1; bne %l0 # LOOP.1.1";
1421 return "ld.w %1, %2; add -1, %2; st.w %2, %1; bne %l0 # LOOP.2.1";
1426 [(set (attr "length")
1427 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1431 (set_attr "cc" "none")])
1433 ;; Conditional jump instructions
1435 (define_insn "*branch_normal"
1437 (if_then_else (match_operator 1 "comparison_operator"
1438 [(cc0) (const_int 0)])
1439 (label_ref (match_operand 0 "" ""))
1443 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1444 && (GET_CODE (operands[1]) == GT
1445 || GET_CODE (operands[1]) == GE
1446 || GET_CODE (operands[1]) == LE
1447 || GET_CODE (operands[1]) == LT))
1450 if (get_attr_length (insn) == 2)
1452 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1454 return "b%B1 .+6 ; jr %l0";
1456 [(set (attr "length")
1457 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1460 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1464 (set_attr "cc" "none")])
1466 (define_insn "*branch_invert"
1468 (if_then_else (match_operator 1 "comparison_operator"
1469 [(cc0) (const_int 0)])
1471 (label_ref (match_operand 0 "" ""))))]
1474 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1475 && (GET_CODE (operands[1]) == GT
1476 || GET_CODE (operands[1]) == GE
1477 || GET_CODE (operands[1]) == LE
1478 || GET_CODE (operands[1]) == LT))
1481 if (get_attr_length (insn) == 2)
1484 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1487 return "b%b1 .+6 ; jr %l0";
1489 [(set (attr "length")
1490 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1493 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1497 (set_attr "cc" "none")])
1499 (define_insn "branch_z_normal"
1501 (if_then_else (match_operand 1 "v850_float_z_comparison_operator" "")
1502 (label_ref (match_operand 0 "" ""))
1504 "TARGET_V850E2V3_UP"
1506 if (get_attr_length (insn) == 2)
1509 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1512 return "bnz 1f ; jr %l0 ; 1:";
1514 [(set (attr "length")
1515 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1518 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1522 (set_attr "cc" "none")])
1524 (define_insn "*branch_z_invert"
1526 (if_then_else (match_operand 1 "v850_float_z_comparison_operator" "")
1528 (label_ref (match_operand 0 "" ""))))]
1529 "TARGET_V850E2V3_UP"
1531 if (get_attr_length (insn) == 2)
1534 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1537 return "bz 1f ; jr %l0 ; 1:";
1539 [(set (attr "length")
1540 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1543 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1547 (set_attr "cc" "none")])
1549 (define_insn "branch_nz_normal"
1551 (if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "")
1552 (label_ref (match_operand 0 "" ""))
1554 "TARGET_V850E2V3_UP"
1556 if (get_attr_length (insn) == 2)
1559 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1562 return "bz 1f ; jr %l0 ; 1:";
1564 [(set (attr "length")
1565 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1568 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1572 (set_attr "cc" "none")])
1574 (define_insn "*branch_nz_invert"
1576 (if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "")
1578 (label_ref (match_operand 0 "" ""))))]
1579 "TARGET_V850E2V3_UP"
1581 if (get_attr_length (insn) == 2)
1584 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1587 return "bnz 1f ; jr %l0 ; 1:";
1589 [(set (attr "length")
1590 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1593 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1597 (set_attr "cc" "none")])
1599 ;; Unconditional and other jump instructions.
1603 (label_ref (match_operand 0 "" "")))]
1606 if (get_attr_length (insn) == 2)
1611 [(set (attr "length")
1612 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1616 (set_attr "cc" "none")])
1618 (define_insn "indirect_jump"
1619 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1622 [(set_attr "length" "2")
1623 (set_attr "cc" "none")])
1625 (define_insn "tablejump"
1626 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1627 (use (label_ref (match_operand 1 "" "")))]
1630 [(set_attr "length" "2")
1631 (set_attr "cc" "none")])
1633 (define_insn "switch"
1638 (plus:SI (ashift:SI (match_operand:SI 0 "register_operand" "r")
1640 (label_ref (match_operand 1 "" "")))))
1641 (label_ref (match_dup 1))))]
1644 [(set_attr "length" "2")
1645 (set_attr "cc" "none")])
1647 (define_expand "casesi"
1648 [(match_operand:SI 0 "register_operand" "")
1649 (match_operand:SI 1 "register_operand" "")
1650 (match_operand:SI 2 "register_operand" "")
1651 (match_operand 3 "" "") (match_operand 4 "" "")]
1654 rtx reg = gen_reg_rtx (SImode);
1655 rtx tableaddress = gen_reg_rtx (SImode);
1659 /* Subtract the lower bound from the index. */
1660 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
1662 /* Compare the result against the number of table entries;
1663 branch to the default label if out of range of the table. */
1664 test = gen_rtx_fmt_ee (GTU, VOIDmode, reg, operands[2]);
1665 emit_jump_insn (gen_cbranchsi4 (test, reg, operands[2], operands[4]));
1667 /* Shift index for the table array access. */
1668 emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
1669 /* Load the table address into a pseudo. */
1670 emit_insn (gen_movsi (tableaddress,
1671 gen_rtx_LABEL_REF (Pmode, operands[3])));
1672 /* Add the table address to the index. */
1673 emit_insn (gen_addsi3 (reg, reg, tableaddress));
1674 /* Load the table entry. */
1675 mem = gen_const_mem (CASE_VECTOR_MODE, reg);
1676 if (! TARGET_BIG_SWITCH)
1678 rtx reg2 = gen_reg_rtx (HImode);
1679 emit_insn (gen_movhi (reg2, mem));
1680 emit_insn (gen_extendhisi2 (reg, reg2));
1683 emit_insn (gen_movsi (reg, mem));
1684 /* Add the table address. */
1685 emit_insn (gen_addsi3 (reg, reg, tableaddress));
1686 /* Branch to the switch label. */
1687 emit_jump_insn (gen_tablejump (reg, operands[3]));
1691 ;; Call subroutine with no return value.
1693 (define_expand "call"
1694 [(call (match_operand:QI 0 "general_operand" "")
1695 (match_operand:SI 1 "general_operand" ""))]
1698 if (! call_address_operand (XEXP (operands[0], 0), QImode)
1699 || TARGET_LONG_CALLS)
1700 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1701 if (TARGET_LONG_CALLS)
1702 emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));
1704 emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
1709 (define_insn "call_internal_short"
1710 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1711 (match_operand:SI 1 "general_operand" "g,g"))
1712 (clobber (reg:SI 31))]
1713 "! TARGET_LONG_CALLS"
1715 if (which_alternative == 1)
1717 if (TARGET_V850E3V5_UP)
1718 return "jarl [%0], r31";
1720 return "jarl .+4, r31 ; add 4, r31 ; jmp %0";
1723 return "jarl %0, r31";
1725 [(set_attr "length" "4,8")
1726 (set_attr "cc" "clobber,clobber")]
1729 (define_insn "call_internal_long"
1730 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1731 (match_operand:SI 1 "general_operand" "g,g"))
1732 (clobber (reg:SI 31))]
1735 if (which_alternative == 0)
1737 if (GET_CODE (operands[0]) == REG)
1738 return "jarl %0,r31";
1740 if (TARGET_V850E3V5_UP)
1741 return "mov hilo(%0), r11 ; jarl [r11], r31";
1743 return "movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11";
1746 if (TARGET_V850E3V5_UP)
1747 return "jarl [%0], r31";
1749 return "jarl .+4,r31 ; add 4,r31 ; jmp %0";
1751 [(set_attr "length" "16,8")
1752 (set_attr "cc" "clobber,clobber")]
1755 ;; Call subroutine, returning value in operand 0
1756 ;; (which must be a hard register).
1758 (define_expand "call_value"
1759 [(set (match_operand 0 "" "")
1760 (call (match_operand:QI 1 "general_operand" "")
1761 (match_operand:SI 2 "general_operand" "")))]
1764 if (! call_address_operand (XEXP (operands[1], 0), QImode)
1765 || TARGET_LONG_CALLS)
1766 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1767 if (TARGET_LONG_CALLS)
1768 emit_call_insn (gen_call_value_internal_long (operands[0],
1769 XEXP (operands[1], 0),
1772 emit_call_insn (gen_call_value_internal_short (operands[0],
1773 XEXP (operands[1], 0),
1778 (define_insn "call_value_internal_short"
1779 [(set (match_operand 0 "" "=r,r")
1780 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1781 (match_operand:SI 2 "general_operand" "g,g")))
1782 (clobber (reg:SI 31))]
1783 "! TARGET_LONG_CALLS"
1785 if (which_alternative == 1)
1787 if (TARGET_V850E3V5_UP)
1788 return "jarl [%1], r31";
1790 return "jarl .+4, r31 ; add 4, r31 ; jmp %1";
1793 return "jarl %1, r31";
1795 [(set_attr "length" "4,8")
1796 (set_attr "cc" "clobber,clobber")]
1799 (define_insn "call_value_internal_long"
1800 [(set (match_operand 0 "" "=r,r")
1801 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1802 (match_operand:SI 2 "general_operand" "g,g")))
1803 (clobber (reg:SI 31))]
1806 if (which_alternative == 0)
1808 if (GET_CODE (operands[1]) == REG)
1809 return "jarl %1, r31";
1811 /* Reload can generate this pattern.... */
1812 if (TARGET_V850E3V5_UP)
1813 return "mov hilo(%1), r11 ; jarl [r11], r31";
1815 return "movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11";
1818 if (TARGET_V850E3V5_UP)
1819 return "jarl [%1], r31";
1821 return "jarl .+4, r31 ; add 4, r31 ; jmp %1";
1823 [(set_attr "length" "16,8")
1824 (set_attr "cc" "clobber,clobber")]
1831 [(set_attr "length" "2")
1832 (set_attr "cc" "none")])
1834 ;; ----------------------------------------------------------------------
1835 ;; EXTEND INSTRUCTIONS
1836 ;; ----------------------------------------------------------------------
1838 (define_insn "*zero_extendhisi2_v850e"
1839 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1841 (match_operand:HI 1 "nonimmediate_operand" "0,r,T,m")))
1842 (clobber (reg:CC CC_REGNUM))]
1849 [(set_attr "length" "2,4,2,4")
1850 (set_attr "cc" "none_0hit,set_zn,none_0hit,none_0hit")])
1852 (define_insn "*zero_extendhisi2_v850"
1853 [(set (match_operand:SI 0 "register_operand" "=r")
1855 (match_operand:HI 1 "register_operand" "r")))
1856 (clobber (reg:CC CC_REGNUM))] ;; A lie, but we have to match the expander
1859 [(set_attr "length" "4")
1860 (set_attr "cc" "set_zn")])
1862 (define_expand "zero_extendhisi2"
1863 [(parallel [(set (match_operand:SI 0 "register_operand")
1865 (match_operand:HI 1 "nonimmediate_operand")))
1866 (clobber (reg:CC CC_REGNUM))])]
1869 if (! (TARGET_V850E_UP))
1870 operands[1] = force_reg (HImode, operands[1]);
1873 (define_insn "*zero_extendqisi2_v850e"
1874 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1876 (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m")))
1877 (clobber (reg:CC CC_REGNUM))]
1884 [(set_attr "length" "2,4,2,4")
1885 (set_attr "cc" "none_0hit,set_zn,none_0hit,none_0hit")])
1887 (define_insn "*zero_extendqisi2_v850"
1888 [(set (match_operand:SI 0 "register_operand" "=r")
1890 (match_operand:QI 1 "register_operand" "r")))
1891 (clobber (reg:CC CC_REGNUM))] ;; A lie, but we have to match the expander
1894 [(set_attr "length" "4")
1895 (set_attr "cc" "set_zn")])
1897 (define_expand "zero_extendqisi2"
1898 [(parallel [(set (match_operand:SI 0 "register_operand")
1900 (match_operand:QI 1 "nonimmediate_operand")))
1901 (clobber (reg:CC CC_REGNUM))])]
1904 if (! (TARGET_V850E_UP))
1905 operands[1] = force_reg (QImode, operands[1]);
1908 ;;- sign extension instructions
1910 ;; ??? The extendhisi2 pattern should not emit shifts for v850e?
1912 (define_insn "*extendhisi_insn"
1913 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1914 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))
1915 (clobber (reg:CC CC_REGNUM))]
1921 [(set_attr "length" "2,2,4")
1922 (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1924 ;; ??? This is missing a sign extend from memory pattern to match the ld.h
1927 (define_expand "extendhisi2"
1928 [(parallel [(set (match_dup 2)
1929 (ashift:SI (match_operand:HI 1 "register_operand" "")
1931 (clobber (reg:CC CC_REGNUM))])
1932 (parallel [(set (match_operand:SI 0 "register_operand" "")
1933 (ashiftrt:SI (match_dup 2)
1935 (clobber (reg:CC CC_REGNUM))])]
1938 operands[1] = gen_lowpart (SImode, operands[1]);
1939 operands[2] = gen_reg_rtx (SImode);
1942 ;; ??? The extendqisi2 pattern should not emit shifts for v850e?
1944 (define_insn "*extendqisi_insn"
1945 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1946 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))
1947 (clobber (reg:CC CC_REGNUM))]
1953 [(set_attr "length" "2,2,4")
1954 (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1956 ;; ??? This is missing a sign extend from memory pattern to match the ld.b
1959 (define_expand "extendqisi2"
1960 [(parallel [(set (match_dup 2)
1961 (ashift:SI (match_operand:QI 1 "register_operand" "")
1963 (clobber (reg:CC CC_REGNUM))])
1964 (parallel [(set (match_operand:SI 0 "register_operand" "")
1965 (ashiftrt:SI (match_dup 2)
1967 (clobber (reg:CC CC_REGNUM))])]
1970 operands[1] = gen_lowpart (SImode, operands[1]);
1971 operands[2] = gen_reg_rtx (SImode);
1974 ;; ----------------------------------------------------------------------
1976 ;; ----------------------------------------------------------------------
1978 (define_insn "ashlsi3"
1979 [(set (match_operand:SI 0 "register_operand" "=r,r")
1981 (match_operand:SI 1 "register_operand" "0,0")
1982 (match_operand:SI 2 "nonmemory_operand" "r,N")))
1983 (clobber (reg:CC CC_REGNUM))]
1988 [(set_attr "length" "4,2")
1989 (set_attr "cc" "set_zn")])
1991 (define_insn "ashlsi3_v850e2"
1992 [(set (match_operand:SI 0 "register_operand" "=r")
1994 (match_operand:SI 1 "register_operand" "r")
1995 (match_operand:SI 2 "nonmemory_operand" "r")))
1996 (clobber (reg:CC CC_REGNUM))]
1999 [(set_attr "length" "4")
2000 (set_attr "cc" "set_znv")])
2002 (define_insn "lshrsi3"
2003 [(set (match_operand:SI 0 "register_operand" "=r,r")
2005 (match_operand:SI 1 "register_operand" "0,0")
2006 (match_operand:SI 2 "nonmemory_operand" "r,N")))
2007 (clobber (reg:CC CC_REGNUM))]
2012 [(set_attr "length" "4,2")
2013 (set_attr "cc" "set_zn")])
2015 (define_insn "lshrsi3_v850e2"
2016 [(set (match_operand:SI 0 "register_operand" "=r")
2018 (match_operand:SI 1 "register_operand" "r")
2019 (match_operand:SI 2 "nonmemory_operand" "r")))
2020 (clobber (reg:CC CC_REGNUM))]
2023 [(set_attr "length" "4")
2024 (set_attr "cc" "set_zn")])
2026 (define_insn "ashrsi3"
2027 [(set (match_operand:SI 0 "register_operand" "=r,r")
2029 (match_operand:SI 1 "register_operand" "0,0")
2030 (match_operand:SI 2 "nonmemory_operand" "r,N")))
2031 (clobber (reg:CC CC_REGNUM))]
2036 [(set_attr "length" "4,2")
2037 (set_attr "cc" "set_zn, set_zn")])
2039 (define_insn "ashrsi3_v850e2"
2040 [(set (match_operand:SI 0 "register_operand" "=r")
2042 (match_operand:SI 1 "register_operand" "r")
2043 (match_operand:SI 2 "nonmemory_operand" "r")))
2044 (clobber (reg:CC CC_REGNUM))]
2047 [(set_attr "length" "4")
2048 (set_attr "cc" "set_zn")])
2050 ;; ----------------------------------------------------------------------
2051 ;; FIND FIRST BIT INSTRUCTION
2052 ;; ----------------------------------------------------------------------
2054 (define_insn "ffssi2"
2055 [(set (match_operand:SI 0 "register_operand" "=r")
2056 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
2057 (clobber (reg:CC CC_REGNUM))]
2060 [(set_attr "length" "4")
2061 (set_attr "cc" "clobber")])
2063 ;; ----------------------------------------------------------------------
2064 ;; PROLOGUE/EPILOGUE
2065 ;; ----------------------------------------------------------------------
2066 (define_expand "prologue"
2074 (define_expand "epilogue"
2082 (define_insn "return_simple"
2086 [(set_attr "length" "2")
2087 (set_attr "cc" "none")])
2089 (define_insn "return_internal"
2094 [(set_attr "length" "2")
2095 (set_attr "cc" "none")])
2097 ;; ----------------------------------------------------------------------
2098 ;; v850e2V3 floating-point hardware support
2099 ;; ----------------------------------------------------------------------
2102 (define_insn "addsf3"
2103 [(set (match_operand:SF 0 "register_operand" "=r")
2104 (plus:SF (match_operand:SF 1 "register_operand" "r")
2105 (match_operand:SF 2 "register_operand" "r")))]
2108 [(set_attr "length" "4")
2109 (set_attr "cc" "none_0hit")
2110 (set_attr "type" "fpu")])
2112 (define_insn "adddf3"
2113 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2114 (plus:DF (match_operand:DF 1 "even_reg_operand" "r")
2115 (match_operand:DF 2 "even_reg_operand" "r")))]
2118 [(set_attr "length" "4")
2119 (set_attr "cc" "none_0hit")
2120 (set_attr "type" "fpu")])
2122 (define_insn "subsf3"
2123 [(set (match_operand:SF 0 "register_operand" "=r")
2124 (minus:SF (match_operand:SF 1 "register_operand" "r")
2125 (match_operand:SF 2 "register_operand" "r")))]
2128 [(set_attr "length" "4")
2129 (set_attr "cc" "none_0hit")
2130 (set_attr "type" "fpu")])
2132 (define_insn "subdf3"
2133 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2134 (minus:DF (match_operand:DF 1 "even_reg_operand" "r")
2135 (match_operand:DF 2 "even_reg_operand" "r")))]
2138 [(set_attr "length" "4")
2139 (set_attr "cc" "none_0hit")
2140 (set_attr "type" "fpu")])
2142 (define_insn "mulsf3"
2143 [(set (match_operand:SF 0 "register_operand" "=r")
2144 (mult:SF (match_operand:SF 1 "register_operand" "r")
2145 (match_operand:SF 2 "register_operand" "r")))]
2148 [(set_attr "length" "4")
2149 (set_attr "cc" "none_0hit")
2150 (set_attr "type" "fpu")])
2152 (define_insn "muldf3"
2153 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2154 (mult:DF (match_operand:DF 1 "even_reg_operand" "r")
2155 (match_operand:DF 2 "even_reg_operand" "r")))]
2158 [(set_attr "length" "4")
2159 (set_attr "cc" "none_0hit")
2160 (set_attr "type" "fpu")])
2162 (define_insn "divsf3"
2163 [(set (match_operand:SF 0 "register_operand" "=r")
2164 (div:SF (match_operand:SF 1 "register_operand" "r")
2165 (match_operand:SF 2 "register_operand" "r")))]
2168 [(set_attr "length" "4")
2169 (set_attr "cc" "none_0hit")
2170 (set_attr "type" "fpu")])
2172 (define_insn "divdf3"
2173 [(set (match_operand:DF 0 "register_operand" "=r")
2174 (div:DF (match_operand:DF 1 "even_reg_operand" "r")
2175 (match_operand:DF 2 "even_reg_operand" "r")))]
2178 [(set_attr "length" "4")
2179 (set_attr "cc" "none_0hit")
2180 (set_attr "type" "fpu")])
2182 (define_insn "minsf3"
2183 [(set (match_operand:SF 0 "register_operand" "=r")
2184 (smin:SF (match_operand:SF 1 "reg_or_0_operand" "r")
2185 (match_operand:SF 2 "reg_or_0_operand" "r")))]
2188 [(set_attr "length" "4")
2189 (set_attr "cc" "none_0hit")
2190 (set_attr "type" "fpu")])
2192 (define_insn "mindf3"
2193 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2194 (smin:DF (match_operand:DF 1 "even_reg_operand" "r")
2195 (match_operand:DF 2 "even_reg_operand" "r")))]
2198 [(set_attr "length" "4")
2199 (set_attr "cc" "none_0hit")
2200 (set_attr "type" "fpu")])
2202 (define_insn "maxsf3"
2203 [(set (match_operand:SF 0 "register_operand" "=r")
2204 (smax:SF (match_operand:SF 1 "reg_or_0_operand" "r")
2205 (match_operand:SF 2 "reg_or_0_operand" "r")))]
2208 [(set_attr "length" "4")
2209 (set_attr "cc" "none_0hit")
2210 (set_attr "type" "fpu")])
2212 (define_insn "maxdf3"
2213 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2214 (smax:DF (match_operand:DF 1 "even_reg_operand" "r")
2215 (match_operand:DF 2 "even_reg_operand" "r")))]
2218 [(set_attr "length" "4")
2219 (set_attr "cc" "none_0hit")
2220 (set_attr "type" "fpu")])
2222 (define_insn "abssf2"
2223 [(set (match_operand:SF 0 "register_operand" "=r")
2224 (abs:SF (match_operand:SF 1 "register_operand" "r")))]
2227 [(set_attr "length" "4")
2228 (set_attr "cc" "none_0hit")
2229 (set_attr "type" "fpu")])
2231 (define_insn "absdf2"
2232 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2233 (abs:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2236 [(set_attr "length" "4")
2237 (set_attr "cc" "none_0hit")
2238 (set_attr "type" "fpu")])
2240 (define_insn "negsf2"
2241 [(set (match_operand:SF 0 "register_operand" "=r")
2242 (neg:SF (match_operand:SF 1 "register_operand" "r")))]
2245 [(set_attr "length" "4")
2246 (set_attr "cc" "none_0hit")
2247 (set_attr "type" "fpu")])
2249 (define_insn "negdf2"
2250 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2251 (neg:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2254 [(set_attr "length" "4")
2255 (set_attr "cc" "none_0hit")
2256 (set_attr "type" "fpu")])
2259 (define_insn "sqrtsf2"
2260 [(set (match_operand:SF 0 "register_operand" "=r")
2261 (sqrt:SF (match_operand:SF 1 "register_operand" "r")))]
2264 [(set_attr "length" "4")
2265 (set_attr "cc" "none_0hit")
2266 (set_attr "type" "fpu")])
2268 (define_insn "sqrtdf2"
2269 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2270 (sqrt:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2273 [(set_attr "length" "4")
2274 (set_attr "cc" "none_0hit")
2275 (set_attr "type" "fpu")])
2278 (define_insn "fix_truncsfsi2"
2279 [(set (match_operand:SI 0 "register_operand" "=r")
2280 (fix:SI (match_operand:SF 1 "register_operand" "r")))]
2283 [(set_attr "length" "4")
2284 (set_attr "cc" "none_0hit")
2285 (set_attr "type" "fpu")])
2287 (define_insn "fixuns_truncsfsi2"
2288 [(set (match_operand:SI 0 "register_operand" "=r")
2289 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "r")))]
2292 [(set_attr "length" "4")
2293 (set_attr "cc" "none_0hit")
2294 (set_attr "type" "fpu")]
2297 (define_insn "fix_truncdfsi2"
2298 [(set (match_operand:SI 0 "register_operand" "=r")
2299 (fix:SI (match_operand:DF 1 "even_reg_operand" "r")))]
2302 [(set_attr "length" "4")
2303 (set_attr "cc" "none_0hit")
2304 (set_attr "type" "fpu")])
2306 (define_insn "fixuns_truncdfsi2"
2307 [(set (match_operand:SI 0 "register_operand" "=r")
2308 (unsigned_fix:SI (match_operand:DF 1 "even_reg_operand" "r")))]
2311 [(set_attr "length" "4")
2312 (set_attr "cc" "none_0hit")
2313 (set_attr "type" "fpu")]
2316 (define_insn "fix_truncsfdi2"
2317 [(set (match_operand:DI 0 "register_operand" "=r")
2318 (fix:DI (match_operand:SF 1 "register_operand" "r")))]
2321 [(set_attr "length" "4")
2322 (set_attr "cc" "none_0hit")
2323 (set_attr "type" "fpu")])
2325 (define_insn "fixuns_truncsfdi2"
2326 [(set (match_operand:DI 0 "register_operand" "=r")
2327 (unsigned_fix:DI (match_operand:SF 1 "register_operand" "r")))]
2330 [(set_attr "length" "4")
2331 (set_attr "cc" "none_0hit")
2332 (set_attr "type" "fpu")]
2335 (define_insn "fix_truncdfdi2"
2336 [(set (match_operand:DI 0 "register_operand" "=r")
2337 (fix:DI (match_operand:DF 1 "even_reg_operand" "r")))]
2340 [(set_attr "length" "4")
2341 (set_attr "cc" "none_0hit")
2342 (set_attr "type" "fpu")])
2344 (define_insn "fixuns_truncdfdi2"
2345 [(set (match_operand:DI 0 "register_operand" "=r")
2346 (unsigned_fix:DI (match_operand:DF 1 "even_reg_operand" "r")))]
2349 [(set_attr "length" "4")
2350 (set_attr "cc" "none_0hit")
2351 (set_attr "type" "fpu")]
2355 (define_insn "floatsisf2"
2356 [(set (match_operand:SF 0 "register_operand" "=r")
2357 (float:SF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2360 [(set_attr "length" "4")
2361 (set_attr "cc" "none_0hit")
2362 (set_attr "type" "fpu")])
2364 (define_insn "unsfloatsisf2"
2365 [(set (match_operand:SF 0 "register_operand" "=r")
2366 (unsigned_float:SF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2369 [(set_attr "length" "4")
2370 (set_attr "cc" "none_0hit")
2371 (set_attr "type" "fpu")])
2373 (define_insn "floatsidf2"
2374 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2375 (float:DF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2378 [(set_attr "length" "4")
2379 (set_attr "cc" "none_0hit")
2380 (set_attr "type" "fpu")])
2382 (define_insn "unsfloatsidf2"
2383 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2384 (unsigned_float:DF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2387 [(set_attr "length" "4")
2388 (set_attr "cc" "none_0hit")
2389 (set_attr "type" "fpu")])
2391 (define_insn "floatdisf2"
2392 [(set (match_operand:SF 0 "even_reg_operand" "=r")
2393 (float:SF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2396 [(set_attr "length" "4")
2397 (set_attr "cc" "none_0hit")
2398 (set_attr "type" "fpu")])
2400 (define_insn "unsfloatdisf2"
2401 [(set (match_operand:SF 0 "even_reg_operand" "=r")
2402 (unsigned_float:SF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2405 [(set_attr "length" "4")
2406 (set_attr "cc" "none_0hit")
2407 (set_attr "type" "fpu")])
2409 (define_insn "floatdidf2"
2410 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2411 (float:DF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2414 [(set_attr "length" "4")
2415 (set_attr "cc" "none_0hit")
2416 (set_attr "type" "fpu")])
2418 (define_insn "unsfloatdidf2"
2419 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2420 (unsigned_float:DF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2423 [(set_attr "length" "4")
2424 (set_attr "cc" "none_0hit")
2425 (set_attr "type" "fpu")])
2427 ;; single-float -> double-float
2428 (define_insn "extendsfdf2"
2429 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2431 (match_operand:SF 1 "reg_or_0_operand" "rI")))]
2434 [(set_attr "length" "4")
2435 (set_attr "cc" "none_0hit")
2436 (set_attr "type" "fpu")])
2438 ;; double-float -> single-float
2439 (define_insn "truncdfsf2"
2440 [(set (match_operand:SF 0 "register_operand" "=r")
2442 (match_operand:DF 1 "even_reg_operand" "r")))]
2445 [(set_attr "length" "4")
2446 (set_attr "cc" "none_0hit")
2447 (set_attr "type" "fpu")])
2450 ;; ---------------- special insns
2454 (define_insn "recipsf2"
2455 [(set (match_operand:SF 0 "register_operand" "=r")
2456 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2457 (match_operand:SF 2 "register_operand" "r")))]
2460 [(set_attr "length" "4")
2461 (set_attr "cc" "none_0hit")
2462 (set_attr "type" "fpu")])
2464 (define_insn "recipdf2"
2465 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2466 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2467 (match_operand:DF 2 "even_reg_operand" "r")))]
2470 [(set_attr "length" "4")
2471 (set_attr "cc" "none_0hit")
2472 (set_attr "type" "fpu")])
2474 ;;; reciprocal of square-root
2475 (define_insn "rsqrtsf2"
2476 [(set (match_operand:SF 0 "register_operand" "=r")
2477 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2478 (sqrt:SF (match_operand:SF 2 "register_operand" "r"))))]
2481 [(set_attr "length" "4")
2482 (set_attr "cc" "none_0hit")
2483 (set_attr "type" "fpu")])
2485 (define_insn "rsqrtdf2"
2486 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2487 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2488 (sqrt:DF (match_operand:DF 2 "even_reg_operand" "r"))))]
2491 [(set_attr "length" "4")
2492 (set_attr "cc" "none_0hit")
2493 (set_attr "type" "fpu")])
2495 ;; Note: The FPU-2.0 (ie pre e3v5) versions of these routines do not actually
2496 ;; need operand 4 to be the same as operand 0. But the FPU-2.0 versions are
2497 ;; also deprecated so the loss of flexibility is unimportant.
2500 (define_insn "fmasf4"
2501 [(set (match_operand:SF 0 "register_operand" "=r")
2502 (fma:SF (match_operand:SF 1 "register_operand" "r")
2503 (match_operand:SF 2 "register_operand" "r")
2504 (match_operand:SF 3 "register_operand" "0")))]
2506 { return TARGET_V850E3V5_UP ? "fmaf.s %1, %2, %0" : "maddf.s %2, %1, %3, %0"; }
2507 [(set_attr "length" "4")
2508 (set_attr "cc" "none_0hit")
2509 (set_attr "type" "fpu")])
2511 ;;; multiply-subtract
2512 (define_insn "fmssf4"
2513 [(set (match_operand:SF 0 "register_operand" "=r")
2514 (fma:SF (match_operand:SF 1 "register_operand" "r")
2515 (match_operand:SF 2 "register_operand" "r")
2516 (neg:SF (match_operand:SF 3 "register_operand" "0"))))]
2518 { return TARGET_V850E3V5_UP ? "fmsf.s %1, %2, %0" : "msubf.s %2, %1, %3, %0"; }
2519 [(set_attr "length" "4")
2520 (set_attr "cc" "none_0hit")
2521 (set_attr "type" "fpu")])
2523 ;;; negative-multiply-add
2524 (define_insn "fnmasf4"
2525 [(set (match_operand:SF 0 "register_operand" "=r")
2526 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "r")
2527 (match_operand:SF 2 "register_operand" "r")
2528 (match_operand:SF 3 "register_operand" "0"))))]
2530 { return TARGET_V850E3V5_UP ? "fnmaf.s %1, %2, %0" : "nmaddf.s %2, %1, %3, %0"; }
2531 [(set_attr "length" "4")
2532 (set_attr "cc" "none_0hit")
2533 (set_attr "type" "fpu")])
2535 ;; negative-multiply-subtract
2536 (define_insn "fnmssf4"
2537 [(set (match_operand:SF 0 "register_operand" "=r")
2538 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "r")
2539 (match_operand:SF 2 "register_operand" "r")
2540 (neg:SF (match_operand:SF 3 "register_operand" "0")))))]
2542 { return TARGET_V850E3V5_UP ? "fnmsf.s %1, %2, %0" : "nmsubf.s %2, %1, %3, %0"; }
2543 [(set_attr "length" "4")
2544 (set_attr "cc" "none_0hit")
2545 (set_attr "type" "fpu")])
2547 ; ---------------- comparison/conditionals
2551 (define_insn "cmpsf_le_insn"
2552 [(set (reg:CC_FPU_LE FCC_REGNUM)
2553 (compare:CC_FPU_LE (match_operand:SF 0 "register_operand" "r")
2554 (match_operand:SF 1 "register_operand" "r")))]
2556 "cmpf.s le, %z0, %z1"
2557 [(set_attr "length" "4")
2558 (set_attr "cc" "none_0hit")
2559 (set_attr "type" "fpu")])
2561 (define_insn "cmpsf_lt_insn"
2562 [(set (reg:CC_FPU_LT FCC_REGNUM)
2563 (compare:CC_FPU_LT (match_operand:SF 0 "register_operand" "r")
2564 (match_operand:SF 1 "register_operand" "r")))]
2566 "cmpf.s lt, %z0, %z1"
2567 [(set_attr "length" "4")
2568 (set_attr "cc" "none_0hit")
2569 (set_attr "type" "fpu")])
2571 (define_insn "cmpsf_ge_insn"
2572 [(set (reg:CC_FPU_GE FCC_REGNUM)
2573 (compare:CC_FPU_GE (match_operand:SF 0 "register_operand" "r")
2574 (match_operand:SF 1 "register_operand" "r")))]
2576 "cmpf.s le, %z1, %z0"
2577 [(set_attr "length" "4")
2578 (set_attr "cc" "none_0hit")
2579 (set_attr "type" "fpu")])
2581 (define_insn "cmpsf_gt_insn"
2582 [(set (reg:CC_FPU_GT FCC_REGNUM)
2583 (compare:CC_FPU_GT (match_operand:SF 0 "register_operand" "r")
2584 (match_operand:SF 1 "register_operand" "r")))]
2586 "cmpf.s lt, %z1, %z0"
2587 [(set_attr "length" "4")
2588 (set_attr "cc" "none_0hit")
2589 (set_attr "type" "fpu")])
2591 (define_insn "cmpsf_eq_insn"
2592 [(set (reg:CC_FPU_EQ FCC_REGNUM)
2593 (compare:CC_FPU_EQ (match_operand:SF 0 "register_operand" "r")
2594 (match_operand:SF 1 "register_operand" "r")))]
2596 "cmpf.s eq, %z0, %z1"
2597 [(set_attr "length" "4")
2598 (set_attr "cc" "none_0hit")
2599 (set_attr "type" "fpu")])
2603 (define_insn "cmpdf_le_insn"
2604 [(set (reg:CC_FPU_LE FCC_REGNUM)
2605 (compare:CC_FPU_LE (match_operand:DF 0 "even_reg_operand" "r")
2606 (match_operand:DF 1 "even_reg_operand" "r")))]
2608 "cmpf.d le, %z0, %z1"
2609 [(set_attr "length" "4")
2610 (set_attr "cc" "none_0hit")
2611 (set_attr "type" "fpu")])
2613 (define_insn "cmpdf_lt_insn"
2614 [(set (reg:CC_FPU_LT FCC_REGNUM)
2615 (compare:CC_FPU_LT (match_operand:DF 0 "even_reg_operand" "r")
2616 (match_operand:DF 1 "even_reg_operand" "r")))]
2618 "cmpf.d lt, %z0, %z1"
2619 [(set_attr "length" "4")
2620 (set_attr "cc" "none_0hit")
2621 (set_attr "type" "fpu")])
2623 (define_insn "cmpdf_ge_insn"
2624 [(set (reg:CC_FPU_GE FCC_REGNUM)
2625 (compare:CC_FPU_GE (match_operand:DF 0 "even_reg_operand" "r")
2626 (match_operand:DF 1 "even_reg_operand" "r")))]
2628 "cmpf.d le, %z1, %z0"
2629 [(set_attr "length" "4")
2630 (set_attr "cc" "none_0hit")
2631 (set_attr "type" "fpu")])
2633 (define_insn "cmpdf_gt_insn"
2634 [(set (reg:CC_FPU_GT FCC_REGNUM)
2635 (compare:CC_FPU_GT (match_operand:DF 0 "even_reg_operand" "r")
2636 (match_operand:DF 1 "even_reg_operand" "r")))]
2638 "cmpf.d lt, %z1, %z0"
2639 [(set_attr "length" "4")
2640 (set_attr "cc" "none_0hit")
2641 (set_attr "type" "fpu")])
2643 (define_insn "cmpdf_eq_insn"
2644 [(set (reg:CC_FPU_EQ FCC_REGNUM)
2645 (compare:CC_FPU_EQ (match_operand:DF 0 "even_reg_operand" "r")
2646 (match_operand:DF 1 "even_reg_operand" "r")))]
2648 "cmpf.d eq, %z0, %z1"
2649 [(set_attr "length" "4")
2650 (set_attr "cc" "none_0hit")
2651 (set_attr "type" "fpu")])
2654 ;; Transfer a v850e2v3 fcc to the Z bit of CC0 (this is necessary to do a
2655 ;; conditional branch based on a floating-point compare)
2658 (define_insn "trfsr"
2659 [(set (match_operand 0 "" "") (match_operand 1 "" ""))]
2661 && GET_MODE(operands[0]) == GET_MODE(operands[1])
2662 && GET_CODE(operands[0]) == REG && REGNO (operands[0]) == CC_REGNUM
2663 && GET_CODE(operands[1]) == REG && REGNO (operands[1]) == FCC_REGNUM
2664 && (GET_MODE(operands[0]) == CC_FPU_LEmode
2665 || GET_MODE(operands[0]) == CC_FPU_GEmode
2666 || GET_MODE(operands[0]) == CC_FPU_LTmode
2667 || GET_MODE(operands[0]) == CC_FPU_GTmode
2668 || GET_MODE(operands[0]) == CC_FPU_EQmode
2669 || GET_MODE(operands[0]) == CC_FPU_NEmode)"
2671 [(set_attr "length" "4")
2672 (set_attr "cc" "set_z")
2673 (set_attr "type" "fpu")])
2676 ;; Floating-point conditional moves for the v850e2v3.
2679 ;; The actual v850e2v3 conditional move instructions
2681 (define_insn "movsfcc_z_insn"
2682 [(set (match_operand:SF 0 "register_operand" "=r")
2684 (match_operand 3 "v850_float_z_comparison_operator" "")
2685 (match_operand:SF 1 "reg_or_0_operand" "rIG")
2686 (match_operand:SF 2 "reg_or_0_operand" "rIG")))]
2688 "cmovf.s 0,%z1,%z2,%0"
2689 [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2691 (define_insn "movsfcc_nz_insn"
2692 [(set (match_operand:SF 0 "register_operand" "=r")
2694 (match_operand 3 "v850_float_nz_comparison_operator" "")
2695 (match_operand:SF 1 "reg_or_0_operand" "rIG")
2696 (match_operand:SF 2 "reg_or_0_operand" "rIG")))]
2698 "cmovf.s 0,%z2,%z1,%0"
2699 [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2701 (define_insn "movdfcc_z_insn"
2702 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2704 (match_operand 3 "v850_float_z_comparison_operator" "")
2705 (match_operand:DF 1 "even_reg_operand" "r")
2706 (match_operand:DF 2 "even_reg_operand" "r")))]
2708 "cmovf.d 0,%z1,%z2,%0"
2709 [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2711 (define_insn "movdfcc_nz_insn"
2712 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2714 (match_operand 3 "v850_float_nz_comparison_operator" "")
2715 (match_operand:DF 1 "even_reg_operand" "r")
2716 (match_operand:DF 2 "even_reg_operand" "r")))]
2718 "cmovf.d 0,%z2,%z1,%0"
2719 [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2721 (define_insn "movedfcc_z_zero"
2722 [(set (match_operand:DF 0 "register_operand" "=r")
2724 (match_operand 3 "v850_float_z_comparison_operator" "")
2725 (match_operand:DF 1 "reg_or_0_operand" "rIG")
2726 (match_operand:DF 2 "reg_or_0_operand" "rIG")))]
2728 "cmovf.s 0,%z1,%z2,%0 ; cmovf.s 0,%Z1,%Z2,%R0"
2729 [(set_attr "length" "8")
2730 (set_attr "cc" "clobber")]) ;; ??? or none_0hit
2732 (define_insn "movedfcc_nz_zero"
2733 [(set (match_operand:DF 0 "register_operand" "=r")
2735 (match_operand 3 "v850_float_nz_comparison_operator" "")
2736 (match_operand:DF 1 "reg_or_0_operand" "rIG")
2737 (match_operand:DF 2 "reg_or_0_operand" "rIG")))]
2739 "cmovf.s 0,%z2,%z1,%0 ; cmovf.s 0,%Z2,%Z1,%R0"
2740 [(set_attr "length" "8")
2741 (set_attr "cc" "clobber")]) ;; ??? or none_0hit
2744 ;; ----------------------------------------------------------------------
2745 ;; HELPER INSTRUCTIONS for saving the prologue and epilogue registers
2746 ;; ----------------------------------------------------------------------
2748 ;; This pattern will match a stack adjust RTX followed by any number of push
2749 ;; RTXs. These RTXs will then be turned into a suitable call to a worker
2753 ;; Actually, convert the RTXs into a PREPARE instruction.
2757 [(match_parallel 0 "pattern_is_ok_for_prepare"
2759 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2760 (set (mem:SI (plus:SI (reg:SI 3)
2761 (match_operand:SI 2 "immediate_operand" "i")))
2762 (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
2763 "TARGET_PROLOG_FUNCTION && (TARGET_V850E_UP)"
2765 return construct_prepare_instruction (operands[0]);
2767 [(set_attr "length" "4")
2768 (set_attr "cc" "clobber")])
2771 [(match_parallel 0 "pattern_is_ok_for_prologue"
2773 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2774 (set (mem:SI (plus:SI (reg:SI 3)
2775 (match_operand:SI 2 "immediate_operand" "i")))
2776 (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
2777 "TARGET_PROLOG_FUNCTION"
2779 return construct_save_jarl (operands[0]);
2781 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
2783 (const_string "4")))
2784 (set_attr "cc" "clobber")])
2787 ;; Actually, turn the RTXs into a DISPOSE instruction.
2790 [(match_parallel 0 "pattern_is_ok_for_dispose"
2793 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2794 (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
2795 (mem:SI (plus:SI (reg:SI 3)
2796 (match_operand:SI 3 "immediate_operand" "i"))))])]
2797 "TARGET_PROLOG_FUNCTION && (TARGET_V850E_UP)"
2799 return construct_dispose_instruction (operands[0]);
2801 [(set_attr "length" "4")
2802 (set_attr "cc" "clobber")])
2804 ;; This pattern will match a return RTX followed by any number of pop RTXs
2805 ;; and possible a stack adjustment as well. These RTXs will be turned into
2806 ;; a suitable call to a worker function.
2809 [(match_parallel 0 "pattern_is_ok_for_epilogue"
2812 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2813 (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
2814 (mem:SI (plus:SI (reg:SI 3)
2815 (match_operand:SI 3 "immediate_operand" "i"))))])]
2816 "TARGET_PROLOG_FUNCTION"
2818 return construct_restore_jr (operands[0]);
2820 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
2822 (const_string "4")))
2823 (set_attr "cc" "clobber")])
2825 ;; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION.
2826 (define_insn "callt_save_interrupt"
2827 [(unspec_volatile [(const_int 0)] 2)]
2828 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2829 ;; The CALLT instruction stores the next address of CALLT to CTPC register
2830 ;; without saving its previous value. So if the interrupt handler
2831 ;; or its caller could possibly execute the CALLT insn, save_interrupt
2832 ;; MUST NOT be called via CALLT.
2834 output_asm_insn ("addi -28, sp, sp", operands);
2835 output_asm_insn ("st.w r1, 24[sp]", operands);
2836 output_asm_insn ("st.w r10, 12[sp]", operands);
2837 output_asm_insn ("st.w r11, 16[sp]", operands);
2838 output_asm_insn ("stsr ctpc, r10", operands);
2839 output_asm_insn ("st.w r10, 20[sp]", operands);
2840 output_asm_insn ("stsr ctpsw, r10", operands);
2841 output_asm_insn ("st.w r10, 24[sp]", operands);
2842 output_asm_insn ("callt ctoff(__callt_save_interrupt)", operands);
2845 [(set_attr "length" "26")
2846 (set_attr "cc" "clobber")])
2848 (define_insn "callt_return_interrupt"
2849 [(unspec_volatile [(const_int 0)] 3)]
2850 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2851 "callt ctoff(__callt_return_interrupt)"
2852 [(set_attr "length" "2")
2853 (set_attr "cc" "clobber")])
2855 (define_insn "save_interrupt"
2856 [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -20)))
2857 (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 30))
2858 (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 4))
2859 (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))
2860 (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 10))
2861 (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 11))]
2864 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2865 return "addi -20,sp,sp \; st.w r11,16[sp] \; st.w r10,12[sp] \; jarl __save_interrupt,r10";
2868 output_asm_insn ("addi -20, sp, sp", operands);
2869 output_asm_insn ("st.w r11, 16[sp]", operands);
2870 output_asm_insn ("st.w r10, 12[sp]", operands);
2871 output_asm_insn ("st.w ep, 0[sp]", operands);
2872 output_asm_insn ("st.w gp, 4[sp]", operands);
2873 output_asm_insn ("st.w r1, 8[sp]", operands);
2874 output_asm_insn ("movhi hi(__ep), r0, ep", operands);
2875 output_asm_insn ("movea lo(__ep), ep, ep", operands);
2876 output_asm_insn ("movhi hi(__gp), r0, gp", operands);
2877 output_asm_insn ("movea lo(__gp), gp, gp", operands);
2881 [(set (attr "length")
2882 (if_then_else (match_test "TARGET_LONG_CALLS")
2885 (set_attr "cc" "clobber")])
2887 ;; Restore r1, r4, r10, and return from the interrupt
2888 (define_insn "return_interrupt"
2890 (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 20)))
2891 (set (reg:SI 11) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))
2892 (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
2893 (set (reg:SI 1) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
2894 (set (reg:SI 4) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))
2895 (set (reg:SI 30) (mem:SI (reg:SI 3)))]
2898 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2899 return "jr __return_interrupt";
2902 output_asm_insn ("ld.w 0[sp], ep", operands);
2903 output_asm_insn ("ld.w 4[sp], gp", operands);
2904 output_asm_insn ("ld.w 8[sp], r1", operands);
2905 output_asm_insn ("ld.w 12[sp], r10", operands);
2906 output_asm_insn ("ld.w 16[sp], r11", operands);
2907 output_asm_insn ("addi 20, sp, sp", operands);
2908 output_asm_insn ("reti", operands);
2912 [(set (attr "length")
2913 (if_then_else (match_test "TARGET_LONG_CALLS")
2916 (set_attr "cc" "clobber")])
2918 ;; Save all registers except for the registers saved in save_interrupt when
2919 ;; an interrupt function makes a call.
2920 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2921 ;; all of memory. This blocks insns from being moved across this point.
2922 ;; This is needed because the rest of the compiler is not ready to handle
2923 ;; insns this complicated.
2925 (define_insn "callt_save_all_interrupt"
2926 [(unspec_volatile [(const_int 0)] 0)]
2927 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2928 "callt ctoff(__callt_save_all_interrupt)"
2929 [(set_attr "length" "2")
2930 (set_attr "cc" "none")])
2932 (define_insn "save_all_interrupt"
2933 [(unspec_volatile [(const_int 0)] 0)]
2936 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2937 return "jarl __save_all_interrupt,r10";
2939 output_asm_insn ("addi -120, sp, sp", operands);
2943 output_asm_insn ("mov ep, r1", operands);
2944 output_asm_insn ("mov sp, ep", operands);
2945 output_asm_insn ("sst.w r31, 116[ep]", operands);
2946 output_asm_insn ("sst.w r2, 112[ep]", operands);
2947 output_asm_insn ("sst.w gp, 108[ep]", operands);
2948 output_asm_insn ("sst.w r6, 104[ep]", operands);
2949 output_asm_insn ("sst.w r7, 100[ep]", operands);
2950 output_asm_insn ("sst.w r8, 96[ep]", operands);
2951 output_asm_insn ("sst.w r9, 92[ep]", operands);
2952 output_asm_insn ("sst.w r11, 88[ep]", operands);
2953 output_asm_insn ("sst.w r12, 84[ep]", operands);
2954 output_asm_insn ("sst.w r13, 80[ep]", operands);
2955 output_asm_insn ("sst.w r14, 76[ep]", operands);
2956 output_asm_insn ("sst.w r15, 72[ep]", operands);
2957 output_asm_insn ("sst.w r16, 68[ep]", operands);
2958 output_asm_insn ("sst.w r17, 64[ep]", operands);
2959 output_asm_insn ("sst.w r18, 60[ep]", operands);
2960 output_asm_insn ("sst.w r19, 56[ep]", operands);
2961 output_asm_insn ("sst.w r20, 52[ep]", operands);
2962 output_asm_insn ("sst.w r21, 48[ep]", operands);
2963 output_asm_insn ("sst.w r22, 44[ep]", operands);
2964 output_asm_insn ("sst.w r23, 40[ep]", operands);
2965 output_asm_insn ("sst.w r24, 36[ep]", operands);
2966 output_asm_insn ("sst.w r25, 32[ep]", operands);
2967 output_asm_insn ("sst.w r26, 28[ep]", operands);
2968 output_asm_insn ("sst.w r27, 24[ep]", operands);
2969 output_asm_insn ("sst.w r28, 20[ep]", operands);
2970 output_asm_insn ("sst.w r29, 16[ep]", operands);
2971 output_asm_insn ("mov r1, ep", operands);
2975 output_asm_insn ("st.w r31, 116[sp]", operands);
2976 output_asm_insn ("st.w r2, 112[sp]", operands);
2977 output_asm_insn ("st.w gp, 108[sp]", operands);
2978 output_asm_insn ("st.w r6, 104[sp]", operands);
2979 output_asm_insn ("st.w r7, 100[sp]", operands);
2980 output_asm_insn ("st.w r8, 96[sp]", operands);
2981 output_asm_insn ("st.w r9, 92[sp]", operands);
2982 output_asm_insn ("st.w r11, 88[sp]", operands);
2983 output_asm_insn ("st.w r12, 84[sp]", operands);
2984 output_asm_insn ("st.w r13, 80[sp]", operands);
2985 output_asm_insn ("st.w r14, 76[sp]", operands);
2986 output_asm_insn ("st.w r15, 72[sp]", operands);
2987 output_asm_insn ("st.w r16, 68[sp]", operands);
2988 output_asm_insn ("st.w r17, 64[sp]", operands);
2989 output_asm_insn ("st.w r18, 60[sp]", operands);
2990 output_asm_insn ("st.w r19, 56[sp]", operands);
2991 output_asm_insn ("st.w r20, 52[sp]", operands);
2992 output_asm_insn ("st.w r21, 48[sp]", operands);
2993 output_asm_insn ("st.w r22, 44[sp]", operands);
2994 output_asm_insn ("st.w r23, 40[sp]", operands);
2995 output_asm_insn ("st.w r24, 36[sp]", operands);
2996 output_asm_insn ("st.w r25, 32[sp]", operands);
2997 output_asm_insn ("st.w r26, 28[sp]", operands);
2998 output_asm_insn ("st.w r27, 24[sp]", operands);
2999 output_asm_insn ("st.w r28, 20[sp]", operands);
3000 output_asm_insn ("st.w r29, 16[sp]", operands);
3005 [(set (attr "length")
3006 (if_then_else (match_test "TARGET_LONG_CALLS")
3010 (set_attr "cc" "clobber")])
3012 (define_insn "_save_all_interrupt"
3013 [(unspec_volatile [(const_int 0)] 0)]
3014 "TARGET_V850 && ! TARGET_LONG_CALLS"
3015 "jarl __save_all_interrupt,r10"
3016 [(set_attr "length" "4")
3017 (set_attr "cc" "clobber")])
3019 ;; Restore all registers saved when an interrupt function makes a call.
3020 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3021 ;; all of memory. This blocks insns from being moved across this point.
3022 ;; This is needed because the rest of the compiler is not ready to handle
3023 ;; insns this complicated.
3025 (define_insn "callt_restore_all_interrupt"
3026 [(unspec_volatile [(const_int 0)] 1)]
3027 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
3028 "callt ctoff(__callt_restore_all_interrupt)"
3029 [(set_attr "length" "2")
3030 (set_attr "cc" "none")])
3032 (define_insn "restore_all_interrupt"
3033 [(unspec_volatile [(const_int 0)] 1)]
3036 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
3037 return "jarl __restore_all_interrupt,r10";
3041 output_asm_insn ("mov ep, r1", operands);
3042 output_asm_insn ("mov sp, ep", operands);
3043 output_asm_insn ("sld.w 116[ep], r31", operands);
3044 output_asm_insn ("sld.w 112[ep], r2", operands);
3045 output_asm_insn ("sld.w 108[ep], gp", operands);
3046 output_asm_insn ("sld.w 104[ep], r6", operands);
3047 output_asm_insn ("sld.w 100[ep], r7", operands);
3048 output_asm_insn ("sld.w 96[ep], r8", operands);
3049 output_asm_insn ("sld.w 92[ep], r9", operands);
3050 output_asm_insn ("sld.w 88[ep], r11", operands);
3051 output_asm_insn ("sld.w 84[ep], r12", operands);
3052 output_asm_insn ("sld.w 80[ep], r13", operands);
3053 output_asm_insn ("sld.w 76[ep], r14", operands);
3054 output_asm_insn ("sld.w 72[ep], r15", operands);
3055 output_asm_insn ("sld.w 68[ep], r16", operands);
3056 output_asm_insn ("sld.w 64[ep], r17", operands);
3057 output_asm_insn ("sld.w 60[ep], r18", operands);
3058 output_asm_insn ("sld.w 56[ep], r19", operands);
3059 output_asm_insn ("sld.w 52[ep], r20", operands);
3060 output_asm_insn ("sld.w 48[ep], r21", operands);
3061 output_asm_insn ("sld.w 44[ep], r22", operands);
3062 output_asm_insn ("sld.w 40[ep], r23", operands);
3063 output_asm_insn ("sld.w 36[ep], r24", operands);
3064 output_asm_insn ("sld.w 32[ep], r25", operands);
3065 output_asm_insn ("sld.w 28[ep], r26", operands);
3066 output_asm_insn ("sld.w 24[ep], r27", operands);
3067 output_asm_insn ("sld.w 20[ep], r28", operands);
3068 output_asm_insn ("sld.w 16[ep], r29", operands);
3069 output_asm_insn ("mov r1, ep", operands);
3073 output_asm_insn ("ld.w 116[sp], r31", operands);
3074 output_asm_insn ("ld.w 112[sp], r2", operands);
3075 output_asm_insn ("ld.w 108[sp], gp", operands);
3076 output_asm_insn ("ld.w 104[sp], r6", operands);
3077 output_asm_insn ("ld.w 100[sp], r7", operands);
3078 output_asm_insn ("ld.w 96[sp], r8", operands);
3079 output_asm_insn ("ld.w 92[sp], r9", operands);
3080 output_asm_insn ("ld.w 88[sp], r11", operands);
3081 output_asm_insn ("ld.w 84[sp], r12", operands);
3082 output_asm_insn ("ld.w 80[sp], r13", operands);
3083 output_asm_insn ("ld.w 76[sp], r14", operands);
3084 output_asm_insn ("ld.w 72[sp], r15", operands);
3085 output_asm_insn ("ld.w 68[sp], r16", operands);
3086 output_asm_insn ("ld.w 64[sp], r17", operands);
3087 output_asm_insn ("ld.w 60[sp], r18", operands);
3088 output_asm_insn ("ld.w 56[sp], r19", operands);
3089 output_asm_insn ("ld.w 52[sp], r20", operands);
3090 output_asm_insn ("ld.w 48[sp], r21", operands);
3091 output_asm_insn ("ld.w 44[sp], r22", operands);
3092 output_asm_insn ("ld.w 40[sp], r23", operands);
3093 output_asm_insn ("ld.w 36[sp], r24", operands);
3094 output_asm_insn ("ld.w 32[sp], r25", operands);
3095 output_asm_insn ("ld.w 28[sp], r26", operands);
3096 output_asm_insn ("ld.w 24[sp], r27", operands);
3097 output_asm_insn ("ld.w 20[sp], r28", operands);
3098 output_asm_insn ("ld.w 16[sp], r29", operands);
3100 output_asm_insn ("addi 120, sp, sp", operands);
3103 [(set (attr "length")
3104 (if_then_else (match_test "TARGET_LONG_CALLS")
3108 (set_attr "cc" "clobber")])
3110 (define_insn "_restore_all_interrupt"
3111 [(unspec_volatile [(const_int 0)] 1)]
3112 "TARGET_V850 && ! TARGET_LONG_CALLS"
3113 "jarl __restore_all_interrupt,r10"
3114 [(set_attr "length" "4")
3115 (set_attr "cc" "clobber")])