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