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
35 ;; Data movement (load, store, register copy) does not modify condition
36 ;; codes. But there is no way to add two registers together without
37 ;; modifying the condition codes.
39 ;; So we do not expose the condition codes until after reload. The
40 ;; general approach is to have a define_insn_and_split for the basic
41 ;; operation with no condition codes in the pattern (to give the
42 ;; optimizers maximal freedom). The splitter adds a clobber of the
43 ;; condition codes after reload. There is a distinct pattern which
44 ;; sets the condition codes.
46 ;; As noted, data movement does not affect condition codes.
48 ;; Arithmetic generally set the codes in the expected ways, with mul
49 ;; instructions being a notable outlier. div instructions generally
50 ;; do the right thing, except when the output registers are the same
51 ;; when the flags do not get set. We just assume they're clobbered
52 ;; for div instructions to avoid MD bloat with marginal benefit
54 ;; The bit manipulation instructions (clr1, not1, set1) set condition
55 ;; codes, but not in a useful way (they're set to the prior status of
56 ;; the bit). So we just model those as clobbers. tst1 does set the
57 ;; condition codes in a useful way. We could perhaps do better with
58 ;; these by noting they only modify the Z flag, it doesn't seem worth
61 ;; Byte swaps seem to change the condition codes, but I haven't tried
64 ;; I have no documentation on the rotate instructions. They likely
65 ;; set the condition codes, but I've left them as clobbers for now.
68 ;; The size of instructions in bytes.
70 ;;---------------------------------------------------------------------------
75 [(ZERO_REGNUM 0) ; constant zero
76 (SP_REGNUM 3) ; Stack Pointer
77 (GP_REGNUM 4) ; GP Pointer
78 (RV_REGNUM 10) ; Return value register
79 (EP_REGNUM 30) ; EP pointer
80 (LP_REGNUM 31) ; Return address register
81 (CC_REGNUM 32) ; Condition code pseudo register
82 (FCC_REGNUM 33) ; Floating Condition code pseudo register
86 (define_c_enum "unspec" [
92 (define_attr "length" ""
95 (define_attr "long_calls" "yes,no"
96 (const (if_then_else (symbol_ref "TARGET_LONG_CALLS")
98 (const_string "no"))))
100 ;; Types of instructions (for scheduling purposes).
102 (define_attr "type" "load,store,bit1,mult,macc,div,fpu,single,other"
103 (const_string "other"))
105 (define_attr "cpu" "none,v850,v850e,v850e1,v850e2,v850e2v3,v850e3v5"
106 (cond [(match_test "TARGET_V850")
107 (const_string "v850")
108 (match_test "TARGET_V850E")
109 (const_string "v850e")
110 (match_test "TARGET_V850E1")
111 (const_string "v850e1")
112 (match_test "TARGET_V850E2")
113 (const_string "v850e2")
114 (match_test "TARGET_V850E2V3")
115 (const_string "v850e2v3")
116 (match_test "TARGET_V850E3V5")
117 (const_string "v850e3v5")]
118 (const_string "none")))
121 ;; Function units for the V850. As best as I can tell, there's
122 ;; a traditional memory load/use stall as well as a stall if
123 ;; the result of a multiply is used too early.
125 (define_insn_reservation "v850_other" 1
126 (eq_attr "type" "other")
128 (define_insn_reservation "v850_mult" 2
129 (eq_attr "type" "mult")
131 (define_insn_reservation "v850_memory" 2
132 (eq_attr "type" "load")
135 (include "predicates.md")
136 (include "constraints.md")
138 ;; ----------------------------------------------------------------------
140 ;; ----------------------------------------------------------------------
143 (define_expand "movdi"
144 [(set (match_operand:DI 0 "general_operand")
145 (match_operand:DI 1 "general_operand"))]
148 /* One of the ops has to be in a register or 0. */
149 if (!register_operand (operand0, DImode)
150 && !register_operand (operand1, DImode))
151 operands[1] = copy_to_mode_reg (DImode, operand1);
153 if (register_operand (operand0, DImode)
154 && (CONST_INT_P (operands[1]) || CONST_DOUBLE_P (operands[1])))
158 for (i = 0; i < UNITS_PER_WORD * 2; i += UNITS_PER_WORD)
159 emit_move_insn (simplify_gen_subreg (SImode, operands[0], DImode, i),
160 simplify_gen_subreg (SImode, operands[1], DImode, i));
166 (define_insn "*movdi_internal"
167 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,e!r,m")
168 (match_operand:DI 1 "nonimmediate_operand" "r,m,e!r"))]
170 || (register_operand (operands[0], DImode) && register_operand (operands[1], DImode))"
171 { return v850_gen_movdi (operands); }
172 [(set_attr "length" "4,12,12")
173 (set_attr "type" "other,load,store")])
177 (define_expand "movqi"
178 [(set (match_operand:QI 0 "general_operand" "")
179 (match_operand:QI 1 "general_operand" ""))]
182 /* One of the ops has to be in a register or 0 */
183 if (!register_operand (operand0, QImode)
184 && !reg_or_0_operand (operand1, QImode))
185 operands[1] = copy_to_mode_reg (QImode, operand1);
188 (define_insn "*movqi_internal"
189 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,Q,r,m,m")
190 (match_operand:QI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
191 "register_operand (operands[0], QImode)
192 || reg_or_0_operand (operands[1], QImode)"
194 return output_move_single (operands);
196 [(set_attr "length" "2,4,2,2,4,4,4")
197 (set_attr "type" "other,other,load,other,load,store,store")])
201 (define_expand "movhi"
202 [(set (match_operand:HI 0 "general_operand" "")
203 (match_operand:HI 1 "general_operand" ""))]
206 /* One of the ops has to be in a register or 0 */
207 if (!register_operand (operand0, HImode)
208 && !reg_or_0_operand (operand1, HImode))
209 operands[1] = copy_to_mode_reg (HImode, operand1);
212 (define_insn "*movhi_internal"
213 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,Q,r,m,m")
214 (match_operand:HI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
215 "register_operand (operands[0], HImode)
216 || reg_or_0_operand (operands[1], HImode)"
218 return output_move_single (operands);
220 [(set_attr "length" "2,4,2,2,4,4,4")
221 (set_attr "type" "other,other,load,other,load,store,store")])
225 (define_insn "*movsi_high"
226 [(set (match_operand:SI 0 "register_operand" "=r")
227 (high:SI (match_operand 1 "immediate_operand" "i")))]
230 [(set_attr "length" "4")
231 (set_attr "type" "other")])
233 (define_insn "*movsi_lo"
234 [(set (match_operand:SI 0 "register_operand" "=r")
235 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
236 (match_operand:SI 2 "immediate_operand" "i")))]
239 [(set_attr "length" "4")
240 (set_attr "type" "other")])
242 (define_expand "movsi"
243 [(set (match_operand:SI 0 "general_operand" "")
244 (match_operand:SI 1 "general_operand" ""))]
247 /* One of the ops has to be in a register or 0 */
248 if (!register_operand (operand0, SImode)
249 && !reg_or_0_operand (operand1, SImode))
250 operands[1] = copy_to_mode_reg (SImode, operand1);
252 /* Some constants, as well as symbolic operands
253 must be done with HIGH & LO_SUM patterns. */
254 if (CONSTANT_P (operands[1])
255 && GET_CODE (operands[1]) != HIGH
256 && ! (TARGET_V850E_UP)
257 && !special_symbolref_operand (operands[1], VOIDmode)
258 && !(GET_CODE (operands[1]) == CONST_INT
259 && (CONST_OK_FOR_J (INTVAL (operands[1]))
260 || CONST_OK_FOR_K (INTVAL (operands[1]))
261 || CONST_OK_FOR_L (INTVAL (operands[1])))))
265 if (reload_in_progress || reload_completed)
268 temp = gen_reg_rtx (SImode);
270 emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (SImode, operand1)));
271 emit_insn (gen_rtx_SET (operand0,
272 gen_rtx_LO_SUM (SImode, temp, operand1)));
277 ;; This is the same as the following pattern, except that it includes
278 ;; support for arbitrary 32-bit immediates.
280 ;; ??? This always loads addresses using hilo. If the only use of this address
281 ;; was in a load/store, then we would get smaller code if we only loaded the
282 ;; upper part with hi, and then put the lower part in the load/store insn.
284 (define_insn "*movsi_internal_v850e"
285 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,Q,r,r,m,m,r")
286 (match_operand:SI 1 "general_operand" "Jr,K,L,Q,Ir,m,R,r,I,i"))]
288 && (register_operand (operands[0], SImode)
289 || reg_or_0_operand (operands[1], SImode))"
291 return output_move_single (operands);
293 [(set_attr "length" "2,4,4,2,2,4,4,4,4,6")
294 (set_attr "type" "other,other,other,load,other,load,other,store,store,other")])
296 (define_insn "*movsi_internal"
297 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,Q,r,r,m,m")
298 (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))]
299 "register_operand (operands[0], SImode)
300 || reg_or_0_operand (operands[1], SImode)"
302 return output_move_single (operands);
304 [(set_attr "length" "2,4,4,2,2,4,4,4,4")
305 (set_attr "type" "other,other,other,load,other,load,store,store,other")])
307 (define_insn "*movsf_internal"
308 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,Q,r,m,m,r")
309 (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))]
310 "register_operand (operands[0], SFmode)
311 || reg_or_0_operand (operands[1], SFmode)"
313 return output_move_single (operands);
315 [(set_attr "length" "2,4,4,8,2,2,4,4,4,8")
316 (set_attr "type" "other,other,other,other,load,other,load,store,store,other")])
318 ;; ----------------------------------------------------------------------
320 ;; ----------------------------------------------------------------------
322 (define_insn "*v850_tst1"
323 [(set (reg:CCZ CC_REGNUM)
324 (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
326 (match_operand:QI 1 "const_int_operand" "n"))
330 [(set_attr "length" "4")])
332 ;; This replaces ld.b;sar;andi with tst1;setf nz.
333 ;; Should there be variants for HI or SI modes?
335 (define_insn_and_split ""
336 [(set (match_operand:SI 0 "register_operand" "")
337 (compare (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
339 (match_operand 2 "const_int_operand" ""))
344 [(set (reg:CCZ CC_REGNUM) (compare (zero_extract:SI (match_dup 1)
348 (set (match_dup 0) (ne:SI (reg:CCZ CC_REGNUM) (const_int 0)))])
350 (define_expand "cbranchsi4"
353 (match_operator 0 "comparison_operator"
354 [(match_operand:SI 1 "register_operand")
355 (match_operand:SI 2 "reg_or_int5_operand")])
356 (label_ref (match_operand 3 "" ""))
360 (define_insn "cmpsi_insn"
361 [(set (reg:CC CC_REGNUM)
362 (compare (match_operand:SI 0 "register_operand" "r,r")
363 (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
366 [(set_attr "length" "2,2")])
368 (define_insn_and_split "cbranchsf4"
370 (if_then_else (match_operator 0 "ordered_comparison_operator"
371 [(match_operand:SF 1 "register_operand" "r")
372 (match_operand:SF 2 "register_operand" "r")])
373 (label_ref (match_operand 3 ""))
378 [(set (match_dup 4) (match_dup 5))
380 (if_then_else (match_dup 6)
381 (label_ref (match_dup 3))
384 /* This will generate the comparison insn at the start of
385 the sequence and get us the right mode to use for our
386 condition code registers. */
387 enum machine_mode mode
388 = v850_gen_float_compare (GET_CODE (operands[0]),
389 GET_MODE (operands[1]),
390 operands[1], operands[2]);
391 /* We want operands referring to CC_REGNUM and FCC_REGNUM
393 operands[4] = gen_rtx_REG (mode, CC_REGNUM);
394 operands[5] = gen_rtx_REG (mode, FCC_REGNUM);
395 if (mode == CC_FPU_NEmode)
396 operands[6] = gen_rtx_NE (mode, operands[4], const0_rtx);
398 operands[6] = gen_rtx_EQ (mode, operands[4], const0_rtx);
401 (define_insn "cstoresf4"
402 [(set (match_operand:SI 0 "register_operand" "=r")
403 (match_operator:SI 1 "ordered_comparison_operator"
404 [(match_operand:SF 2 "register_operand" "r")
405 (match_operand:SF 3 "register_operand" "r")]))
406 (clobber (reg:CC CC_REGNUM))]
409 if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
410 return "cmpf.s %c1, %z2, %z3 ; trfsr ; setf nz, %0";
411 if (GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE)
412 return "cmpf.s %c1, %z2, %z3 ; trfsr ; setf z, %0";
413 if (GET_CODE (operands[1]) == EQ)
414 return "cmpf.s eq, %z2, %z3 ; trfsr ; setf z, %0";
415 if (GET_CODE (operands[1]) == NE)
416 return "cmpf.s neq, %z2, %z3 ; trfsr ; setf nz, %0";
419 [(set_attr "length" "12")
420 (set_attr "type" "fpu")])
422 (define_insn_and_split "cbranchdf4"
424 (if_then_else (match_operator 0 "ordered_comparison_operator"
425 [(match_operand:DF 1 "even_reg_operand" "r")
426 (match_operand:DF 2 "even_reg_operand" "r")])
427 (label_ref (match_operand 3 ""))
432 ;; How to get the mode here?
433 [(set (match_dup 4) (match_dup 5))
435 (if_then_else (match_dup 6)
436 (label_ref (match_dup 3))
439 /* This will generate the comparison insn at the start of
440 the sequence and get us the right mode to use for our
441 condition code registers. */
442 enum machine_mode mode
443 = v850_gen_float_compare (GET_CODE (operands[0]),
444 GET_MODE (operands[1]),
445 operands[1], operands[2]);
446 PUT_MODE (operands[0], mode);
447 /* We want operands referring to CC_REGNUM and FCC_REGNUM
449 operands[4] = gen_rtx_REG (mode, CC_REGNUM);
450 operands[5] = gen_rtx_REG (mode, FCC_REGNUM);
451 if (mode == CC_FPU_NEmode)
452 operands[6] = gen_rtx_NE (mode, operands[4], const0_rtx);
454 operands[6] = gen_rtx_EQ (mode, operands[4], const0_rtx);
457 (define_insn "cstoredf4"
458 [(set (match_operand:SI 0 "register_operand" "=r")
459 (match_operator:SI 1 "ordered_comparison_operator"
460 [(match_operand:DF 2 "even_reg_operand" "r")
461 (match_operand:DF 3 "even_reg_operand" "r")]))
462 (clobber (reg:CC CC_REGNUM))]
465 if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
466 return "cmpf.d %c1, %z2, %z3 ; trfsr ; setf nz, %0";
467 if (GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE)
468 return "cmpf.d %c1, %z2, %z3 ; trfsr ; setf z, %0";
469 if (GET_CODE (operands[1]) == EQ)
470 return "cmpf.d eq, %z2, %z3 ; trfsr ; setf z ,%0";
471 if (GET_CODE (operands[1]) == NE)
472 return "cmpf.d neq, %z2, %z3 ; trfsr ; setf nz, %0";
475 [(set_attr "length" "12")
476 (set_attr "type" "fpu")])
478 ;; ----------------------------------------------------------------------
480 ;; ----------------------------------------------------------------------
482 (define_insn_and_split "addsi3"
483 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
484 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
485 (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))]
489 [(parallel [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
490 (clobber (reg:CC CC_REGNUM))])])
492 (define_insn "addsi3_clobber_flags"
493 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
494 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
495 (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))
496 (clobber (reg:CC CC_REGNUM))]
502 [(set_attr "length" "2,4,4")])
504 (define_insn "addsi3_set_flags"
505 [(set (reg:CCNZ CC_REGNUM)
506 (compare:CCNZ (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
507 (match_operand:SI 2 "nonmemory_operand" "rJ,K,U"))
509 (set (match_operand:SI 0 "register_operand" "=r,r,r")
510 (plus:SI (match_dup 1) (match_dup 2)))]
516 [(set_attr "length" "2,4,4")])
518 ;; ----------------------------------------------------------------------
519 ;; SUBTRACT INSTRUCTIONS
520 ;; ----------------------------------------------------------------------
521 (define_insn_and_split "subsi3"
522 [(set (match_operand:SI 0 "register_operand" "=r,r")
523 (minus:SI (match_operand:SI 1 "register_operand" "0,r")
524 (match_operand:SI 2 "register_operand" "r,0")))]
528 [(parallel [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
529 (clobber (reg:CC CC_REGNUM))])])
531 (define_insn "subsi3_clobber_flags"
532 [(set (match_operand:SI 0 "register_operand" "=r,r")
533 (minus:SI (match_operand:SI 1 "register_operand" "0,r")
534 (match_operand:SI 2 "register_operand" "r,0")))
535 (clobber (reg:CC CC_REGNUM))]
540 [(set_attr "length" "2,2")])
542 (define_insn "*subsi3_set_flags"
543 [(set (reg:CCNZ CC_REGNUM)
544 (compare:CCNZ (minus:SI (match_operand:SI 1 "register_operand" "0,r")
545 (match_operand:SI 2 "nonmemory_operand" "r,0"))
547 (set (match_operand:SI 0 "register_operand" "=r,r")
548 (minus:SI (match_dup 1) (match_dup 2)))]
553 [(set_attr "length" "2,2")])
555 (define_insn_and_split "negsi2"
556 [(set (match_operand:SI 0 "register_operand" "=r")
557 (neg:SI (match_operand:SI 1 "register_operand" "0")))]
561 [(parallel [(set (match_dup 0) (neg:SI (match_dup 1)))
562 (clobber (reg:CC CC_REGNUM))])])
564 (define_insn "negsi2_clobber_flags"
565 [(set (match_operand:SI 0 "register_operand" "=r")
566 (neg:SI (match_operand:SI 1 "register_operand" "0")))
567 (clobber (reg:CC CC_REGNUM))]
570 [(set_attr "length" "2")])
572 (define_insn "*negsi2_set_flags"
573 [(set (reg:CCNZ CC_REGNUM)
574 (compare:CCNZ (neg:SI (match_operand:SI 1 "register_operand" "0"))
576 (set (match_operand:SI 0 "register_operand" "=r")
577 (neg:SI (match_dup 1)))]
580 [(set_attr "length" "2")])
582 ;; ----------------------------------------------------------------------
583 ;; MULTIPLY INSTRUCTIONS
584 ;; ----------------------------------------------------------------------
586 (define_expand "mulhisi3"
587 [(set (match_operand:SI 0 "register_operand" "")
589 (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
590 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
593 if (GET_CODE (operands[2]) == CONST_INT)
595 emit_insn (gen_mulhisi3_internal2 (operands[0], operands[1], operands[2]));
600 (define_insn "*mulhisi3_internal1"
601 [(set (match_operand:SI 0 "register_operand" "=r")
603 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
604 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
607 [(set_attr "length" "2")
608 (set_attr "type" "mult")])
610 (define_insn "mulhisi3_internal2"
611 [(set (match_operand:SI 0 "register_operand" "=r,r")
613 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
614 (match_operand:HI 2 "const_int_operand" "J,K")))]
619 [(set_attr "length" "2,4")
620 (set_attr "type" "mult")])
622 ;; ??? The scheduling info is probably wrong.
624 ;; ??? This instruction can also generate the 32-bit highpart, but using it
625 ;; may increase code size counter to the desired result.
627 ;; ??? This instructions can also give a DImode result.
629 ;; ??? There is unsigned version, but it matters only for the DImode/highpart
632 (define_insn "mulsi3"
633 [(set (match_operand:SI 0 "register_operand" "=r")
634 (mult:SI (match_operand:SI 1 "register_operand" "%0")
635 (match_operand:SI 2 "reg_or_int9_operand" "rO")))]
638 [(set_attr "length" "4")
639 (set_attr "type" "mult")])
641 ;; ----------------------------------------------------------------------
642 ;; DIVIDE INSTRUCTIONS
643 ;; ----------------------------------------------------------------------
645 ;; ??? These insns do set the Z/N condition codes, except that they are based
646 ;; on only one of the two results, so it doesn't seem to make sense to use
649 ;; ??? The scheduling info is probably wrong.
651 (define_insn "divmodsi4"
652 [(set (match_operand:SI 0 "register_operand" "=r")
653 (div:SI (match_operand:SI 1 "register_operand" "0")
654 (match_operand:SI 2 "register_operand" "r")))
655 (set (match_operand:SI 3 "register_operand" "=r")
656 (mod:SI (match_dup 1)
658 (clobber (reg:CC CC_REGNUM))]
661 if (TARGET_V850E2_UP)
662 return "divq %2,%0,%3";
664 return "div %2,%0,%3";
666 [(set_attr "length" "4")
667 (set_attr "type" "div")])
669 (define_insn "udivmodsi4"
670 [(set (match_operand:SI 0 "register_operand" "=r")
671 (udiv:SI (match_operand:SI 1 "register_operand" "0")
672 (match_operand:SI 2 "register_operand" "r")))
673 (set (match_operand:SI 3 "register_operand" "=r")
674 (umod:SI (match_dup 1)
676 (clobber (reg:CC CC_REGNUM))]
679 if (TARGET_V850E2_UP)
680 return "divqu %2,%0,%3";
682 return "divu %2,%0,%3";
684 [(set_attr "length" "4")
685 (set_attr "type" "div")])
687 ;; ??? There is a 2 byte instruction for generating only the quotient.
688 ;; However, it isn't clear how to compute the length field correctly.
690 (define_insn "divmodhi4"
691 [(set (match_operand:HI 0 "register_operand" "=r")
692 (div:HI (match_operand:HI 1 "register_operand" "0")
693 (match_operand:HI 2 "register_operand" "r")))
694 (set (match_operand:HI 3 "register_operand" "=r")
695 (mod:HI (match_dup 1)
697 (clobber (reg:CC CC_REGNUM))]
699 "sxh %0\\n\\tdivh %2,%0,%3"
700 [(set_attr "length" "6")
701 (set_attr "type" "div")])
703 ;; The half word needs to be zero/sign extended to 32 bits before doing
704 ;; the division/modulo operation.
706 (define_insn "udivmodhi4"
707 [(set (match_operand:HI 0 "register_operand" "=r")
708 (udiv:HI (match_operand:HI 1 "register_operand" "0")
709 (match_operand:HI 2 "register_operand" "r")))
710 (set (match_operand:HI 3 "register_operand" "=r")
711 (umod:HI (match_dup 1)
713 (clobber (reg:CC CC_REGNUM))]
715 "zxh %0\\n\\ndivhu %2,%0,%3"
716 [(set_attr "length" "6")
717 (set_attr "type" "div")])
719 ;; ----------------------------------------------------------------------
721 ;; ----------------------------------------------------------------------
723 (define_insn "*v850_clr1_1"
724 [(set (match_operand:QI 0 "memory_operand" "=m")
726 (and:SI (subreg:SI (match_dup 0) 0)
727 (match_operand:QI 1 "not_power_of_two_operand" "")) 0))
728 (clobber (reg:CC CC_REGNUM))]
732 xoperands[0] = operands[0];
733 xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
734 output_asm_insn ("clr1 %M1,%0", xoperands);
737 [(set_attr "length" "4")
738 (set_attr "type" "bit1")])
740 (define_insn "*v850_clr1_2"
741 [(set (match_operand:HI 0 "indirect_operand" "=m")
743 (and:SI (subreg:SI (match_dup 0) 0)
744 (match_operand:HI 1 "not_power_of_two_operand" "")) 0))
745 (clobber (reg:CC CC_REGNUM))]
748 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
751 xoperands[0] = gen_rtx_MEM (QImode,
752 plus_constant (Pmode, XEXP (operands[0], 0),
754 xoperands[1] = GEN_INT (log2 % 8);
755 output_asm_insn ("clr1 %1,%0", xoperands);
758 [(set_attr "length" "4")
759 (set_attr "type" "bit1")])
761 (define_insn "*v850_clr1_3"
762 [(set (match_operand:SI 0 "indirect_operand" "=m")
763 (and:SI (match_dup 0)
764 (match_operand:SI 1 "not_power_of_two_operand" "")))
765 (clobber (reg:CC CC_REGNUM))]
768 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
771 xoperands[0] = gen_rtx_MEM (QImode,
772 plus_constant (Pmode, XEXP (operands[0], 0),
774 xoperands[1] = GEN_INT (log2 % 8);
775 output_asm_insn ("clr1 %1,%0", xoperands);
778 [(set_attr "length" "4")
779 (set_attr "type" "bit1")])
781 (define_insn_and_split "andsi3"
782 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
783 (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
784 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
788 [(parallel [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
789 (clobber (reg:CC CC_REGNUM))])])
791 (define_insn "andsi3_clobber_flags"
792 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
793 (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
794 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
795 (clobber (reg:CC CC_REGNUM))]
801 [(set_attr "length" "2,2,4")])
803 (define_insn "andsi3_set_flags"
804 [(set (reg:CC CC_REGNUM)
805 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
806 (match_operand:SI 2 "nonmemory_operand" "r,I,M"))
808 (set (match_operand:SI 0 "register_operand" "=r,r,r")
809 (and:SI (match_dup 1) (match_dup 2)))]
815 [(set_attr "length" "2,2,4")])
817 ;; ----------------------------------------------------------------------
819 ;; ----------------------------------------------------------------------
821 (define_insn "*v850_set1_1"
822 [(set (match_operand:QI 0 "memory_operand" "=m")
823 (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
824 (match_operand 1 "power_of_two_operand" "")) 0))
825 (clobber (reg:CC CC_REGNUM))]
828 [(set_attr "length" "4")
829 (set_attr "type" "bit1")])
831 (define_insn "*v850_set1_2"
832 [(set (match_operand:HI 0 "indirect_operand" "=m")
833 (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
834 (match_operand 1 "power_of_two_operand" "")) 0))]
837 int log2 = exact_log2 (INTVAL (operands[1]));
840 return "set1 %M1,%0";
844 xoperands[0] = gen_rtx_MEM (QImode,
845 plus_constant (Pmode, XEXP (operands[0], 0),
847 xoperands[1] = GEN_INT (log2 % 8);
848 output_asm_insn ("set1 %1,%0", xoperands);
852 [(set_attr "length" "4")
853 (set_attr "type" "bit1")])
855 (define_insn "*v850_set1_3"
856 [(set (match_operand:SI 0 "indirect_operand" "=m")
857 (ior:SI (match_dup 0)
858 (match_operand 1 "power_of_two_operand" "")))
859 (clobber (reg:CC CC_REGNUM))]
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 "type" "bit1")])
880 (define_insn_and_split "iorsi3"
881 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
882 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
883 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
887 [(parallel [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
888 (clobber (reg:CC CC_REGNUM))])])
890 (define_insn "iorsi3_clobber_flags"
891 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
892 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
893 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
894 (clobber (reg:CC CC_REGNUM))]
900 [(set_attr "length" "2,2,4")])
902 (define_insn "*iorsi3_set_flags"
903 [(set (reg:CC CC_REGNUM)
904 (compare:CC (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
905 (match_operand:SI 2 "nonmemory_operand" "r,I,M"))
907 (set (match_operand:SI 0 "register_operand" "=r,r,r")
908 (ior:SI (match_dup 1) (match_dup 2)))]
914 [(set_attr "length" "2,2,4")])
916 ;; ----------------------------------------------------------------------
918 ;; ----------------------------------------------------------------------
920 (define_insn "*v850_not1_1"
921 [(set (match_operand:QI 0 "memory_operand" "=m")
922 (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0)
923 (match_operand 1 "power_of_two_operand" "")) 0))
924 (clobber (reg:CC CC_REGNUM))]
927 [(set_attr "length" "4")
928 (set_attr "type" "bit1")])
930 (define_insn "*v850_not1_2"
931 [(set (match_operand:HI 0 "indirect_operand" "=m")
932 (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
933 (match_operand 1 "power_of_two_operand" "")) 0))]
936 int log2 = exact_log2 (INTVAL (operands[1]));
939 return "not1 %M1,%0";
943 xoperands[0] = gen_rtx_MEM (QImode,
944 plus_constant (Pmode, XEXP (operands[0], 0),
946 xoperands[1] = GEN_INT (log2 % 8);
947 output_asm_insn ("not1 %1,%0", xoperands);
951 [(set_attr "length" "4")
952 (set_attr "type" "bit1")])
954 (define_insn "*v850_not1_3"
955 [(set (match_operand:SI 0 "indirect_operand" "=m")
956 (xor:SI (match_dup 0)
957 (match_operand 1 "power_of_two_operand" "")))
958 (clobber (reg:CC CC_REGNUM))]
961 int log2 = exact_log2 (INTVAL (operands[1]));
964 return "not1 %M1,%0";
968 xoperands[0] = gen_rtx_MEM (QImode,
969 plus_constant (Pmode, XEXP (operands[0], 0),
971 xoperands[1] = GEN_INT (log2 % 8);
972 output_asm_insn ("not1 %1,%0", xoperands);
976 [(set_attr "length" "4")
977 (set_attr "type" "bit1")])
979 (define_insn_and_split "xorsi3"
980 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
981 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
982 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
986 [(parallel [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
987 (clobber (reg:CC CC_REGNUM))])])
989 (define_insn "xorsi3_clobber_flags"
990 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
991 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
992 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
993 (clobber (reg:CC CC_REGNUM))]
999 [(set_attr "length" "2,2,4")])
1001 (define_insn "*xorsi3_set_flags"
1002 [(set (reg:CC CC_REGNUM)
1003 (compare:CC (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1004 (match_operand:SI 2 "nonmemory_operand" "r,I,M"))
1006 (set (match_operand:SI 0 "register_operand" "=r,r,r")
1007 (xor:SI (match_dup 1) (match_dup 2)))]
1013 [(set_attr "length" "2,2,4")])
1016 ;; ----------------------------------------------------------------------
1018 ;; ----------------------------------------------------------------------
1020 (define_insn_and_split "one_cmplsi2"
1021 [(set (match_operand:SI 0 "register_operand" "=r")
1022 (not:SI (match_operand:SI 1 "register_operand" "r")))]
1026 [(parallel [(set (match_dup 0) (not:SI (match_dup 1)))
1027 (clobber (reg:CC CC_REGNUM))])])
1030 (define_insn "one_cmplsi2_clobber_flags"
1031 [(set (match_operand:SI 0 "register_operand" "=r")
1032 (not:SI (match_operand:SI 1 "register_operand" "r")))
1033 (clobber (reg:CC CC_REGNUM))]
1036 [(set_attr "length" "2")])
1038 (define_insn "*one_cmplsi2_set_flags"
1039 [(set (reg:CC CC_REGNUM)
1040 (compare:CC (not:SI (match_operand:SI 1 "register_operand" "r"))
1042 (set (match_operand:SI 0 "register_operand" "=r")
1043 (not:SI (match_dup 1)))]
1046 [(set_attr "length" "2")])
1048 ;; -----------------------------------------------------------------
1050 ;; -----------------------------------------------------------------
1052 ;; ??? Is it worth defining insv and extv for the V850 series?!?
1054 ;; An insv pattern would be useful, but does not get used because
1055 ;; store_bit_field never calls insv when storing a constant value into a
1056 ;; single-bit bitfield.
1058 ;; extv/extzv patterns would be useful, but do not get used because
1059 ;; optimize_bitfield_compare in fold-const usually converts single
1060 ;; bit extracts into an AND with a mask.
1063 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1064 (match_operand:SI 1 "immediate_operand" "n")
1065 (match_operand:SI 2 "immediate_operand" "n"))
1066 (match_operand:SI 3 "register_operand" "r"))
1067 (clobber (reg:CC CC_REGNUM))]
1068 "TARGET_V850E3V5_UP"
1069 "bins %3, %2, %1, %0"
1070 [(set_attr "length" "4")])
1072 ;; -----------------------------------------------------------------
1074 ;; -----------------------------------------------------------------
1076 (define_insn_and_split "*cbranchsi4_insn"
1078 (if_then_else (match_operator 0 "comparison_operator"
1079 [(match_operand:SI 1 "register_operand" "r")
1080 (match_operand:SI 2 "reg_or_int5_operand" "rJ")])
1081 (label_ref (match_operand 3 "" ""))
1086 [(set (reg:CC CC_REGNUM)
1087 (compare:CC (match_dup 1) (match_dup 2)))
1089 (if_then_else (match_op_dup 0
1090 [(reg:CC CC_REGNUM) (const_int 0)])
1091 (label_ref (match_dup 3))
1096 (define_insn_and_split "cstoresi4"
1097 [(set (match_operand:SI 0 "register_operand" "=r")
1098 (match_operator:SI 1 "comparison_operator"
1099 [(match_operand:SI 2 "register_operand" "r")
1100 (match_operand:SI 3 "reg_or_int5_operand" "rJ")]))]
1104 [(set (reg:CC CC_REGNUM)
1105 (compare:CC (match_dup 2) (match_dup 3)))
1106 (set (match_dup 0) (match_op_dup 1
1107 [(reg:CC CC_REGNUM) (const_int 0)]))]
1110 (define_insn "*setcc_insn"
1111 [(set (match_operand:SI 0 "register_operand" "=r")
1112 (match_operator:SI 1 "comparison_operator"
1113 [(reg:CC CC_REGNUM) (const_int 0)]))]
1116 [(set_attr "length" "4")])
1118 (define_insn "set_z_insn"
1119 [(set (match_operand:SI 0 "register_operand" "=r")
1120 (match_operand 1 "v850_float_z_comparison_operator" ""))]
1121 "TARGET_V850E2V3_UP"
1123 [(set_attr "length" "4")])
1125 (define_insn "set_nz_insn"
1126 [(set (match_operand:SI 0 "register_operand" "=r")
1127 (match_operand 1 "v850_float_nz_comparison_operator" ""))]
1128 "TARGET_V850E2V3_UP"
1130 [(set_attr "length" "4")])
1132 ;; ----------------------------------------------------------------------
1133 ;; CONDITIONAL MOVE INSTRUCTIONS
1134 ;; ----------------------------------------------------------------------
1136 ;; Instructions using cc0 aren't allowed to have input reloads, so we must
1137 ;; hide the fact that this instruction uses cc0. We do so by including the
1138 ;; compare instruction inside it.
1140 (define_expand "movsicc"
1141 [(set (match_operand:SI 0 "register_operand" "=r")
1143 (match_operand 1 "comparison_operator")
1144 (match_operand:SI 2 "reg_or_const_operand" "rJ")
1145 (match_operand:SI 3 "reg_or_const_operand" "rI")))]
1148 /* Make sure that we have an integer comparison... */
1149 if (GET_MODE (XEXP (operands[1], 0)) != CCmode
1150 && GET_MODE (XEXP (operands[1], 0)) != SImode)
1153 if ((GET_CODE (operands[2]) == CONST_INT
1154 && GET_CODE (operands[3]) == CONST_INT))
1156 int o2 = INTVAL (operands[2]);
1157 int o3 = INTVAL (operands[3]);
1159 if (o2 == 1 && o3 == 0)
1161 if (o3 == 1 && o2 == 0)
1163 if (o2 == 0 && (o3 < -16 || o3 > 15) && exact_log2 (o3) >= 0)
1164 FAIL; /* setf + shift */
1165 if (o3 == 0 && (o2 < -16 || o2 > 15) && exact_log2 (o2) >=0)
1166 FAIL; /* setf + shift */
1168 operands[2] = copy_to_mode_reg (SImode, operands[2]);
1170 operands[3] = copy_to_mode_reg (SImode, operands[3]);
1174 if (GET_CODE (operands[2]) != REG)
1175 operands[2] = copy_to_mode_reg (SImode,operands[2]);
1176 if (GET_CODE (operands[3]) != REG)
1177 operands[3] = copy_to_mode_reg (SImode, operands[3]);
1181 (define_insn "movsicc_normal_cc"
1182 [(set (match_operand:SI 0 "register_operand" "=r")
1184 (match_operator 1 "comparison_operator"
1185 [(reg:CC CC_REGNUM) (const_int 0)])
1186 (match_operand:SI 2 "reg_or_int5_operand" "rJ")
1187 (match_operand:SI 3 "reg_or_0_operand" "rI")))]
1188 "reload_completed && (TARGET_V850E_UP)"
1189 "cmov %c1,%2,%z3,%0";
1190 [(set_attr "length" "6")])
1192 (define_insn "movsicc_reversed_cc"
1193 [(set (match_operand:SI 0 "register_operand" "=r")
1195 (match_operator 1 "comparison_operator"
1196 [(reg:CC CC_REGNUM) (const_int 0)])
1197 (match_operand:SI 2 "reg_or_0_operand" "rI")
1198 (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
1199 "reload_completed && (TARGET_V850E_UP)"
1200 "cmov %C1,%3,%z2,%0"
1201 [(set_attr "length" "6")])
1203 (define_insn_and_split "*movsicc_normal"
1204 [(set (match_operand:SI 0 "register_operand" "=r")
1206 (match_operator 1 "comparison_operator"
1207 [(match_operand:SI 4 "register_operand" "r")
1208 (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
1209 (match_operand:SI 2 "reg_or_int5_operand" "rJ")
1210 (match_operand:SI 3 "reg_or_0_operand" "rI")))]
1214 [(set (reg:CC CC_REGNUM)
1215 (compare:CC (match_dup 4) (match_dup 5)))
1217 (if_then_else:SI (match_op_dup 1
1218 [(reg:CC CC_REGNUM) (const_int 0)])
1219 (match_dup 2) (match_dup 3)))])
1222 (define_insn_and_split "*movsicc_reversed"
1223 [(set (match_operand:SI 0 "register_operand" "=r")
1225 (match_operator 1 "comparison_operator"
1226 [(match_operand:SI 4 "register_operand" "r")
1227 (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
1228 (match_operand:SI 2 "reg_or_int5_operand" "rI")
1229 (match_operand:SI 3 "reg_or_0_operand" "rJ")))]
1233 [(set (reg:CC CC_REGNUM)
1234 (compare:CC (match_dup 4) (match_dup 5)))
1236 (if_then_else:SI (match_op_dup 1
1237 [(reg:CC CC_REGNUM) (const_int 0)])
1238 (match_dup 2) (match_dup 3)))])
1240 ;; We could expose the setting of the condition codes here.
1241 (define_insn "*movsicc_tst1"
1242 [(set (match_operand:SI 0 "register_operand" "=r")
1244 (match_operator 1 "comparison_operator"
1246 (match_operand:QI 2 "memory_operand" "m")
1248 (match_operand 3 "const_int_operand" "n"))
1250 (match_operand:SI 4 "reg_or_int5_operand" "rJ")
1251 (match_operand:SI 5 "reg_or_0_operand" "rI")))
1252 (clobber (reg:CC CC_REGNUM))]
1254 "tst1 %3,%2 ; cmov %c1,%4,%z5,%0"
1255 [(set_attr "length" "8")])
1257 ;; We could expose the setting of the condition codes here.
1258 (define_insn "*movsicc_tst1_reversed"
1259 [(set (match_operand:SI 0 "register_operand" "=r")
1261 (match_operator 1 "comparison_operator"
1263 (match_operand:QI 2 "memory_operand" "m")
1265 (match_operand 3 "const_int_operand" "n"))
1267 (match_operand:SI 4 "reg_or_0_operand" "rI")
1268 (match_operand:SI 5 "reg_or_int5_operand" "rJ")))
1269 (clobber (reg:CC CC_REGNUM))]
1271 "tst1 %3,%2 ; cmov %C1,%5,%z4,%0"
1272 [(set_attr "length" "8")])
1274 ;; Matching for sasf requires combining 4 instructions, so we provide a
1275 ;; dummy pattern to match the first 3, which will always be turned into the
1276 ;; second pattern by subsequent combining. As above, we must include the
1277 ;; comparison to avoid input reloads in an insn using cc0.
1279 ;; We could expose the setting of the condition codes here.
1280 ;; However, I haven't seen this pattern used, so I'm not going
1282 (define_insn "*sasf"
1283 [(set (match_operand:SI 0 "register_operand" "=r")
1285 (match_operator 1 "comparison_operator"
1286 [(match_operand:SI 3 "register_operand" "r")
1287 (match_operand:SI 4 "reg_or_int5_operand" "rJ")])
1288 (ashift:SI (match_operand:SI 2 "register_operand" "0")
1290 (clobber (reg:CC CC_REGNUM))]
1292 "cmp %4,%3 ; sasf %c1,%0"
1293 [(set_attr "length" "6")])
1296 [(set (match_operand:SI 0 "register_operand" "")
1298 (match_operator 1 "comparison_operator"
1299 [(match_operand:SI 4 "register_operand" "")
1300 (match_operand:SI 5 "reg_or_int5_operand" "")])
1301 (match_operand:SI 2 "const_int_operand" "")
1302 (match_operand:SI 3 "const_int_operand" "")))
1303 (clobber (reg:CC CC_REGNUM))]
1305 && ((INTVAL (operands[2]) ^ INTVAL (operands[3])) == 1)
1306 && ((INTVAL (operands[2]) + INTVAL (operands[3])) != 1)
1307 && (GET_CODE (operands[5]) == CONST_INT
1308 || REGNO (operands[0]) != REGNO (operands[5]))
1309 && REGNO (operands[0]) != REGNO (operands[4])"
1310 [(set (match_dup 0) (match_dup 6))
1311 (parallel [(set (match_dup 0)
1312 (ior:SI (match_op_dup 7 [(match_dup 4) (match_dup 5)])
1313 (ashift:SI (match_dup 0) (const_int 1))))
1314 (clobber (reg:CC CC_REGNUM))])]
1316 operands[6] = GEN_INT (INTVAL (operands[2]) >> 1);
1317 if (INTVAL (operands[2]) & 0x1)
1318 operands[7] = operands[1];
1320 operands[7] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
1321 GET_MODE (operands[1]),
1322 XEXP (operands[1], 0), XEXP (operands[1], 1));
1325 ;; ---------------------------------------------------------------------
1326 ;; BYTE SWAP INSTRUCTIONS
1327 ;; ---------------------------------------------------------------------
1328 (define_expand "rotlhi3"
1329 [(parallel [(set (match_operand:HI 0 "register_operand" "")
1330 (rotate:HI (match_operand:HI 1 "register_operand" "")
1331 (match_operand:HI 2 "const_int_operand" "")))
1332 (clobber (reg:CC CC_REGNUM))])]
1335 if (INTVAL (operands[2]) != 8)
1339 (define_insn "*rotlhi3_8"
1340 [(set (match_operand:HI 0 "register_operand" "=r")
1341 (rotate:HI (match_operand:HI 1 "register_operand" "r")
1343 (clobber (reg:CC CC_REGNUM))]
1346 [(set_attr "length" "4")])
1348 (define_expand "rotlsi3"
1349 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1350 (rotate:SI (match_operand:SI 1 "register_operand" "")
1351 (match_operand:SI 2 "const_int_operand" "")))
1352 (clobber (reg:CC CC_REGNUM))])]
1355 if (INTVAL (operands[2]) != 16)
1359 (define_insn "rotlsi3_a"
1360 [(set (match_operand:SI 0 "register_operand" "=r")
1361 (match_operator:SI 4 "ior_operator"
1362 [(ashift:SI (match_operand:SI 1 "register_operand" "r")
1363 (match_operand:SI 2 "const_int_operand" "n"))
1364 (lshiftrt:SI (match_dup 1)
1365 (match_operand:SI 3 "const_int_operand" "n"))]))
1366 (clobber (reg:CC CC_REGNUM))]
1367 "TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)"
1369 [(set_attr "length" "4")])
1371 (define_insn "rotlsi3_b"
1372 [(set (match_operand:SI 0 "register_operand" "=r")
1373 (match_operator:SI 4 "ior_operator"
1374 [(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1375 (match_operand:SI 3 "const_int_operand" "n"))
1376 (ashift:SI (match_dup 1)
1377 (match_operand:SI 2 "const_int_operand" "n"))]))
1378 (clobber (reg:CC CC_REGNUM))]
1379 "TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)"
1381 [(set_attr "length" "4")])
1383 (define_insn "rotlsi3_v850e3v5"
1384 [(set (match_operand:SI 0 "register_operand" "=r")
1385 (rotate:SI (match_operand:SI 1 "register_operand" "r")
1386 (match_operand:SI 2 "e3v5_shift_operand" "rn")))
1387 (clobber (reg:CC CC_REGNUM))]
1388 "TARGET_V850E3V5_UP"
1390 [(set_attr "length" "4")])
1392 (define_insn "*rotlsi3_16"
1393 [(set (match_operand:SI 0 "register_operand" "=r")
1394 (rotate:SI (match_operand:SI 1 "register_operand" "r")
1396 (clobber (reg:CC CC_REGNUM))]
1399 [(set_attr "length" "4")])
1401 ;; ----------------------------------------------------------------------
1402 ;; JUMP INSTRUCTIONS
1403 ;; ----------------------------------------------------------------------
1407 (define_expand "doloop_begin"
1408 [(use (match_operand 0 "" "")) ; loop pseudo
1409 (use (match_operand 1 "" ""))] ; doloop_end pattern
1410 "TARGET_V850E3V5_UP && TARGET_LOOP"
1412 rtx loop_cnt = operands[0];
1413 gcc_assert (GET_MODE (loop_cnt) == SImode);
1414 emit_insn (gen_fix_loop_counter (loop_cnt));
1419 ;; Note the embedded arithmetic. That affects the condition codes!
1420 (define_insn "fix_loop_counter"
1421 [(unspec:SI [(match_operand:SI 0 "register_operand" "+r,!m")
1422 (clobber (match_scratch:SI 1 "=X,r"))] UNSPEC_LOOP)
1423 (clobber (reg:CC CC_REGNUM))]
1424 "TARGET_V850E3V5_UP && TARGET_LOOP"
1426 switch (which_alternative)
1428 case 0: return "add 1, %0 # LOOP_BEGIN";
1429 case 1: return "ld.w %0, %1; add 1, %1; st.w %1, %0 # LOOP_BEGIN";
1430 default: gcc_unreachable ();
1433 [(set_attr "length" "2,6")])
1435 (define_expand "doloop_end"
1436 [(use (match_operand 0 "" "")) ; loop pseudo
1437 (use (match_operand 1 "" ""))] ; label
1438 "TARGET_V850E3V5_UP && TARGET_LOOP"
1440 rtx loop_cnt = operands[0];
1441 rtx label = operands[1];
1443 if (GET_MODE (loop_cnt) != SImode)
1446 emit_jump_insn (gen_doloop_end_internal_loop (label, loop_cnt));
1451 (define_insn "doloop_end_internal_loop"
1453 (if_then_else (ne (match_operand:SI 1 "register_operand" "+r,!m")
1455 (label_ref (match_operand 0 "" ""))
1457 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))
1458 (clobber (match_scratch:SI 2 "=X,r"))
1459 (clobber (reg:CC CC_REGNUM))]
1460 "TARGET_V850E3V5_UP && TARGET_LOOP"
1462 switch (which_alternative)
1465 if (get_attr_length (insn) == 4)
1466 return "loop %1, %0 # LOOP.1.0";
1468 return "add -1, %1; bne %l0 # LOOP.1.1";
1470 return "ld.w %1, %2; add -1, %2; st.w %2, %1; bne %l0 # LOOP.2.1";
1475 [(set (attr "length")
1476 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1481 ;; Conditional jump instructions
1483 (define_insn_and_split "*cbranchsi4_insn"
1485 (if_then_else (match_operator 0 "comparison_operator"
1486 [(match_operand:SI 1 "register_operand" "r")
1487 (match_operand:SI 2 "reg_or_int5_operand" "rJ")])
1488 (label_ref (match_operand 3 "" ""))
1493 [(set (reg:CC CC_REGNUM)
1494 (compare:CC (match_dup 1) (match_dup 2)))
1496 (if_then_else (match_op_dup 0
1497 [(reg:CC CC_REGNUM) (const_int 0)])
1498 (label_ref (match_dup 3))
1502 (define_insn "*branch_normal"
1504 (if_then_else (match_operator 1 "comparison_operator"
1505 [(reg CC_REGNUM) (const_int 0)])
1506 (label_ref (match_operand 0 "" ""))
1510 bool nzmode = GET_MODE (XEXP (operands[1], 0)) == CCNZmode;
1511 if (get_attr_length (insn) == 2)
1518 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1526 return "b%D1 .+6 ; jr %l0";
1528 return "b%B1 .+6 ; jr %l0";
1530 [(set (attr "length")
1531 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1534 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1539 (define_insn "*branch_invert"
1541 (if_then_else (match_operator 1 "comparison_operator"
1542 [(reg CC_REGNUM) (const_int 0)])
1544 (label_ref (match_operand 0 "" ""))))]
1547 bool nzmode = GET_MODE (XEXP (operands[1], 0)) == CCNZmode;
1549 if (get_attr_length (insn) == 2)
1557 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1566 return "b%d1 .+6 ; jr %l0";
1568 return "b%b1 .+6 ; jr %l0";
1570 [(set (attr "length")
1571 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1574 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1579 ;; Unconditional and other jump instructions.
1583 (label_ref (match_operand 0 "" "")))]
1586 if (get_attr_length (insn) == 2)
1591 [(set (attr "length")
1592 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1597 (define_insn "indirect_jump"
1598 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1601 [(set_attr "length" "2")])
1603 (define_insn "tablejump"
1604 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1605 (use (label_ref (match_operand 1 "" "")))]
1608 [(set_attr "length" "2")])
1610 (define_insn "switch"
1615 (plus:SI (ashift:SI (match_operand:SI 0 "register_operand" "r")
1617 (label_ref (match_operand 1 "" "")))))
1618 (label_ref (match_dup 1))))]
1621 [(set_attr "length" "2")])
1623 (define_expand "casesi"
1624 [(match_operand:SI 0 "register_operand" "")
1625 (match_operand:SI 1 "register_operand" "")
1626 (match_operand:SI 2 "register_operand" "")
1627 (match_operand 3 "" "") (match_operand 4 "" "")]
1630 rtx reg = gen_reg_rtx (SImode);
1631 rtx tableaddress = gen_reg_rtx (SImode);
1635 /* Subtract the lower bound from the index. */
1636 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
1638 /* Compare the result against the number of table entries;
1639 branch to the default label if out of range of the table. */
1640 test = gen_rtx_fmt_ee (GTU, VOIDmode, reg, operands[2]);
1641 emit_jump_insn (gen_cbranchsi4 (test, reg, operands[2], operands[4]));
1643 /* Shift index for the table array access. */
1644 emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
1645 /* Load the table address into a pseudo. */
1646 emit_insn (gen_movsi (tableaddress,
1647 gen_rtx_LABEL_REF (Pmode, operands[3])));
1648 /* Add the table address to the index. */
1649 emit_insn (gen_addsi3 (reg, reg, tableaddress));
1650 /* Load the table entry. */
1651 mem = gen_const_mem (CASE_VECTOR_MODE, reg);
1652 if (! TARGET_BIG_SWITCH)
1654 rtx reg2 = gen_reg_rtx (HImode);
1655 emit_insn (gen_movhi (reg2, mem));
1656 emit_insn (gen_extendhisi2 (reg, reg2));
1659 emit_insn (gen_movsi (reg, mem));
1660 /* Add the table address. */
1661 emit_insn (gen_addsi3 (reg, reg, tableaddress));
1662 /* Branch to the switch label. */
1663 emit_jump_insn (gen_tablejump (reg, operands[3]));
1667 ;; Call subroutine with no return value.
1669 (define_expand "call"
1670 [(call (match_operand:QI 0 "general_operand" "")
1671 (match_operand:SI 1 "general_operand" ""))]
1674 if (! call_address_operand (XEXP (operands[0], 0), QImode)
1675 || TARGET_LONG_CALLS)
1676 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1677 if (TARGET_LONG_CALLS)
1678 emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));
1680 emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
1685 (define_insn "call_internal_short"
1686 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1687 (match_operand:SI 1 "general_operand" "g,g"))
1688 (clobber (reg:CC CC_REGNUM))
1689 (clobber (reg:SI 31))]
1690 "! TARGET_LONG_CALLS"
1692 if (which_alternative == 1)
1694 if (TARGET_V850E3V5_UP)
1695 return "jarl [%0], r31";
1697 return "jarl .+4, r31 ; add 4, r31 ; jmp %0";
1700 return "jarl %0, r31";
1702 [(set_attr "length" "4,8")])
1704 (define_insn "call_internal_long"
1705 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1706 (match_operand:SI 1 "general_operand" "g,g"))
1707 (clobber (reg:CC CC_REGNUM))
1708 (clobber (reg:SI 31))]
1711 if (which_alternative == 0)
1713 if (GET_CODE (operands[0]) == REG)
1714 return "jarl %0,r31";
1716 if (TARGET_V850E3V5_UP)
1717 return "mov hilo(%0), r11 ; jarl [r11], r31";
1719 return "movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11";
1722 if (TARGET_V850E3V5_UP)
1723 return "jarl [%0], r31";
1725 return "jarl .+4,r31 ; add 4,r31 ; jmp %0";
1727 [(set_attr "length" "16,8")])
1729 ;; Call subroutine, returning value in operand 0
1730 ;; (which must be a hard register).
1732 (define_expand "call_value"
1733 [(set (match_operand 0 "" "")
1734 (call (match_operand:QI 1 "general_operand" "")
1735 (match_operand:SI 2 "general_operand" "")))]
1738 if (! call_address_operand (XEXP (operands[1], 0), QImode)
1739 || TARGET_LONG_CALLS)
1740 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1741 if (TARGET_LONG_CALLS)
1742 emit_call_insn (gen_call_value_internal_long (operands[0],
1743 XEXP (operands[1], 0),
1746 emit_call_insn (gen_call_value_internal_short (operands[0],
1747 XEXP (operands[1], 0),
1752 (define_insn "call_value_internal_short"
1753 [(set (match_operand 0 "" "=r,r")
1754 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1755 (match_operand:SI 2 "general_operand" "g,g")))
1756 (clobber (reg:CC CC_REGNUM))
1757 (clobber (reg:SI 31))]
1758 "! TARGET_LONG_CALLS"
1760 if (which_alternative == 1)
1762 if (TARGET_V850E3V5_UP)
1763 return "jarl [%1], r31";
1765 return "jarl .+4, r31 ; add 4, r31 ; jmp %1";
1768 return "jarl %1, r31";
1770 [(set_attr "length" "4,8")])
1772 (define_insn "call_value_internal_long"
1773 [(set (match_operand 0 "" "=r,r")
1774 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1775 (match_operand:SI 2 "general_operand" "g,g")))
1776 (clobber (reg:CC CC_REGNUM))
1777 (clobber (reg:SI 31))]
1780 if (which_alternative == 0)
1782 if (GET_CODE (operands[1]) == REG)
1783 return "jarl %1, r31";
1785 /* Reload can generate this pattern.... */
1786 if (TARGET_V850E3V5_UP)
1787 return "mov hilo(%1), r11 ; jarl [r11], r31";
1789 return "movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11";
1792 if (TARGET_V850E3V5_UP)
1793 return "jarl [%1], r31";
1795 return "jarl .+4, r31 ; add 4, r31 ; jmp %1";
1797 [(set_attr "length" "16,8")])
1803 [(set_attr "length" "2")])
1805 ;; ----------------------------------------------------------------------
1806 ;; EXTEND INSTRUCTIONS
1807 ;; ----------------------------------------------------------------------
1809 ;; We only need the CC clobber because of the andi alternative
1810 (define_insn "*zero_extendhisi2_v850e"
1811 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1813 (match_operand:HI 1 "nonimmediate_operand" "0,r,T,m")))
1814 (clobber (reg:CC CC_REGNUM))]
1821 [(set_attr "length" "2,4,2,4")])
1823 (define_insn "*zero_extendhisi2_v850"
1824 [(set (match_operand:SI 0 "register_operand" "=r")
1826 (match_operand:HI 1 "register_operand" "r")))
1827 (clobber (reg:CC CC_REGNUM))] ;; A lie, but we have to match the expander
1830 [(set_attr "length" "4")])
1832 (define_insn "*zero_extendhisi2_v850_set_flags"
1833 [(set (reg:CCNZ CC_REGNUM)
1834 (compare:CCNZ (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1836 (set (match_operand:SI 0 "register_operand" "=r")
1837 (zero_extend:SI (match_dup 1)))]
1840 [(set_attr "length" "4")])
1842 (define_expand "zero_extendhisi2"
1843 [(parallel [(set (match_operand:SI 0 "register_operand")
1845 (match_operand:HI 1 "nonimmediate_operand")))
1846 (clobber (reg:CC CC_REGNUM))])]
1849 if (! (TARGET_V850E_UP))
1850 operands[1] = force_reg (HImode, operands[1]);
1853 (define_insn "*zero_extendqisi2_v850e"
1854 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1856 (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m")))
1857 (clobber (reg:CC CC_REGNUM))]
1864 [(set_attr "length" "2,4,2,4")])
1866 (define_insn "*zero_extendqisi2_v850"
1867 [(set (match_operand:SI 0 "register_operand" "=r")
1869 (match_operand:QI 1 "register_operand" "r")))
1870 (clobber (reg:CC CC_REGNUM))] ;; A lie, but we have to match the expander
1873 [(set_attr "length" "4")])
1875 (define_insn "*zero_extendqisi2_v850_set_flags"
1876 [(set (reg:CCNZ CC_REGNUM)
1877 (compare:CCNZ (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1879 (set (match_operand:SI 0 "register_operand" "=r")
1880 (zero_extend:SI (match_dup 1)))]
1883 [(set_attr "length" "4")])
1885 (define_expand "zero_extendqisi2"
1886 [(parallel [(set (match_operand:SI 0 "register_operand")
1888 (match_operand:QI 1 "nonimmediate_operand")))
1889 (clobber (reg:CC CC_REGNUM))])]
1892 if (! (TARGET_V850E_UP))
1893 operands[1] = force_reg (QImode, operands[1]);
1896 ;;- sign extension instructions
1898 ;; ??? The extendhisi2 pattern should not emit shifts for v850e?
1900 (define_insn "*extendhisi_insn"
1901 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1902 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))]
1908 [(set_attr "length" "2,2,4")])
1910 ;; ??? This is missing a sign extend from memory pattern to match the ld.h
1913 (define_expand "extendhisi2"
1914 [(parallel [(set (match_dup 2)
1915 (ashift:SI (match_operand:HI 1 "register_operand" "")
1917 (clobber (reg:CC CC_REGNUM))])
1918 (parallel [(set (match_operand:SI 0 "register_operand" "")
1919 (ashiftrt:SI (match_dup 2)
1921 (clobber (reg:CC CC_REGNUM))])]
1924 operands[1] = gen_lowpart (SImode, operands[1]);
1925 operands[2] = gen_reg_rtx (SImode);
1928 ;; ??? The extendqisi2 pattern should not emit shifts for v850e?
1930 (define_insn "*extendqisi_insn"
1931 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1932 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))]
1938 [(set_attr "length" "2,2,4")])
1940 ;; ??? This is missing a sign extend from memory pattern to match the ld.b
1943 (define_expand "extendqisi2"
1944 [(parallel [(set (match_dup 2)
1945 (ashift:SI (match_operand:QI 1 "register_operand" "")
1947 (clobber (reg:CC CC_REGNUM))])
1948 (parallel [(set (match_operand:SI 0 "register_operand" "")
1949 (ashiftrt:SI (match_dup 2)
1951 (clobber (reg:CC CC_REGNUM))])]
1954 operands[1] = gen_lowpart (SImode, operands[1]);
1955 operands[2] = gen_reg_rtx (SImode);
1958 ;; ----------------------------------------------------------------------
1960 ;; ----------------------------------------------------------------------
1962 (define_insn_and_split "ashlsi3"
1963 [(set (match_operand:SI 0 "register_operand" "=r,r")
1965 (match_operand:SI 1 "register_operand" "0,0")
1966 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1970 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1971 (clobber (reg:CC CC_REGNUM))])])
1973 (define_insn "ashlsi3_clobber_flags"
1974 [(set (match_operand:SI 0 "register_operand" "=r,r")
1976 (match_operand:SI 1 "register_operand" "0,0")
1977 (match_operand:SI 2 "nonmemory_operand" "r,N")))
1978 (clobber (reg:CC CC_REGNUM))]
1983 [(set_attr "length" "4,2")])
1985 (define_insn "ashlsi3_set_flags"
1986 [(set (reg:CCNZ CC_REGNUM)
1987 (compare:CCNZ (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
1988 (match_operand:SI 2 "nonmemory_operand" "r,N"))
1990 (set (match_operand:SI 0 "register_operand" "=r,r")
1991 (ashift:SI (match_dup 1) (match_dup 2)))]
1996 [(set_attr "length" "4,2")])
1998 (define_insn "ashlsi3_v850e2_clobber_flags"
1999 [(set (match_operand:SI 0 "register_operand" "=r")
2001 (match_operand:SI 1 "register_operand" "r")
2002 (match_operand:SI 2 "nonmemory_operand" "r")))
2003 (clobber (reg:CC CC_REGNUM))]
2006 [(set_attr "length" "4")])
2008 (define_insn "ashlsi3_v850e2_set_flags"
2009 [(set (reg:CCNZ CC_REGNUM)
2010 (compare:CCNZ (ashift:SI (match_operand:SI 1 "register_operand" "r")
2011 (match_operand:SI 2 "nonmemory_operand" "r"))
2013 (set (match_operand:SI 0 "register_operand" "=r")
2014 (ashift:SI (match_dup 1) (match_dup 2)))]
2015 "reload_completed && TARGET_V850E2_UP"
2017 [(set_attr "length" "4")])
2019 (define_insn_and_split "lshrsi3"
2020 [(set (match_operand:SI 0 "register_operand" "=r,r")
2022 (match_operand:SI 1 "register_operand" "0,0")
2023 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
2027 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
2028 (clobber (reg:CC CC_REGNUM))])])
2030 (define_insn "lshrsi3_clobber_flags"
2031 [(set (match_operand:SI 0 "register_operand" "=r,r")
2033 (match_operand:SI 1 "register_operand" "0,0")
2034 (match_operand:SI 2 "nonmemory_operand" "r,N")))
2035 (clobber (reg:CC CC_REGNUM))]
2040 [(set_attr "length" "4,2")])
2042 (define_insn "lshrsi3_set_flags"
2043 [(set (reg:CC CC_REGNUM)
2044 (compare:CC (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
2045 (match_operand:SI 2 "nonmemory_operand" "r,N"))
2047 (set (match_operand:SI 0 "register_operand" "=r,r")
2048 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
2053 [(set_attr "length" "4,2")])
2055 (define_insn "lshrsi3_v850e2_clobber_flags"
2056 [(set (match_operand:SI 0 "register_operand" "=r")
2058 (match_operand:SI 1 "register_operand" "r")
2059 (match_operand:SI 2 "nonmemory_operand" "r")))
2060 (clobber (reg:CC CC_REGNUM))]
2063 [(set_attr "length" "4")])
2065 (define_insn "lshrsi3_v850e2_set_flags"
2066 [(set (reg:CC CC_REGNUM)
2067 (compare:CC (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2068 (match_operand:SI 2 "nonmemory_operand" "r"))
2070 (set (match_operand:SI 0 "register_operand" "=r")
2071 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
2072 "reload_completed && TARGET_V850E2_UP"
2074 [(set_attr "length" "4")])
2076 (define_insn_and_split "ashrsi3"
2077 [(set (match_operand:SI 0 "register_operand" "=r,r")
2079 (match_operand:SI 1 "register_operand" "0,0")
2080 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
2084 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
2085 (clobber (reg:CC CC_REGNUM))])])
2087 (define_insn "ashrsi3_clobber_flags"
2088 [(set (match_operand:SI 0 "register_operand" "=r,r")
2090 (match_operand:SI 1 "register_operand" "0,0")
2091 (match_operand:SI 2 "nonmemory_operand" "r,N")))
2092 (clobber (reg:CC CC_REGNUM))]
2097 [(set_attr "length" "4,2")])
2099 (define_insn "ashrsi3_set_flags"
2100 [(set (reg:CC CC_REGNUM)
2101 (compare:CC (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
2102 (match_operand:SI 2 "nonmemory_operand" "r,N"))
2104 (set (match_operand:SI 0 "register_operand" "=r,r")
2105 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
2110 [(set_attr "length" "4,2")])
2112 (define_insn "ashrsi3_v850e2_clobber_flags"
2113 [(set (match_operand:SI 0 "register_operand" "=r")
2115 (match_operand:SI 1 "register_operand" "r")
2116 (match_operand:SI 2 "nonmemory_operand" "r")))
2117 (clobber (reg:CC CC_REGNUM))]
2120 [(set_attr "length" "4")])
2122 (define_insn "ashrsi3_v850e2_set_flags"
2123 [(set (reg:CC CC_REGNUM)
2124 (compare:CC (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2125 (match_operand:SI 2 "nonmemory_operand" "r"))
2127 (set (match_operand:SI 0 "register_operand" "=r")
2128 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
2129 "reload_completed && TARGET_V850E2_UP"
2131 [(set_attr "length" "4")])
2133 ;; ----------------------------------------------------------------------
2134 ;; FIND FIRST BIT INSTRUCTION
2135 ;; ----------------------------------------------------------------------
2137 (define_insn "ffssi2"
2138 [(set (match_operand:SI 0 "register_operand" "=r")
2139 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
2140 (clobber (reg:CC CC_REGNUM))]
2143 [(set_attr "length" "4")])
2145 ;; ----------------------------------------------------------------------
2146 ;; PROLOGUE/EPILOGUE
2147 ;; ----------------------------------------------------------------------
2148 (define_expand "prologue"
2156 (define_expand "epilogue"
2164 (define_insn "return_simple"
2168 [(set_attr "length" "2")])
2170 (define_insn "return_internal"
2175 [(set_attr "length" "2")])
2177 ;; ----------------------------------------------------------------------
2178 ;; v850e2V3 floating-point hardware support
2179 ;; ----------------------------------------------------------------------
2182 (define_insn "addsf3"
2183 [(set (match_operand:SF 0 "register_operand" "=r")
2184 (plus:SF (match_operand:SF 1 "register_operand" "r")
2185 (match_operand:SF 2 "register_operand" "r")))]
2188 [(set_attr "length" "4")
2189 (set_attr "type" "fpu")])
2191 (define_insn "adddf3"
2192 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2193 (plus:DF (match_operand:DF 1 "even_reg_operand" "r")
2194 (match_operand:DF 2 "even_reg_operand" "r")))]
2197 [(set_attr "length" "4")
2198 (set_attr "type" "fpu")])
2200 (define_insn "subsf3"
2201 [(set (match_operand:SF 0 "register_operand" "=r")
2202 (minus:SF (match_operand:SF 1 "register_operand" "r")
2203 (match_operand:SF 2 "register_operand" "r")))]
2206 [(set_attr "length" "4")
2207 (set_attr "type" "fpu")])
2209 (define_insn "subdf3"
2210 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2211 (minus:DF (match_operand:DF 1 "even_reg_operand" "r")
2212 (match_operand:DF 2 "even_reg_operand" "r")))]
2215 [(set_attr "length" "4")
2216 (set_attr "type" "fpu")])
2218 (define_insn "mulsf3"
2219 [(set (match_operand:SF 0 "register_operand" "=r")
2220 (mult:SF (match_operand:SF 1 "register_operand" "r")
2221 (match_operand:SF 2 "register_operand" "r")))]
2224 [(set_attr "length" "4")
2225 (set_attr "type" "fpu")])
2227 (define_insn "muldf3"
2228 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2229 (mult:DF (match_operand:DF 1 "even_reg_operand" "r")
2230 (match_operand:DF 2 "even_reg_operand" "r")))]
2233 [(set_attr "length" "4")
2234 (set_attr "type" "fpu")])
2236 (define_insn "divsf3"
2237 [(set (match_operand:SF 0 "register_operand" "=r")
2238 (div:SF (match_operand:SF 1 "register_operand" "r")
2239 (match_operand:SF 2 "register_operand" "r")))]
2242 [(set_attr "length" "4")
2243 (set_attr "type" "fpu")])
2245 (define_insn "divdf3"
2246 [(set (match_operand:DF 0 "register_operand" "=r")
2247 (div:DF (match_operand:DF 1 "even_reg_operand" "r")
2248 (match_operand:DF 2 "even_reg_operand" "r")))]
2251 [(set_attr "length" "4")
2252 (set_attr "type" "fpu")])
2254 (define_insn "minsf3"
2255 [(set (match_operand:SF 0 "register_operand" "=r")
2256 (smin:SF (match_operand:SF 1 "reg_or_0_operand" "r")
2257 (match_operand:SF 2 "reg_or_0_operand" "r")))]
2260 [(set_attr "length" "4")
2261 (set_attr "type" "fpu")])
2263 (define_insn "mindf3"
2264 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2265 (smin:DF (match_operand:DF 1 "even_reg_operand" "r")
2266 (match_operand:DF 2 "even_reg_operand" "r")))]
2269 [(set_attr "length" "4")
2270 (set_attr "type" "fpu")])
2272 (define_insn "maxsf3"
2273 [(set (match_operand:SF 0 "register_operand" "=r")
2274 (smax:SF (match_operand:SF 1 "reg_or_0_operand" "r")
2275 (match_operand:SF 2 "reg_or_0_operand" "r")))]
2278 [(set_attr "length" "4")
2279 (set_attr "type" "fpu")])
2281 (define_insn "maxdf3"
2282 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2283 (smax:DF (match_operand:DF 1 "even_reg_operand" "r")
2284 (match_operand:DF 2 "even_reg_operand" "r")))]
2287 [(set_attr "length" "4")
2288 (set_attr "type" "fpu")])
2290 (define_insn "abssf2"
2291 [(set (match_operand:SF 0 "register_operand" "=r")
2292 (abs:SF (match_operand:SF 1 "register_operand" "r")))]
2295 [(set_attr "length" "4")
2296 (set_attr "type" "fpu")])
2298 (define_insn "absdf2"
2299 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2300 (abs:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2303 [(set_attr "length" "4")
2304 (set_attr "type" "fpu")])
2306 (define_insn "negsf2"
2307 [(set (match_operand:SF 0 "register_operand" "=r")
2308 (neg:SF (match_operand:SF 1 "register_operand" "r")))]
2311 [(set_attr "length" "4")
2312 (set_attr "type" "fpu")])
2314 (define_insn "negdf2"
2315 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2316 (neg:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2319 [(set_attr "length" "4")
2320 (set_attr "type" "fpu")])
2323 (define_insn "sqrtsf2"
2324 [(set (match_operand:SF 0 "register_operand" "=r")
2325 (sqrt:SF (match_operand:SF 1 "register_operand" "r")))]
2328 [(set_attr "length" "4")
2329 (set_attr "type" "fpu")])
2331 (define_insn "sqrtdf2"
2332 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2333 (sqrt:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2336 [(set_attr "length" "4")
2337 (set_attr "type" "fpu")])
2340 (define_insn "fix_truncsfsi2"
2341 [(set (match_operand:SI 0 "register_operand" "=r")
2342 (fix:SI (match_operand:SF 1 "register_operand" "r")))]
2345 [(set_attr "length" "4")
2346 (set_attr "type" "fpu")])
2348 (define_insn "fixuns_truncsfsi2"
2349 [(set (match_operand:SI 0 "register_operand" "=r")
2350 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "r")))]
2353 [(set_attr "length" "4")
2354 (set_attr "type" "fpu")])
2356 (define_insn "fix_truncdfsi2"
2357 [(set (match_operand:SI 0 "register_operand" "=r")
2358 (fix:SI (match_operand:DF 1 "even_reg_operand" "r")))]
2361 [(set_attr "length" "4")
2362 (set_attr "type" "fpu")])
2364 (define_insn "fixuns_truncdfsi2"
2365 [(set (match_operand:SI 0 "register_operand" "=r")
2366 (unsigned_fix:SI (match_operand:DF 1 "even_reg_operand" "r")))]
2369 [(set_attr "length" "4")
2370 (set_attr "type" "fpu")])
2372 (define_insn "fix_truncsfdi2"
2373 [(set (match_operand:DI 0 "register_operand" "=r")
2374 (fix:DI (match_operand:SF 1 "register_operand" "r")))]
2377 [(set_attr "length" "4")
2378 (set_attr "type" "fpu")])
2380 (define_insn "fixuns_truncsfdi2"
2381 [(set (match_operand:DI 0 "register_operand" "=r")
2382 (unsigned_fix:DI (match_operand:SF 1 "register_operand" "r")))]
2385 [(set_attr "length" "4")
2386 (set_attr "type" "fpu")])
2388 (define_insn "fix_truncdfdi2"
2389 [(set (match_operand:DI 0 "register_operand" "=r")
2390 (fix:DI (match_operand:DF 1 "even_reg_operand" "r")))]
2393 [(set_attr "length" "4")
2394 (set_attr "type" "fpu")])
2396 (define_insn "fixuns_truncdfdi2"
2397 [(set (match_operand:DI 0 "register_operand" "=r")
2398 (unsigned_fix:DI (match_operand:DF 1 "even_reg_operand" "r")))]
2401 [(set_attr "length" "4")
2402 (set_attr "type" "fpu")])
2405 (define_insn "floatsisf2"
2406 [(set (match_operand:SF 0 "register_operand" "=r")
2407 (float:SF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2410 [(set_attr "length" "4")
2411 (set_attr "type" "fpu")])
2413 (define_insn "unsfloatsisf2"
2414 [(set (match_operand:SF 0 "register_operand" "=r")
2415 (unsigned_float:SF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2418 [(set_attr "length" "4")
2419 (set_attr "type" "fpu")])
2421 (define_insn "floatsidf2"
2422 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2423 (float:DF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2426 [(set_attr "length" "4")
2427 (set_attr "type" "fpu")])
2429 (define_insn "unsfloatsidf2"
2430 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2431 (unsigned_float:DF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2434 [(set_attr "length" "4")
2435 (set_attr "type" "fpu")])
2437 (define_insn "floatdisf2"
2438 [(set (match_operand:SF 0 "even_reg_operand" "=r")
2439 (float:SF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2442 [(set_attr "length" "4")
2443 (set_attr "type" "fpu")])
2445 (define_insn "unsfloatdisf2"
2446 [(set (match_operand:SF 0 "even_reg_operand" "=r")
2447 (unsigned_float:SF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2450 [(set_attr "length" "4")
2451 (set_attr "type" "fpu")])
2453 (define_insn "floatdidf2"
2454 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2455 (float:DF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2458 [(set_attr "length" "4")
2459 (set_attr "type" "fpu")])
2461 (define_insn "unsfloatdidf2"
2462 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2463 (unsigned_float:DF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2466 [(set_attr "length" "4")
2467 (set_attr "type" "fpu")])
2469 ;; single-float -> double-float
2470 (define_insn "extendsfdf2"
2471 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2473 (match_operand:SF 1 "reg_or_0_operand" "rI")))]
2476 [(set_attr "length" "4")
2477 (set_attr "type" "fpu")])
2479 ;; double-float -> single-float
2480 (define_insn "truncdfsf2"
2481 [(set (match_operand:SF 0 "register_operand" "=r")
2483 (match_operand:DF 1 "even_reg_operand" "r")))]
2486 [(set_attr "length" "4")
2487 (set_attr "type" "fpu")])
2490 ;; ---------------- special insns
2495 ;; Generic code demands that the recip and rsqrt named patterns
2496 ;; have precisely one operand. So that's what we expose in the
2497 ;; expander via the strange UNSPEC. However, those expanders
2498 ;; generate normal looking recip and rsqrt patterns.
2500 (define_expand "recipsf2"
2501 [(set (match_operand:SF 0 "register_operand" "")
2502 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
2506 emit_insn (gen_recipsf2_insn (operands[0], CONST1_RTX (SFmode), operands[1]));
2510 (define_insn "recipsf2_insn"
2511 [(set (match_operand:SF 0 "register_operand" "=r")
2512 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2513 (match_operand:SF 2 "register_operand" "r")))]
2516 [(set_attr "length" "4")
2517 (set_attr "type" "fpu")])
2519 (define_expand "recipdf2"
2520 [(set (match_operand:DF 0 "even_reg_operand" "")
2521 (unspec:DF [(match_operand:SF 1 "even_reg_operand" "")]
2525 emit_insn (gen_recipdf2_insn (operands[0], CONST1_RTX (DFmode), operands[1]));
2529 (define_insn "recipdf2_insn"
2530 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2531 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2532 (match_operand:DF 2 "even_reg_operand" "r")))]
2535 [(set_attr "length" "4")
2536 (set_attr "type" "fpu")])
2538 ;;; reciprocal of square-root
2539 (define_expand "rsqrtsf2"
2540 [(set (match_operand:SF 0 "register_operand" "=")
2541 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
2545 emit_insn (gen_rsqrtsf2_insn (operands[0], CONST1_RTX (SFmode), operands[1]));
2549 (define_insn "rsqrtsf2_insn"
2550 [(set (match_operand:SF 0 "register_operand" "=r")
2551 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2552 (sqrt:SF (match_operand:SF 2 "register_operand" "r"))))]
2555 [(set_attr "length" "4")
2556 (set_attr "type" "fpu")])
2558 (define_expand "rsqrtdf2"
2559 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2560 (unspec:DF [(match_operand:DF 1 "even_reg_operand" "r")]
2564 emit_insn (gen_rsqrtdf2_insn (operands[0], CONST1_RTX (DFmode), operands[1]));
2568 (define_insn "rsqrtdf2_insn"
2569 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2570 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2571 (sqrt:DF (match_operand:DF 2 "even_reg_operand" "r"))))]
2574 [(set_attr "length" "4")
2575 (set_attr "type" "fpu")])
2577 ;; Note: The FPU-2.0 (ie pre e3v5) versions of these routines do not actually
2578 ;; need operand 4 to be the same as operand 0. But the FPU-2.0 versions are
2579 ;; also deprecated so the loss of flexibility is unimportant.
2582 (define_insn "fmasf4"
2583 [(set (match_operand:SF 0 "register_operand" "=r")
2584 (fma:SF (match_operand:SF 1 "register_operand" "r")
2585 (match_operand:SF 2 "register_operand" "r")
2586 (match_operand:SF 3 "register_operand" "0")))]
2588 { return TARGET_V850E3V5_UP ? "fmaf.s %1, %2, %0" : "maddf.s %2, %1, %3, %0"; }
2589 [(set_attr "length" "4")
2590 (set_attr "type" "fpu")])
2592 ;;; multiply-subtract
2593 (define_insn "fmssf4"
2594 [(set (match_operand:SF 0 "register_operand" "=r")
2595 (fma:SF (match_operand:SF 1 "register_operand" "r")
2596 (match_operand:SF 2 "register_operand" "r")
2597 (neg:SF (match_operand:SF 3 "register_operand" "0"))))]
2599 { return TARGET_V850E3V5_UP ? "fmsf.s %1, %2, %0" : "msubf.s %2, %1, %3, %0"; }
2600 [(set_attr "length" "4")
2601 (set_attr "type" "fpu")])
2603 ;;; negative-multiply-add
2604 (define_insn "fnmasf4"
2605 [(set (match_operand:SF 0 "register_operand" "=r")
2606 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "r")
2607 (match_operand:SF 2 "register_operand" "r")
2608 (match_operand:SF 3 "register_operand" "0"))))]
2610 { return TARGET_V850E3V5_UP ? "fnmaf.s %1, %2, %0" : "nmaddf.s %2, %1, %3, %0"; }
2611 [(set_attr "length" "4")
2612 (set_attr "type" "fpu")])
2614 ;; negative-multiply-subtract
2615 (define_insn "fnmssf4"
2616 [(set (match_operand:SF 0 "register_operand" "=r")
2617 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "r")
2618 (match_operand:SF 2 "register_operand" "r")
2619 (neg:SF (match_operand:SF 3 "register_operand" "0")))))]
2621 { return TARGET_V850E3V5_UP ? "fnmsf.s %1, %2, %0" : "nmsubf.s %2, %1, %3, %0"; }
2622 [(set_attr "length" "4")
2623 (set_attr "type" "fpu")])
2625 ; ---------------- comparison/conditionals
2629 (define_insn "cmpsf_le_insn"
2630 [(set (reg:CC_FPU_LE FCC_REGNUM)
2631 (compare:CC_FPU_LE (match_operand:SF 0 "register_operand" "r")
2632 (match_operand:SF 1 "register_operand" "r")))]
2633 "reload_completed && TARGET_USE_FPU"
2634 "cmpf.s le, %z0, %z1"
2635 [(set_attr "length" "4")
2636 (set_attr "type" "fpu")])
2638 (define_insn "cmpsf_lt_insn"
2639 [(set (reg:CC_FPU_LT FCC_REGNUM)
2640 (compare:CC_FPU_LT (match_operand:SF 0 "register_operand" "r")
2641 (match_operand:SF 1 "register_operand" "r")))]
2642 "reload_completed && TARGET_USE_FPU"
2643 "cmpf.s lt, %z0, %z1"
2644 [(set_attr "length" "4")
2645 (set_attr "type" "fpu")])
2647 (define_insn "cmpsf_ge_insn"
2648 [(set (reg:CC_FPU_GE FCC_REGNUM)
2649 (compare:CC_FPU_GE (match_operand:SF 0 "register_operand" "r")
2650 (match_operand:SF 1 "register_operand" "r")))]
2651 "reload_completed && TARGET_USE_FPU"
2652 "cmpf.s le, %z1, %z0"
2653 [(set_attr "length" "4")
2654 (set_attr "type" "fpu")])
2656 (define_insn "cmpsf_gt_insn"
2657 [(set (reg:CC_FPU_GT FCC_REGNUM)
2658 (compare:CC_FPU_GT (match_operand:SF 0 "register_operand" "r")
2659 (match_operand:SF 1 "register_operand" "r")))]
2660 "reload_completed && TARGET_USE_FPU"
2661 "cmpf.s lt, %z1, %z0"
2662 [(set_attr "length" "4")
2663 (set_attr "type" "fpu")])
2665 (define_insn "cmpsf_eq_insn"
2666 [(set (reg:CC_FPU_EQ FCC_REGNUM)
2667 (compare:CC_FPU_EQ (match_operand:SF 0 "register_operand" "r")
2668 (match_operand:SF 1 "register_operand" "r")))]
2669 "reload_completed && TARGET_USE_FPU"
2670 "cmpf.s eq, %z0, %z1"
2671 [(set_attr "length" "4")
2672 (set_attr "type" "fpu")])
2676 (define_insn "cmpdf_le_insn"
2677 [(set (reg:CC_FPU_LE FCC_REGNUM)
2678 (compare:CC_FPU_LE (match_operand:DF 0 "even_reg_operand" "r")
2679 (match_operand:DF 1 "even_reg_operand" "r")))]
2680 "reload_completed && TARGET_USE_FPU"
2681 "cmpf.d le, %z0, %z1"
2682 [(set_attr "length" "4")
2683 (set_attr "type" "fpu")])
2685 (define_insn "cmpdf_lt_insn"
2686 [(set (reg:CC_FPU_LT FCC_REGNUM)
2687 (compare:CC_FPU_LT (match_operand:DF 0 "even_reg_operand" "r")
2688 (match_operand:DF 1 "even_reg_operand" "r")))]
2689 "reload_completed && TARGET_USE_FPU"
2690 "cmpf.d lt, %z0, %z1"
2691 [(set_attr "length" "4")
2692 (set_attr "type" "fpu")])
2694 (define_insn "cmpdf_ge_insn"
2695 [(set (reg:CC_FPU_GE FCC_REGNUM)
2696 (compare:CC_FPU_GE (match_operand:DF 0 "even_reg_operand" "r")
2697 (match_operand:DF 1 "even_reg_operand" "r")))]
2698 "reload_completed && TARGET_USE_FPU"
2699 "cmpf.d le, %z1, %z0"
2700 [(set_attr "length" "4")
2701 (set_attr "type" "fpu")])
2703 (define_insn "cmpdf_gt_insn"
2704 [(set (reg:CC_FPU_GT FCC_REGNUM)
2705 (compare:CC_FPU_GT (match_operand:DF 0 "even_reg_operand" "r")
2706 (match_operand:DF 1 "even_reg_operand" "r")))]
2707 "reload_completed && TARGET_USE_FPU"
2708 "cmpf.d lt, %z1, %z0"
2709 [(set_attr "length" "4")
2710 (set_attr "type" "fpu")])
2712 (define_insn "cmpdf_eq_insn"
2713 [(set (reg:CC_FPU_EQ FCC_REGNUM)
2714 (compare:CC_FPU_EQ (match_operand:DF 0 "even_reg_operand" "r")
2715 (match_operand:DF 1 "even_reg_operand" "r")))]
2716 "reload_completed && TARGET_USE_FPU"
2717 "cmpf.d eq, %z0, %z1"
2718 [(set_attr "length" "4")
2719 (set_attr "type" "fpu")])
2722 ;; Transfer a v850e2v3 fcc to the Z bit of CC0 (this is necessary to do a
2723 ;; conditional branch based on a floating-point compare)
2726 (define_insn "trfsr"
2727 [(set (match_operand 0 "" "") (match_operand 1 "" ""))]
2730 && GET_MODE(operands[0]) == GET_MODE(operands[1])
2731 && GET_CODE(operands[0]) == REG && REGNO (operands[0]) == CC_REGNUM
2732 && GET_CODE(operands[1]) == REG && REGNO (operands[1]) == FCC_REGNUM
2733 && (GET_MODE(operands[0]) == CC_FPU_LEmode
2734 || GET_MODE(operands[0]) == CC_FPU_GEmode
2735 || GET_MODE(operands[0]) == CC_FPU_LTmode
2736 || GET_MODE(operands[0]) == CC_FPU_GTmode
2737 || GET_MODE(operands[0]) == CC_FPU_EQmode
2738 || GET_MODE(operands[0]) == CC_FPU_NEmode)"
2740 [(set_attr "length" "4")
2741 (set_attr "type" "fpu")])
2744 ;; Floating-point conditional moves for the v850e2v3.
2747 ;; The actual v850e2v3 conditional move instructions
2749 (define_insn "movsfcc_z_insn"
2750 [(set (match_operand:SF 0 "register_operand" "=r")
2752 (match_operand 3 "v850_float_z_comparison_operator" "")
2753 (match_operand:SF 1 "reg_or_0_operand" "rIG")
2754 (match_operand:SF 2 "reg_or_0_operand" "rIG")))]
2756 "cmovf.s 0,%z1,%z2,%0")
2758 (define_insn "movsfcc_nz_insn"
2759 [(set (match_operand:SF 0 "register_operand" "=r")
2761 (match_operand 3 "v850_float_nz_comparison_operator" "")
2762 (match_operand:SF 1 "reg_or_0_operand" "rIG")
2763 (match_operand:SF 2 "reg_or_0_operand" "rIG")))]
2765 "cmovf.s 0,%z2,%z1,%0")
2767 (define_insn "movdfcc_z_insn"
2768 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2770 (match_operand 3 "v850_float_z_comparison_operator" "")
2771 (match_operand:DF 1 "even_reg_operand" "r")
2772 (match_operand:DF 2 "even_reg_operand" "r")))]
2774 "cmovf.d 0,%z1,%z2,%0")
2776 (define_insn "movdfcc_nz_insn"
2777 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2779 (match_operand 3 "v850_float_nz_comparison_operator" "")
2780 (match_operand:DF 1 "even_reg_operand" "r")
2781 (match_operand:DF 2 "even_reg_operand" "r")))]
2783 "cmovf.d 0,%z2,%z1,%0")
2785 (define_insn "movedfcc_z_zero"
2786 [(set (match_operand:DF 0 "register_operand" "=r")
2788 (match_operand 3 "v850_float_z_comparison_operator" "")
2789 (match_operand:DF 1 "reg_or_0_operand" "rIG")
2790 (match_operand:DF 2 "reg_or_0_operand" "rIG")))]
2792 "cmovf.s 0,%z1,%z2,%0 ; cmovf.s 0,%Z1,%Z2,%R0"
2793 [(set_attr "length" "8")])
2795 (define_insn "movedfcc_nz_zero"
2796 [(set (match_operand:DF 0 "register_operand" "=r")
2798 (match_operand 3 "v850_float_nz_comparison_operator" "")
2799 (match_operand:DF 1 "reg_or_0_operand" "rIG")
2800 (match_operand:DF 2 "reg_or_0_operand" "rIG")))]
2802 "cmovf.s 0,%z2,%z1,%0 ; cmovf.s 0,%Z2,%Z1,%R0"
2803 [(set_attr "length" "8")])
2806 ;; ----------------------------------------------------------------------
2807 ;; HELPER INSTRUCTIONS for saving the prologue and epilogue registers
2808 ;; ----------------------------------------------------------------------
2810 ;; This pattern will match a stack adjust RTX followed by any number of push
2811 ;; RTXs. These RTXs will then be turned into a suitable call to a worker
2815 ;; Actually, convert the RTXs into a PREPARE instruction.
2819 [(match_parallel 0 "pattern_is_ok_for_prepare"
2821 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2822 (set (mem:SI (plus:SI (reg:SI 3)
2823 (match_operand:SI 2 "immediate_operand" "i")))
2824 (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
2825 "TARGET_PROLOG_FUNCTION && (TARGET_V850E_UP)"
2827 return construct_prepare_instruction (operands[0]);
2829 [(set_attr "length" "4")])
2832 [(match_parallel 0 "pattern_is_ok_for_prologue"
2834 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2835 (set (mem:SI (plus:SI (reg:SI 3)
2836 (match_operand:SI 2 "immediate_operand" "i")))
2837 (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
2838 "TARGET_PROLOG_FUNCTION"
2840 return construct_save_jarl (operands[0]);
2842 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
2844 (const_string "4")))])
2847 ;; Actually, turn the RTXs into a DISPOSE instruction.
2850 [(match_parallel 0 "pattern_is_ok_for_dispose"
2853 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2854 (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
2855 (mem:SI (plus:SI (reg:SI 3)
2856 (match_operand:SI 3 "immediate_operand" "i"))))])]
2857 "TARGET_PROLOG_FUNCTION && (TARGET_V850E_UP)"
2859 return construct_dispose_instruction (operands[0]);
2861 [(set_attr "length" "4")])
2863 ;; This pattern will match a return RTX followed by any number of pop RTXs
2864 ;; and possible a stack adjustment as well. These RTXs will be turned into
2865 ;; a suitable call to a worker function.
2868 [(match_parallel 0 "pattern_is_ok_for_epilogue"
2871 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2872 (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
2873 (mem:SI (plus:SI (reg:SI 3)
2874 (match_operand:SI 3 "immediate_operand" "i"))))])]
2875 "TARGET_PROLOG_FUNCTION"
2877 return construct_restore_jr (operands[0]);
2879 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
2881 (const_string "4")))])
2883 ;; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION.
2884 (define_insn "callt_save_interrupt"
2885 [(unspec_volatile [(const_int 0)] 2)
2886 (clobber (reg:CC CC_REGNUM))]
2887 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2888 ;; The CALLT instruction stores the next address of CALLT to CTPC register
2889 ;; without saving its previous value. So if the interrupt handler
2890 ;; or its caller could possibly execute the CALLT insn, save_interrupt
2891 ;; MUST NOT be called via CALLT.
2893 output_asm_insn ("addi -28, sp, sp", operands);
2894 output_asm_insn ("st.w r1, 24[sp]", operands);
2895 output_asm_insn ("st.w r10, 12[sp]", operands);
2896 output_asm_insn ("st.w r11, 16[sp]", operands);
2897 output_asm_insn ("stsr ctpc, r10", operands);
2898 output_asm_insn ("st.w r10, 20[sp]", operands);
2899 output_asm_insn ("stsr ctpsw, r10", operands);
2900 output_asm_insn ("st.w r10, 24[sp]", operands);
2901 output_asm_insn ("callt ctoff(__callt_save_interrupt)", operands);
2904 [(set_attr "length" "26")])
2906 (define_insn "callt_return_interrupt"
2907 [(unspec_volatile [(const_int 0)] 3)
2908 (clobber (reg:CC CC_REGNUM))]
2909 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2910 "callt ctoff(__callt_return_interrupt)"
2911 [(set_attr "length" "2")])
2913 (define_insn "save_interrupt"
2914 [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -20)))
2915 (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 30))
2916 (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 4))
2917 (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))
2918 (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 10))
2919 (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 11))
2920 (clobber (reg:CC CC_REGNUM))]
2923 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2924 return "addi -20,sp,sp \; st.w r11,16[sp] \; st.w r10,12[sp] \; jarl __save_interrupt,r10";
2927 output_asm_insn ("addi -20, sp, sp", operands);
2928 output_asm_insn ("st.w r11, 16[sp]", operands);
2929 output_asm_insn ("st.w r10, 12[sp]", operands);
2930 output_asm_insn ("st.w ep, 0[sp]", operands);
2931 output_asm_insn ("st.w gp, 4[sp]", operands);
2932 output_asm_insn ("st.w r1, 8[sp]", operands);
2933 output_asm_insn ("movhi hi(__ep), r0, ep", operands);
2934 output_asm_insn ("movea lo(__ep), ep, ep", operands);
2935 output_asm_insn ("movhi hi(__gp), r0, gp", operands);
2936 output_asm_insn ("movea lo(__gp), gp, gp", operands);
2940 [(set (attr "length")
2941 (if_then_else (match_test "TARGET_LONG_CALLS")
2945 ;; Restore r1, r4, r10, and return from the interrupt
2946 (define_insn "return_interrupt"
2948 (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 20)))
2949 (set (reg:SI 11) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))
2950 (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
2951 (set (reg:SI 1) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
2952 (set (reg:SI 4) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))
2953 (set (reg:SI 30) (mem:SI (reg:SI 3)))
2954 (clobber (reg:CC CC_REGNUM))]
2957 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2958 return "jr __return_interrupt";
2961 output_asm_insn ("ld.w 0[sp], ep", operands);
2962 output_asm_insn ("ld.w 4[sp], gp", operands);
2963 output_asm_insn ("ld.w 8[sp], r1", operands);
2964 output_asm_insn ("ld.w 12[sp], r10", operands);
2965 output_asm_insn ("ld.w 16[sp], r11", operands);
2966 output_asm_insn ("addi 20, sp, sp", operands);
2967 output_asm_insn ("reti", operands);
2971 [(set (attr "length")
2972 (if_then_else (match_test "TARGET_LONG_CALLS")
2976 ;; Save all registers except for the registers saved in save_interrupt when
2977 ;; an interrupt function makes a call.
2978 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2979 ;; all of memory. This blocks insns from being moved across this point.
2980 ;; This is needed because the rest of the compiler is not ready to handle
2981 ;; insns this complicated.
2983 (define_insn "callt_save_all_interrupt"
2984 [(unspec_volatile [(const_int 0)] 0)
2985 (clobber (reg:CC CC_REGNUM))]
2986 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2987 "callt ctoff(__callt_save_all_interrupt)"
2988 [(set_attr "length" "2")])
2990 (define_insn "save_all_interrupt"
2991 [(unspec_volatile [(const_int 0)] 0)
2992 (clobber (reg:CC CC_REGNUM))]
2995 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2996 return "jarl __save_all_interrupt,r10";
2998 output_asm_insn ("addi -120, sp, sp", operands);
3002 output_asm_insn ("mov ep, r1", operands);
3003 output_asm_insn ("mov sp, ep", operands);
3004 output_asm_insn ("sst.w r31, 116[ep]", operands);
3005 output_asm_insn ("sst.w r2, 112[ep]", operands);
3006 output_asm_insn ("sst.w gp, 108[ep]", operands);
3007 output_asm_insn ("sst.w r6, 104[ep]", operands);
3008 output_asm_insn ("sst.w r7, 100[ep]", operands);
3009 output_asm_insn ("sst.w r8, 96[ep]", operands);
3010 output_asm_insn ("sst.w r9, 92[ep]", operands);
3011 output_asm_insn ("sst.w r11, 88[ep]", operands);
3012 output_asm_insn ("sst.w r12, 84[ep]", operands);
3013 output_asm_insn ("sst.w r13, 80[ep]", operands);
3014 output_asm_insn ("sst.w r14, 76[ep]", operands);
3015 output_asm_insn ("sst.w r15, 72[ep]", operands);
3016 output_asm_insn ("sst.w r16, 68[ep]", operands);
3017 output_asm_insn ("sst.w r17, 64[ep]", operands);
3018 output_asm_insn ("sst.w r18, 60[ep]", operands);
3019 output_asm_insn ("sst.w r19, 56[ep]", operands);
3020 output_asm_insn ("sst.w r20, 52[ep]", operands);
3021 output_asm_insn ("sst.w r21, 48[ep]", operands);
3022 output_asm_insn ("sst.w r22, 44[ep]", operands);
3023 output_asm_insn ("sst.w r23, 40[ep]", operands);
3024 output_asm_insn ("sst.w r24, 36[ep]", operands);
3025 output_asm_insn ("sst.w r25, 32[ep]", operands);
3026 output_asm_insn ("sst.w r26, 28[ep]", operands);
3027 output_asm_insn ("sst.w r27, 24[ep]", operands);
3028 output_asm_insn ("sst.w r28, 20[ep]", operands);
3029 output_asm_insn ("sst.w r29, 16[ep]", operands);
3030 output_asm_insn ("mov r1, ep", operands);
3034 output_asm_insn ("st.w r31, 116[sp]", operands);
3035 output_asm_insn ("st.w r2, 112[sp]", operands);
3036 output_asm_insn ("st.w gp, 108[sp]", operands);
3037 output_asm_insn ("st.w r6, 104[sp]", operands);
3038 output_asm_insn ("st.w r7, 100[sp]", operands);
3039 output_asm_insn ("st.w r8, 96[sp]", operands);
3040 output_asm_insn ("st.w r9, 92[sp]", operands);
3041 output_asm_insn ("st.w r11, 88[sp]", operands);
3042 output_asm_insn ("st.w r12, 84[sp]", operands);
3043 output_asm_insn ("st.w r13, 80[sp]", operands);
3044 output_asm_insn ("st.w r14, 76[sp]", operands);
3045 output_asm_insn ("st.w r15, 72[sp]", operands);
3046 output_asm_insn ("st.w r16, 68[sp]", operands);
3047 output_asm_insn ("st.w r17, 64[sp]", operands);
3048 output_asm_insn ("st.w r18, 60[sp]", operands);
3049 output_asm_insn ("st.w r19, 56[sp]", operands);
3050 output_asm_insn ("st.w r20, 52[sp]", operands);
3051 output_asm_insn ("st.w r21, 48[sp]", operands);
3052 output_asm_insn ("st.w r22, 44[sp]", operands);
3053 output_asm_insn ("st.w r23, 40[sp]", operands);
3054 output_asm_insn ("st.w r24, 36[sp]", operands);
3055 output_asm_insn ("st.w r25, 32[sp]", operands);
3056 output_asm_insn ("st.w r26, 28[sp]", operands);
3057 output_asm_insn ("st.w r27, 24[sp]", operands);
3058 output_asm_insn ("st.w r28, 20[sp]", operands);
3059 output_asm_insn ("st.w r29, 16[sp]", operands);
3064 [(set (attr "length")
3065 (if_then_else (match_test "TARGET_LONG_CALLS")
3070 (define_insn "_save_all_interrupt"
3071 [(unspec_volatile [(const_int 0)] 0)
3072 (clobber (reg:CC CC_REGNUM))]
3073 "TARGET_V850 && ! TARGET_LONG_CALLS"
3074 "jarl __save_all_interrupt,r10"
3075 [(set_attr "length" "4")])
3077 ;; Restore all registers saved when an interrupt function makes a call.
3078 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3079 ;; all of memory. This blocks insns from being moved across this point.
3080 ;; This is needed because the rest of the compiler is not ready to handle
3081 ;; insns this complicated.
3083 (define_insn "callt_restore_all_interrupt"
3084 [(unspec_volatile [(const_int 0)] 1)
3085 (clobber (reg:CC CC_REGNUM))]
3086 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
3087 "callt ctoff(__callt_restore_all_interrupt)"
3088 [(set_attr "length" "2")])
3090 (define_insn "restore_all_interrupt"
3091 [(unspec_volatile [(const_int 0)] 1)
3092 (clobber (reg:CC CC_REGNUM))]
3095 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
3096 return "jarl __restore_all_interrupt,r10";
3100 output_asm_insn ("mov ep, r1", operands);
3101 output_asm_insn ("mov sp, ep", operands);
3102 output_asm_insn ("sld.w 116[ep], r31", operands);
3103 output_asm_insn ("sld.w 112[ep], r2", operands);
3104 output_asm_insn ("sld.w 108[ep], gp", operands);
3105 output_asm_insn ("sld.w 104[ep], r6", operands);
3106 output_asm_insn ("sld.w 100[ep], r7", operands);
3107 output_asm_insn ("sld.w 96[ep], r8", operands);
3108 output_asm_insn ("sld.w 92[ep], r9", operands);
3109 output_asm_insn ("sld.w 88[ep], r11", operands);
3110 output_asm_insn ("sld.w 84[ep], r12", operands);
3111 output_asm_insn ("sld.w 80[ep], r13", operands);
3112 output_asm_insn ("sld.w 76[ep], r14", operands);
3113 output_asm_insn ("sld.w 72[ep], r15", operands);
3114 output_asm_insn ("sld.w 68[ep], r16", operands);
3115 output_asm_insn ("sld.w 64[ep], r17", operands);
3116 output_asm_insn ("sld.w 60[ep], r18", operands);
3117 output_asm_insn ("sld.w 56[ep], r19", operands);
3118 output_asm_insn ("sld.w 52[ep], r20", operands);
3119 output_asm_insn ("sld.w 48[ep], r21", operands);
3120 output_asm_insn ("sld.w 44[ep], r22", operands);
3121 output_asm_insn ("sld.w 40[ep], r23", operands);
3122 output_asm_insn ("sld.w 36[ep], r24", operands);
3123 output_asm_insn ("sld.w 32[ep], r25", operands);
3124 output_asm_insn ("sld.w 28[ep], r26", operands);
3125 output_asm_insn ("sld.w 24[ep], r27", operands);
3126 output_asm_insn ("sld.w 20[ep], r28", operands);
3127 output_asm_insn ("sld.w 16[ep], r29", operands);
3128 output_asm_insn ("mov r1, ep", operands);
3132 output_asm_insn ("ld.w 116[sp], r31", operands);
3133 output_asm_insn ("ld.w 112[sp], r2", operands);
3134 output_asm_insn ("ld.w 108[sp], gp", operands);
3135 output_asm_insn ("ld.w 104[sp], r6", operands);
3136 output_asm_insn ("ld.w 100[sp], r7", operands);
3137 output_asm_insn ("ld.w 96[sp], r8", operands);
3138 output_asm_insn ("ld.w 92[sp], r9", operands);
3139 output_asm_insn ("ld.w 88[sp], r11", operands);
3140 output_asm_insn ("ld.w 84[sp], r12", operands);
3141 output_asm_insn ("ld.w 80[sp], r13", operands);
3142 output_asm_insn ("ld.w 76[sp], r14", operands);
3143 output_asm_insn ("ld.w 72[sp], r15", operands);
3144 output_asm_insn ("ld.w 68[sp], r16", operands);
3145 output_asm_insn ("ld.w 64[sp], r17", operands);
3146 output_asm_insn ("ld.w 60[sp], r18", operands);
3147 output_asm_insn ("ld.w 56[sp], r19", operands);
3148 output_asm_insn ("ld.w 52[sp], r20", operands);
3149 output_asm_insn ("ld.w 48[sp], r21", operands);
3150 output_asm_insn ("ld.w 44[sp], r22", operands);
3151 output_asm_insn ("ld.w 40[sp], r23", operands);
3152 output_asm_insn ("ld.w 36[sp], r24", operands);
3153 output_asm_insn ("ld.w 32[sp], r25", operands);
3154 output_asm_insn ("ld.w 28[sp], r26", operands);
3155 output_asm_insn ("ld.w 24[sp], r27", operands);
3156 output_asm_insn ("ld.w 20[sp], r28", operands);
3157 output_asm_insn ("ld.w 16[sp], r29", operands);
3159 output_asm_insn ("addi 120, sp, sp", operands);
3162 [(set (attr "length")
3163 (if_then_else (match_test "TARGET_LONG_CALLS")
3168 (define_insn "_restore_all_interrupt"
3169 [(unspec_volatile [(const_int 0)] 1)
3170 (clobber (reg:CC CC_REGNUM))]
3171 "TARGET_V850 && ! TARGET_LONG_CALLS"
3172 "jarl __restore_all_interrupt,r10"
3173 [(set_attr "length" "4")])