]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/v850/v850.md
rtl.h (always_void_p): New function.
[thirdparty/gcc.git] / gcc / config / v850 / v850.md
1 ;; GCC machine description for NEC V850
2 ;; Copyright (C) 1996-2015 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 ;; The size of instructions in bytes.
33
34 ;;---------------------------------------------------------------------------
35 ;; Constants
36
37 ;;
38 (define_constants
39 [(ZERO_REGNUM 0) ; constant zero
40 (SP_REGNUM 3) ; Stack Pointer
41 (GP_REGNUM 4) ; GP Pointer
42 (EP_REGNUM 30) ; EP pointer
43 (LP_REGNUM 31) ; Return address register
44 (CC_REGNUM 32) ; Condition code pseudo register
45 (FCC_REGNUM 33) ; Floating Condition code pseudo register
46 (UNSPEC_LOOP 200) ; loop counter
47 ]
48 )
49
50 (define_attr "length" ""
51 (const_int 4))
52
53 (define_attr "long_calls" "yes,no"
54 (const (if_then_else (symbol_ref "TARGET_LONG_CALLS")
55 (const_string "yes")
56 (const_string "no"))))
57
58 ;; Types of instructions (for scheduling purposes).
59
60 (define_attr "type" "load,store,bit1,mult,macc,div,fpu,single,other"
61 (const_string "other"))
62
63 (define_attr "cpu" "none,v850,v850e,v850e1,v850e2,v850e2v3,v850e3v5"
64 (cond [(match_test "TARGET_V850")
65 (const_string "v850")
66 (match_test "TARGET_V850E")
67 (const_string "v850e")
68 (match_test "TARGET_V850E1")
69 (const_string "v850e1")
70 (match_test "TARGET_V850E2")
71 (const_string "v850e2")
72 (match_test "TARGET_V850E2V3")
73 (const_string "v850e2v3")
74 (match_test "TARGET_V850E3V5")
75 (const_string "v850e3v5")]
76 (const_string "none")))
77
78 ;; Condition code settings.
79 ;; none - insn does not affect cc
80 ;; none_0hit - insn does not affect cc but it does modify operand 0
81 ;; This attribute is used to keep track of when operand 0 changes.
82 ;; See the description of NOTICE_UPDATE_CC for more info.
83 ;; set_znv - sets z,n,v to usable values; c is unknown.
84 ;; set_zn - sets z,n to usable values; v,c is unknown.
85 ;; compare - compare instruction
86 ;; clobber - value of cc is unknown
87 (define_attr "cc" "none,none_0hit,set_z,set_zn,set_znv,compare,clobber"
88 (const_string "clobber"))
89 \f
90 ;; Function units for the V850. As best as I can tell, there's
91 ;; a traditional memory load/use stall as well as a stall if
92 ;; the result of a multiply is used too early.
93
94 (define_insn_reservation "v850_other" 1
95 (eq_attr "type" "other")
96 "nothing")
97 (define_insn_reservation "v850_mult" 2
98 (eq_attr "type" "mult")
99 "nothing")
100 (define_insn_reservation "v850_memory" 2
101 (eq_attr "type" "load")
102 "nothing")
103
104 (include "predicates.md")
105 (include "constraints.md")
106 \f
107 ;; ----------------------------------------------------------------------
108 ;; MOVE INSTRUCTIONS
109 ;; ----------------------------------------------------------------------
110 (define_insn "sign23byte_load"
111 [(set (match_operand:SI 0 "register_operand" "=r")
112 (sign_extend:SI
113 (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
114 (match_operand 2 "disp23_operand" "W")))))]
115 "TARGET_V850E2V3_UP"
116 "ld.b %2[%1],%0"
117 [(set_attr "length" "4")
118 (set_attr "cc" "none_0hit")])
119
120 (define_insn "unsign23byte_load"
121 [(set (match_operand:SI 0 "register_operand" "=r")
122 (zero_extend:SI
123 (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
124 (match_operand 2 "disp23_operand" "W")))))]
125 "TARGET_V850E2V3_UP"
126 "ld.bu %2[%1],%0"
127 [(set_attr "length" "4")
128 (set_attr "cc" "none_0hit")])
129
130 (define_insn "sign23hword_load"
131 [(set (match_operand:SI 0 "register_operand" "=r")
132 (sign_extend:SI
133 (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
134 (match_operand 2 "disp23_operand" "W")))))]
135 "TARGET_V850E2V3_UP"
136 "ld.h %2[%1],%0"
137 [(set_attr "length" "4")
138 (set_attr "cc" "none_0hit")])
139
140 (define_insn "unsign23hword_load"
141 [(set (match_operand:SI 0 "register_operand" "=r")
142 (zero_extend:SI
143 (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
144 (match_operand 2 "disp23_operand" "W")))))]
145 "TARGET_V850E2V3_UP"
146 "ld.hu %2[%1],%0"
147 [(set_attr "length" "4")
148 (set_attr "cc" "none_0hit")])
149
150 (define_insn "23word_load"
151 [(set (match_operand:SI 0 "register_operand" "=r")
152 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
153 (match_operand 2 "disp23_operand" "W"))))]
154 "TARGET_V850E2V3_UP"
155 "ld.w %2[%1],%0"
156 [(set_attr "length" "4")
157 (set_attr "cc" "none_0hit")])
158
159 (define_insn "23byte_store"
160 [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "r")
161 (match_operand 1 "disp23_operand" "W")))
162 (match_operand:QI 2 "register_operand" "r"))]
163 "TARGET_V850E2V3_UP"
164 "st.b %2,%1[%0]"
165 [(set_attr "length" "4")
166 (set_attr "cc" "none_0hit")])
167
168 (define_insn "23hword_store"
169 [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "r")
170 (match_operand 1 "disp23_operand" "W")))
171 (match_operand:HI 2 "register_operand" "r"))]
172 "TARGET_V850E2V3_UP"
173 "st.h %2,%1[%0]"
174 [(set_attr "length" "4")
175 (set_attr "cc" "none_0hit")])
176
177 (define_insn "23word_store"
178 [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
179 (match_operand 1 "disp23_operand" "W")))
180 (match_operand:SI 2 "register_operand" "r"))]
181 "TARGET_V850E2V3_UP"
182 "st.w %2,%1[%0]"
183 [(set_attr "length" "4")
184 (set_attr "cc" "none_0hit")])
185
186 ;; movdi
187
188 (define_expand "movdi"
189 [(set (match_operand:DI 0 "general_operand")
190 (match_operand:DI 1 "general_operand"))]
191 "TARGET_V850E3V5_UP"
192 {
193 /* One of the ops has to be in a register or 0. */
194 if (!register_operand (operand0, DImode)
195 && !register_operand (operand1, DImode))
196 operands[1] = copy_to_mode_reg (DImode, operand1);
197
198 if (register_operand (operand0, DImode)
199 && (CONST_INT_P (operands[1]) || CONST_DOUBLE_P (operands[1])))
200 {
201 int i;
202
203 for (i = 0; i < UNITS_PER_WORD * 2; i += UNITS_PER_WORD)
204 emit_move_insn (simplify_gen_subreg (SImode, operands[0], DImode, i),
205 simplify_gen_subreg (SImode, operands[1], DImode, i));
206 DONE;
207 }
208 }
209 )
210
211 (define_insn "*movdi_internal"
212 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,e!r,m")
213 (match_operand:DI 1 "nonimmediate_operand" "r,m,e!r"))]
214 "TARGET_V850E3V5_UP
215 || (register_operand (operands[0], DImode) && register_operand (operands[1], DImode))"
216 { return v850_gen_movdi (operands); }
217 [(set_attr "length" "4,12,12")
218 (set_attr "cc" "none_0hit")
219 (set_attr "type" "other,load,store")]
220 )
221
222 ;; movqi
223
224 (define_expand "movqi"
225 [(set (match_operand:QI 0 "general_operand" "")
226 (match_operand:QI 1 "general_operand" ""))]
227 ""
228 {
229 /* One of the ops has to be in a register or 0 */
230 if (!register_operand (operand0, QImode)
231 && !reg_or_0_operand (operand1, QImode))
232 operands[1] = copy_to_mode_reg (QImode, operand1);
233 })
234
235 (define_insn "*movqi_internal"
236 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,Q,r,m,m")
237 (match_operand:QI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
238 "register_operand (operands[0], QImode)
239 || reg_or_0_operand (operands[1], QImode)"
240 {
241 return output_move_single (operands);
242 }
243 [(set_attr "length" "2,4,2,2,4,4,4")
244 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
245 (set_attr "type" "other,other,load,other,load,store,store")])
246
247 ;; movhi
248
249 (define_expand "movhi"
250 [(set (match_operand:HI 0 "general_operand" "")
251 (match_operand:HI 1 "general_operand" ""))]
252 ""
253 {
254 /* One of the ops has to be in a register or 0 */
255 if (!register_operand (operand0, HImode)
256 && !reg_or_0_operand (operand1, HImode))
257 operands[1] = copy_to_mode_reg (HImode, operand1);
258 })
259
260 (define_insn "*movhi_internal"
261 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,Q,r,m,m")
262 (match_operand:HI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
263 "register_operand (operands[0], HImode)
264 || reg_or_0_operand (operands[1], HImode)"
265 {
266 return output_move_single (operands);
267 }
268 [(set_attr "length" "2,4,2,2,4,4,4")
269 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
270 (set_attr "type" "other,other,load,other,load,store,store")])
271
272 ;; movsi and helpers
273
274 (define_insn "*movsi_high"
275 [(set (match_operand:SI 0 "register_operand" "=r")
276 (high:SI (match_operand 1 "immediate_operand" "i")))]
277 ""
278 "movhi hi(%1),%.,%0"
279 [(set_attr "length" "4")
280 (set_attr "cc" "none_0hit")
281 (set_attr "type" "other")])
282
283 (define_insn "*movsi_lo"
284 [(set (match_operand:SI 0 "register_operand" "=r")
285 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
286 (match_operand:SI 2 "immediate_operand" "i")))]
287 ""
288 "movea lo(%2),%1,%0"
289 [(set_attr "length" "4")
290 (set_attr "cc" "none_0hit")
291 (set_attr "type" "other")])
292
293 (define_expand "movsi"
294 [(set (match_operand:SI 0 "general_operand" "")
295 (match_operand:SI 1 "general_operand" ""))]
296 ""
297 {
298 /* One of the ops has to be in a register or 0 */
299 if (!register_operand (operand0, SImode)
300 && !reg_or_0_operand (operand1, SImode))
301 operands[1] = copy_to_mode_reg (SImode, operand1);
302
303 /* Some constants, as well as symbolic operands
304 must be done with HIGH & LO_SUM patterns. */
305 if (CONSTANT_P (operands[1])
306 && GET_CODE (operands[1]) != HIGH
307 && ! (TARGET_V850E_UP)
308 && !special_symbolref_operand (operands[1], VOIDmode)
309 && !(GET_CODE (operands[1]) == CONST_INT
310 && (CONST_OK_FOR_J (INTVAL (operands[1]))
311 || CONST_OK_FOR_K (INTVAL (operands[1]))
312 || CONST_OK_FOR_L (INTVAL (operands[1])))))
313 {
314 rtx temp;
315
316 if (reload_in_progress || reload_completed)
317 temp = operands[0];
318 else
319 temp = gen_reg_rtx (SImode);
320
321 emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (SImode, operand1)));
322 emit_insn (gen_rtx_SET (operand0,
323 gen_rtx_LO_SUM (SImode, temp, operand1)));
324 DONE;
325 }
326 })
327
328 ;; This is the same as the following pattern, except that it includes
329 ;; support for arbitrary 32-bit immediates.
330
331 ;; ??? This always loads addresses using hilo. If the only use of this address
332 ;; was in a load/store, then we would get smaller code if we only loaded the
333 ;; upper part with hi, and then put the lower part in the load/store insn.
334
335 (define_insn "*movsi_internal_v850e"
336 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,Q,r,r,m,m,r")
337 (match_operand:SI 1 "general_operand" "Jr,K,L,Q,Ir,m,R,r,I,i"))]
338 "(TARGET_V850E_UP)
339 && (register_operand (operands[0], SImode)
340 || reg_or_0_operand (operands[1], SImode))"
341 {
342 return output_move_single (operands);
343 }
344 [(set_attr "length" "2,4,4,2,2,4,4,4,4,6")
345 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
346 (set_attr "type" "other,other,other,load,other,load,other,store,store,other")])
347
348 (define_insn "*movsi_internal"
349 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,Q,r,r,m,m")
350 (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))]
351 "register_operand (operands[0], SImode)
352 || reg_or_0_operand (operands[1], SImode)"
353 {
354 return output_move_single (operands);
355 }
356 [(set_attr "length" "2,4,4,2,2,4,4,4,4")
357 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
358 (set_attr "type" "other,other,other,load,other,load,store,store,other")])
359
360 (define_insn "*movsf_internal"
361 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,Q,r,m,m,r")
362 (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))]
363 "register_operand (operands[0], SFmode)
364 || reg_or_0_operand (operands[1], SFmode)"
365 {
366 return output_move_single (operands);
367 }
368 [(set_attr "length" "2,4,4,8,2,2,4,4,4,8")
369 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
370 (set_attr "type" "other,other,other,other,load,other,load,store,store,other")])
371
372 ;; ----------------------------------------------------------------------
373 ;; TEST INSTRUCTIONS
374 ;; ----------------------------------------------------------------------
375
376 (define_insn "*v850_tst1"
377 [(set (cc0)
378 (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
379 (const_int 1)
380 (match_operand:QI 1 "const_int_operand" "n"))
381 (const_int 0)))]
382 ""
383 "tst1 %1,%0"
384 [(set_attr "length" "4")
385 (set_attr "cc" "clobber")])
386
387 ;; This replaces ld.b;sar;andi with tst1;setf nz.
388
389 (define_split
390 [(set (match_operand:SI 0 "register_operand" "")
391 (compare (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
392 (const_int 1)
393 (match_operand 2 "const_int_operand" ""))
394 (const_int 0)))]
395 ""
396 [(set (cc0) (compare (zero_extract:SI (match_dup 1)
397 (const_int 1)
398 (match_dup 2))
399 (const_int 0)))
400 (set (match_dup 0) (ne:SI (cc0) (const_int 0)))])
401
402 (define_expand "cbranchsi4"
403 [(set (cc0)
404 (compare (match_operand:SI 1 "register_operand" "")
405 (match_operand:SI 2 "reg_or_int5_operand" "")))
406 (set (pc)
407 (if_then_else
408 (match_operator 0 "ordered_comparison_operator" [(cc0)
409 (const_int 0)])
410 (label_ref (match_operand 3 "" ""))
411 (pc)))]
412 "")
413
414 (define_expand "cstoresi4"
415 [(set (cc0)
416 (compare (match_operand:SI 2 "register_operand" "")
417 (match_operand:SI 3 "reg_or_int5_operand" "")))
418 (set (match_operand:SI 0 "register_operand")
419 (match_operator:SI 1 "ordered_comparison_operator" [(cc0)
420 (const_int 0)]))]
421 "")
422
423 (define_expand "cmpsi"
424 [(set (cc0)
425 (compare (match_operand:SI 0 "register_operand" "r,r")
426 (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
427 ""
428 {
429 v850_compare_op0 = operands[0];
430 v850_compare_op1 = operands[1];
431 DONE;
432 })
433
434 (define_insn "cmpsi_insn"
435 [(set (cc0)
436 (compare (match_operand:SI 0 "register_operand" "r,r")
437 (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
438 ""
439 "@
440 cmp %1,%0
441 cmp %1,%0"
442 [(set_attr "length" "2,2")
443 (set_attr "cc" "compare")])
444
445 (define_expand "cbranchsf4"
446 [(set (pc)
447 (if_then_else (match_operator 0 "ordered_comparison_operator"
448 [(match_operand:SF 1 "register_operand")
449 (match_operand:SF 2 "register_operand")])
450 (label_ref (match_operand 3 ""))
451 (pc)))
452 (clobber (cc0))]
453 "TARGET_USE_FPU"
454 {
455 enum rtx_code cond = GET_CODE (operands[0]);
456 machine_mode mode;
457 rtx fcc_reg;
458 rtx cc_reg;
459 rtx tmp;
460
461 v850_compare_op0 = operands[1];
462 v850_compare_op1 = operands[2];
463
464 if (GET_MODE_CLASS (GET_MODE (v850_compare_op0)) != MODE_FLOAT)
465 FAIL;
466
467 mode = v850_gen_float_compare (cond, VOIDmode, v850_compare_op0, v850_compare_op1);
468 fcc_reg = gen_rtx_REG (mode, FCC_REGNUM);
469 cc_reg = gen_rtx_REG (mode, CC_REGNUM);
470 emit_insn (gen_rtx_SET (cc_reg, fcc_reg));
471 tmp = gen_rtx_fmt_ee (cond, mode, cc_reg, const0_rtx);
472 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
473 gen_rtx_LABEL_REF (VOIDmode, operands[3]), pc_rtx);
474 emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
475 DONE;
476 })
477
478 (define_insn "cstoresf4"
479 [(set (match_operand:SI 0 "register_operand" "=r")
480 (match_operator:SI 1 "ordered_comparison_operator"
481 [(match_operand:SF 2 "register_operand" "r")
482 (match_operand:SF 3 "register_operand" "r")]))]
483 "TARGET_USE_FPU"
484 {
485 if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
486 return "cmpf.s %c1, %z2, %z3 ; trfsr ; setf nz, %0";
487 if (GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE)
488 return "cmpf.s %c1, %z2, %z3 ; trfsr ; setf z, %0";
489 if (GET_CODE (operands[1]) == EQ)
490 return "cmpf.s eq, %z2, %z3 ; trfsr ; setf z, %0";
491 if (GET_CODE (operands[1]) == NE)
492 return "cmpf.s neq, %z2, %z3 ; trfsr ; setf nz, %0";
493 gcc_unreachable ();
494 }
495 [(set_attr "length" "12")
496 (set_attr "type" "fpu")]
497 )
498
499 (define_expand "cbranchdf4"
500 [(set (pc)
501 (if_then_else (match_operator 0 "ordered_comparison_operator"
502 [(match_operand:DF 1 "even_reg_operand")
503 (match_operand:DF 2 "even_reg_operand")])
504 (label_ref (match_operand 3 ""))
505 (pc)))
506 (clobber (cc0))]
507 "TARGET_USE_FPU"
508 {
509 enum rtx_code cond = GET_CODE (operands[0]);
510 machine_mode mode;
511 rtx fcc_reg;
512 rtx cc_reg;
513 rtx tmp;
514
515 v850_compare_op0 = operands[1];
516 v850_compare_op1 = operands[2];
517
518 if (GET_MODE_CLASS (GET_MODE (v850_compare_op0)) != MODE_FLOAT)
519 FAIL;
520
521 mode = v850_gen_float_compare (cond, VOIDmode, v850_compare_op0, v850_compare_op1);
522 fcc_reg = gen_rtx_REG (mode, FCC_REGNUM);
523 cc_reg = gen_rtx_REG (mode, CC_REGNUM);
524 emit_insn (gen_rtx_SET (cc_reg, fcc_reg));
525 tmp = gen_rtx_fmt_ee (cond, mode, cc_reg, const0_rtx);
526 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
527 gen_rtx_LABEL_REF (VOIDmode, operands[3]), pc_rtx);
528 emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
529 DONE;
530 })
531
532 (define_insn "cstoredf4"
533 [(set (match_operand:SI 0 "register_operand" "=r")
534 (match_operator:SI 1 "ordered_comparison_operator"
535 [(match_operand:DF 2 "even_reg_operand" "r")
536 (match_operand:DF 3 "even_reg_operand" "r")]))]
537 "TARGET_USE_FPU"
538 {
539 if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
540 return "cmpf.d %c1, %z2, %z3 ; trfsr ; setf nz, %0";
541 if (GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE)
542 return "cmpf.d %c1, %z2, %z3 ; trfsr ; setf z, %0";
543 if (GET_CODE (operands[1]) == EQ)
544 return "cmpf.d eq, %z2, %z3 ; trfsr ; setf z ,%0";
545 if (GET_CODE (operands[1]) == NE)
546 return "cmpf.d neq, %z2, %z3 ; trfsr ; setf nz, %0";
547 gcc_unreachable ();
548 }
549 [(set_attr "length" "12")
550 (set_attr "type" "fpu")]
551 )
552
553 (define_expand "cmpsf"
554 [(set (reg:CC CC_REGNUM)
555 (compare (match_operand:SF 0 "register_operand" "r")
556 (match_operand:SF 1 "register_operand" "r")))]
557 "TARGET_USE_FPU"
558 {
559 v850_compare_op0 = operands[0];
560 v850_compare_op1 = operands[1];
561 DONE;
562 })
563
564 (define_expand "cmpdf"
565 [(set (reg:CC CC_REGNUM)
566 (compare (match_operand:DF 0 "even_reg_operand" "r")
567 (match_operand:DF 1 "even_reg_operand" "r")))]
568 "TARGET_USE_FPU"
569 {
570 v850_compare_op0 = operands[0];
571 v850_compare_op1 = operands[1];
572 DONE;
573 })
574
575 ;; ----------------------------------------------------------------------
576 ;; ADD INSTRUCTIONS
577 ;; ----------------------------------------------------------------------
578
579 (define_insn "addsi3"
580 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
581 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
582 (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))
583 (clobber (reg:CC CC_REGNUM))]
584
585 ""
586 "@
587 add %2,%0
588 addi %2,%1,%0
589 addi %O2(%P2),%1,%0"
590 [(set_attr "length" "2,4,4")
591 (set_attr "cc" "set_zn,set_zn,set_zn")])
592
593 ;; ----------------------------------------------------------------------
594 ;; SUBTRACT INSTRUCTIONS
595 ;; ----------------------------------------------------------------------
596
597 (define_insn "subsi3"
598 [(set (match_operand:SI 0 "register_operand" "=r,r")
599 (minus:SI (match_operand:SI 1 "register_operand" "0,r")
600 (match_operand:SI 2 "register_operand" "r,0")))
601 (clobber (reg:CC CC_REGNUM))]
602 ""
603 "@
604 sub %2,%0
605 subr %1,%0"
606 [(set_attr "length" "2,2")
607 (set_attr "cc" "set_zn,set_zn")])
608
609 (define_insn "negsi2"
610 [(set (match_operand:SI 0 "register_operand" "=r")
611 (neg:SI (match_operand:SI 1 "register_operand" "0")))
612 (clobber (reg:CC CC_REGNUM))]
613 ""
614 "subr %.,%0"
615 [(set_attr "length" "2")
616 (set_attr "cc" "set_zn")])
617
618 ;; ----------------------------------------------------------------------
619 ;; MULTIPLY INSTRUCTIONS
620 ;; ----------------------------------------------------------------------
621
622 (define_expand "mulhisi3"
623 [(set (match_operand:SI 0 "register_operand" "")
624 (mult:SI
625 (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
626 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
627 ""
628 {
629 if (GET_CODE (operands[2]) == CONST_INT)
630 {
631 emit_insn (gen_mulhisi3_internal2 (operands[0], operands[1], operands[2]));
632 DONE;
633 }
634 })
635
636 (define_insn "*mulhisi3_internal1"
637 [(set (match_operand:SI 0 "register_operand" "=r")
638 (mult:SI
639 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
640 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
641 ""
642 "mulh %2,%0"
643 [(set_attr "length" "2")
644 (set_attr "cc" "none_0hit")
645 (set_attr "type" "mult")])
646
647 (define_insn "mulhisi3_internal2"
648 [(set (match_operand:SI 0 "register_operand" "=r,r")
649 (mult:SI
650 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
651 (match_operand:HI 2 "const_int_operand" "J,K")))]
652 ""
653 "@
654 mulh %2,%0
655 mulhi %2,%1,%0"
656 [(set_attr "length" "2,4")
657 (set_attr "cc" "none_0hit,none_0hit")
658 (set_attr "type" "mult")])
659
660 ;; ??? The scheduling info is probably wrong.
661
662 ;; ??? This instruction can also generate the 32-bit highpart, but using it
663 ;; may increase code size counter to the desired result.
664
665 ;; ??? This instructions can also give a DImode result.
666
667 ;; ??? There is unsigned version, but it matters only for the DImode/highpart
668 ;; results.
669
670 (define_insn "mulsi3"
671 [(set (match_operand:SI 0 "register_operand" "=r")
672 (mult:SI (match_operand:SI 1 "register_operand" "%0")
673 (match_operand:SI 2 "reg_or_int9_operand" "rO")))]
674 "(TARGET_V850E_UP)"
675 "mul %2,%1,%."
676 [(set_attr "length" "4")
677 (set_attr "cc" "none_0hit")
678 (set_attr "type" "mult")])
679
680 ;; ----------------------------------------------------------------------
681 ;; DIVIDE INSTRUCTIONS
682 ;; ----------------------------------------------------------------------
683
684 ;; ??? These insns do set the Z/N condition codes, except that they are based
685 ;; on only one of the two results, so it doesn't seem to make sense to use
686 ;; them.
687
688 ;; ??? The scheduling info is probably wrong.
689
690 (define_insn "divmodsi4"
691 [(set (match_operand:SI 0 "register_operand" "=r")
692 (div:SI (match_operand:SI 1 "register_operand" "0")
693 (match_operand:SI 2 "register_operand" "r")))
694 (set (match_operand:SI 3 "register_operand" "=r")
695 (mod:SI (match_dup 1)
696 (match_dup 2)))
697 (clobber (reg:CC CC_REGNUM))]
698 "TARGET_V850E_UP"
699 {
700 if (TARGET_V850E2_UP)
701 return "divq %2,%0,%3";
702 else
703 return "div %2,%0,%3";
704 }
705 [(set_attr "length" "4")
706 (set_attr "cc" "clobber")
707 (set_attr "type" "div")])
708
709 (define_insn "udivmodsi4"
710 [(set (match_operand:SI 0 "register_operand" "=r")
711 (udiv:SI (match_operand:SI 1 "register_operand" "0")
712 (match_operand:SI 2 "register_operand" "r")))
713 (set (match_operand:SI 3 "register_operand" "=r")
714 (umod:SI (match_dup 1)
715 (match_dup 2)))
716 (clobber (reg:CC CC_REGNUM))]
717 "TARGET_V850E_UP"
718 {
719 if (TARGET_V850E2_UP)
720 return "divqu %2,%0,%3";
721 else
722 return "divu %2,%0,%3";
723 }
724 [(set_attr "length" "4")
725 (set_attr "cc" "clobber")
726 (set_attr "type" "div")])
727
728 ;; ??? There is a 2 byte instruction for generating only the quotient.
729 ;; However, it isn't clear how to compute the length field correctly.
730
731 (define_insn "divmodhi4"
732 [(set (match_operand:HI 0 "register_operand" "=r")
733 (div:HI (match_operand:HI 1 "register_operand" "0")
734 (match_operand:HI 2 "register_operand" "r")))
735 (set (match_operand:HI 3 "register_operand" "=r")
736 (mod:HI (match_dup 1)
737 (match_dup 2)))
738 (clobber (reg:CC CC_REGNUM))]
739 "TARGET_V850E_UP"
740 "divh %2,%0,%3"
741 [(set_attr "length" "4")
742 (set_attr "cc" "clobber")
743 (set_attr "type" "div")])
744
745 ;; Half-words are sign-extended by default, so we must zero extend to a word
746 ;; here before doing the divide.
747
748 (define_insn "udivmodhi4"
749 [(set (match_operand:HI 0 "register_operand" "=r")
750 (udiv:HI (match_operand:HI 1 "register_operand" "0")
751 (match_operand:HI 2 "register_operand" "r")))
752 (set (match_operand:HI 3 "register_operand" "=r")
753 (umod:HI (match_dup 1)
754 (match_dup 2)))
755 (clobber (reg:CC CC_REGNUM))]
756 "TARGET_V850E_UP"
757 "zxh %0 ; divhu %2,%0,%3"
758 [(set_attr "length" "4")
759 (set_attr "cc" "clobber")
760 (set_attr "type" "div")])
761 \f
762 ;; ----------------------------------------------------------------------
763 ;; AND INSTRUCTIONS
764 ;; ----------------------------------------------------------------------
765
766 (define_insn "*v850_clr1_1"
767 [(set (match_operand:QI 0 "memory_operand" "=m")
768 (subreg:QI
769 (and:SI (subreg:SI (match_dup 0) 0)
770 (match_operand:QI 1 "not_power_of_two_operand" "")) 0))
771 (clobber (reg:CC CC_REGNUM))]
772 ""
773 {
774 rtx xoperands[2];
775 xoperands[0] = operands[0];
776 xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
777 output_asm_insn ("clr1 %M1,%0", xoperands);
778 return "";
779 }
780 [(set_attr "length" "4")
781 (set_attr "cc" "clobber")
782 (set_attr "type" "bit1")])
783
784 (define_insn "*v850_clr1_2"
785 [(set (match_operand:HI 0 "indirect_operand" "=m")
786 (subreg:HI
787 (and:SI (subreg:SI (match_dup 0) 0)
788 (match_operand:HI 1 "not_power_of_two_operand" "")) 0))
789 (clobber (reg:CC CC_REGNUM))]
790 ""
791 {
792 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
793
794 rtx xoperands[2];
795 xoperands[0] = gen_rtx_MEM (QImode,
796 plus_constant (Pmode, XEXP (operands[0], 0),
797 log2 / 8));
798 xoperands[1] = GEN_INT (log2 % 8);
799 output_asm_insn ("clr1 %1,%0", xoperands);
800 return "";
801 }
802 [(set_attr "length" "4")
803 (set_attr "cc" "clobber")
804 (set_attr "type" "bit1")])
805
806 (define_insn "*v850_clr1_3"
807 [(set (match_operand:SI 0 "indirect_operand" "=m")
808 (and:SI (match_dup 0)
809 (match_operand:SI 1 "not_power_of_two_operand" "")))
810 (clobber (reg:CC CC_REGNUM))]
811 ""
812 {
813 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
814
815 rtx xoperands[2];
816 xoperands[0] = gen_rtx_MEM (QImode,
817 plus_constant (Pmode, XEXP (operands[0], 0),
818 log2 / 8));
819 xoperands[1] = GEN_INT (log2 % 8);
820 output_asm_insn ("clr1 %1,%0", xoperands);
821 return "";
822 }
823 [(set_attr "length" "4")
824 (set_attr "cc" "clobber")
825 (set_attr "type" "bit1")])
826
827 (define_insn "andsi3"
828 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
829 (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
830 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
831 (clobber (reg:CC CC_REGNUM))]
832 ""
833 "@
834 and %2,%0
835 and %.,%0
836 andi %2,%1,%0"
837 [(set_attr "length" "2,2,4")
838 (set_attr "cc" "set_zn")])
839
840 ;; ----------------------------------------------------------------------
841 ;; OR INSTRUCTIONS
842 ;; ----------------------------------------------------------------------
843
844 (define_insn "*v850_set1_1"
845 [(set (match_operand:QI 0 "memory_operand" "=m")
846 (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
847 (match_operand 1 "power_of_two_operand" "")) 0))
848 (clobber (reg:CC CC_REGNUM))]
849 ""
850 "set1 %M1,%0"
851 [(set_attr "length" "4")
852 (set_attr "cc" "clobber")
853 (set_attr "type" "bit1")])
854
855 (define_insn "*v850_set1_2"
856 [(set (match_operand:HI 0 "indirect_operand" "=m")
857 (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
858 (match_operand 1 "power_of_two_operand" "")) 0))]
859 ""
860 {
861 int log2 = exact_log2 (INTVAL (operands[1]));
862
863 if (log2 < 8)
864 return "set1 %M1,%0";
865 else
866 {
867 rtx xoperands[2];
868 xoperands[0] = gen_rtx_MEM (QImode,
869 plus_constant (Pmode, XEXP (operands[0], 0),
870 log2 / 8));
871 xoperands[1] = GEN_INT (log2 % 8);
872 output_asm_insn ("set1 %1,%0", xoperands);
873 }
874 return "";
875 }
876 [(set_attr "length" "4")
877 (set_attr "cc" "clobber")
878 (set_attr "type" "bit1")])
879
880 (define_insn "*v850_set1_3"
881 [(set (match_operand:SI 0 "indirect_operand" "=m")
882 (ior:SI (match_dup 0)
883 (match_operand 1 "power_of_two_operand" "")))
884 (clobber (reg:CC CC_REGNUM))]
885 ""
886 {
887 int log2 = exact_log2 (INTVAL (operands[1]));
888
889 if (log2 < 8)
890 return "set1 %M1,%0";
891 else
892 {
893 rtx xoperands[2];
894 xoperands[0] = gen_rtx_MEM (QImode,
895 plus_constant (Pmode, XEXP (operands[0], 0),
896 log2 / 8));
897 xoperands[1] = GEN_INT (log2 % 8);
898 output_asm_insn ("set1 %1,%0", xoperands);
899 }
900 return "";
901 }
902 [(set_attr "length" "4")
903 (set_attr "cc" "clobber")
904 (set_attr "type" "bit1")])
905
906 (define_insn "iorsi3"
907 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
908 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
909 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
910 (clobber (reg:CC CC_REGNUM))]
911 ""
912 "@
913 or %2,%0
914 or %.,%0
915 ori %2,%1,%0"
916 [(set_attr "length" "2,2,4")
917 (set_attr "cc" "set_zn")])
918
919 ;; ----------------------------------------------------------------------
920 ;; XOR INSTRUCTIONS
921 ;; ----------------------------------------------------------------------
922
923 (define_insn "*v850_not1_1"
924 [(set (match_operand:QI 0 "memory_operand" "=m")
925 (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0)
926 (match_operand 1 "power_of_two_operand" "")) 0))
927 (clobber (reg:CC CC_REGNUM))]
928 ""
929 "not1 %M1,%0"
930 [(set_attr "length" "4")
931 (set_attr "cc" "clobber")
932 (set_attr "type" "bit1")])
933
934 (define_insn "*v850_not1_2"
935 [(set (match_operand:HI 0 "indirect_operand" "=m")
936 (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
937 (match_operand 1 "power_of_two_operand" "")) 0))]
938 ""
939 {
940 int log2 = exact_log2 (INTVAL (operands[1]));
941
942 if (log2 < 8)
943 return "not1 %M1,%0";
944 else
945 {
946 rtx xoperands[2];
947 xoperands[0] = gen_rtx_MEM (QImode,
948 plus_constant (Pmode, XEXP (operands[0], 0),
949 log2 / 8));
950 xoperands[1] = GEN_INT (log2 % 8);
951 output_asm_insn ("not1 %1,%0", xoperands);
952 }
953 return "";
954 }
955 [(set_attr "length" "4")
956 (set_attr "cc" "clobber")
957 (set_attr "type" "bit1")])
958
959 (define_insn "*v850_not1_3"
960 [(set (match_operand:SI 0 "indirect_operand" "=m")
961 (xor:SI (match_dup 0)
962 (match_operand 1 "power_of_two_operand" "")))
963 (clobber (reg:CC CC_REGNUM))]
964 ""
965 {
966 int log2 = exact_log2 (INTVAL (operands[1]));
967
968 if (log2 < 8)
969 return "not1 %M1,%0";
970 else
971 {
972 rtx xoperands[2];
973 xoperands[0] = gen_rtx_MEM (QImode,
974 plus_constant (Pmode, XEXP (operands[0], 0),
975 log2 / 8));
976 xoperands[1] = GEN_INT (log2 % 8);
977 output_asm_insn ("not1 %1,%0", xoperands);
978 }
979 return "";
980 }
981 [(set_attr "length" "4")
982 (set_attr "cc" "clobber")
983 (set_attr "type" "bit1")])
984
985 (define_insn "xorsi3"
986 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
987 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
988 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))
989 (clobber (reg:CC CC_REGNUM))]
990 ""
991 "@
992 xor %2,%0
993 xor %.,%0
994 xori %2,%1,%0"
995 [(set_attr "length" "2,2,4")
996 (set_attr "cc" "set_zn")])
997 \f
998 ;; ----------------------------------------------------------------------
999 ;; NOT INSTRUCTIONS
1000 ;; ----------------------------------------------------------------------
1001
1002 (define_insn "one_cmplsi2"
1003 [(set (match_operand:SI 0 "register_operand" "=r")
1004 (not:SI (match_operand:SI 1 "register_operand" "r")))
1005 (clobber (reg:CC CC_REGNUM))]
1006 ""
1007 "not %1,%0"
1008 [(set_attr "length" "2")
1009 (set_attr "cc" "set_zn")])
1010
1011 ;; -----------------------------------------------------------------
1012 ;; BIT FIELDS
1013 ;; -----------------------------------------------------------------
1014
1015 ;; ??? Is it worth defining insv and extv for the V850 series?!?
1016
1017 ;; An insv pattern would be useful, but does not get used because
1018 ;; store_bit_field never calls insv when storing a constant value into a
1019 ;; single-bit bitfield.
1020
1021 ;; extv/extzv patterns would be useful, but do not get used because
1022 ;; optimize_bitfield_compare in fold-const usually converts single
1023 ;; bit extracts into an AND with a mask.
1024
1025 (define_insn "insv"
1026 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1027 (match_operand:SI 1 "immediate_operand" "n")
1028 (match_operand:SI 2 "immediate_operand" "n"))
1029 (match_operand:SI 3 "register_operand" "r"))]
1030 "TARGET_V850E3V5_UP"
1031 "bins %3, %2, %1, %0"
1032 [(set_attr "length" "4")
1033 (set_attr "cc" "set_zn")]
1034 )
1035
1036 ;; -----------------------------------------------------------------
1037 ;; Scc INSTRUCTIONS
1038 ;; -----------------------------------------------------------------
1039
1040 (define_insn "*setcc"
1041 [(set (match_operand:SI 0 "register_operand" "=r")
1042 (match_operator:SI 1 "comparison_operator"
1043 [(cc0) (const_int 0)]))]
1044 ""
1045 {
1046 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1047 && (GET_CODE (operands[1]) == GT
1048 || GET_CODE (operands[1]) == GE
1049 || GET_CODE (operands[1]) == LE
1050 || GET_CODE (operands[1]) == LT))
1051 return 0;
1052
1053 return "setf %c1,%0";
1054 }
1055 [(set_attr "length" "4")
1056 (set_attr "cc" "none_0hit")])
1057
1058 (define_insn "setf_insn"
1059 [(set (match_operand:SI 0 "register_operand" "=r")
1060 (match_operator:SI 1 "comparison_operator"
1061 [(reg:CC CC_REGNUM) (const_int 0)]))]
1062 ""
1063 "setf %b1,%0"
1064 [(set_attr "length" "4")
1065 (set_attr "cc" "none_0hit")])
1066
1067 (define_insn "set_z_insn"
1068 [(set (match_operand:SI 0 "register_operand" "=r")
1069 (match_operand 1 "v850_float_z_comparison_operator" ""))]
1070 "TARGET_V850E2V3_UP"
1071 "setf z,%0"
1072 [(set_attr "length" "4")
1073 (set_attr "cc" "none_0hit")])
1074
1075 (define_insn "set_nz_insn"
1076 [(set (match_operand:SI 0 "register_operand" "=r")
1077 (match_operand 1 "v850_float_nz_comparison_operator" ""))]
1078 "TARGET_V850E2V3_UP"
1079 "setf nz,%0"
1080 [(set_attr "length" "4")
1081 (set_attr "cc" "none_0hit")])
1082
1083 ;; ----------------------------------------------------------------------
1084 ;; CONDITIONAL MOVE INSTRUCTIONS
1085 ;; ----------------------------------------------------------------------
1086
1087 ;; Instructions using cc0 aren't allowed to have input reloads, so we must
1088 ;; hide the fact that this instruction uses cc0. We do so by including the
1089 ;; compare instruction inside it.
1090
1091 (define_expand "movsicc"
1092 [(set (match_operand:SI 0 "register_operand" "=r")
1093 (if_then_else:SI
1094 (match_operand 1 "comparison_operator")
1095 (match_operand:SI 2 "reg_or_const_operand" "rJ")
1096 (match_operand:SI 3 "reg_or_const_operand" "rI")))]
1097 "(TARGET_V850E_UP)"
1098 {
1099 /* Make sure that we have an integer comparison... */
1100 if (GET_MODE (XEXP (operands[1], 0)) != CCmode
1101 && GET_MODE (XEXP (operands[1], 0)) != SImode)
1102 FAIL;
1103
1104 if ((GET_CODE (operands[2]) == CONST_INT
1105 && GET_CODE (operands[3]) == CONST_INT))
1106 {
1107 int o2 = INTVAL (operands[2]);
1108 int o3 = INTVAL (operands[3]);
1109
1110 if (o2 == 1 && o3 == 0)
1111 FAIL; /* setf */
1112 if (o3 == 1 && o2 == 0)
1113 FAIL; /* setf */
1114 if (o2 == 0 && (o3 < -16 || o3 > 15) && exact_log2 (o3) >= 0)
1115 FAIL; /* setf + shift */
1116 if (o3 == 0 && (o2 < -16 || o2 > 15) && exact_log2 (o2) >=0)
1117 FAIL; /* setf + shift */
1118 if (o2 != 0)
1119 operands[2] = copy_to_mode_reg (SImode, operands[2]);
1120 if (o3 !=0 )
1121 operands[3] = copy_to_mode_reg (SImode, operands[3]);
1122 }
1123 else
1124 {
1125 if (GET_CODE (operands[2]) != REG)
1126 operands[2] = copy_to_mode_reg (SImode,operands[2]);
1127 if (GET_CODE (operands[3]) != REG)
1128 operands[3] = copy_to_mode_reg (SImode, operands[3]);
1129 }
1130 })
1131
1132 ;; ??? Clobbering the condition codes is overkill.
1133
1134 ;; ??? We sometimes emit an unnecessary compare instruction because the
1135 ;; condition codes may have already been set by an earlier instruction,
1136 ;; but we have no code here to avoid the compare if it is unnecessary.
1137
1138 (define_insn "movsicc_normal_cc"
1139 [(set (match_operand:SI 0 "register_operand" "=r")
1140 (if_then_else:SI
1141 (match_operator 1 "comparison_operator"
1142 [(reg:CC CC_REGNUM) (const_int 0)])
1143 (match_operand:SI 2 "reg_or_int5_operand" "rJ")
1144 (match_operand:SI 3 "reg_or_0_operand" "rI")))]
1145 "(TARGET_V850E_UP)"
1146 "cmov %c1,%2,%z3,%0";
1147 [(set_attr "length" "6")
1148 (set_attr "cc" "compare")])
1149
1150 (define_insn "movsicc_reversed_cc"
1151 [(set (match_operand:SI 0 "register_operand" "=r")
1152 (if_then_else:SI
1153 (match_operator 1 "comparison_operator"
1154 [(reg:CC CC_REGNUM) (const_int 0)])
1155 (match_operand:SI 2 "reg_or_0_operand" "rI")
1156 (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
1157 "(TARGET_V850E_UP)"
1158 "cmov %C1,%3,%z2,%0"
1159 [(set_attr "length" "6")
1160 (set_attr "cc" "compare")])
1161
1162 (define_insn "*movsicc_normal"
1163 [(set (match_operand:SI 0 "register_operand" "=r")
1164 (if_then_else:SI
1165 (match_operator 1 "comparison_operator"
1166 [(match_operand:SI 4 "register_operand" "r")
1167 (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
1168 (match_operand:SI 2 "reg_or_int5_operand" "rJ")
1169 (match_operand:SI 3 "reg_or_0_operand" "rI")))]
1170 "(TARGET_V850E_UP)"
1171 "cmp %5,%4 ; cmov %c1,%2,%z3,%0"
1172 [(set_attr "length" "6")
1173 (set_attr "cc" "clobber")])
1174
1175 (define_insn "*movsicc_reversed"
1176 [(set (match_operand:SI 0 "register_operand" "=r")
1177 (if_then_else:SI
1178 (match_operator 1 "comparison_operator"
1179 [(match_operand:SI 4 "register_operand" "r")
1180 (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
1181 (match_operand:SI 2 "reg_or_0_operand" "rI")
1182 (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
1183 "(TARGET_V850E_UP)"
1184 "cmp %5,%4 ; cmov %C1,%3,%z2,%0"
1185 [(set_attr "length" "6")
1186 (set_attr "cc" "clobber")])
1187
1188 (define_insn "*movsicc_tst1"
1189 [(set (match_operand:SI 0 "register_operand" "=r")
1190 (if_then_else:SI
1191 (match_operator 1 "comparison_operator"
1192 [(zero_extract:SI
1193 (match_operand:QI 2 "memory_operand" "m")
1194 (const_int 1)
1195 (match_operand 3 "const_int_operand" "n"))
1196 (const_int 0)])
1197 (match_operand:SI 4 "reg_or_int5_operand" "rJ")
1198 (match_operand:SI 5 "reg_or_0_operand" "rI")))]
1199 "(TARGET_V850E_UP)"
1200 "tst1 %3,%2 ; cmov %c1,%4,%z5,%0"
1201 [(set_attr "length" "8")
1202 (set_attr "cc" "clobber")])
1203
1204 (define_insn "*movsicc_tst1_reversed"
1205 [(set (match_operand:SI 0 "register_operand" "=r")
1206 (if_then_else:SI
1207 (match_operator 1 "comparison_operator"
1208 [(zero_extract:SI
1209 (match_operand:QI 2 "memory_operand" "m")
1210 (const_int 1)
1211 (match_operand 3 "const_int_operand" "n"))
1212 (const_int 0)])
1213 (match_operand:SI 4 "reg_or_0_operand" "rI")
1214 (match_operand:SI 5 "reg_or_int5_operand" "rJ")))]
1215 "(TARGET_V850E_UP)"
1216 "tst1 %3,%2 ; cmov %C1,%5,%z4,%0"
1217 [(set_attr "length" "8")
1218 (set_attr "cc" "clobber")])
1219
1220 ;; Matching for sasf requires combining 4 instructions, so we provide a
1221 ;; dummy pattern to match the first 3, which will always be turned into the
1222 ;; second pattern by subsequent combining. As above, we must include the
1223 ;; comparison to avoid input reloads in an insn using cc0.
1224
1225 (define_insn "*sasf"
1226 [(set (match_operand:SI 0 "register_operand" "=r")
1227 (ior:SI
1228 (match_operator 1 "comparison_operator"
1229 [(match_operand:SI 3 "register_operand" "r")
1230 (match_operand:SI 4 "reg_or_int5_operand" "rJ")])
1231 (ashift:SI (match_operand:SI 2 "register_operand" "0")
1232 (const_int 1))))
1233 (clobber (reg:CC CC_REGNUM))]
1234 "(TARGET_V850E_UP)"
1235 "cmp %4,%3 ; sasf %c1,%0"
1236 [(set_attr "length" "6")
1237 (set_attr "cc" "clobber")])
1238
1239 (define_split
1240 [(set (match_operand:SI 0 "register_operand" "")
1241 (if_then_else:SI
1242 (match_operator 1 "comparison_operator"
1243 [(match_operand:SI 4 "register_operand" "")
1244 (match_operand:SI 5 "reg_or_int5_operand" "")])
1245 (match_operand:SI 2 "const_int_operand" "")
1246 (match_operand:SI 3 "const_int_operand" "")))
1247 (clobber (reg:CC CC_REGNUM))]
1248 "(TARGET_V850E_UP)
1249 && ((INTVAL (operands[2]) ^ INTVAL (operands[3])) == 1)
1250 && ((INTVAL (operands[2]) + INTVAL (operands[3])) != 1)
1251 && (GET_CODE (operands[5]) == CONST_INT
1252 || REGNO (operands[0]) != REGNO (operands[5]))
1253 && REGNO (operands[0]) != REGNO (operands[4])"
1254 [(set (match_dup 0) (match_dup 6))
1255 (parallel [(set (match_dup 0)
1256 (ior:SI (match_op_dup 7 [(match_dup 4) (match_dup 5)])
1257 (ashift:SI (match_dup 0) (const_int 1))))
1258 (clobber (reg:CC CC_REGNUM))])]
1259 {
1260 operands[6] = GEN_INT (INTVAL (operands[2]) >> 1);
1261 if (INTVAL (operands[2]) & 0x1)
1262 operands[7] = operands[1];
1263 else
1264 operands[7] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
1265 GET_MODE (operands[1]),
1266 XEXP (operands[1], 0), XEXP (operands[1], 1));
1267 })
1268
1269 ;; ---------------------------------------------------------------------
1270 ;; BYTE SWAP INSTRUCTIONS
1271 ;; ---------------------------------------------------------------------
1272 (define_expand "rotlhi3"
1273 [(parallel [(set (match_operand:HI 0 "register_operand" "")
1274 (rotate:HI (match_operand:HI 1 "register_operand" "")
1275 (match_operand:HI 2 "const_int_operand" "")))
1276 (clobber (reg:CC CC_REGNUM))])]
1277 "(TARGET_V850E_UP)"
1278 {
1279 if (INTVAL (operands[2]) != 8)
1280 FAIL;
1281 })
1282
1283 (define_insn "*rotlhi3_8"
1284 [(set (match_operand:HI 0 "register_operand" "=r")
1285 (rotate:HI (match_operand:HI 1 "register_operand" "r")
1286 (const_int 8)))
1287 (clobber (reg:CC CC_REGNUM))]
1288 "(TARGET_V850E_UP)"
1289 "bsh %1,%0"
1290 [(set_attr "length" "4")
1291 (set_attr "cc" "clobber")])
1292
1293 (define_expand "rotlsi3"
1294 [(parallel [(set (match_operand:SI 0 "register_operand" "")
1295 (rotate:SI (match_operand:SI 1 "register_operand" "")
1296 (match_operand:SI 2 "const_int_operand" "")))
1297 (clobber (reg:CC CC_REGNUM))])]
1298 "(TARGET_V850E_UP)"
1299 {
1300 if (INTVAL (operands[2]) != 16)
1301 FAIL;
1302 })
1303
1304 (define_insn "rotlsi3_a"
1305 [(set (match_operand:SI 0 "register_operand" "=r")
1306 (match_operator:SI 4 "ior_operator"
1307 [(ashift:SI (match_operand:SI 1 "register_operand" "r")
1308 (match_operand:SI 2 "const_int_operand" "n"))
1309 (lshiftrt:SI (match_dup 1)
1310 (match_operand:SI 3 "const_int_operand" "n"))]))]
1311 "TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)"
1312 "rotl %2, %1, %0"
1313 [(set_attr "length" "4")
1314 (set_attr "cc" "set_zn")]
1315 )
1316
1317 (define_insn "rotlsi3_b"
1318 [(set (match_operand:SI 0 "register_operand" "=r")
1319 (match_operator:SI 4 "ior_operator"
1320 [(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1321 (match_operand:SI 3 "const_int_operand" "n"))
1322 (ashift:SI (match_dup 1)
1323 (match_operand:SI 2 "const_int_operand" "n"))]))]
1324 "TARGET_V850E3V5_UP && (INTVAL (operands[2]) + INTVAL (operands[3]) == 32)"
1325 "rotl %2, %1, %0"
1326 [(set_attr "length" "4")
1327 (set_attr "cc" "set_zn")]
1328 )
1329
1330 (define_insn "rotlsi3_v850e3v5"
1331 [(set (match_operand:SI 0 "register_operand" "=r")
1332 (rotate:SI (match_operand:SI 1 "register_operand" "r")
1333 (match_operand:SI 2 "e3v5_shift_operand" "rn")))
1334 (clobber (reg:CC CC_REGNUM))]
1335 "TARGET_V850E3V5_UP"
1336 "rotl %2, %1, %0"
1337 [(set_attr "length" "4")
1338 (set_attr "cc" "set_zn")]
1339 )
1340
1341 (define_insn "*rotlsi3_16"
1342 [(set (match_operand:SI 0 "register_operand" "=r")
1343 (rotate:SI (match_operand:SI 1 "register_operand" "r")
1344 (const_int 16)))
1345 (clobber (reg:CC CC_REGNUM))]
1346 "(TARGET_V850E_UP)"
1347 "hsw %1,%0"
1348 [(set_attr "length" "4")
1349 (set_attr "cc" "clobber")])
1350
1351 ;; ----------------------------------------------------------------------
1352 ;; JUMP INSTRUCTIONS
1353 ;; ----------------------------------------------------------------------
1354
1355 ;; Doloop
1356
1357 (define_expand "doloop_begin"
1358 [(use (match_operand 0 "" "")) ; loop pseudo
1359 (use (match_operand 1 "" ""))] ; doloop_end pattern
1360 "TARGET_V850E3V5_UP && TARGET_LOOP"
1361 {
1362 rtx loop_cnt = operands[0];
1363 gcc_assert (GET_MODE (loop_cnt) == SImode);
1364 emit_insn (gen_fix_loop_counter (loop_cnt));
1365 DONE;
1366 }
1367 )
1368
1369 (define_insn "fix_loop_counter"
1370 [(unspec:SI [(match_operand:SI 0 "register_operand" "+r,!m")
1371 (clobber (match_scratch:SI 1 "=X,r"))] UNSPEC_LOOP)]
1372 "TARGET_V850E3V5_UP && TARGET_LOOP"
1373 {
1374 switch (which_alternative)
1375 {
1376 case 0: return "add 1, %0 # LOOP_BEGIN";
1377 case 1: return "ld.w %0, %1; add 1, %1; st.w %1, %0 # LOOP_BEGIN";
1378 default: gcc_unreachable ();
1379 }
1380 }
1381 [(set_attr "length" "2,6")
1382 (set_attr "cc" "none")]
1383 )
1384
1385 (define_expand "doloop_end"
1386 [(use (match_operand 0 "" "")) ; loop pseudo
1387 (use (match_operand 1 "" ""))] ; label
1388 "TARGET_V850E3V5_UP && TARGET_LOOP"
1389 {
1390 rtx loop_cnt = operands[0];
1391 rtx label = operands[1];
1392
1393 if (GET_MODE (loop_cnt) != SImode)
1394 FAIL;
1395
1396 emit_jump_insn (gen_doloop_end_internal_loop (label, loop_cnt));
1397 DONE;
1398 }
1399 )
1400
1401 (define_insn "doloop_end_internal_loop"
1402 [(set (pc)
1403 (if_then_else (ne (match_operand:SI 1 "register_operand" "+r,!m")
1404 (const_int 0))
1405 (label_ref (match_operand 0 "" ""))
1406 (pc)))
1407 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))
1408 (clobber (match_scratch:SI 2 "=X,r"))
1409 (clobber (reg:CC CC_REGNUM))]
1410 "TARGET_V850E3V5_UP && TARGET_LOOP"
1411 {
1412 switch (which_alternative)
1413 {
1414 case 0:
1415 if (get_attr_length (insn) == 4)
1416 return "loop %1, %0 # LOOP.1.0";
1417
1418 return "add -1, %1; bne %l0 # LOOP.1.1";
1419 case 1:
1420 return "ld.w %1, %2; add -1, %2; st.w %2, %1; bne %l0 # LOOP.2.1";
1421 default:
1422 gcc_unreachable ();
1423 }
1424 }
1425 [(set (attr "length")
1426 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1427 (const_int 65534))
1428 (const_int 4)
1429 (const_int 14)))
1430 (set_attr "cc" "none")])
1431
1432 ;; Conditional jump instructions
1433
1434 (define_insn "*branch_normal"
1435 [(set (pc)
1436 (if_then_else (match_operator 1 "comparison_operator"
1437 [(cc0) (const_int 0)])
1438 (label_ref (match_operand 0 "" ""))
1439 (pc)))]
1440 ""
1441 {
1442 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1443 && (GET_CODE (operands[1]) == GT
1444 || GET_CODE (operands[1]) == GE
1445 || GET_CODE (operands[1]) == LE
1446 || GET_CODE (operands[1]) == LT))
1447 return 0;
1448
1449 if (get_attr_length (insn) == 2)
1450 return "b%b1 %l0";
1451 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1452 return "b%b1 %l0";
1453 return "b%B1 .+6 ; jr %l0";
1454 }
1455 [(set (attr "length")
1456 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1457 (const_int 256))
1458 (const_int 2)
1459 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1460 (const_int 65536))
1461 (const_int 4)
1462 (const_int 6))))
1463 (set_attr "cc" "none")])
1464
1465 (define_insn "*branch_invert"
1466 [(set (pc)
1467 (if_then_else (match_operator 1 "comparison_operator"
1468 [(cc0) (const_int 0)])
1469 (pc)
1470 (label_ref (match_operand 0 "" ""))))]
1471 ""
1472 {
1473 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1474 && (GET_CODE (operands[1]) == GT
1475 || GET_CODE (operands[1]) == GE
1476 || GET_CODE (operands[1]) == LE
1477 || GET_CODE (operands[1]) == LT))
1478 return NULL;
1479
1480 if (get_attr_length (insn) == 2)
1481 return "b%B1 %l0";
1482
1483 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1484 return "b%B1 %l0";
1485
1486 return "b%b1 .+6 ; jr %l0";
1487 }
1488 [(set (attr "length")
1489 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1490 (const_int 256))
1491 (const_int 2)
1492 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1493 (const_int 65536))
1494 (const_int 4)
1495 (const_int 6))))
1496 (set_attr "cc" "none")])
1497
1498 (define_insn "branch_z_normal"
1499 [(set (pc)
1500 (if_then_else (match_operand 1 "v850_float_z_comparison_operator" "")
1501 (label_ref (match_operand 0 "" ""))
1502 (pc)))]
1503 "TARGET_V850E2V3_UP"
1504 {
1505 if (get_attr_length (insn) == 2)
1506 return "bz %l0";
1507
1508 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1509 return "bz %l0";
1510
1511 return "bnz 1f ; jr %l0 ; 1:";
1512 }
1513 [(set (attr "length")
1514 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1515 (const_int 256))
1516 (const_int 2)
1517 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1518 (const_int 65536))
1519 (const_int 4)
1520 (const_int 6))))
1521 (set_attr "cc" "none")])
1522
1523 (define_insn "*branch_z_invert"
1524 [(set (pc)
1525 (if_then_else (match_operand 1 "v850_float_z_comparison_operator" "")
1526 (pc)
1527 (label_ref (match_operand 0 "" ""))))]
1528 "TARGET_V850E2V3_UP"
1529 {
1530 if (get_attr_length (insn) == 2)
1531 return "bnz %l0";
1532
1533 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1534 return "bnz %l0";
1535
1536 return "bz 1f ; jr %l0 ; 1:";
1537 }
1538 [(set (attr "length")
1539 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1540 (const_int 256))
1541 (const_int 2)
1542 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1543 (const_int 65536))
1544 (const_int 4)
1545 (const_int 6))))
1546 (set_attr "cc" "none")])
1547
1548 (define_insn "branch_nz_normal"
1549 [(set (pc)
1550 (if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "")
1551 (label_ref (match_operand 0 "" ""))
1552 (pc)))]
1553 "TARGET_V850E2V3_UP"
1554 {
1555 if (get_attr_length (insn) == 2)
1556 return "bnz %l0";
1557
1558 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1559 return "bnz %l0";
1560
1561 return "bz 1f ; jr %l0 ; 1:";
1562 }
1563 [(set (attr "length")
1564 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1565 (const_int 256))
1566 (const_int 2)
1567 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1568 (const_int 65536))
1569 (const_int 4)
1570 (const_int 6))))
1571 (set_attr "cc" "none")])
1572
1573 (define_insn "*branch_nz_invert"
1574 [(set (pc)
1575 (if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "")
1576 (pc)
1577 (label_ref (match_operand 0 "" ""))))]
1578 "TARGET_V850E2V3_UP"
1579 {
1580 if (get_attr_length (insn) == 2)
1581 return "bz %l0";
1582
1583 if (TARGET_V850E3V5_UP && get_attr_length (insn) == 4)
1584 return "bz %l0";
1585
1586 return "bnz 1f ; jr %l0 ; 1:";
1587 }
1588 [(set (attr "length")
1589 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1590 (const_int 256))
1591 (const_int 2)
1592 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1593 (const_int 65536))
1594 (const_int 4)
1595 (const_int 6))))
1596 (set_attr "cc" "none")])
1597
1598 ;; Unconditional and other jump instructions.
1599
1600 (define_insn "jump"
1601 [(set (pc)
1602 (label_ref (match_operand 0 "" "")))]
1603 ""
1604 {
1605 if (get_attr_length (insn) == 2)
1606 return "br %0";
1607 else
1608 return "jr %0";
1609 }
1610 [(set (attr "length")
1611 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1612 (const_int 256))
1613 (const_int 2)
1614 (const_int 4)))
1615 (set_attr "cc" "none")])
1616
1617 (define_insn "indirect_jump"
1618 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1619 ""
1620 "jmp %0"
1621 [(set_attr "length" "2")
1622 (set_attr "cc" "none")])
1623
1624 (define_insn "tablejump"
1625 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1626 (use (label_ref (match_operand 1 "" "")))]
1627 ""
1628 "jmp %0"
1629 [(set_attr "length" "2")
1630 (set_attr "cc" "none")])
1631
1632 (define_insn "switch"
1633 [(set (pc)
1634 (plus:SI
1635 (sign_extend:SI
1636 (mem:HI
1637 (plus:SI (ashift:SI (match_operand:SI 0 "register_operand" "r")
1638 (const_int 1))
1639 (label_ref (match_operand 1 "" "")))))
1640 (label_ref (match_dup 1))))]
1641 "(TARGET_V850E_UP)"
1642 "switch %0"
1643 [(set_attr "length" "2")
1644 (set_attr "cc" "none")])
1645
1646 (define_expand "casesi"
1647 [(match_operand:SI 0 "register_operand" "")
1648 (match_operand:SI 1 "register_operand" "")
1649 (match_operand:SI 2 "register_operand" "")
1650 (match_operand 3 "" "") (match_operand 4 "" "")]
1651 ""
1652 {
1653 rtx reg = gen_reg_rtx (SImode);
1654 rtx tableaddress = gen_reg_rtx (SImode);
1655 rtx test;
1656 rtx mem;
1657
1658 /* Subtract the lower bound from the index. */
1659 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
1660
1661 /* Compare the result against the number of table entries;
1662 branch to the default label if out of range of the table. */
1663 test = gen_rtx_fmt_ee (GTU, VOIDmode, reg, operands[2]);
1664 emit_jump_insn (gen_cbranchsi4 (test, reg, operands[2], operands[4]));
1665
1666 /* Shift index for the table array access. */
1667 emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
1668 /* Load the table address into a pseudo. */
1669 emit_insn (gen_movsi (tableaddress,
1670 gen_rtx_LABEL_REF (Pmode, operands[3])));
1671 /* Add the table address to the index. */
1672 emit_insn (gen_addsi3 (reg, reg, tableaddress));
1673 /* Load the table entry. */
1674 mem = gen_const_mem (CASE_VECTOR_MODE, reg);
1675 if (! TARGET_BIG_SWITCH)
1676 {
1677 rtx reg2 = gen_reg_rtx (HImode);
1678 emit_insn (gen_movhi (reg2, mem));
1679 emit_insn (gen_extendhisi2 (reg, reg2));
1680 }
1681 else
1682 emit_insn (gen_movsi (reg, mem));
1683 /* Add the table address. */
1684 emit_insn (gen_addsi3 (reg, reg, tableaddress));
1685 /* Branch to the switch label. */
1686 emit_jump_insn (gen_tablejump (reg, operands[3]));
1687 DONE;
1688 })
1689
1690 ;; Call subroutine with no return value.
1691
1692 (define_expand "call"
1693 [(call (match_operand:QI 0 "general_operand" "")
1694 (match_operand:SI 1 "general_operand" ""))]
1695 ""
1696 {
1697 if (! call_address_operand (XEXP (operands[0], 0), QImode)
1698 || TARGET_LONG_CALLS)
1699 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1700 if (TARGET_LONG_CALLS)
1701 emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));
1702 else
1703 emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
1704
1705 DONE;
1706 })
1707
1708 (define_insn "call_internal_short"
1709 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1710 (match_operand:SI 1 "general_operand" "g,g"))
1711 (clobber (reg:SI 31))]
1712 "! TARGET_LONG_CALLS"
1713 {
1714 if (which_alternative == 1)
1715 {
1716 if (TARGET_V850E3V5_UP)
1717 return "jarl [%0], r31";
1718
1719 return "jarl .+4, r31 ; add 4, r31 ; jmp %0";
1720 }
1721
1722 return "jarl %0, r31";
1723 }
1724 [(set_attr "length" "4,8")
1725 (set_attr "cc" "clobber,clobber")]
1726 )
1727
1728 (define_insn "call_internal_long"
1729 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1730 (match_operand:SI 1 "general_operand" "g,g"))
1731 (clobber (reg:SI 31))]
1732 "TARGET_LONG_CALLS"
1733 {
1734 if (which_alternative == 0)
1735 {
1736 if (GET_CODE (operands[0]) == REG)
1737 return "jarl %0,r31";
1738
1739 if (TARGET_V850E3V5_UP)
1740 return "mov hilo(%0), r11 ; jarl [r11], r31";
1741
1742 return "movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11";
1743 }
1744
1745 if (TARGET_V850E3V5_UP)
1746 return "jarl [%0], r31";
1747
1748 return "jarl .+4,r31 ; add 4,r31 ; jmp %0";
1749 }
1750 [(set_attr "length" "16,8")
1751 (set_attr "cc" "clobber,clobber")]
1752 )
1753
1754 ;; Call subroutine, returning value in operand 0
1755 ;; (which must be a hard register).
1756
1757 (define_expand "call_value"
1758 [(set (match_operand 0 "" "")
1759 (call (match_operand:QI 1 "general_operand" "")
1760 (match_operand:SI 2 "general_operand" "")))]
1761 ""
1762 {
1763 if (! call_address_operand (XEXP (operands[1], 0), QImode)
1764 || TARGET_LONG_CALLS)
1765 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1766 if (TARGET_LONG_CALLS)
1767 emit_call_insn (gen_call_value_internal_long (operands[0],
1768 XEXP (operands[1], 0),
1769 operands[2]));
1770 else
1771 emit_call_insn (gen_call_value_internal_short (operands[0],
1772 XEXP (operands[1], 0),
1773 operands[2]));
1774 DONE;
1775 })
1776
1777 (define_insn "call_value_internal_short"
1778 [(set (match_operand 0 "" "=r,r")
1779 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1780 (match_operand:SI 2 "general_operand" "g,g")))
1781 (clobber (reg:SI 31))]
1782 "! TARGET_LONG_CALLS"
1783 {
1784 if (which_alternative == 1)
1785 {
1786 if (TARGET_V850E3V5_UP)
1787 return "jarl [%1], r31";
1788
1789 return "jarl .+4, r31 ; add 4, r31 ; jmp %1";
1790 }
1791
1792 return "jarl %1, r31";
1793 }
1794 [(set_attr "length" "4,8")
1795 (set_attr "cc" "clobber,clobber")]
1796 )
1797
1798 (define_insn "call_value_internal_long"
1799 [(set (match_operand 0 "" "=r,r")
1800 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1801 (match_operand:SI 2 "general_operand" "g,g")))
1802 (clobber (reg:SI 31))]
1803 "TARGET_LONG_CALLS"
1804 {
1805 if (which_alternative == 0)
1806 {
1807 if (GET_CODE (operands[1]) == REG)
1808 return "jarl %1, r31";
1809
1810 /* Reload can generate this pattern.... */
1811 if (TARGET_V850E3V5_UP)
1812 return "mov hilo(%1), r11 ; jarl [r11], r31";
1813
1814 return "movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11";
1815 }
1816
1817 if (TARGET_V850E3V5_UP)
1818 return "jarl [%1], r31";
1819
1820 return "jarl .+4, r31 ; add 4, r31 ; jmp %1";
1821 }
1822 [(set_attr "length" "16,8")
1823 (set_attr "cc" "clobber,clobber")]
1824 )
1825
1826 (define_insn "nop"
1827 [(const_int 0)]
1828 ""
1829 "nop"
1830 [(set_attr "length" "2")
1831 (set_attr "cc" "none")])
1832 \f
1833 ;; ----------------------------------------------------------------------
1834 ;; EXTEND INSTRUCTIONS
1835 ;; ----------------------------------------------------------------------
1836
1837 (define_insn "*zero_extendhisi2_v850e"
1838 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1839 (zero_extend:SI
1840 (match_operand:HI 1 "nonimmediate_operand" "0,r,T,m")))
1841 (clobber (reg:CC CC_REGNUM))]
1842 "(TARGET_V850E_UP)"
1843 "@
1844 zxh %0
1845 andi 65535,%1,%0
1846 sld.hu %1,%0
1847 ld.hu %1,%0"
1848 [(set_attr "length" "2,4,2,4")
1849 (set_attr "cc" "none_0hit,set_zn,none_0hit,none_0hit")])
1850
1851 (define_insn "*zero_extendhisi2_v850"
1852 [(set (match_operand:SI 0 "register_operand" "=r")
1853 (zero_extend:SI
1854 (match_operand:HI 1 "register_operand" "r")))
1855 (clobber (reg:CC CC_REGNUM))] ;; A lie, but we have to match the expander
1856 ""
1857 "andi 65535,%1,%0"
1858 [(set_attr "length" "4")
1859 (set_attr "cc" "set_zn")])
1860
1861 (define_expand "zero_extendhisi2"
1862 [(parallel [(set (match_operand:SI 0 "register_operand")
1863 (zero_extend:SI
1864 (match_operand:HI 1 "nonimmediate_operand")))
1865 (clobber (reg:CC CC_REGNUM))])]
1866 ""
1867 {
1868 if (! (TARGET_V850E_UP))
1869 operands[1] = force_reg (HImode, operands[1]);
1870 })
1871
1872 (define_insn "*zero_extendqisi2_v850e"
1873 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1874 (zero_extend:SI
1875 (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m")))
1876 (clobber (reg:CC CC_REGNUM))]
1877 "(TARGET_V850E_UP)"
1878 "@
1879 zxb %0
1880 andi 255,%1,%0
1881 sld.bu %1,%0
1882 ld.bu %1,%0"
1883 [(set_attr "length" "2,4,2,4")
1884 (set_attr "cc" "none_0hit,set_zn,none_0hit,none_0hit")])
1885
1886 (define_insn "*zero_extendqisi2_v850"
1887 [(set (match_operand:SI 0 "register_operand" "=r")
1888 (zero_extend:SI
1889 (match_operand:QI 1 "register_operand" "r")))
1890 (clobber (reg:CC CC_REGNUM))] ;; A lie, but we have to match the expander
1891 ""
1892 "andi 255,%1,%0"
1893 [(set_attr "length" "4")
1894 (set_attr "cc" "set_zn")])
1895
1896 (define_expand "zero_extendqisi2"
1897 [(parallel [(set (match_operand:SI 0 "register_operand")
1898 (zero_extend:SI
1899 (match_operand:QI 1 "nonimmediate_operand")))
1900 (clobber (reg:CC CC_REGNUM))])]
1901 ""
1902 {
1903 if (! (TARGET_V850E_UP))
1904 operands[1] = force_reg (QImode, operands[1]);
1905 })
1906
1907 ;;- sign extension instructions
1908
1909 ;; ??? The extendhisi2 pattern should not emit shifts for v850e?
1910
1911 (define_insn "*extendhisi_insn"
1912 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1913 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))
1914 (clobber (reg:CC CC_REGNUM))]
1915 "(TARGET_V850E_UP)"
1916 "@
1917 sxh %0
1918 sld.h %1,%0
1919 ld.h %1,%0"
1920 [(set_attr "length" "2,2,4")
1921 (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1922
1923 ;; ??? This is missing a sign extend from memory pattern to match the ld.h
1924 ;; instruction.
1925
1926 (define_expand "extendhisi2"
1927 [(parallel [(set (match_dup 2)
1928 (ashift:SI (match_operand:HI 1 "register_operand" "")
1929 (const_int 16)))
1930 (clobber (reg:CC CC_REGNUM))])
1931 (parallel [(set (match_operand:SI 0 "register_operand" "")
1932 (ashiftrt:SI (match_dup 2)
1933 (const_int 16)))
1934 (clobber (reg:CC CC_REGNUM))])]
1935 ""
1936 {
1937 operands[1] = gen_lowpart (SImode, operands[1]);
1938 operands[2] = gen_reg_rtx (SImode);
1939 })
1940
1941 ;; ??? The extendqisi2 pattern should not emit shifts for v850e?
1942
1943 (define_insn "*extendqisi_insn"
1944 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1945 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))
1946 (clobber (reg:CC CC_REGNUM))]
1947 "(TARGET_V850E_UP)"
1948 "@
1949 sxb %0
1950 sld.b %1,%0
1951 ld.b %1,%0"
1952 [(set_attr "length" "2,2,4")
1953 (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1954
1955 ;; ??? This is missing a sign extend from memory pattern to match the ld.b
1956 ;; instruction.
1957
1958 (define_expand "extendqisi2"
1959 [(parallel [(set (match_dup 2)
1960 (ashift:SI (match_operand:QI 1 "register_operand" "")
1961 (const_int 24)))
1962 (clobber (reg:CC CC_REGNUM))])
1963 (parallel [(set (match_operand:SI 0 "register_operand" "")
1964 (ashiftrt:SI (match_dup 2)
1965 (const_int 24)))
1966 (clobber (reg:CC CC_REGNUM))])]
1967 ""
1968 {
1969 operands[1] = gen_lowpart (SImode, operands[1]);
1970 operands[2] = gen_reg_rtx (SImode);
1971 })
1972 \f
1973 ;; ----------------------------------------------------------------------
1974 ;; SHIFTS
1975 ;; ----------------------------------------------------------------------
1976
1977 (define_insn "ashlsi3"
1978 [(set (match_operand:SI 0 "register_operand" "=r,r")
1979 (ashift:SI
1980 (match_operand:SI 1 "register_operand" "0,0")
1981 (match_operand:SI 2 "nonmemory_operand" "r,N")))
1982 (clobber (reg:CC CC_REGNUM))]
1983 ""
1984 "@
1985 shl %2,%0
1986 shl %2,%0"
1987 [(set_attr "length" "4,2")
1988 (set_attr "cc" "set_zn")])
1989
1990 (define_insn "ashlsi3_v850e2"
1991 [(set (match_operand:SI 0 "register_operand" "=r")
1992 (ashift:SI
1993 (match_operand:SI 1 "register_operand" "r")
1994 (match_operand:SI 2 "nonmemory_operand" "r")))
1995 (clobber (reg:CC CC_REGNUM))]
1996 "TARGET_V850E2_UP"
1997 "shl %2,%1,%0"
1998 [(set_attr "length" "4")
1999 (set_attr "cc" "set_znv")])
2000
2001 (define_insn "lshrsi3"
2002 [(set (match_operand:SI 0 "register_operand" "=r,r")
2003 (lshiftrt:SI
2004 (match_operand:SI 1 "register_operand" "0,0")
2005 (match_operand:SI 2 "nonmemory_operand" "r,N")))
2006 (clobber (reg:CC CC_REGNUM))]
2007 ""
2008 "@
2009 shr %2,%0
2010 shr %2,%0"
2011 [(set_attr "length" "4,2")
2012 (set_attr "cc" "set_zn")])
2013
2014 (define_insn "lshrsi3_v850e2"
2015 [(set (match_operand:SI 0 "register_operand" "=r")
2016 (lshiftrt:SI
2017 (match_operand:SI 1 "register_operand" "r")
2018 (match_operand:SI 2 "nonmemory_operand" "r")))
2019 (clobber (reg:CC CC_REGNUM))]
2020 "TARGET_V850E2_UP"
2021 "shr %2,%1,%0"
2022 [(set_attr "length" "4")
2023 (set_attr "cc" "set_zn")])
2024
2025 (define_insn "ashrsi3"
2026 [(set (match_operand:SI 0 "register_operand" "=r,r")
2027 (ashiftrt:SI
2028 (match_operand:SI 1 "register_operand" "0,0")
2029 (match_operand:SI 2 "nonmemory_operand" "r,N")))
2030 (clobber (reg:CC CC_REGNUM))]
2031 ""
2032 "@
2033 sar %2,%0
2034 sar %2,%0"
2035 [(set_attr "length" "4,2")
2036 (set_attr "cc" "set_zn, set_zn")])
2037
2038 (define_insn "ashrsi3_v850e2"
2039 [(set (match_operand:SI 0 "register_operand" "=r")
2040 (ashiftrt:SI
2041 (match_operand:SI 1 "register_operand" "r")
2042 (match_operand:SI 2 "nonmemory_operand" "r")))
2043 (clobber (reg:CC CC_REGNUM))]
2044 "TARGET_V850E2_UP"
2045 "sar %2,%1,%0"
2046 [(set_attr "length" "4")
2047 (set_attr "cc" "set_zn")])
2048
2049 ;; ----------------------------------------------------------------------
2050 ;; FIND FIRST BIT INSTRUCTION
2051 ;; ----------------------------------------------------------------------
2052
2053 (define_insn "ffssi2"
2054 [(set (match_operand:SI 0 "register_operand" "=r")
2055 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
2056 (clobber (reg:CC CC_REGNUM))]
2057 "TARGET_V850E2_UP"
2058 "sch1r %1,%0"
2059 [(set_attr "length" "4")
2060 (set_attr "cc" "clobber")])
2061
2062 ;; ----------------------------------------------------------------------
2063 ;; PROLOGUE/EPILOGUE
2064 ;; ----------------------------------------------------------------------
2065 (define_expand "prologue"
2066 [(const_int 0)]
2067 ""
2068 {
2069 expand_prologue ();
2070 DONE;
2071 })
2072
2073 (define_expand "epilogue"
2074 [(return)]
2075 ""
2076 {
2077 expand_epilogue ();
2078 DONE;
2079 })
2080
2081 (define_insn "return_simple"
2082 [(return)]
2083 "reload_completed"
2084 "jmp [r31]"
2085 [(set_attr "length" "2")
2086 (set_attr "cc" "none")])
2087
2088 (define_insn "return_internal"
2089 [(return)
2090 (use (reg:SI 31))]
2091 ""
2092 "jmp [r31]"
2093 [(set_attr "length" "2")
2094 (set_attr "cc" "none")])
2095
2096 ;; ----------------------------------------------------------------------
2097 ;; v850e2V3 floating-point hardware support
2098 ;; ----------------------------------------------------------------------
2099
2100
2101 (define_insn "addsf3"
2102 [(set (match_operand:SF 0 "register_operand" "=r")
2103 (plus:SF (match_operand:SF 1 "register_operand" "r")
2104 (match_operand:SF 2 "register_operand" "r")))]
2105 "TARGET_USE_FPU"
2106 "addf.s %1,%2,%0"
2107 [(set_attr "length" "4")
2108 (set_attr "cc" "none_0hit")
2109 (set_attr "type" "fpu")])
2110
2111 (define_insn "adddf3"
2112 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2113 (plus:DF (match_operand:DF 1 "even_reg_operand" "r")
2114 (match_operand:DF 2 "even_reg_operand" "r")))]
2115 "TARGET_USE_FPU"
2116 "addf.d %1,%2,%0"
2117 [(set_attr "length" "4")
2118 (set_attr "cc" "none_0hit")
2119 (set_attr "type" "fpu")])
2120
2121 (define_insn "subsf3"
2122 [(set (match_operand:SF 0 "register_operand" "=r")
2123 (minus:SF (match_operand:SF 1 "register_operand" "r")
2124 (match_operand:SF 2 "register_operand" "r")))]
2125 "TARGET_USE_FPU"
2126 "subf.s %2,%1,%0"
2127 [(set_attr "length" "4")
2128 (set_attr "cc" "none_0hit")
2129 (set_attr "type" "fpu")])
2130
2131 (define_insn "subdf3"
2132 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2133 (minus:DF (match_operand:DF 1 "even_reg_operand" "r")
2134 (match_operand:DF 2 "even_reg_operand" "r")))]
2135 "TARGET_USE_FPU"
2136 "subf.d %2,%1,%0"
2137 [(set_attr "length" "4")
2138 (set_attr "cc" "none_0hit")
2139 (set_attr "type" "fpu")])
2140
2141 (define_insn "mulsf3"
2142 [(set (match_operand:SF 0 "register_operand" "=r")
2143 (mult:SF (match_operand:SF 1 "register_operand" "r")
2144 (match_operand:SF 2 "register_operand" "r")))]
2145 "TARGET_USE_FPU"
2146 "mulf.s %1,%2,%0"
2147 [(set_attr "length" "4")
2148 (set_attr "cc" "none_0hit")
2149 (set_attr "type" "fpu")])
2150
2151 (define_insn "muldf3"
2152 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2153 (mult:DF (match_operand:DF 1 "even_reg_operand" "r")
2154 (match_operand:DF 2 "even_reg_operand" "r")))]
2155 "TARGET_USE_FPU"
2156 "mulf.d %1,%2,%0"
2157 [(set_attr "length" "4")
2158 (set_attr "cc" "none_0hit")
2159 (set_attr "type" "fpu")])
2160
2161 (define_insn "divsf3"
2162 [(set (match_operand:SF 0 "register_operand" "=r")
2163 (div:SF (match_operand:SF 1 "register_operand" "r")
2164 (match_operand:SF 2 "register_operand" "r")))]
2165 "TARGET_USE_FPU"
2166 "divf.s %2,%1,%0"
2167 [(set_attr "length" "4")
2168 (set_attr "cc" "none_0hit")
2169 (set_attr "type" "fpu")])
2170
2171 (define_insn "divdf3"
2172 [(set (match_operand:DF 0 "register_operand" "=r")
2173 (div:DF (match_operand:DF 1 "even_reg_operand" "r")
2174 (match_operand:DF 2 "even_reg_operand" "r")))]
2175 "TARGET_USE_FPU"
2176 "divf.d %2,%1,%0"
2177 [(set_attr "length" "4")
2178 (set_attr "cc" "none_0hit")
2179 (set_attr "type" "fpu")])
2180
2181 (define_insn "minsf3"
2182 [(set (match_operand:SF 0 "register_operand" "=r")
2183 (smin:SF (match_operand:SF 1 "reg_or_0_operand" "r")
2184 (match_operand:SF 2 "reg_or_0_operand" "r")))]
2185 "TARGET_USE_FPU"
2186 "minf.s %z1,%z2,%0"
2187 [(set_attr "length" "4")
2188 (set_attr "cc" "none_0hit")
2189 (set_attr "type" "fpu")])
2190
2191 (define_insn "mindf3"
2192 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2193 (smin:DF (match_operand:DF 1 "even_reg_operand" "r")
2194 (match_operand:DF 2 "even_reg_operand" "r")))]
2195 "TARGET_USE_FPU"
2196 "minf.d %1,%2,%0"
2197 [(set_attr "length" "4")
2198 (set_attr "cc" "none_0hit")
2199 (set_attr "type" "fpu")])
2200
2201 (define_insn "maxsf3"
2202 [(set (match_operand:SF 0 "register_operand" "=r")
2203 (smax:SF (match_operand:SF 1 "reg_or_0_operand" "r")
2204 (match_operand:SF 2 "reg_or_0_operand" "r")))]
2205 "TARGET_USE_FPU"
2206 "maxf.s %z1,%z2,%0"
2207 [(set_attr "length" "4")
2208 (set_attr "cc" "none_0hit")
2209 (set_attr "type" "fpu")])
2210
2211 (define_insn "maxdf3"
2212 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2213 (smax:DF (match_operand:DF 1 "even_reg_operand" "r")
2214 (match_operand:DF 2 "even_reg_operand" "r")))]
2215 "TARGET_USE_FPU"
2216 "maxf.d %1,%2,%0"
2217 [(set_attr "length" "4")
2218 (set_attr "cc" "none_0hit")
2219 (set_attr "type" "fpu")])
2220
2221 (define_insn "abssf2"
2222 [(set (match_operand:SF 0 "register_operand" "=r")
2223 (abs:SF (match_operand:SF 1 "register_operand" "r")))]
2224 "TARGET_USE_FPU"
2225 "absf.s %1,%0"
2226 [(set_attr "length" "4")
2227 (set_attr "cc" "none_0hit")
2228 (set_attr "type" "fpu")])
2229
2230 (define_insn "absdf2"
2231 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2232 (abs:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2233 "TARGET_USE_FPU"
2234 "absf.d %1,%0"
2235 [(set_attr "length" "4")
2236 (set_attr "cc" "none_0hit")
2237 (set_attr "type" "fpu")])
2238
2239 (define_insn "negsf2"
2240 [(set (match_operand:SF 0 "register_operand" "=r")
2241 (neg:SF (match_operand:SF 1 "register_operand" "r")))]
2242 "TARGET_USE_FPU"
2243 "negf.s %1,%0"
2244 [(set_attr "length" "4")
2245 (set_attr "cc" "none_0hit")
2246 (set_attr "type" "fpu")])
2247
2248 (define_insn "negdf2"
2249 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2250 (neg:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2251 "TARGET_USE_FPU"
2252 "negf.d %1,%0"
2253 [(set_attr "length" "4")
2254 (set_attr "cc" "none_0hit")
2255 (set_attr "type" "fpu")])
2256
2257 ;; square-root
2258 (define_insn "sqrtsf2"
2259 [(set (match_operand:SF 0 "register_operand" "=r")
2260 (sqrt:SF (match_operand:SF 1 "register_operand" "r")))]
2261 "TARGET_USE_FPU"
2262 "sqrtf.s %1,%0"
2263 [(set_attr "length" "4")
2264 (set_attr "cc" "none_0hit")
2265 (set_attr "type" "fpu")])
2266
2267 (define_insn "sqrtdf2"
2268 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2269 (sqrt:DF (match_operand:DF 1 "even_reg_operand" "r")))]
2270 "TARGET_USE_FPU"
2271 "sqrtf.d %1,%0"
2272 [(set_attr "length" "4")
2273 (set_attr "cc" "none_0hit")
2274 (set_attr "type" "fpu")])
2275
2276 ;; float -> int
2277 (define_insn "fix_truncsfsi2"
2278 [(set (match_operand:SI 0 "register_operand" "=r")
2279 (fix:SI (match_operand:SF 1 "register_operand" "r")))]
2280 "TARGET_USE_FPU"
2281 "trncf.sw %1,%0"
2282 [(set_attr "length" "4")
2283 (set_attr "cc" "none_0hit")
2284 (set_attr "type" "fpu")])
2285
2286 (define_insn "fixuns_truncsfsi2"
2287 [(set (match_operand:SI 0 "register_operand" "=r")
2288 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "r")))]
2289 "TARGET_USE_FPU"
2290 "trncf.suw %1, %0"
2291 [(set_attr "length" "4")
2292 (set_attr "cc" "none_0hit")
2293 (set_attr "type" "fpu")]
2294 )
2295
2296 (define_insn "fix_truncdfsi2"
2297 [(set (match_operand:SI 0 "register_operand" "=r")
2298 (fix:SI (match_operand:DF 1 "even_reg_operand" "r")))]
2299 "TARGET_USE_FPU"
2300 "trncf.dw %1,%0"
2301 [(set_attr "length" "4")
2302 (set_attr "cc" "none_0hit")
2303 (set_attr "type" "fpu")])
2304
2305 (define_insn "fixuns_truncdfsi2"
2306 [(set (match_operand:SI 0 "register_operand" "=r")
2307 (unsigned_fix:SI (match_operand:DF 1 "even_reg_operand" "r")))]
2308 "TARGET_USE_FPU"
2309 "trncf.duw %1, %0"
2310 [(set_attr "length" "4")
2311 (set_attr "cc" "none_0hit")
2312 (set_attr "type" "fpu")]
2313 )
2314
2315 (define_insn "fix_truncsfdi2"
2316 [(set (match_operand:DI 0 "register_operand" "=r")
2317 (fix:DI (match_operand:SF 1 "register_operand" "r")))]
2318 "TARGET_USE_FPU"
2319 "trncf.sl %1, %0"
2320 [(set_attr "length" "4")
2321 (set_attr "cc" "none_0hit")
2322 (set_attr "type" "fpu")])
2323
2324 (define_insn "fixuns_truncsfdi2"
2325 [(set (match_operand:DI 0 "register_operand" "=r")
2326 (unsigned_fix:DI (match_operand:SF 1 "register_operand" "r")))]
2327 "TARGET_USE_FPU"
2328 "trncf.sul %1, %0"
2329 [(set_attr "length" "4")
2330 (set_attr "cc" "none_0hit")
2331 (set_attr "type" "fpu")]
2332 )
2333
2334 (define_insn "fix_truncdfdi2"
2335 [(set (match_operand:DI 0 "register_operand" "=r")
2336 (fix:DI (match_operand:DF 1 "even_reg_operand" "r")))]
2337 "TARGET_USE_FPU"
2338 "trncf.dl %1, %0"
2339 [(set_attr "length" "4")
2340 (set_attr "cc" "none_0hit")
2341 (set_attr "type" "fpu")])
2342
2343 (define_insn "fixuns_truncdfdi2"
2344 [(set (match_operand:DI 0 "register_operand" "=r")
2345 (unsigned_fix:DI (match_operand:DF 1 "even_reg_operand" "r")))]
2346 "TARGET_USE_FPU"
2347 "trncf.dul %1, %0"
2348 [(set_attr "length" "4")
2349 (set_attr "cc" "none_0hit")
2350 (set_attr "type" "fpu")]
2351 )
2352
2353 ;; int -> float
2354 (define_insn "floatsisf2"
2355 [(set (match_operand:SF 0 "register_operand" "=r")
2356 (float:SF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2357 "TARGET_USE_FPU"
2358 "cvtf.ws %z1, %0"
2359 [(set_attr "length" "4")
2360 (set_attr "cc" "none_0hit")
2361 (set_attr "type" "fpu")])
2362
2363 (define_insn "unsfloatsisf2"
2364 [(set (match_operand:SF 0 "register_operand" "=r")
2365 (unsigned_float:SF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2366 "TARGET_USE_FPU"
2367 "cvtf.uws %z1, %0"
2368 [(set_attr "length" "4")
2369 (set_attr "cc" "none_0hit")
2370 (set_attr "type" "fpu")])
2371
2372 (define_insn "floatsidf2"
2373 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2374 (float:DF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2375 "TARGET_USE_FPU"
2376 "cvtf.wd %z1,%0"
2377 [(set_attr "length" "4")
2378 (set_attr "cc" "none_0hit")
2379 (set_attr "type" "fpu")])
2380
2381 (define_insn "unsfloatsidf2"
2382 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2383 (unsigned_float:DF (match_operand:SI 1 "reg_or_0_operand" "rI")))]
2384 "TARGET_USE_FPU"
2385 "cvtf.uwd %z1, %0"
2386 [(set_attr "length" "4")
2387 (set_attr "cc" "none_0hit")
2388 (set_attr "type" "fpu")])
2389
2390 (define_insn "floatdisf2"
2391 [(set (match_operand:SF 0 "even_reg_operand" "=r")
2392 (float:SF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2393 "TARGET_USE_FPU"
2394 "cvtf.ls %z1, %0"
2395 [(set_attr "length" "4")
2396 (set_attr "cc" "none_0hit")
2397 (set_attr "type" "fpu")])
2398
2399 (define_insn "unsfloatdisf2"
2400 [(set (match_operand:SF 0 "even_reg_operand" "=r")
2401 (unsigned_float:SF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2402 "TARGET_USE_FPU"
2403 "cvtf.uls %z1, %0"
2404 [(set_attr "length" "4")
2405 (set_attr "cc" "none_0hit")
2406 (set_attr "type" "fpu")])
2407
2408 (define_insn "floatdidf2"
2409 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2410 (float:DF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2411 "TARGET_USE_FPU"
2412 "cvtf.ld %z1, %0"
2413 [(set_attr "length" "4")
2414 (set_attr "cc" "none_0hit")
2415 (set_attr "type" "fpu")])
2416
2417 (define_insn "unsfloatdidf2"
2418 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2419 (unsigned_float:DF (match_operand:DI 1 "reg_or_0_operand" "rI")))]
2420 "TARGET_USE_FPU"
2421 "cvtf.uld %z1, %0"
2422 [(set_attr "length" "4")
2423 (set_attr "cc" "none_0hit")
2424 (set_attr "type" "fpu")])
2425
2426 ;; single-float -> double-float
2427 (define_insn "extendsfdf2"
2428 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2429 (float_extend:DF
2430 (match_operand:SF 1 "reg_or_0_operand" "rI")))]
2431 "TARGET_USE_FPU"
2432 "cvtf.sd %z1,%0"
2433 [(set_attr "length" "4")
2434 (set_attr "cc" "none_0hit")
2435 (set_attr "type" "fpu")])
2436
2437 ;; double-float -> single-float
2438 (define_insn "truncdfsf2"
2439 [(set (match_operand:SF 0 "register_operand" "=r")
2440 (float_truncate:SF
2441 (match_operand:DF 1 "even_reg_operand" "r")))]
2442 "TARGET_USE_FPU"
2443 "cvtf.ds %1,%0"
2444 [(set_attr "length" "4")
2445 (set_attr "cc" "none_0hit")
2446 (set_attr "type" "fpu")])
2447
2448 ;;
2449 ;; ---------------- special insns
2450 ;;
2451
2452 ;;; reciprocal
2453 (define_insn "recipsf2"
2454 [(set (match_operand:SF 0 "register_operand" "=r")
2455 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2456 (match_operand:SF 2 "register_operand" "r")))]
2457 "TARGET_USE_FPU"
2458 "recipf.s %2,%0"
2459 [(set_attr "length" "4")
2460 (set_attr "cc" "none_0hit")
2461 (set_attr "type" "fpu")])
2462
2463 (define_insn "recipdf2"
2464 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2465 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2466 (match_operand:DF 2 "even_reg_operand" "r")))]
2467 "TARGET_USE_FPU"
2468 "recipf.d %2,%0"
2469 [(set_attr "length" "4")
2470 (set_attr "cc" "none_0hit")
2471 (set_attr "type" "fpu")])
2472
2473 ;;; reciprocal of square-root
2474 (define_insn "rsqrtsf2"
2475 [(set (match_operand:SF 0 "register_operand" "=r")
2476 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2477 (sqrt:SF (match_operand:SF 2 "register_operand" "r"))))]
2478 "TARGET_USE_FPU"
2479 "rsqrtf.s %2,%0"
2480 [(set_attr "length" "4")
2481 (set_attr "cc" "none_0hit")
2482 (set_attr "type" "fpu")])
2483
2484 (define_insn "rsqrtdf2"
2485 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2486 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2487 (sqrt:DF (match_operand:DF 2 "even_reg_operand" "r"))))]
2488 "TARGET_USE_FPU"
2489 "rsqrtf.d %2,%0"
2490 [(set_attr "length" "4")
2491 (set_attr "cc" "none_0hit")
2492 (set_attr "type" "fpu")])
2493
2494 ;; Note: The FPU-2.0 (ie pre e3v5) versions of these routines do not actually
2495 ;; need operand 4 to be the same as operand 0. But the FPU-2.0 versions are
2496 ;; also deprecated so the loss of flexibility is unimportant.
2497
2498 ;;; multiply-add
2499 (define_insn "fmasf4"
2500 [(set (match_operand:SF 0 "register_operand" "=r")
2501 (fma:SF (match_operand:SF 1 "register_operand" "r")
2502 (match_operand:SF 2 "register_operand" "r")
2503 (match_operand:SF 3 "register_operand" "0")))]
2504 "TARGET_USE_FPU"
2505 { return TARGET_V850E3V5_UP ? "fmaf.s %1, %2, %0" : "maddf.s %2, %1, %3, %0"; }
2506 [(set_attr "length" "4")
2507 (set_attr "cc" "none_0hit")
2508 (set_attr "type" "fpu")])
2509
2510 ;;; multiply-subtract
2511 (define_insn "fmssf4"
2512 [(set (match_operand:SF 0 "register_operand" "=r")
2513 (fma:SF (match_operand:SF 1 "register_operand" "r")
2514 (match_operand:SF 2 "register_operand" "r")
2515 (neg:SF (match_operand:SF 3 "register_operand" "0"))))]
2516 "TARGET_USE_FPU"
2517 { return TARGET_V850E3V5_UP ? "fmsf.s %1, %2, %0" : "msubf.s %2, %1, %3, %0"; }
2518 [(set_attr "length" "4")
2519 (set_attr "cc" "none_0hit")
2520 (set_attr "type" "fpu")])
2521
2522 ;;; negative-multiply-add
2523 (define_insn "fnmasf4"
2524 [(set (match_operand:SF 0 "register_operand" "=r")
2525 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "r")
2526 (match_operand:SF 2 "register_operand" "r")
2527 (match_operand:SF 3 "register_operand" "0"))))]
2528 "TARGET_USE_FPU"
2529 { return TARGET_V850E3V5_UP ? "fnmaf.s %1, %2, %0" : "nmaddf.s %2, %1, %3, %0"; }
2530 [(set_attr "length" "4")
2531 (set_attr "cc" "none_0hit")
2532 (set_attr "type" "fpu")])
2533
2534 ;; negative-multiply-subtract
2535 (define_insn "fnmssf4"
2536 [(set (match_operand:SF 0 "register_operand" "=r")
2537 (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "r")
2538 (match_operand:SF 2 "register_operand" "r")
2539 (neg:SF (match_operand:SF 3 "register_operand" "0")))))]
2540 "TARGET_USE_FPU"
2541 { return TARGET_V850E3V5_UP ? "fnmsf.s %1, %2, %0" : "nmsubf.s %2, %1, %3, %0"; }
2542 [(set_attr "length" "4")
2543 (set_attr "cc" "none_0hit")
2544 (set_attr "type" "fpu")])
2545 ;
2546 ; ---------------- comparison/conditionals
2547 ;
2548 ; SF
2549
2550 (define_insn "cmpsf_le_insn"
2551 [(set (reg:CC_FPU_LE FCC_REGNUM)
2552 (compare:CC_FPU_LE (match_operand:SF 0 "register_operand" "r")
2553 (match_operand:SF 1 "register_operand" "r")))]
2554 "TARGET_USE_FPU"
2555 "cmpf.s le, %z0, %z1"
2556 [(set_attr "length" "4")
2557 (set_attr "cc" "none_0hit")
2558 (set_attr "type" "fpu")])
2559
2560 (define_insn "cmpsf_lt_insn"
2561 [(set (reg:CC_FPU_LT FCC_REGNUM)
2562 (compare:CC_FPU_LT (match_operand:SF 0 "register_operand" "r")
2563 (match_operand:SF 1 "register_operand" "r")))]
2564 "TARGET_USE_FPU"
2565 "cmpf.s lt, %z0, %z1"
2566 [(set_attr "length" "4")
2567 (set_attr "cc" "none_0hit")
2568 (set_attr "type" "fpu")])
2569
2570 (define_insn "cmpsf_ge_insn"
2571 [(set (reg:CC_FPU_GE FCC_REGNUM)
2572 (compare:CC_FPU_GE (match_operand:SF 0 "register_operand" "r")
2573 (match_operand:SF 1 "register_operand" "r")))]
2574 "TARGET_USE_FPU"
2575 "cmpf.s le, %z1, %z0"
2576 [(set_attr "length" "4")
2577 (set_attr "cc" "none_0hit")
2578 (set_attr "type" "fpu")])
2579
2580 (define_insn "cmpsf_gt_insn"
2581 [(set (reg:CC_FPU_GT FCC_REGNUM)
2582 (compare:CC_FPU_GT (match_operand:SF 0 "register_operand" "r")
2583 (match_operand:SF 1 "register_operand" "r")))]
2584 "TARGET_USE_FPU"
2585 "cmpf.s lt, %z1, %z0"
2586 [(set_attr "length" "4")
2587 (set_attr "cc" "none_0hit")
2588 (set_attr "type" "fpu")])
2589
2590 (define_insn "cmpsf_eq_insn"
2591 [(set (reg:CC_FPU_EQ FCC_REGNUM)
2592 (compare:CC_FPU_EQ (match_operand:SF 0 "register_operand" "r")
2593 (match_operand:SF 1 "register_operand" "r")))]
2594 "TARGET_USE_FPU"
2595 "cmpf.s eq, %z0, %z1"
2596 [(set_attr "length" "4")
2597 (set_attr "cc" "none_0hit")
2598 (set_attr "type" "fpu")])
2599
2600 ; DF
2601
2602 (define_insn "cmpdf_le_insn"
2603 [(set (reg:CC_FPU_LE FCC_REGNUM)
2604 (compare:CC_FPU_LE (match_operand:DF 0 "even_reg_operand" "r")
2605 (match_operand:DF 1 "even_reg_operand" "r")))]
2606 "TARGET_USE_FPU"
2607 "cmpf.d le, %z0, %z1"
2608 [(set_attr "length" "4")
2609 (set_attr "cc" "none_0hit")
2610 (set_attr "type" "fpu")])
2611
2612 (define_insn "cmpdf_lt_insn"
2613 [(set (reg:CC_FPU_LT FCC_REGNUM)
2614 (compare:CC_FPU_LT (match_operand:DF 0 "even_reg_operand" "r")
2615 (match_operand:DF 1 "even_reg_operand" "r")))]
2616 "TARGET_USE_FPU"
2617 "cmpf.d lt, %z0, %z1"
2618 [(set_attr "length" "4")
2619 (set_attr "cc" "none_0hit")
2620 (set_attr "type" "fpu")])
2621
2622 (define_insn "cmpdf_ge_insn"
2623 [(set (reg:CC_FPU_GE FCC_REGNUM)
2624 (compare:CC_FPU_GE (match_operand:DF 0 "even_reg_operand" "r")
2625 (match_operand:DF 1 "even_reg_operand" "r")))]
2626 "TARGET_USE_FPU"
2627 "cmpf.d le, %z1, %z0"
2628 [(set_attr "length" "4")
2629 (set_attr "cc" "none_0hit")
2630 (set_attr "type" "fpu")])
2631
2632 (define_insn "cmpdf_gt_insn"
2633 [(set (reg:CC_FPU_GT FCC_REGNUM)
2634 (compare:CC_FPU_GT (match_operand:DF 0 "even_reg_operand" "r")
2635 (match_operand:DF 1 "even_reg_operand" "r")))]
2636 "TARGET_USE_FPU"
2637 "cmpf.d lt, %z1, %z0"
2638 [(set_attr "length" "4")
2639 (set_attr "cc" "none_0hit")
2640 (set_attr "type" "fpu")])
2641
2642 (define_insn "cmpdf_eq_insn"
2643 [(set (reg:CC_FPU_EQ FCC_REGNUM)
2644 (compare:CC_FPU_EQ (match_operand:DF 0 "even_reg_operand" "r")
2645 (match_operand:DF 1 "even_reg_operand" "r")))]
2646 "TARGET_USE_FPU"
2647 "cmpf.d eq, %z0, %z1"
2648 [(set_attr "length" "4")
2649 (set_attr "cc" "none_0hit")
2650 (set_attr "type" "fpu")])
2651
2652 ;;
2653 ;; Transfer a v850e2v3 fcc to the Z bit of CC0 (this is necessary to do a
2654 ;; conditional branch based on a floating-point compare)
2655 ;;
2656
2657 (define_insn "trfsr"
2658 [(set (match_operand 0 "" "") (match_operand 1 "" ""))]
2659 "TARGET_USE_FPU
2660 && GET_MODE(operands[0]) == GET_MODE(operands[1])
2661 && GET_CODE(operands[0]) == REG && REGNO (operands[0]) == CC_REGNUM
2662 && GET_CODE(operands[1]) == REG && REGNO (operands[1]) == FCC_REGNUM
2663 && (GET_MODE(operands[0]) == CC_FPU_LEmode
2664 || GET_MODE(operands[0]) == CC_FPU_GEmode
2665 || GET_MODE(operands[0]) == CC_FPU_LTmode
2666 || GET_MODE(operands[0]) == CC_FPU_GTmode
2667 || GET_MODE(operands[0]) == CC_FPU_EQmode
2668 || GET_MODE(operands[0]) == CC_FPU_NEmode)"
2669 "trfsr"
2670 [(set_attr "length" "4")
2671 (set_attr "cc" "set_z")
2672 (set_attr "type" "fpu")])
2673
2674 ;;
2675 ;; Floating-point conditional moves for the v850e2v3.
2676 ;;
2677
2678 ;; The actual v850e2v3 conditional move instructions
2679 ;;
2680 (define_insn "movsfcc_z_insn"
2681 [(set (match_operand:SF 0 "register_operand" "=r")
2682 (if_then_else:SF
2683 (match_operand 3 "v850_float_z_comparison_operator" "")
2684 (match_operand:SF 1 "reg_or_0_operand" "rIG")
2685 (match_operand:SF 2 "reg_or_0_operand" "rIG")))]
2686 "TARGET_USE_FPU"
2687 "cmovf.s 0,%z1,%z2,%0"
2688 [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2689
2690 (define_insn "movsfcc_nz_insn"
2691 [(set (match_operand:SF 0 "register_operand" "=r")
2692 (if_then_else:SF
2693 (match_operand 3 "v850_float_nz_comparison_operator" "")
2694 (match_operand:SF 1 "reg_or_0_operand" "rIG")
2695 (match_operand:SF 2 "reg_or_0_operand" "rIG")))]
2696 "TARGET_USE_FPU"
2697 "cmovf.s 0,%z2,%z1,%0"
2698 [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2699
2700 (define_insn "movdfcc_z_insn"
2701 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2702 (if_then_else:DF
2703 (match_operand 3 "v850_float_z_comparison_operator" "")
2704 (match_operand:DF 1 "even_reg_operand" "r")
2705 (match_operand:DF 2 "even_reg_operand" "r")))]
2706 "TARGET_USE_FPU"
2707 "cmovf.d 0,%z1,%z2,%0"
2708 [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2709
2710 (define_insn "movdfcc_nz_insn"
2711 [(set (match_operand:DF 0 "even_reg_operand" "=r")
2712 (if_then_else:DF
2713 (match_operand 3 "v850_float_nz_comparison_operator" "")
2714 (match_operand:DF 1 "even_reg_operand" "r")
2715 (match_operand:DF 2 "even_reg_operand" "r")))]
2716 "TARGET_USE_FPU"
2717 "cmovf.d 0,%z2,%z1,%0"
2718 [(set_attr "cc" "clobber")]) ;; ??? or none_0hit
2719
2720 (define_insn "movedfcc_z_zero"
2721 [(set (match_operand:DF 0 "register_operand" "=r")
2722 (if_then_else:DF
2723 (match_operand 3 "v850_float_z_comparison_operator" "")
2724 (match_operand:DF 1 "reg_or_0_operand" "rIG")
2725 (match_operand:DF 2 "reg_or_0_operand" "rIG")))]
2726 "TARGET_USE_FPU"
2727 "cmovf.s 0,%z1,%z2,%0 ; cmovf.s 0,%Z1,%Z2,%R0"
2728 [(set_attr "length" "8")
2729 (set_attr "cc" "clobber")]) ;; ??? or none_0hit
2730
2731 (define_insn "movedfcc_nz_zero"
2732 [(set (match_operand:DF 0 "register_operand" "=r")
2733 (if_then_else:DF
2734 (match_operand 3 "v850_float_nz_comparison_operator" "")
2735 (match_operand:DF 1 "reg_or_0_operand" "rIG")
2736 (match_operand:DF 2 "reg_or_0_operand" "rIG")))]
2737 "TARGET_USE_FPU"
2738 "cmovf.s 0,%z2,%z1,%0 ; cmovf.s 0,%Z2,%Z1,%R0"
2739 [(set_attr "length" "8")
2740 (set_attr "cc" "clobber")]) ;; ??? or none_0hit
2741
2742
2743 ;; ----------------------------------------------------------------------
2744 ;; HELPER INSTRUCTIONS for saving the prologue and epilogue registers
2745 ;; ----------------------------------------------------------------------
2746
2747 ;; This pattern will match a stack adjust RTX followed by any number of push
2748 ;; RTXs. These RTXs will then be turned into a suitable call to a worker
2749 ;; function.
2750
2751 ;;
2752 ;; Actually, convert the RTXs into a PREPARE instruction.
2753 ;;
2754
2755 (define_insn ""
2756 [(match_parallel 0 "pattern_is_ok_for_prepare"
2757 [(set (reg:SI 3)
2758 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2759 (set (mem:SI (plus:SI (reg:SI 3)
2760 (match_operand:SI 2 "immediate_operand" "i")))
2761 (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
2762 "TARGET_PROLOG_FUNCTION && (TARGET_V850E_UP)"
2763 {
2764 return construct_prepare_instruction (operands[0]);
2765 }
2766 [(set_attr "length" "4")
2767 (set_attr "cc" "clobber")])
2768
2769 (define_insn ""
2770 [(match_parallel 0 "pattern_is_ok_for_prologue"
2771 [(set (reg:SI 3)
2772 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2773 (set (mem:SI (plus:SI (reg:SI 3)
2774 (match_operand:SI 2 "immediate_operand" "i")))
2775 (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
2776 "TARGET_PROLOG_FUNCTION"
2777 {
2778 return construct_save_jarl (operands[0]);
2779 }
2780 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
2781 (const_string "16")
2782 (const_string "4")))
2783 (set_attr "cc" "clobber")])
2784
2785 ;;
2786 ;; Actually, turn the RTXs into a DISPOSE instruction.
2787 ;;
2788 (define_insn ""
2789 [(match_parallel 0 "pattern_is_ok_for_dispose"
2790 [(return)
2791 (set (reg:SI 3)
2792 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2793 (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
2794 (mem:SI (plus:SI (reg:SI 3)
2795 (match_operand:SI 3 "immediate_operand" "i"))))])]
2796 "TARGET_PROLOG_FUNCTION && (TARGET_V850E_UP)"
2797 {
2798 return construct_dispose_instruction (operands[0]);
2799 }
2800 [(set_attr "length" "4")
2801 (set_attr "cc" "clobber")])
2802
2803 ;; This pattern will match a return RTX followed by any number of pop RTXs
2804 ;; and possible a stack adjustment as well. These RTXs will be turned into
2805 ;; a suitable call to a worker function.
2806
2807 (define_insn ""
2808 [(match_parallel 0 "pattern_is_ok_for_epilogue"
2809 [(return)
2810 (set (reg:SI 3)
2811 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
2812 (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
2813 (mem:SI (plus:SI (reg:SI 3)
2814 (match_operand:SI 3 "immediate_operand" "i"))))])]
2815 "TARGET_PROLOG_FUNCTION"
2816 {
2817 return construct_restore_jr (operands[0]);
2818 }
2819 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
2820 (const_string "12")
2821 (const_string "4")))
2822 (set_attr "cc" "clobber")])
2823
2824 ;; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION.
2825 (define_insn "callt_save_interrupt"
2826 [(unspec_volatile [(const_int 0)] 2)]
2827 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2828 ;; The CALLT instruction stores the next address of CALLT to CTPC register
2829 ;; without saving its previous value. So if the interrupt handler
2830 ;; or its caller could possibly execute the CALLT insn, save_interrupt
2831 ;; MUST NOT be called via CALLT.
2832 {
2833 output_asm_insn ("addi -28, sp, sp", operands);
2834 output_asm_insn ("st.w r1, 24[sp]", operands);
2835 output_asm_insn ("st.w r10, 12[sp]", operands);
2836 output_asm_insn ("st.w r11, 16[sp]", operands);
2837 output_asm_insn ("stsr ctpc, r10", operands);
2838 output_asm_insn ("st.w r10, 20[sp]", operands);
2839 output_asm_insn ("stsr ctpsw, r10", operands);
2840 output_asm_insn ("st.w r10, 24[sp]", operands);
2841 output_asm_insn ("callt ctoff(__callt_save_interrupt)", operands);
2842 return "";
2843 }
2844 [(set_attr "length" "26")
2845 (set_attr "cc" "clobber")])
2846
2847 (define_insn "callt_return_interrupt"
2848 [(unspec_volatile [(const_int 0)] 3)]
2849 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2850 "callt ctoff(__callt_return_interrupt)"
2851 [(set_attr "length" "2")
2852 (set_attr "cc" "clobber")])
2853
2854 (define_insn "save_interrupt"
2855 [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -20)))
2856 (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 30))
2857 (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 4))
2858 (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))
2859 (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 10))
2860 (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 11))]
2861 ""
2862 {
2863 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2864 return "addi -20,sp,sp \; st.w r11,16[sp] \; st.w r10,12[sp] \; jarl __save_interrupt,r10";
2865 else
2866 {
2867 output_asm_insn ("addi -20, sp, sp", operands);
2868 output_asm_insn ("st.w r11, 16[sp]", operands);
2869 output_asm_insn ("st.w r10, 12[sp]", operands);
2870 output_asm_insn ("st.w ep, 0[sp]", operands);
2871 output_asm_insn ("st.w gp, 4[sp]", operands);
2872 output_asm_insn ("st.w r1, 8[sp]", operands);
2873 output_asm_insn ("movhi hi(__ep), r0, ep", operands);
2874 output_asm_insn ("movea lo(__ep), ep, ep", operands);
2875 output_asm_insn ("movhi hi(__gp), r0, gp", operands);
2876 output_asm_insn ("movea lo(__gp), gp, gp", operands);
2877 return "";
2878 }
2879 }
2880 [(set (attr "length")
2881 (if_then_else (match_test "TARGET_LONG_CALLS")
2882 (const_int 10)
2883 (const_int 34)))
2884 (set_attr "cc" "clobber")])
2885
2886 ;; Restore r1, r4, r10, and return from the interrupt
2887 (define_insn "return_interrupt"
2888 [(return)
2889 (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 20)))
2890 (set (reg:SI 11) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))
2891 (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
2892 (set (reg:SI 1) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
2893 (set (reg:SI 4) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))
2894 (set (reg:SI 30) (mem:SI (reg:SI 3)))]
2895 ""
2896 {
2897 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2898 return "jr __return_interrupt";
2899 else
2900 {
2901 output_asm_insn ("ld.w 0[sp], ep", operands);
2902 output_asm_insn ("ld.w 4[sp], gp", operands);
2903 output_asm_insn ("ld.w 8[sp], r1", operands);
2904 output_asm_insn ("ld.w 12[sp], r10", operands);
2905 output_asm_insn ("ld.w 16[sp], r11", operands);
2906 output_asm_insn ("addi 20, sp, sp", operands);
2907 output_asm_insn ("reti", operands);
2908 return "";
2909 }
2910 }
2911 [(set (attr "length")
2912 (if_then_else (match_test "TARGET_LONG_CALLS")
2913 (const_int 4)
2914 (const_int 24)))
2915 (set_attr "cc" "clobber")])
2916
2917 ;; Save all registers except for the registers saved in save_interrupt when
2918 ;; an interrupt function makes a call.
2919 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2920 ;; all of memory. This blocks insns from being moved across this point.
2921 ;; This is needed because the rest of the compiler is not ready to handle
2922 ;; insns this complicated.
2923
2924 (define_insn "callt_save_all_interrupt"
2925 [(unspec_volatile [(const_int 0)] 0)]
2926 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
2927 "callt ctoff(__callt_save_all_interrupt)"
2928 [(set_attr "length" "2")
2929 (set_attr "cc" "none")])
2930
2931 (define_insn "save_all_interrupt"
2932 [(unspec_volatile [(const_int 0)] 0)]
2933 ""
2934 {
2935 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
2936 return "jarl __save_all_interrupt,r10";
2937
2938 output_asm_insn ("addi -120, sp, sp", operands);
2939
2940 if (TARGET_EP)
2941 {
2942 output_asm_insn ("mov ep, r1", operands);
2943 output_asm_insn ("mov sp, ep", operands);
2944 output_asm_insn ("sst.w r31, 116[ep]", operands);
2945 output_asm_insn ("sst.w r2, 112[ep]", operands);
2946 output_asm_insn ("sst.w gp, 108[ep]", operands);
2947 output_asm_insn ("sst.w r6, 104[ep]", operands);
2948 output_asm_insn ("sst.w r7, 100[ep]", operands);
2949 output_asm_insn ("sst.w r8, 96[ep]", operands);
2950 output_asm_insn ("sst.w r9, 92[ep]", operands);
2951 output_asm_insn ("sst.w r11, 88[ep]", operands);
2952 output_asm_insn ("sst.w r12, 84[ep]", operands);
2953 output_asm_insn ("sst.w r13, 80[ep]", operands);
2954 output_asm_insn ("sst.w r14, 76[ep]", operands);
2955 output_asm_insn ("sst.w r15, 72[ep]", operands);
2956 output_asm_insn ("sst.w r16, 68[ep]", operands);
2957 output_asm_insn ("sst.w r17, 64[ep]", operands);
2958 output_asm_insn ("sst.w r18, 60[ep]", operands);
2959 output_asm_insn ("sst.w r19, 56[ep]", operands);
2960 output_asm_insn ("sst.w r20, 52[ep]", operands);
2961 output_asm_insn ("sst.w r21, 48[ep]", operands);
2962 output_asm_insn ("sst.w r22, 44[ep]", operands);
2963 output_asm_insn ("sst.w r23, 40[ep]", operands);
2964 output_asm_insn ("sst.w r24, 36[ep]", operands);
2965 output_asm_insn ("sst.w r25, 32[ep]", operands);
2966 output_asm_insn ("sst.w r26, 28[ep]", operands);
2967 output_asm_insn ("sst.w r27, 24[ep]", operands);
2968 output_asm_insn ("sst.w r28, 20[ep]", operands);
2969 output_asm_insn ("sst.w r29, 16[ep]", operands);
2970 output_asm_insn ("mov r1, ep", operands);
2971 }
2972 else
2973 {
2974 output_asm_insn ("st.w r31, 116[sp]", operands);
2975 output_asm_insn ("st.w r2, 112[sp]", operands);
2976 output_asm_insn ("st.w gp, 108[sp]", operands);
2977 output_asm_insn ("st.w r6, 104[sp]", operands);
2978 output_asm_insn ("st.w r7, 100[sp]", operands);
2979 output_asm_insn ("st.w r8, 96[sp]", operands);
2980 output_asm_insn ("st.w r9, 92[sp]", operands);
2981 output_asm_insn ("st.w r11, 88[sp]", operands);
2982 output_asm_insn ("st.w r12, 84[sp]", operands);
2983 output_asm_insn ("st.w r13, 80[sp]", operands);
2984 output_asm_insn ("st.w r14, 76[sp]", operands);
2985 output_asm_insn ("st.w r15, 72[sp]", operands);
2986 output_asm_insn ("st.w r16, 68[sp]", operands);
2987 output_asm_insn ("st.w r17, 64[sp]", operands);
2988 output_asm_insn ("st.w r18, 60[sp]", operands);
2989 output_asm_insn ("st.w r19, 56[sp]", operands);
2990 output_asm_insn ("st.w r20, 52[sp]", operands);
2991 output_asm_insn ("st.w r21, 48[sp]", operands);
2992 output_asm_insn ("st.w r22, 44[sp]", operands);
2993 output_asm_insn ("st.w r23, 40[sp]", operands);
2994 output_asm_insn ("st.w r24, 36[sp]", operands);
2995 output_asm_insn ("st.w r25, 32[sp]", operands);
2996 output_asm_insn ("st.w r26, 28[sp]", operands);
2997 output_asm_insn ("st.w r27, 24[sp]", operands);
2998 output_asm_insn ("st.w r28, 20[sp]", operands);
2999 output_asm_insn ("st.w r29, 16[sp]", operands);
3000 }
3001
3002 return "";
3003 }
3004 [(set (attr "length")
3005 (if_then_else (match_test "TARGET_LONG_CALLS")
3006 (const_int 4)
3007 (const_int 62)
3008 ))
3009 (set_attr "cc" "clobber")])
3010
3011 (define_insn "_save_all_interrupt"
3012 [(unspec_volatile [(const_int 0)] 0)]
3013 "TARGET_V850 && ! TARGET_LONG_CALLS"
3014 "jarl __save_all_interrupt,r10"
3015 [(set_attr "length" "4")
3016 (set_attr "cc" "clobber")])
3017
3018 ;; Restore all registers saved when an interrupt function makes a call.
3019 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3020 ;; all of memory. This blocks insns from being moved across this point.
3021 ;; This is needed because the rest of the compiler is not ready to handle
3022 ;; insns this complicated.
3023
3024 (define_insn "callt_restore_all_interrupt"
3025 [(unspec_volatile [(const_int 0)] 1)]
3026 "(TARGET_V850E_UP) && !TARGET_DISABLE_CALLT"
3027 "callt ctoff(__callt_restore_all_interrupt)"
3028 [(set_attr "length" "2")
3029 (set_attr "cc" "none")])
3030
3031 (define_insn "restore_all_interrupt"
3032 [(unspec_volatile [(const_int 0)] 1)]
3033 ""
3034 {
3035 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
3036 return "jarl __restore_all_interrupt,r10";
3037
3038 if (TARGET_EP)
3039 {
3040 output_asm_insn ("mov ep, r1", operands);
3041 output_asm_insn ("mov sp, ep", operands);
3042 output_asm_insn ("sld.w 116[ep], r31", operands);
3043 output_asm_insn ("sld.w 112[ep], r2", operands);
3044 output_asm_insn ("sld.w 108[ep], gp", operands);
3045 output_asm_insn ("sld.w 104[ep], r6", operands);
3046 output_asm_insn ("sld.w 100[ep], r7", operands);
3047 output_asm_insn ("sld.w 96[ep], r8", operands);
3048 output_asm_insn ("sld.w 92[ep], r9", operands);
3049 output_asm_insn ("sld.w 88[ep], r11", operands);
3050 output_asm_insn ("sld.w 84[ep], r12", operands);
3051 output_asm_insn ("sld.w 80[ep], r13", operands);
3052 output_asm_insn ("sld.w 76[ep], r14", operands);
3053 output_asm_insn ("sld.w 72[ep], r15", operands);
3054 output_asm_insn ("sld.w 68[ep], r16", operands);
3055 output_asm_insn ("sld.w 64[ep], r17", operands);
3056 output_asm_insn ("sld.w 60[ep], r18", operands);
3057 output_asm_insn ("sld.w 56[ep], r19", operands);
3058 output_asm_insn ("sld.w 52[ep], r20", operands);
3059 output_asm_insn ("sld.w 48[ep], r21", operands);
3060 output_asm_insn ("sld.w 44[ep], r22", operands);
3061 output_asm_insn ("sld.w 40[ep], r23", operands);
3062 output_asm_insn ("sld.w 36[ep], r24", operands);
3063 output_asm_insn ("sld.w 32[ep], r25", operands);
3064 output_asm_insn ("sld.w 28[ep], r26", operands);
3065 output_asm_insn ("sld.w 24[ep], r27", operands);
3066 output_asm_insn ("sld.w 20[ep], r28", operands);
3067 output_asm_insn ("sld.w 16[ep], r29", operands);
3068 output_asm_insn ("mov r1, ep", operands);
3069 }
3070 else
3071 {
3072 output_asm_insn ("ld.w 116[sp], r31", operands);
3073 output_asm_insn ("ld.w 112[sp], r2", operands);
3074 output_asm_insn ("ld.w 108[sp], gp", operands);
3075 output_asm_insn ("ld.w 104[sp], r6", operands);
3076 output_asm_insn ("ld.w 100[sp], r7", operands);
3077 output_asm_insn ("ld.w 96[sp], r8", operands);
3078 output_asm_insn ("ld.w 92[sp], r9", operands);
3079 output_asm_insn ("ld.w 88[sp], r11", operands);
3080 output_asm_insn ("ld.w 84[sp], r12", operands);
3081 output_asm_insn ("ld.w 80[sp], r13", operands);
3082 output_asm_insn ("ld.w 76[sp], r14", operands);
3083 output_asm_insn ("ld.w 72[sp], r15", operands);
3084 output_asm_insn ("ld.w 68[sp], r16", operands);
3085 output_asm_insn ("ld.w 64[sp], r17", operands);
3086 output_asm_insn ("ld.w 60[sp], r18", operands);
3087 output_asm_insn ("ld.w 56[sp], r19", operands);
3088 output_asm_insn ("ld.w 52[sp], r20", operands);
3089 output_asm_insn ("ld.w 48[sp], r21", operands);
3090 output_asm_insn ("ld.w 44[sp], r22", operands);
3091 output_asm_insn ("ld.w 40[sp], r23", operands);
3092 output_asm_insn ("ld.w 36[sp], r24", operands);
3093 output_asm_insn ("ld.w 32[sp], r25", operands);
3094 output_asm_insn ("ld.w 28[sp], r26", operands);
3095 output_asm_insn ("ld.w 24[sp], r27", operands);
3096 output_asm_insn ("ld.w 20[sp], r28", operands);
3097 output_asm_insn ("ld.w 16[sp], r29", operands);
3098 }
3099 output_asm_insn ("addi 120, sp, sp", operands);
3100 return "";
3101 }
3102 [(set (attr "length")
3103 (if_then_else (match_test "TARGET_LONG_CALLS")
3104 (const_int 4)
3105 (const_int 62)
3106 ))
3107 (set_attr "cc" "clobber")])
3108
3109 (define_insn "_restore_all_interrupt"
3110 [(unspec_volatile [(const_int 0)] 1)]
3111 "TARGET_V850 && ! TARGET_LONG_CALLS"
3112 "jarl __restore_all_interrupt,r10"
3113 [(set_attr "length" "4")
3114 (set_attr "cc" "clobber")])