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