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