]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/v850/v850.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / v850 / v850.md
1 ;; GCC machine description for NEC V850
2 ;; Copyright (C) 1996-2022 Free Software Foundation, Inc.
3 ;; Contributed by Jeff Law (law@cygnus.com).
4
5 ;; This file is part of GCC.
6
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)
10 ;; any later version.
11
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.
16
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/>.
20
21 ;; The original PO technology requires these to be ordered by speed,
22 ;; so that assigner will pick the fastest.
23
24 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
25
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).
28 ;;
29 ;; One day we'll probably need to handle calls to targets more than 4M
30 ;; away.
31 ;;
32
33 ;; Condition codes
34 ;;
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.
38 ;;
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.
45 ;;
46 ;; As noted, data movement does not affect condition codes.
47 ;;
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
53 ;;
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
59 ;; the effort.
60 ;;
61 ;; Byte swaps seem to change the condition codes, but I haven't tried
62 ;; to describe how.
63 ;;
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.
66
67
68 ;; The size of instructions in bytes.
69
70 ;;---------------------------------------------------------------------------
71 ;; Constants
72
73 ;;
74 (define_constants
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
83 ]
84 )
85
86 (define_c_enum "unspec" [
87 UNSPEC_LOOP
88 UNSPEC_RCP
89 UNSPEC_RSQRT
90 ])
91
92 (define_attr "length" ""
93 (const_int 4))
94
95 (define_attr "long_calls" "yes,no"
96 (const (if_then_else (symbol_ref "TARGET_LONG_CALLS")
97 (const_string "yes")
98 (const_string "no"))))
99
100 ;; Types of instructions (for scheduling purposes).
101
102 (define_attr "type" "load,store,bit1,mult,macc,div,fpu,single,other"
103 (const_string "other"))
104
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")))
119
120 \f
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.
124
125 (define_insn_reservation "v850_other" 1
126 (eq_attr "type" "other")
127 "nothing")
128 (define_insn_reservation "v850_mult" 2
129 (eq_attr "type" "mult")
130 "nothing")
131 (define_insn_reservation "v850_memory" 2
132 (eq_attr "type" "load")
133 "nothing")
134
135 (include "predicates.md")
136 (include "constraints.md")
137 \f
138 ;; ----------------------------------------------------------------------
139 ;; MOVE INSTRUCTIONS
140 ;; ----------------------------------------------------------------------
141 ;; movdi
142
143 (define_expand "movdi"
144 [(set (match_operand:DI 0 "general_operand")
145 (match_operand:DI 1 "general_operand"))]
146 "TARGET_V850E3V5_UP"
147 {
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);
152
153 if (register_operand (operand0, DImode)
154 && (CONST_INT_P (operands[1]) || CONST_DOUBLE_P (operands[1])))
155 {
156 int i;
157
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));
161 DONE;
162 }
163 }
164 )
165
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"))]
169 "TARGET_V850E3V5_UP
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")])
174
175 ;; movqi
176
177 (define_expand "movqi"
178 [(set (match_operand:QI 0 "general_operand" "")
179 (match_operand:QI 1 "general_operand" ""))]
180 ""
181 {
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);
186 })
187
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)"
193 {
194 return output_move_single (operands);
195 }
196 [(set_attr "length" "2,4,2,2,4,4,4")
197 (set_attr "type" "other,other,load,other,load,store,store")])
198
199 ;; movhi
200
201 (define_expand "movhi"
202 [(set (match_operand:HI 0 "general_operand" "")
203 (match_operand:HI 1 "general_operand" ""))]
204 ""
205 {
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);
210 })
211
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)"
217 {
218 return output_move_single (operands);
219 }
220 [(set_attr "length" "2,4,2,2,4,4,4")
221 (set_attr "type" "other,other,load,other,load,store,store")])
222
223 ;; movsi and helpers
224
225 (define_insn "*movsi_high"
226 [(set (match_operand:SI 0 "register_operand" "=r")
227 (high:SI (match_operand 1 "immediate_operand" "i")))]
228 ""
229 "movhi hi(%1),%.,%0"
230 [(set_attr "length" "4")
231 (set_attr "type" "other")])
232
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")))]
237 ""
238 "movea lo(%2),%1,%0"
239 [(set_attr "length" "4")
240 (set_attr "type" "other")])
241
242 (define_expand "movsi"
243 [(set (match_operand:SI 0 "general_operand" "")
244 (match_operand:SI 1 "general_operand" ""))]
245 ""
246 {
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);
251
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])))))
262 {
263 rtx temp;
264
265 if (reload_in_progress || reload_completed)
266 temp = operands[0];
267 else
268 temp = gen_reg_rtx (SImode);
269
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)));
273 DONE;
274 }
275 })
276
277 ;; This is the same as the following pattern, except that it includes
278 ;; support for arbitrary 32-bit immediates.
279
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.
283
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"))]
287 "(TARGET_V850E_UP)
288 && (register_operand (operands[0], SImode)
289 || reg_or_0_operand (operands[1], SImode))"
290 {
291 return output_move_single (operands);
292 }
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")])
295
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)"
301 {
302 return output_move_single (operands);
303 }
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")])
306
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)"
312 {
313 return output_move_single (operands);
314 }
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")])
317
318 ;; ----------------------------------------------------------------------
319 ;; TEST INSTRUCTIONS
320 ;; ----------------------------------------------------------------------
321
322 (define_insn "*v850_tst1"
323 [(set (reg:CCZ CC_REGNUM)
324 (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
325 (const_int 1)
326 (match_operand:QI 1 "const_int_operand" "n"))
327 (const_int 0)))]
328 "reload_completed"
329 "tst1 %1,%0"
330 [(set_attr "length" "4")])
331
332 ;; This replaces ld.b;sar;andi with tst1;setf nz.
333 ;; Should there be variants for HI or SI modes?
334
335 (define_insn_and_split ""
336 [(set (match_operand:SI 0 "register_operand" "")
337 (compare (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
338 (const_int 1)
339 (match_operand 2 "const_int_operand" ""))
340 (const_int 0)))]
341 ""
342 "#"
343 "reload_completed"
344 [(set (reg:CCZ CC_REGNUM) (compare (zero_extract:SI (match_dup 1)
345 (const_int 1)
346 (match_dup 2))
347 (const_int 0)))
348 (set (match_dup 0) (ne:SI (reg:CCZ CC_REGNUM) (const_int 0)))])
349
350 (define_expand "cbranchsi4"
351 [(set (pc)
352 (if_then_else
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 "" ""))
357 (pc)))]
358 "")
359
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")))]
364 "reload_completed"
365 "cmp %1,%0"
366 [(set_attr "length" "2,2")])
367
368 (define_insn_and_split "cbranchsf4"
369 [(set (pc)
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 ""))
374 (pc)))]
375 "TARGET_USE_FPU"
376 "#"
377 "reload_completed"
378 [(set (match_dup 4) (match_dup 5))
379 (set (pc)
380 (if_then_else (match_dup 6)
381 (label_ref (match_dup 3))
382 (pc)))]
383 "{
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
392 in mode MODE. */
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);
397 else
398 operands[6] = gen_rtx_EQ (mode, operands[4], const0_rtx);
399 }")
400
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))]
407 "TARGET_USE_FPU"
408 {
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";
417 gcc_unreachable ();
418 }
419 [(set_attr "length" "12")
420 (set_attr "type" "fpu")])
421
422 (define_insn_and_split "cbranchdf4"
423 [(set (pc)
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 ""))
428 (pc)))]
429 "TARGET_USE_FPU"
430 "#"
431 "reload_completed"
432 ;; How to get the mode here?
433 [(set (match_dup 4) (match_dup 5))
434 (set (pc)
435 (if_then_else (match_dup 6)
436 (label_ref (match_dup 3))
437 (pc)))]
438 "{
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
448 in mode MODE. */
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);
453 else
454 operands[6] = gen_rtx_EQ (mode, operands[4], const0_rtx);
455 }")
456
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))]
463 "TARGET_USE_FPU"
464 {
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";
473 gcc_unreachable ();
474 }
475 [(set_attr "length" "12")
476 (set_attr "type" "fpu")])
477
478 ;; ----------------------------------------------------------------------
479 ;; ADD INSTRUCTIONS
480 ;; ----------------------------------------------------------------------
481
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")))]
486 ""
487 "#"
488 "reload_completed"
489 [(parallel [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
490 (clobber (reg:CC CC_REGNUM))])])
491
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))]
497 ""
498 "@
499 add %2,%0
500 addi %2,%1,%0
501 addi %O2(%P2),%1,%0"
502 [(set_attr "length" "2,4,4")])
503
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"))
508 (const_int 0)))
509 (set (match_operand:SI 0 "register_operand" "=r,r,r")
510 (plus:SI (match_dup 1) (match_dup 2)))]
511 "reload_completed"
512 "@
513 add %2,%0
514 addi %2,%1,%0
515 addi %O2(%P2),%1,%0"
516 [(set_attr "length" "2,4,4")])
517
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")))]
525 ""
526 "#"
527 "reload_completed"
528 [(parallel [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
529 (clobber (reg:CC CC_REGNUM))])])
530
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))]
536 ""
537 "@
538 sub %2,%0
539 subr %1,%0"
540 [(set_attr "length" "2,2")])
541
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"))
546 (const_int 0)))
547 (set (match_operand:SI 0 "register_operand" "=r,r")
548 (minus:SI (match_dup 1) (match_dup 2)))]
549 "reload_completed"
550 "@
551 sub %2,%0
552 subr %1,%0"
553 [(set_attr "length" "2,2")])
554
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")))]
558 ""
559 "#"
560 "reload_completed"
561 [(parallel [(set (match_dup 0) (neg:SI (match_dup 1)))
562 (clobber (reg:CC CC_REGNUM))])])
563
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))]
568 ""
569 "subr %.,%0"
570 [(set_attr "length" "2")])
571
572 (define_insn "*negsi2_set_flags"
573 [(set (reg:CCNZ CC_REGNUM)
574 (compare:CCNZ (neg:SI (match_operand:SI 1 "register_operand" "0"))
575 (const_int 0)))
576 (set (match_operand:SI 0 "register_operand" "=r")
577 (neg:SI (match_dup 1)))]
578 "reload_completed"
579 "subr %.,%0"
580 [(set_attr "length" "2")])
581
582 ;; ----------------------------------------------------------------------
583 ;; MULTIPLY INSTRUCTIONS
584 ;; ----------------------------------------------------------------------
585
586 (define_expand "mulhisi3"
587 [(set (match_operand:SI 0 "register_operand" "")
588 (mult:SI
589 (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
590 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
591 ""
592 {
593 if (GET_CODE (operands[2]) == CONST_INT)
594 {
595 emit_insn (gen_mulhisi3_internal2 (operands[0], operands[1], operands[2]));
596 DONE;
597 }
598 })
599
600 (define_insn "*mulhisi3_internal1"
601 [(set (match_operand:SI 0 "register_operand" "=r")
602 (mult:SI
603 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
604 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
605 ""
606 "mulh %2,%0"
607 [(set_attr "length" "2")
608 (set_attr "type" "mult")])
609
610 (define_insn "mulhisi3_internal2"
611 [(set (match_operand:SI 0 "register_operand" "=r,r")
612 (mult:SI
613 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
614 (match_operand:HI 2 "const_int_operand" "J,K")))]
615 ""
616 "@
617 mulh %2,%0
618 mulhi %2,%1,%0"
619 [(set_attr "length" "2,4")
620 (set_attr "type" "mult")])
621
622 ;; ??? The scheduling info is probably wrong.
623
624 ;; ??? This instruction can also generate the 32-bit highpart, but using it
625 ;; may increase code size counter to the desired result.
626
627 ;; ??? This instructions can also give a DImode result.
628
629 ;; ??? There is unsigned version, but it matters only for the DImode/highpart
630 ;; results.
631
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")))]
636 "(TARGET_V850E_UP)"
637 "mul %2,%1,%."
638 [(set_attr "length" "4")
639 (set_attr "type" "mult")])
640
641 ;; ----------------------------------------------------------------------
642 ;; DIVIDE INSTRUCTIONS
643 ;; ----------------------------------------------------------------------
644
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
647 ;; them.
648
649 ;; ??? The scheduling info is probably wrong.
650
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)
657 (match_dup 2)))
658 (clobber (reg:CC CC_REGNUM))]
659 "TARGET_V850E_UP"
660 {
661 if (TARGET_V850E2_UP)
662 return "divq %2,%0,%3";
663 else
664 return "div %2,%0,%3";
665 }
666 [(set_attr "length" "4")
667 (set_attr "type" "div")])
668
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)
675 (match_dup 2)))
676 (clobber (reg:CC CC_REGNUM))]
677 "TARGET_V850E_UP"
678 {
679 if (TARGET_V850E2_UP)
680 return "divqu %2,%0,%3";
681 else
682 return "divu %2,%0,%3";
683 }
684 [(set_attr "length" "4")
685 (set_attr "type" "div")])
686
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.
689
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)
696 (match_dup 2)))
697 (clobber (reg:CC CC_REGNUM))]
698 "TARGET_V850E_UP"
699 "sxh %0\\n\\tdivh %2,%0,%3"
700 [(set_attr "length" "6")
701 (set_attr "type" "div")])
702
703 ;; The half word needs to be zero/sign extended to 32 bits before doing
704 ;; the division/modulo operation.
705
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)
712 (match_dup 2)))
713 (clobber (reg:CC CC_REGNUM))]
714 "TARGET_V850E_UP"
715 "zxh %0\\n\\ndivhu %2,%0,%3"
716 [(set_attr "length" "6")
717 (set_attr "type" "div")])
718 \f
719 ;; ----------------------------------------------------------------------
720 ;; AND INSTRUCTIONS
721 ;; ----------------------------------------------------------------------
722
723 (define_insn "*v850_clr1_1"
724 [(set (match_operand:QI 0 "memory_operand" "=m")
725 (subreg:QI
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))]
729 ""
730 {
731 rtx xoperands[2];
732 xoperands[0] = operands[0];
733 xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
734 output_asm_insn ("clr1 %M1,%0", xoperands);
735 return "";
736 }
737 [(set_attr "length" "4")
738 (set_attr "type" "bit1")])
739
740 (define_insn "*v850_clr1_2"
741 [(set (match_operand:HI 0 "indirect_operand" "=m")
742 (subreg:HI
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))]
746 ""
747 {
748 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
749
750 rtx xoperands[2];
751 xoperands[0] = gen_rtx_MEM (QImode,
752 plus_constant (Pmode, XEXP (operands[0], 0),
753 log2 / 8));
754 xoperands[1] = GEN_INT (log2 % 8);
755 output_asm_insn ("clr1 %1,%0", xoperands);
756 return "";
757 }
758 [(set_attr "length" "4")
759 (set_attr "type" "bit1")])
760
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))]
766 ""
767 {
768 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
769
770 rtx xoperands[2];
771 xoperands[0] = gen_rtx_MEM (QImode,
772 plus_constant (Pmode, XEXP (operands[0], 0),
773 log2 / 8));
774 xoperands[1] = GEN_INT (log2 % 8);
775 output_asm_insn ("clr1 %1,%0", xoperands);
776 return "";
777 }
778 [(set_attr "length" "4")
779 (set_attr "type" "bit1")])
780
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")))]
785 ""
786 "#"
787 "reload_completed"
788 [(parallel [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
789 (clobber (reg:CC CC_REGNUM))])])
790
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))]
796 "reload_completed"
797 "@
798 and %2,%0
799 and %.,%0
800 andi %2,%1,%0"
801 [(set_attr "length" "2,2,4")])
802
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"))
807 (const_int 0)))
808 (set (match_operand:SI 0 "register_operand" "=r,r,r")
809 (and:SI (match_dup 1) (match_dup 2)))]
810 "reload_completed"
811 "@
812 and %2,%0
813 and %.,%0
814 andi %2,%1,%0"
815 [(set_attr "length" "2,2,4")])
816
817 ;; ----------------------------------------------------------------------
818 ;; OR INSTRUCTIONS
819 ;; ----------------------------------------------------------------------
820
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))]
826 ""
827 "set1 %M1,%0"
828 [(set_attr "length" "4")
829 (set_attr "type" "bit1")])
830
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))]
835 ""
836 {
837 int log2 = exact_log2 (INTVAL (operands[1]));
838
839 if (log2 < 8)
840 return "set1 %M1,%0";
841 else
842 {
843 rtx xoperands[2];
844 xoperands[0] = gen_rtx_MEM (QImode,
845 plus_constant (Pmode, XEXP (operands[0], 0),
846 log2 / 8));
847 xoperands[1] = GEN_INT (log2 % 8);
848 output_asm_insn ("set1 %1,%0", xoperands);
849 }
850 return "";
851 }
852 [(set_attr "length" "4")
853 (set_attr "type" "bit1")])
854
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))]
860 ""
861 {
862 int log2 = exact_log2 (INTVAL (operands[1]));
863
864 if (log2 < 8)
865 return "set1 %M1,%0";
866 else
867 {
868 rtx xoperands[2];
869 xoperands[0] = gen_rtx_MEM (QImode,
870 plus_constant (Pmode, XEXP (operands[0], 0),
871 log2 / 8));
872 xoperands[1] = GEN_INT (log2 % 8);
873 output_asm_insn ("set1 %1,%0", xoperands);
874 }
875 return "";
876 }
877 [(set_attr "length" "4")
878 (set_attr "type" "bit1")])
879
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")))]
884 ""
885 "#"
886 "reload_completed"
887 [(parallel [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
888 (clobber (reg:CC CC_REGNUM))])])
889
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))]
895 ""
896 "@
897 or %2,%0
898 or %.,%0
899 ori %2,%1,%0"
900 [(set_attr "length" "2,2,4")])
901
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"))
906 (const_int 0)))
907 (set (match_operand:SI 0 "register_operand" "=r,r,r")
908 (ior:SI (match_dup 1) (match_dup 2)))]
909 "reload_completed"
910 "@
911 or %2,%0
912 or %.,%0
913 ori %2,%1,%0"
914 [(set_attr "length" "2,2,4")])
915
916 ;; ----------------------------------------------------------------------
917 ;; XOR INSTRUCTIONS
918 ;; ----------------------------------------------------------------------
919
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))]
925 ""
926 "not1 %M1,%0"
927 [(set_attr "length" "4")
928 (set_attr "type" "bit1")])
929
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))]
934 ""
935 {
936 int log2 = exact_log2 (INTVAL (operands[1]));
937
938 if (log2 < 8)
939 return "not1 %M1,%0";
940 else
941 {
942 rtx xoperands[2];
943 xoperands[0] = gen_rtx_MEM (QImode,
944 plus_constant (Pmode, XEXP (operands[0], 0),
945 log2 / 8));
946 xoperands[1] = GEN_INT (log2 % 8);
947 output_asm_insn ("not1 %1,%0", xoperands);
948 }
949 return "";
950 }
951 [(set_attr "length" "4")
952 (set_attr "type" "bit1")])
953
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))]
959 ""
960 {
961 int log2 = exact_log2 (INTVAL (operands[1]));
962
963 if (log2 < 8)
964 return "not1 %M1,%0";
965 else
966 {
967 rtx xoperands[2];
968 xoperands[0] = gen_rtx_MEM (QImode,
969 plus_constant (Pmode, XEXP (operands[0], 0),
970 log2 / 8));
971 xoperands[1] = GEN_INT (log2 % 8);
972 output_asm_insn ("not1 %1,%0", xoperands);
973 }
974 return "";
975 }
976 [(set_attr "length" "4")
977 (set_attr "type" "bit1")])
978
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")))]
983 ""
984 "#"
985 "reload_completed"
986 [(parallel [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
987 (clobber (reg:CC CC_REGNUM))])])
988
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))]
994 ""
995 "@
996 xor %2,%0
997 xor %.,%0
998 xori %2,%1,%0"
999 [(set_attr "length" "2,2,4")])
1000
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"))
1005 (const_int 0)))
1006 (set (match_operand:SI 0 "register_operand" "=r,r,r")
1007 (xor:SI (match_dup 1) (match_dup 2)))]
1008 "reload_completed"
1009 "@
1010 xor %2,%0
1011 xor %.,%0
1012 xori %2,%1,%0"
1013 [(set_attr "length" "2,2,4")])
1014
1015 \f
1016 ;; ----------------------------------------------------------------------
1017 ;; NOT INSTRUCTIONS
1018 ;; ----------------------------------------------------------------------
1019
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")))]
1023 ""
1024 "#"
1025 "reload_completed"
1026 [(parallel [(set (match_dup 0) (not:SI (match_dup 1)))
1027 (clobber (reg:CC CC_REGNUM))])])
1028
1029
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))]
1034 ""
1035 "not %1,%0"
1036 [(set_attr "length" "2")])
1037
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"))
1041 (const_int 0)))
1042 (set (match_operand:SI 0 "register_operand" "=r")
1043 (not:SI (match_dup 1)))]
1044 "reload_completed"
1045 "not %1,%0"
1046 [(set_attr "length" "2")])
1047
1048 ;; -----------------------------------------------------------------
1049 ;; BIT FIELDS
1050 ;; -----------------------------------------------------------------
1051
1052 ;; ??? Is it worth defining insv and extv for the V850 series?!?
1053
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.
1057
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.
1061
1062 (define_insn "insv"
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")])
1071
1072 ;; -----------------------------------------------------------------
1073 ;; Scc INSTRUCTIONS
1074 ;; -----------------------------------------------------------------
1075
1076 (define_insn_and_split "*cbranchsi4_insn"
1077 [(set (pc)
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 "" ""))
1082 (pc)))]
1083 ""
1084 "#"
1085 "reload_completed"
1086 [(set (reg:CC CC_REGNUM)
1087 (compare:CC (match_dup 1) (match_dup 2)))
1088 (set (pc)
1089 (if_then_else (match_op_dup 0
1090 [(reg:CC CC_REGNUM) (const_int 0)])
1091 (label_ref (match_dup 3))
1092 (pc)))]
1093 "")
1094
1095
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")]))]
1101 ""
1102 "#"
1103 "reload_completed"
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)]))]
1108 "")
1109
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)]))]
1114 "reload_completed"
1115 "setf %c1,%0"
1116 [(set_attr "length" "4")])
1117
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"
1122 "setf z,%0"
1123 [(set_attr "length" "4")])
1124
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"
1129 "setf nz,%0"
1130 [(set_attr "length" "4")])
1131
1132 ;; ----------------------------------------------------------------------
1133 ;; CONDITIONAL MOVE INSTRUCTIONS
1134 ;; ----------------------------------------------------------------------
1135
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.
1139
1140 (define_expand "movsicc"
1141 [(set (match_operand:SI 0 "register_operand" "=r")
1142 (if_then_else:SI
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")))]
1146 "(TARGET_V850E_UP)"
1147 {
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)
1151 FAIL;
1152
1153 if ((GET_CODE (operands[2]) == CONST_INT
1154 && GET_CODE (operands[3]) == CONST_INT))
1155 {
1156 int o2 = INTVAL (operands[2]);
1157 int o3 = INTVAL (operands[3]);
1158
1159 if (o2 == 1 && o3 == 0)
1160 FAIL; /* setf */
1161 if (o3 == 1 && o2 == 0)
1162 FAIL; /* setf */
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 */
1167 if (o2 != 0)
1168 operands[2] = copy_to_mode_reg (SImode, operands[2]);
1169 if (o3 !=0 )
1170 operands[3] = copy_to_mode_reg (SImode, operands[3]);
1171 }
1172 else
1173 {
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]);
1178 }
1179 })
1180
1181 (define_insn "movsicc_normal_cc"
1182 [(set (match_operand:SI 0 "register_operand" "=r")
1183 (if_then_else:SI
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")])
1191
1192 (define_insn "movsicc_reversed_cc"
1193 [(set (match_operand:SI 0 "register_operand" "=r")
1194 (if_then_else:SI
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")])
1202
1203 (define_insn_and_split "*movsicc_normal"
1204 [(set (match_operand:SI 0 "register_operand" "=r")
1205 (if_then_else:SI
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")))]
1211 "(TARGET_V850E_UP)"
1212 "#"
1213 "reload_completed"
1214 [(set (reg:CC CC_REGNUM)
1215 (compare:CC (match_dup 4) (match_dup 5)))
1216 (set (match_dup 0)
1217 (if_then_else:SI (match_op_dup 1
1218 [(reg:CC CC_REGNUM) (const_int 0)])
1219 (match_dup 2) (match_dup 3)))])
1220
1221
1222 (define_insn_and_split "*movsicc_reversed"
1223 [(set (match_operand:SI 0 "register_operand" "=r")
1224 (if_then_else:SI
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")))]
1230 "(TARGET_V850E_UP)"
1231 "#"
1232 "reload_completed"
1233 [(set (reg:CC CC_REGNUM)
1234 (compare:CC (match_dup 4) (match_dup 5)))
1235 (set (match_dup 0)
1236 (if_then_else:SI (match_op_dup 1
1237 [(reg:CC CC_REGNUM) (const_int 0)])
1238 (match_dup 2) (match_dup 3)))])
1239
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")
1243 (if_then_else:SI
1244 (match_operator 1 "comparison_operator"
1245 [(zero_extract:SI
1246 (match_operand:QI 2 "memory_operand" "m")
1247 (const_int 1)
1248 (match_operand 3 "const_int_operand" "n"))
1249 (const_int 0)])
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))]
1253 "(TARGET_V850E_UP)"
1254 "tst1 %3,%2 ; cmov %c1,%4,%z5,%0"
1255 [(set_attr "length" "8")])
1256
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")
1260 (if_then_else:SI
1261 (match_operator 1 "comparison_operator"
1262 [(zero_extract:SI
1263 (match_operand:QI 2 "memory_operand" "m")
1264 (const_int 1)
1265 (match_operand 3 "const_int_operand" "n"))
1266 (const_int 0)])
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))]
1270 "(TARGET_V850E_UP)"
1271 "tst1 %3,%2 ; cmov %C1,%5,%z4,%0"
1272 [(set_attr "length" "8")])
1273
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.
1278
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
1281 ;; to bother.
1282 (define_insn "*sasf"
1283 [(set (match_operand:SI 0 "register_operand" "=r")
1284 (ior:SI
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")
1289 (const_int 1))))
1290 (clobber (reg:CC CC_REGNUM))]
1291 "(TARGET_V850E_UP)"
1292 "cmp %4,%3 ; sasf %c1,%0"
1293 [(set_attr "length" "6")])
1294
1295 (define_split
1296 [(set (match_operand:SI 0 "register_operand" "")
1297 (if_then_else:SI
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))]
1304 "(TARGET_V850E_UP)
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))])]
1315 {
1316 operands[6] = GEN_INT (INTVAL (operands[2]) >> 1);
1317 if (INTVAL (operands[2]) & 0x1)
1318 operands[7] = operands[1];
1319 else
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));
1323 })
1324
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))])]
1333 "(TARGET_V850E_UP)"
1334 {
1335 if (INTVAL (operands[2]) != 8)
1336 FAIL;
1337 })
1338
1339 (define_insn "*rotlhi3_8"
1340 [(set (match_operand:HI 0 "register_operand" "=r")
1341 (rotate:HI (match_operand:HI 1 "register_operand" "r")
1342 (const_int 8)))
1343 (clobber (reg:CC CC_REGNUM))]
1344 "(TARGET_V850E_UP)"
1345 "bsh %1,%0"
1346 [(set_attr "length" "4")])
1347
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))])]
1353 "(TARGET_V850E_UP)"
1354 {
1355 if (INTVAL (operands[2]) != 16)
1356 FAIL;
1357 })
1358
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)"
1368 "rotl %2, %1, %0"
1369 [(set_attr "length" "4")])
1370
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)"
1380 "rotl %2, %1, %0"
1381 [(set_attr "length" "4")])
1382
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"
1389 "rotl %2, %1, %0"
1390 [(set_attr "length" "4")])
1391
1392 (define_insn "*rotlsi3_16"
1393 [(set (match_operand:SI 0 "register_operand" "=r")
1394 (rotate:SI (match_operand:SI 1 "register_operand" "r")
1395 (const_int 16)))
1396 (clobber (reg:CC CC_REGNUM))]
1397 "(TARGET_V850E_UP)"
1398 "hsw %1,%0"
1399 [(set_attr "length" "4")])
1400
1401 ;; ----------------------------------------------------------------------
1402 ;; JUMP INSTRUCTIONS
1403 ;; ----------------------------------------------------------------------
1404
1405 ;; Doloop
1406
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"
1411 {
1412 rtx loop_cnt = operands[0];
1413 gcc_assert (GET_MODE (loop_cnt) == SImode);
1414 emit_insn (gen_fix_loop_counter (loop_cnt));
1415 DONE;
1416 }
1417 )
1418
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"
1425 {
1426 switch (which_alternative)
1427 {
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 ();
1431 }
1432 }
1433 [(set_attr "length" "2,6")])
1434
1435 (define_expand "doloop_end"
1436 [(use (match_operand 0 "" "")) ; loop pseudo
1437 (use (match_operand 1 "" ""))] ; label
1438 "TARGET_V850E3V5_UP && TARGET_LOOP"
1439 {
1440 rtx loop_cnt = operands[0];
1441 rtx label = operands[1];
1442
1443 if (GET_MODE (loop_cnt) != SImode)
1444 FAIL;
1445
1446 emit_jump_insn (gen_doloop_end_internal_loop (label, loop_cnt));
1447 DONE;
1448 }
1449 )
1450
1451 (define_insn "doloop_end_internal_loop"
1452 [(set (pc)
1453 (if_then_else (ne (match_operand:SI 1 "register_operand" "+r,!m")
1454 (const_int 0))
1455 (label_ref (match_operand 0 "" ""))
1456 (pc)))
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"
1461 {
1462 switch (which_alternative)
1463 {
1464 case 0:
1465 if (get_attr_length (insn) == 4)
1466 return "loop %1, %0 # LOOP.1.0";
1467
1468 return "add -1, %1; bne %l0 # LOOP.1.1";
1469 case 1:
1470 return "ld.w %1, %2; add -1, %2; st.w %2, %1; bne %l0 # LOOP.2.1";
1471 default:
1472 gcc_unreachable ();
1473 }
1474 }
1475 [(set (attr "length")
1476 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1477 (const_int 65534))
1478 (const_int 4)
1479 (const_int 14)))])
1480
1481 ;; Conditional jump instructions
1482
1483 (define_insn_and_split "*cbranchsi4_insn"
1484 [(set (pc)
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 "" ""))
1489 (pc)))]
1490 ""
1491 "#"
1492 "reload_completed"
1493 [(set (reg:CC CC_REGNUM)
1494 (compare:CC (match_dup 1) (match_dup 2)))
1495 (set (pc)
1496 (if_then_else (match_op_dup 0
1497 [(reg:CC CC_REGNUM) (const_int 0)])
1498 (label_ref (match_dup 3))
1499 (pc)))]
1500 "")
1501
1502 (define_insn "*branch_normal"
1503 [(set (pc)
1504 (if_then_else (match_operator 1 "comparison_operator"
1505 [(reg CC_REGNUM) (const_int 0)])
1506 (label_ref (match_operand 0 "" ""))
1507 (pc)))]
1508 "reload_completed"
1509 {
1510 bool nzmode = GET_MODE (XEXP (operands[1], 0)) == CCNZmode;
1511 if (get_attr_length (insn) == 2)
1512 {
1513 if (nzmode)
1514 return "b%d1 %l0";
1515 else
1516 return "b%b1 %l0";
1517 }
1518 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1519 {
1520 if (nzmode)
1521 return "b%d1 %l0";
1522 else
1523 return "b%b1 %l0";
1524 }
1525 if (nzmode)
1526 return "b%D1 .+6 ; jr %l0";
1527 else
1528 return "b%B1 .+6 ; jr %l0";
1529 }
1530 [(set (attr "length")
1531 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1532 (const_int 256))
1533 (const_int 2)
1534 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1535 (const_int 65536))
1536 (const_int 4)
1537 (const_int 6))))])
1538
1539 (define_insn "*branch_invert"
1540 [(set (pc)
1541 (if_then_else (match_operator 1 "comparison_operator"
1542 [(reg CC_REGNUM) (const_int 0)])
1543 (pc)
1544 (label_ref (match_operand 0 "" ""))))]
1545 "reload_completed"
1546 {
1547 bool nzmode = GET_MODE (XEXP (operands[1], 0)) == CCNZmode;
1548
1549 if (get_attr_length (insn) == 2)
1550 {
1551 if (nzmode)
1552 return "b%D1 %l0";
1553 else
1554 return "b%B1 %l0";
1555 }
1556
1557 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1558 {
1559 if (nzmode)
1560 return "b%D1 %l0";
1561 else
1562 return "b%B1 %l0";
1563 }
1564
1565 if (nzmode)
1566 return "b%d1 .+6 ; jr %l0";
1567 else
1568 return "b%b1 .+6 ; jr %l0";
1569 }
1570 [(set (attr "length")
1571 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1572 (const_int 256))
1573 (const_int 2)
1574 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1575 (const_int 65536))
1576 (const_int 4)
1577 (const_int 6))))])
1578
1579 ;; Unconditional and other jump instructions.
1580
1581 (define_insn "jump"
1582 [(set (pc)
1583 (label_ref (match_operand 0 "" "")))]
1584 ""
1585 {
1586 if (get_attr_length (insn) == 2)
1587 return "br %0";
1588 else
1589 return "jr %0";
1590 }
1591 [(set (attr "length")
1592 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1593 (const_int 256))
1594 (const_int 2)
1595 (const_int 4)))])
1596
1597 (define_insn "indirect_jump"
1598 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1599 ""
1600 "jmp %0"
1601 [(set_attr "length" "2")])
1602
1603 (define_insn "tablejump"
1604 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1605 (use (label_ref (match_operand 1 "" "")))]
1606 ""
1607 "jmp %0"
1608 [(set_attr "length" "2")])
1609
1610 (define_insn "switch"
1611 [(set (pc)
1612 (plus:SI
1613 (sign_extend:SI
1614 (mem:HI
1615 (plus:SI (ashift:SI (match_operand:SI 0 "register_operand" "r")
1616 (const_int 1))
1617 (label_ref (match_operand 1 "" "")))))
1618 (label_ref (match_dup 1))))]
1619 "(TARGET_V850E_UP)"
1620 "switch %0"
1621 [(set_attr "length" "2")])
1622
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 "" "")]
1628 ""
1629 {
1630 rtx reg = gen_reg_rtx (SImode);
1631 rtx tableaddress = gen_reg_rtx (SImode);
1632 rtx test;
1633 rtx mem;
1634
1635 /* Subtract the lower bound from the index. */
1636 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
1637
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]));
1642
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)
1653 {
1654 rtx reg2 = gen_reg_rtx (HImode);
1655 emit_insn (gen_movhi (reg2, mem));
1656 emit_insn (gen_extendhisi2 (reg, reg2));
1657 }
1658 else
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]));
1664 DONE;
1665 })
1666
1667 ;; Call subroutine with no return value.
1668
1669 (define_expand "call"
1670 [(call (match_operand:QI 0 "general_operand" "")
1671 (match_operand:SI 1 "general_operand" ""))]
1672 ""
1673 {
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]));
1679 else
1680 emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
1681
1682 DONE;
1683 })
1684
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"
1691 {
1692 if (which_alternative == 1)
1693 {
1694 if (TARGET_V850E3V5_UP)
1695 return "jarl [%0], r31";
1696
1697 return "jarl .+4, r31 ; add 4, r31 ; jmp %0";
1698 }
1699
1700 return "jarl %0, r31";
1701 }
1702 [(set_attr "length" "4,8")])
1703
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))]
1709 "TARGET_LONG_CALLS"
1710 {
1711 if (which_alternative == 0)
1712 {
1713 if (GET_CODE (operands[0]) == REG)
1714 return "jarl %0,r31";
1715
1716 if (TARGET_V850E3V5_UP)
1717 return "mov hilo(%0), r11 ; jarl [r11], r31";
1718
1719 return "movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11";
1720 }
1721
1722 if (TARGET_V850E3V5_UP)
1723 return "jarl [%0], r31";
1724
1725 return "jarl .+4,r31 ; add 4,r31 ; jmp %0";
1726 }
1727 [(set_attr "length" "16,8")])
1728
1729 ;; Call subroutine, returning value in operand 0
1730 ;; (which must be a hard register).
1731
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" "")))]
1736 ""
1737 {
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),
1744 operands[2]));
1745 else
1746 emit_call_insn (gen_call_value_internal_short (operands[0],
1747 XEXP (operands[1], 0),
1748 operands[2]));
1749 DONE;
1750 })
1751
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"
1759 {
1760 if (which_alternative == 1)
1761 {
1762 if (TARGET_V850E3V5_UP)
1763 return "jarl [%1], r31";
1764
1765 return "jarl .+4, r31 ; add 4, r31 ; jmp %1";
1766 }
1767
1768 return "jarl %1, r31";
1769 }
1770 [(set_attr "length" "4,8")])
1771
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))]
1778 "TARGET_LONG_CALLS"
1779 {
1780 if (which_alternative == 0)
1781 {
1782 if (GET_CODE (operands[1]) == REG)
1783 return "jarl %1, r31";
1784
1785 /* Reload can generate this pattern.... */
1786 if (TARGET_V850E3V5_UP)
1787 return "mov hilo(%1), r11 ; jarl [r11], r31";
1788
1789 return "movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11";
1790 }
1791
1792 if (TARGET_V850E3V5_UP)
1793 return "jarl [%1], r31";
1794
1795 return "jarl .+4, r31 ; add 4, r31 ; jmp %1";
1796 }
1797 [(set_attr "length" "16,8")])
1798
1799 (define_insn "nop"
1800 [(const_int 0)]
1801 ""
1802 "nop"
1803 [(set_attr "length" "2")])
1804 \f
1805 ;; ----------------------------------------------------------------------
1806 ;; EXTEND INSTRUCTIONS
1807 ;; ----------------------------------------------------------------------
1808
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")
1812 (zero_extend:SI
1813 (match_operand:HI 1 "nonimmediate_operand" "0,r,T,m")))
1814 (clobber (reg:CC CC_REGNUM))]
1815 "(TARGET_V850E_UP)"
1816 "@
1817 zxh %0
1818 andi 65535,%1,%0
1819 sld.hu %1,%0
1820 ld.hu %1,%0"
1821 [(set_attr "length" "2,4,2,4")])
1822
1823 (define_insn "*zero_extendhisi2_v850"
1824 [(set (match_operand:SI 0 "register_operand" "=r")
1825 (zero_extend:SI
1826 (match_operand:HI 1 "register_operand" "r")))
1827 (clobber (reg:CC CC_REGNUM))] ;; A lie, but we have to match the expander
1828 ""
1829 "andi 65535,%1,%0"
1830 [(set_attr "length" "4")])
1831
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"))
1835 (const_int 0)))
1836 (set (match_operand:SI 0 "register_operand" "=r")
1837 (zero_extend:SI (match_dup 1)))]
1838 "reload_completed"
1839 "andi 65535,%1,%0"
1840 [(set_attr "length" "4")])
1841
1842 (define_expand "zero_extendhisi2"
1843 [(parallel [(set (match_operand:SI 0 "register_operand")
1844 (zero_extend:SI
1845 (match_operand:HI 1 "nonimmediate_operand")))
1846 (clobber (reg:CC CC_REGNUM))])]
1847 ""
1848 {
1849 if (! (TARGET_V850E_UP))
1850 operands[1] = force_reg (HImode, operands[1]);
1851 })
1852
1853 (define_insn "*zero_extendqisi2_v850e"
1854 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1855 (zero_extend:SI
1856 (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m")))
1857 (clobber (reg:CC CC_REGNUM))]
1858 "(TARGET_V850E_UP)"
1859 "@
1860 zxb %0
1861 andi 255,%1,%0
1862 sld.bu %1,%0
1863 ld.bu %1,%0"
1864 [(set_attr "length" "2,4,2,4")])
1865
1866 (define_insn "*zero_extendqisi2_v850"
1867 [(set (match_operand:SI 0 "register_operand" "=r")
1868 (zero_extend:SI
1869 (match_operand:QI 1 "register_operand" "r")))
1870 (clobber (reg:CC CC_REGNUM))] ;; A lie, but we have to match the expander
1871 ""
1872 "andi 255,%1,%0"
1873 [(set_attr "length" "4")])
1874
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"))
1878 (const_int 0)))
1879 (set (match_operand:SI 0 "register_operand" "=r")
1880 (zero_extend:SI (match_dup 1)))]
1881 "reload_completed"
1882 "andi 255,%1,%0"
1883 [(set_attr "length" "4")])
1884
1885 (define_expand "zero_extendqisi2"
1886 [(parallel [(set (match_operand:SI 0 "register_operand")
1887 (zero_extend:SI
1888 (match_operand:QI 1 "nonimmediate_operand")))
1889 (clobber (reg:CC CC_REGNUM))])]
1890 ""
1891 {
1892 if (! (TARGET_V850E_UP))
1893 operands[1] = force_reg (QImode, operands[1]);
1894 })
1895
1896 ;;- sign extension instructions
1897
1898 ;; ??? The extendhisi2 pattern should not emit shifts for v850e?
1899
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")))]
1903 "(TARGET_V850E_UP)"
1904 "@
1905 sxh %0
1906 sld.h %1,%0
1907 ld.h %1,%0"
1908 [(set_attr "length" "2,2,4")])
1909
1910 ;; ??? This is missing a sign extend from memory pattern to match the ld.h
1911 ;; instruction.
1912
1913 (define_expand "extendhisi2"
1914 [(parallel [(set (match_dup 2)
1915 (ashift:SI (match_operand:HI 1 "register_operand" "")
1916 (const_int 16)))
1917 (clobber (reg:CC CC_REGNUM))])
1918 (parallel [(set (match_operand:SI 0 "register_operand" "")
1919 (ashiftrt:SI (match_dup 2)
1920 (const_int 16)))
1921 (clobber (reg:CC CC_REGNUM))])]
1922 ""
1923 {
1924 operands[1] = gen_lowpart (SImode, operands[1]);
1925 operands[2] = gen_reg_rtx (SImode);
1926 })
1927
1928 ;; ??? The extendqisi2 pattern should not emit shifts for v850e?
1929
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")))]
1933 "(TARGET_V850E_UP)"
1934 "@
1935 sxb %0
1936 sld.b %1,%0
1937 ld.b %1,%0"
1938 [(set_attr "length" "2,2,4")])
1939
1940 ;; ??? This is missing a sign extend from memory pattern to match the ld.b
1941 ;; instruction.
1942
1943 (define_expand "extendqisi2"
1944 [(parallel [(set (match_dup 2)
1945 (ashift:SI (match_operand:QI 1 "register_operand" "")
1946 (const_int 24)))
1947 (clobber (reg:CC CC_REGNUM))])
1948 (parallel [(set (match_operand:SI 0 "register_operand" "")
1949 (ashiftrt:SI (match_dup 2)
1950 (const_int 24)))
1951 (clobber (reg:CC CC_REGNUM))])]
1952 ""
1953 {
1954 operands[1] = gen_lowpart (SImode, operands[1]);
1955 operands[2] = gen_reg_rtx (SImode);
1956 })
1957 \f
1958 ;; ----------------------------------------------------------------------
1959 ;; SHIFTS
1960 ;; ----------------------------------------------------------------------
1961
1962 (define_insn_and_split "ashlsi3"
1963 [(set (match_operand:SI 0 "register_operand" "=r,r")
1964 (ashift:SI
1965 (match_operand:SI 1 "register_operand" "0,0")
1966 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1967 ""
1968 "#"
1969 "reload_completed"
1970 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1971 (clobber (reg:CC CC_REGNUM))])])
1972
1973 (define_insn "ashlsi3_clobber_flags"
1974 [(set (match_operand:SI 0 "register_operand" "=r,r")
1975 (ashift:SI
1976 (match_operand:SI 1 "register_operand" "0,0")
1977 (match_operand:SI 2 "nonmemory_operand" "r,N")))
1978 (clobber (reg:CC CC_REGNUM))]
1979 ""
1980 "@
1981 shl %2,%0
1982 shl %2,%0"
1983 [(set_attr "length" "4,2")])
1984
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"))
1989 (const_int 0)))
1990 (set (match_operand:SI 0 "register_operand" "=r,r")
1991 (ashift:SI (match_dup 1) (match_dup 2)))]
1992 "reload_completed"
1993 "@
1994 shl %2,%0
1995 shl %2,%0"
1996 [(set_attr "length" "4,2")])
1997
1998 (define_insn "ashlsi3_v850e2_clobber_flags"
1999 [(set (match_operand:SI 0 "register_operand" "=r")
2000 (ashift:SI
2001 (match_operand:SI 1 "register_operand" "r")
2002 (match_operand:SI 2 "nonmemory_operand" "r")))
2003 (clobber (reg:CC CC_REGNUM))]
2004 "TARGET_V850E2_UP"
2005 "shl %2,%1,%0"
2006 [(set_attr "length" "4")])
2007
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"))
2012 (const_int 0)))
2013 (set (match_operand:SI 0 "register_operand" "=r")
2014 (ashift:SI (match_dup 1) (match_dup 2)))]
2015 "reload_completed && TARGET_V850E2_UP"
2016 "shl %2,%1,%0"
2017 [(set_attr "length" "4")])
2018
2019 (define_insn_and_split "lshrsi3"
2020 [(set (match_operand:SI 0 "register_operand" "=r,r")
2021 (lshiftrt:SI
2022 (match_operand:SI 1 "register_operand" "0,0")
2023 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
2024 ""
2025 "#"
2026 "reload_completed"
2027 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
2028 (clobber (reg:CC CC_REGNUM))])])
2029
2030 (define_insn "lshrsi3_clobber_flags"
2031 [(set (match_operand:SI 0 "register_operand" "=r,r")
2032 (lshiftrt:SI
2033 (match_operand:SI 1 "register_operand" "0,0")
2034 (match_operand:SI 2 "nonmemory_operand" "r,N")))
2035 (clobber (reg:CC CC_REGNUM))]
2036 ""
2037 "@
2038 shr %2,%0
2039 shr %2,%0"
2040 [(set_attr "length" "4,2")])
2041
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"))
2046 (const_int 0)))
2047 (set (match_operand:SI 0 "register_operand" "=r,r")
2048 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
2049 "reload_completed"
2050 "@
2051 shr %2,%0
2052 shr %2,%0"
2053 [(set_attr "length" "4,2")])
2054
2055 (define_insn "lshrsi3_v850e2_clobber_flags"
2056 [(set (match_operand:SI 0 "register_operand" "=r")
2057 (lshiftrt:SI
2058 (match_operand:SI 1 "register_operand" "r")
2059 (match_operand:SI 2 "nonmemory_operand" "r")))
2060 (clobber (reg:CC CC_REGNUM))]
2061 "TARGET_V850E2_UP"
2062 "shr %2,%1,%0"
2063 [(set_attr "length" "4")])
2064
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"))
2069 (const_int 0)))
2070 (set (match_operand:SI 0 "register_operand" "=r")
2071 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
2072 "reload_completed && TARGET_V850E2_UP"
2073 "shr %2,%1,%0"
2074 [(set_attr "length" "4")])
2075
2076 (define_insn_and_split "ashrsi3"
2077 [(set (match_operand:SI 0 "register_operand" "=r,r")
2078 (ashiftrt:SI
2079 (match_operand:SI 1 "register_operand" "0,0")
2080 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
2081 ""
2082 "#"
2083 "reload_completed"
2084 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
2085 (clobber (reg:CC CC_REGNUM))])])
2086
2087 (define_insn "ashrsi3_clobber_flags"
2088 [(set (match_operand:SI 0 "register_operand" "=r,r")
2089 (ashiftrt:SI
2090 (match_operand:SI 1 "register_operand" "0,0")
2091 (match_operand:SI 2 "nonmemory_operand" "r,N")))
2092 (clobber (reg:CC CC_REGNUM))]
2093 ""
2094 "@
2095 sar %2,%0
2096 sar %2,%0"
2097 [(set_attr "length" "4,2")])
2098
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"))
2103 (const_int 0)))
2104 (set (match_operand:SI 0 "register_operand" "=r,r")
2105 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
2106 "reload_completed"
2107 "@
2108 sar %2,%0
2109 sar %2,%0"
2110 [(set_attr "length" "4,2")])
2111
2112 (define_insn "ashrsi3_v850e2_clobber_flags"
2113 [(set (match_operand:SI 0 "register_operand" "=r")
2114 (ashiftrt:SI
2115 (match_operand:SI 1 "register_operand" "r")
2116 (match_operand:SI 2 "nonmemory_operand" "r")))
2117 (clobber (reg:CC CC_REGNUM))]
2118 "TARGET_V850E2_UP"
2119 "sar %2,%1,%0"
2120 [(set_attr "length" "4")])
2121
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"))
2126 (const_int 0)))
2127 (set (match_operand:SI 0 "register_operand" "=r")
2128 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
2129 "reload_completed && TARGET_V850E2_UP"
2130 "sar %2,%1,%0"
2131 [(set_attr "length" "4")])
2132
2133 ;; ----------------------------------------------------------------------
2134 ;; FIND FIRST BIT INSTRUCTION
2135 ;; ----------------------------------------------------------------------
2136
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))]
2141 "TARGET_V850E2_UP"
2142 "sch1r %1,%0"
2143 [(set_attr "length" "4")])
2144
2145 ;; ----------------------------------------------------------------------
2146 ;; PROLOGUE/EPILOGUE
2147 ;; ----------------------------------------------------------------------
2148 (define_expand "prologue"
2149 [(const_int 0)]
2150 ""
2151 {
2152 expand_prologue ();
2153 DONE;
2154 })
2155
2156 (define_expand "epilogue"
2157 [(return)]
2158 ""
2159 {
2160 expand_epilogue ();
2161 DONE;
2162 })
2163
2164 (define_insn "return_simple"
2165 [(return)]
2166 "reload_completed"
2167 "jmp [r31]"
2168 [(set_attr "length" "2")])
2169
2170 (define_insn "return_internal"
2171 [(return)
2172 (use (reg:SI 31))]
2173 ""
2174 "jmp [r31]"
2175 [(set_attr "length" "2")])
2176
2177 ;; ----------------------------------------------------------------------
2178 ;; v850e2V3 floating-point hardware support
2179 ;; ----------------------------------------------------------------------
2180
2181
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")))]
2186 "TARGET_USE_FPU"
2187 "addf.s %1,%2,%0"
2188 [(set_attr "length" "4")
2189 (set_attr "type" "fpu")])
2190
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")))]
2195 "TARGET_USE_FPU"
2196 "addf.d %1,%2,%0"
2197 [(set_attr "length" "4")
2198 (set_attr "type" "fpu")])
2199
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")))]
2204 "TARGET_USE_FPU"
2205 "subf.s %2,%1,%0"
2206 [(set_attr "length" "4")
2207 (set_attr "type" "fpu")])
2208
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")))]
2213 "TARGET_USE_FPU"
2214 "subf.d %2,%1,%0"
2215 [(set_attr "length" "4")
2216 (set_attr "type" "fpu")])
2217
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")))]
2222 "TARGET_USE_FPU"
2223 "mulf.s %1,%2,%0"
2224 [(set_attr "length" "4")
2225 (set_attr "type" "fpu")])
2226
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")))]
2231 "TARGET_USE_FPU"
2232 "mulf.d %1,%2,%0"
2233 [(set_attr "length" "4")
2234 (set_attr "type" "fpu")])
2235
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")))]
2240 "TARGET_USE_FPU"
2241 "divf.s %2,%1,%0"
2242 [(set_attr "length" "4")
2243 (set_attr "type" "fpu")])
2244
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")))]
2249 "TARGET_USE_FPU"
2250 "divf.d %2,%1,%0"
2251 [(set_attr "length" "4")
2252 (set_attr "type" "fpu")])
2253
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")))]
2258 "TARGET_USE_FPU"
2259 "minf.s %z1,%z2,%0"
2260 [(set_attr "length" "4")
2261 (set_attr "type" "fpu")])
2262
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")))]
2267 "TARGET_USE_FPU"
2268 "minf.d %1,%2,%0"
2269 [(set_attr "length" "4")
2270 (set_attr "type" "fpu")])
2271
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")))]
2276 "TARGET_USE_FPU"
2277 "maxf.s %z1,%z2,%0"
2278 [(set_attr "length" "4")
2279 (set_attr "type" "fpu")])
2280
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")))]
2285 "TARGET_USE_FPU"
2286 "maxf.d %1,%2,%0"
2287 [(set_attr "length" "4")
2288 (set_attr "type" "fpu")])
2289
2290 (define_insn "abssf2"
2291 [(set (match_operand:SF 0 "register_operand" "=r")
2292 (abs:SF (match_operand:SF 1 "register_operand" "r")))]
2293 "TARGET_USE_FPU"
2294 "absf.s %1,%0"
2295 [(set_attr "length" "4")
2296 (set_attr "type" "fpu")])
2297
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")))]
2301 "TARGET_USE_FPU"
2302 "absf.d %1,%0"
2303 [(set_attr "length" "4")
2304 (set_attr "type" "fpu")])
2305
2306 (define_insn "negsf2"
2307 [(set (match_operand:SF 0 "register_operand" "=r")
2308 (neg:SF (match_operand:SF 1 "register_operand" "r")))]
2309 "TARGET_USE_FPU"
2310 "negf.s %1,%0"
2311 [(set_attr "length" "4")
2312 (set_attr "type" "fpu")])
2313
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")))]
2317 "TARGET_USE_FPU"
2318 "negf.d %1,%0"
2319 [(set_attr "length" "4")
2320 (set_attr "type" "fpu")])
2321
2322 ;; square-root
2323 (define_insn "sqrtsf2"
2324 [(set (match_operand:SF 0 "register_operand" "=r")
2325 (sqrt:SF (match_operand:SF 1 "register_operand" "r")))]
2326 "TARGET_USE_FPU"
2327 "sqrtf.s %1,%0"
2328 [(set_attr "length" "4")
2329 (set_attr "type" "fpu")])
2330
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")))]
2334 "TARGET_USE_FPU"
2335 "sqrtf.d %1,%0"
2336 [(set_attr "length" "4")
2337 (set_attr "type" "fpu")])
2338
2339 ;; float -> int
2340 (define_insn "fix_truncsfsi2"
2341 [(set (match_operand:SI 0 "register_operand" "=r")
2342 (fix:SI (match_operand:SF 1 "register_operand" "r")))]
2343 "TARGET_USE_FPU"
2344 "trncf.sw %1,%0"
2345 [(set_attr "length" "4")
2346 (set_attr "type" "fpu")])
2347
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")))]
2351 "TARGET_USE_FPU"
2352 "trncf.suw %1, %0"
2353 [(set_attr "length" "4")
2354 (set_attr "type" "fpu")])
2355
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")))]
2359 "TARGET_USE_FPU"
2360 "trncf.dw %1,%0"
2361 [(set_attr "length" "4")
2362 (set_attr "type" "fpu")])
2363
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")))]
2367 "TARGET_USE_FPU"
2368 "trncf.duw %1, %0"
2369 [(set_attr "length" "4")
2370 (set_attr "type" "fpu")])
2371
2372 (define_insn "fix_truncsfdi2"
2373 [(set (match_operand:DI 0 "register_operand" "=r")
2374 (fix:DI (match_operand:SF 1 "register_operand" "r")))]
2375 "TARGET_USE_FPU"
2376 "trncf.sl %1, %0"
2377 [(set_attr "length" "4")
2378 (set_attr "type" "fpu")])
2379
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")))]
2383 "TARGET_USE_FPU"
2384 "trncf.sul %1, %0"
2385 [(set_attr "length" "4")
2386 (set_attr "type" "fpu")])
2387
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")))]
2391 "TARGET_USE_FPU"
2392 "trncf.dl %1, %0"
2393 [(set_attr "length" "4")
2394 (set_attr "type" "fpu")])
2395
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")))]
2399 "TARGET_USE_FPU"
2400 "trncf.dul %1, %0"
2401 [(set_attr "length" "4")
2402 (set_attr "type" "fpu")])
2403
2404 ;; int -> float
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")))]
2408 "TARGET_USE_FPU"
2409 "cvtf.ws %z1, %0"
2410 [(set_attr "length" "4")
2411 (set_attr "type" "fpu")])
2412
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")))]
2416 "TARGET_USE_FPU"
2417 "cvtf.uws %z1, %0"
2418 [(set_attr "length" "4")
2419 (set_attr "type" "fpu")])
2420
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")))]
2424 "TARGET_USE_FPU"
2425 "cvtf.wd %z1,%0"
2426 [(set_attr "length" "4")
2427 (set_attr "type" "fpu")])
2428
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")))]
2432 "TARGET_USE_FPU"
2433 "cvtf.uwd %z1, %0"
2434 [(set_attr "length" "4")
2435 (set_attr "type" "fpu")])
2436
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")))]
2440 "TARGET_USE_FPU"
2441 "cvtf.ls %z1, %0"
2442 [(set_attr "length" "4")
2443 (set_attr "type" "fpu")])
2444
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")))]
2448 "TARGET_USE_FPU"
2449 "cvtf.uls %z1, %0"
2450 [(set_attr "length" "4")
2451 (set_attr "type" "fpu")])
2452
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")))]
2456 "TARGET_USE_FPU"
2457 "cvtf.ld %z1, %0"
2458 [(set_attr "length" "4")
2459 (set_attr "type" "fpu")])
2460
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")))]
2464 "TARGET_USE_FPU"
2465 "cvtf.uld %z1, %0"
2466 [(set_attr "length" "4")
2467 (set_attr "type" "fpu")])
2468
2469 ;; single-float -> double-float
2470 (define_insn "extendsfdf2"
2471 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2472 (float_extend:DF
2473 (match_operand:SF 1 "reg_or_0_operand" "rI")))]
2474 "TARGET_USE_FPU"
2475 "cvtf.sd %z1,%0"
2476 [(set_attr "length" "4")
2477 (set_attr "type" "fpu")])
2478
2479 ;; double-float -> single-float
2480 (define_insn "truncdfsf2"
2481 [(set (match_operand:SF 0 "register_operand" "=r")
2482 (float_truncate:SF
2483 (match_operand:DF 1 "even_reg_operand" "r")))]
2484 "TARGET_USE_FPU"
2485 "cvtf.ds %1,%0"
2486 [(set_attr "length" "4")
2487 (set_attr "type" "fpu")])
2488
2489 ;;
2490 ;; ---------------- special insns
2491 ;;
2492
2493 ;; reciprocal
2494
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.
2499
2500 (define_expand "recipsf2"
2501 [(set (match_operand:SF 0 "register_operand" "")
2502 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
2503 UNSPEC_RCP))]
2504 "TARGET_USE_FPU"
2505 {
2506 emit_insn (gen_recipsf2_insn (operands[0], CONST1_RTX (SFmode), operands[1]));
2507 DONE;
2508 })
2509
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")))]
2514 "TARGET_USE_FPU"
2515 "recipf.s %2,%0"
2516 [(set_attr "length" "4")
2517 (set_attr "type" "fpu")])
2518
2519 (define_expand "recipdf2"
2520 [(set (match_operand:DF 0 "even_reg_operand" "")
2521 (unspec:DF [(match_operand:SF 1 "even_reg_operand" "")]
2522 UNSPEC_RCP))]
2523 "TARGET_USE_FPU"
2524 {
2525 emit_insn (gen_recipdf2_insn (operands[0], CONST1_RTX (DFmode), operands[1]));
2526 DONE;
2527 })
2528
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")))]
2533 "TARGET_USE_FPU"
2534 "recipf.d %2,%0"
2535 [(set_attr "length" "4")
2536 (set_attr "type" "fpu")])
2537
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" "")]
2542 UNSPEC_RSQRT))]
2543 "TARGET_USE_FPU"
2544 {
2545 emit_insn (gen_rsqrtsf2_insn (operands[0], CONST1_RTX (SFmode), operands[1]));
2546 DONE;
2547 })
2548
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"))))]
2553 "TARGET_USE_FPU"
2554 "rsqrtf.s %2,%0"
2555 [(set_attr "length" "4")
2556 (set_attr "type" "fpu")])
2557
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")]
2561 UNSPEC_RSQRT))]
2562 "TARGET_USE_FPU"
2563 {
2564 emit_insn (gen_rsqrtdf2_insn (operands[0], CONST1_RTX (DFmode), operands[1]));
2565 DONE;
2566 })
2567
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"))))]
2572 "TARGET_USE_FPU"
2573 "rsqrtf.d %2,%0"
2574 [(set_attr "length" "4")
2575 (set_attr "type" "fpu")])
2576
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.
2580
2581 ;;; multiply-add
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")))]
2587 "TARGET_USE_FPU"
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")])
2591
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"))))]
2598 "TARGET_USE_FPU"
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")])
2602
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"))))]
2609 "TARGET_USE_FPU"
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")])
2613
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")))))]
2620 "TARGET_USE_FPU"
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")])
2624 ;
2625 ; ---------------- comparison/conditionals
2626 ;
2627 ; SF
2628
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")])
2637
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")])
2646
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")])
2655
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")])
2664
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")])
2673
2674 ; DF
2675
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")])
2684
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")])
2693
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")])
2702
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")])
2711
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")])
2720
2721 ;;
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)
2724 ;;
2725
2726 (define_insn "trfsr"
2727 [(set (match_operand 0 "" "") (match_operand 1 "" ""))]
2728 "reload_completed
2729 && TARGET_USE_FPU
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)"
2739 "trfsr"
2740 [(set_attr "length" "4")
2741 (set_attr "type" "fpu")])
2742
2743 ;;
2744 ;; Floating-point conditional moves for the v850e2v3.
2745 ;;
2746
2747 ;; The actual v850e2v3 conditional move instructions
2748 ;;
2749 (define_insn "movsfcc_z_insn"
2750 [(set (match_operand:SF 0 "register_operand" "=r")
2751 (if_then_else:SF
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")))]
2755 "TARGET_USE_FPU"
2756 "cmovf.s 0,%z1,%z2,%0")
2757
2758 (define_insn "movsfcc_nz_insn"
2759 [(set (match_operand:SF 0 "register_operand" "=r")
2760 (if_then_else:SF
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")))]
2764 "TARGET_USE_FPU"
2765 "cmovf.s 0,%z2,%z1,%0")
2766
2767 (define_insn "movdfcc_z_insn"
2768 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2769 (if_then_else:DF
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")))]
2773 "TARGET_USE_FPU"
2774 "cmovf.d 0,%z1,%z2,%0")
2775
2776 (define_insn "movdfcc_nz_insn"
2777 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2778 (if_then_else:DF
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")))]
2782 "TARGET_USE_FPU"
2783 "cmovf.d 0,%z2,%z1,%0")
2784
2785 (define_insn "movedfcc_z_zero"
2786 [(set (match_operand:DF 0 "register_operand" "=r")
2787 (if_then_else:DF
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")))]
2791 "TARGET_USE_FPU"
2792 "cmovf.s 0,%z1,%z2,%0 ; cmovf.s 0,%Z1,%Z2,%R0"
2793 [(set_attr "length" "8")])
2794
2795 (define_insn "movedfcc_nz_zero"
2796 [(set (match_operand:DF 0 "register_operand" "=r")
2797 (if_then_else:DF
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")))]
2801 "TARGET_USE_FPU"
2802 "cmovf.s 0,%z2,%z1,%0 ; cmovf.s 0,%Z2,%Z1,%R0"
2803 [(set_attr "length" "8")])
2804
2805
2806 ;; ----------------------------------------------------------------------
2807 ;; HELPER INSTRUCTIONS for saving the prologue and epilogue registers
2808 ;; ----------------------------------------------------------------------
2809
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
2812 ;; function.
2813
2814 ;;
2815 ;; Actually, convert the RTXs into a PREPARE instruction.
2816 ;;
2817
2818 (define_insn ""
2819 [(match_parallel 0 "pattern_is_ok_for_prepare"
2820 [(set (reg:SI 3)
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)"
2826 {
2827 return construct_prepare_instruction (operands[0]);
2828 }
2829 [(set_attr "length" "4")])
2830
2831 (define_insn ""
2832 [(match_parallel 0 "pattern_is_ok_for_prologue"
2833 [(set (reg:SI 3)
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"
2839 {
2840 return construct_save_jarl (operands[0]);
2841 }
2842 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
2843 (const_string "16")
2844 (const_string "4")))])
2845
2846 ;;
2847 ;; Actually, turn the RTXs into a DISPOSE instruction.
2848 ;;
2849 (define_insn ""
2850 [(match_parallel 0 "pattern_is_ok_for_dispose"
2851 [(return)
2852 (set (reg:SI 3)
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)"
2858 {
2859 return construct_dispose_instruction (operands[0]);
2860 }
2861 [(set_attr "length" "4")])
2862
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.
2866
2867 (define_insn ""
2868 [(match_parallel 0 "pattern_is_ok_for_epilogue"
2869 [(return)
2870 (set (reg:SI 3)
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"
2876 {
2877 return construct_restore_jr (operands[0]);
2878 }
2879 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
2880 (const_string "12")
2881 (const_string "4")))])
2882
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.
2892 {
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);
2902 return "";
2903 }
2904 [(set_attr "length" "26")])
2905
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")])
2912
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))]
2921 ""
2922 {
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";
2925 else
2926 {
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);
2937 return "";
2938 }
2939 }
2940 [(set (attr "length")
2941 (if_then_else (match_test "TARGET_LONG_CALLS")
2942 (const_int 10)
2943 (const_int 34)))])
2944
2945 ;; Restore r1, r4, r10, and return from the interrupt
2946 (define_insn "return_interrupt"
2947 [(return)
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))]
2955 ""
2956 {
2957 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2958 return "jr __return_interrupt";
2959 else
2960 {
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);
2968 return "";
2969 }
2970 }
2971 [(set (attr "length")
2972 (if_then_else (match_test "TARGET_LONG_CALLS")
2973 (const_int 4)
2974 (const_int 24)))])
2975
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.
2982
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")])
2989
2990 (define_insn "save_all_interrupt"
2991 [(unspec_volatile [(const_int 0)] 0)
2992 (clobber (reg:CC CC_REGNUM))]
2993 ""
2994 {
2995 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2996 return "jarl __save_all_interrupt,r10";
2997
2998 output_asm_insn ("addi -120, sp, sp", operands);
2999
3000 if (TARGET_EP)
3001 {
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);
3031 }
3032 else
3033 {
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);
3060 }
3061
3062 return "";
3063 }
3064 [(set (attr "length")
3065 (if_then_else (match_test "TARGET_LONG_CALLS")
3066 (const_int 4)
3067 (const_int 62)
3068 ))])
3069
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")])
3076
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.
3082
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")])
3089
3090 (define_insn "restore_all_interrupt"
3091 [(unspec_volatile [(const_int 0)] 1)
3092 (clobber (reg:CC CC_REGNUM))]
3093 ""
3094 {
3095 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
3096 return "jarl __restore_all_interrupt,r10";
3097
3098 if (TARGET_EP)
3099 {
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);
3129 }
3130 else
3131 {
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);
3158 }
3159 output_asm_insn ("addi 120, sp, sp", operands);
3160 return "";
3161 }
3162 [(set (attr "length")
3163 (if_then_else (match_test "TARGET_LONG_CALLS")
3164 (const_int 4)
3165 (const_int 62)
3166 ))])
3167
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")])