1 ;; GCC machine description for NEC V850
2 ;; Copyright (C) 1996, 1997, 1998, 1999, 2002 Free Software Foundation, Inc.
3 ;; Contributed by Jeff Law (law@cygnus.com).
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The V851 manual states that the instruction address space is 16M;
28 ;; the various branch/call instructions only have a 22bit offset (4M range).
30 ;; One day we'll probably need to handle calls to targets more than 4M
33 ;; The size of instructions in bytes.
35 (define_attr "length" ""
38 (define_attr "long_calls" "yes,no"
39 (const (if_then_else (symbol_ref "TARGET_LONG_CALLS")
41 (const_string "no"))))
43 ;; Types of instructions (for scheduling purposes).
45 (define_attr "type" "load,mult,other"
46 (const_string "other"))
48 ;; Condition code settings.
49 ;; none - insn does not affect cc
50 ;; none_0hit - insn does not affect cc but it does modify operand 0
51 ;; This attribute is used to keep track of when operand 0 changes.
52 ;; See the description of NOTICE_UPDATE_CC for more info.
53 ;; set_znv - sets z,n,v to usable values; c is unknown.
54 ;; set_zn - sets z,n to usable values; v,c is unknown.
55 ;; compare - compare instruction
56 ;; clobber - value of cc is unknown
57 (define_attr "cc" "none,none_0hit,set_zn,set_znv,compare,clobber"
58 (const_string "clobber"))
60 ;; Function units for the V850. As best as I can tell, there's
61 ;; a traditional memory load/use stall as well as a stall if
62 ;; the result of a multiply is used too early.
64 (define_function_unit "memory" 1 0 (eq_attr "type" "load") 2 0)
65 (define_function_unit "mult" 1 0 (eq_attr "type" "mult") 2 0)
68 ;; ----------------------------------------------------------------------
70 ;; ----------------------------------------------------------------------
74 (define_expand "movqi"
75 [(set (match_operand:QI 0 "general_operand" "")
76 (match_operand:QI 1 "general_operand" ""))]
80 /* One of the ops has to be in a register or 0 */
81 if (!register_operand (operand0, QImode)
82 && !reg_or_0_operand (operand1, QImode))
83 operands[1] = copy_to_mode_reg (QImode, operand1);
86 (define_insn "*movqi_internal"
87 [(set (match_operand:QI 0 "general_operand" "=r,r,r,Q,r,m,m")
88 (match_operand:QI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
89 "register_operand (operands[0], QImode)
90 || reg_or_0_operand (operands[1], QImode)"
91 "* return output_move_single (operands);"
92 [(set_attr "length" "2,4,2,2,4,4,4")
93 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
94 (set_attr "type" "other,other,load,other,load,other,other")])
98 (define_expand "movhi"
99 [(set (match_operand:HI 0 "general_operand" "")
100 (match_operand:HI 1 "general_operand" ""))]
104 /* One of the ops has to be in a register or 0 */
105 if (!register_operand (operand0, HImode)
106 && !reg_or_0_operand (operand1, HImode))
107 operands[1] = copy_to_mode_reg (HImode, operand1);
110 (define_insn "*movhi_internal"
111 [(set (match_operand:HI 0 "general_operand" "=r,r,r,Q,r,m,m")
112 (match_operand:HI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
113 "register_operand (operands[0], HImode)
114 || reg_or_0_operand (operands[1], HImode)"
115 "* return output_move_single (operands);"
116 [(set_attr "length" "2,4,2,2,4,4,4")
117 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
118 (set_attr "type" "other,other,load,other,load,other,other")])
122 (define_insn "*movsi_high"
123 [(set (match_operand:SI 0 "register_operand" "=r")
124 (high:SI (match_operand 1 "" "")))]
127 [(set_attr "length" "4")
128 (set_attr "cc" "none_0hit")
129 (set_attr "type" "other")])
131 (define_insn "*movsi_lo"
132 [(set (match_operand:SI 0 "register_operand" "=r")
133 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
134 (match_operand:SI 2 "immediate_operand" "i")))]
137 [(set_attr "length" "4")
138 (set_attr "cc" "none_0hit")
139 (set_attr "type" "other")])
141 (define_expand "movsi"
142 [(set (match_operand:SI 0 "general_operand" "")
143 (match_operand:SI 1 "general_operand" ""))]
147 /* One of the ops has to be in a register or 0 */
148 if (!register_operand (operand0, SImode)
149 && !reg_or_0_operand (operand1, SImode))
150 operands[1] = copy_to_mode_reg (SImode, operand1);
152 /* Some constants, as well as symbolic operands
153 must be done with HIGH & LO_SUM patterns. */
154 if (CONSTANT_P (operands[1])
155 && GET_CODE (operands[1]) != HIGH
157 && !special_symbolref_operand (operands[1], VOIDmode)
158 && !(GET_CODE (operands[1]) == CONST_INT
159 && (CONST_OK_FOR_J (INTVAL (operands[1]))
160 || CONST_OK_FOR_K (INTVAL (operands[1]))
161 || CONST_OK_FOR_L (INTVAL (operands[1])))))
165 if (reload_in_progress || reload_completed)
168 temp = gen_reg_rtx (SImode);
170 emit_insn (gen_rtx_SET (SImode, temp,
171 gen_rtx_HIGH (SImode, operand1)));
172 emit_insn (gen_rtx_SET (SImode, operand0,
173 gen_rtx_LO_SUM (SImode, temp, operand1)));
178 ;; This is the same as the following pattern, except that it includes
179 ;; support for arbitrary 32 bit immediates.
181 ;; ??? This always loads addresses using hilo. If the only use of this address
182 ;; was in a load/store, then we would get smaller code if we only loaded the
183 ;; upper part with hi, and then put the lower part in the load/store insn.
185 (define_insn "*movsi_internal_v850e"
186 [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m,r")
187 (match_operand:SI 1 "general_operand" "Jr,K,L,Q,Ir,m,R,r,I,i"))]
189 && (register_operand (operands[0], SImode)
190 || reg_or_0_operand (operands[1], SImode))"
191 "* return output_move_single (operands);"
192 [(set_attr "length" "2,4,4,2,2,4,4,4,4,6")
193 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
194 (set_attr "type" "other,other,other,load,other,load,other,other,other,other")])
196 (define_insn "*movsi_internal"
197 [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m")
198 (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))]
199 "register_operand (operands[0], SImode)
200 || reg_or_0_operand (operands[1], SImode)"
201 "* return output_move_single (operands);"
202 [(set_attr "length" "2,4,4,2,2,4,4,4,4")
203 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
204 (set_attr "type" "other,other,other,load,other,load,other,other,other")])
208 (define_expand "movdi"
209 [(set (match_operand:DI 0 "general_operand" "")
210 (match_operand:DI 1 "general_operand" ""))]
214 /* One of the ops has to be in a register or 0 */
215 if (!register_operand (operand0, DImode)
216 && !reg_or_0_operand (operand1, DImode))
217 operands[1] = copy_to_mode_reg (DImode, operand1);
220 (define_insn "*movdi_internal"
221 [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,m,r")
222 (match_operand:DI 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
223 "register_operand (operands[0], DImode)
224 || reg_or_0_operand (operands[1], DImode)"
225 "* return output_move_double (operands);"
226 [(set_attr "length" "4,8,8,16,8,8,8,16")
227 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
228 (set_attr "type" "other,other,other,other,load,other,other,other")])
230 (define_expand "movsf"
231 [(set (match_operand:SF 0 "general_operand" "")
232 (match_operand:SF 1 "general_operand" ""))]
236 /* One of the ops has to be in a register or 0 */
237 if (!register_operand (operand0, SFmode)
238 && !reg_or_0_operand (operand1, SFmode))
239 operands[1] = copy_to_mode_reg (SFmode, operand1);
242 (define_insn "*movsf_internal"
243 [(set (match_operand:SF 0 "general_operand" "=r,r,r,r,r,Q,r,m,m,r")
244 (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))]
245 "register_operand (operands[0], SFmode)
246 || reg_or_0_operand (operands[1], SFmode)"
247 "* return output_move_single (operands);"
248 [(set_attr "length" "2,4,4,8,2,2,4,4,4,8")
249 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
250 (set_attr "type" "other,other,other,other,load,other,load,other,other,other")])
252 (define_expand "movdf"
253 [(set (match_operand:DF 0 "general_operand" "")
254 (match_operand:DF 1 "general_operand" ""))]
258 /* One of the ops has to be in a register or 0 */
259 if (!register_operand (operand0, DFmode)
260 && !reg_or_0_operand (operand1, DFmode))
261 operands[1] = copy_to_mode_reg (DFmode, operand1);
264 (define_insn "*movdf_internal"
265 [(set (match_operand:DF 0 "general_operand" "=r,r,r,r,r,m,m,r")
266 (match_operand:DF 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
267 "register_operand (operands[0], DFmode)
268 || reg_or_0_operand (operands[1], DFmode)"
269 "* return output_move_double (operands);"
270 [(set_attr "length" "4,8,8,16,8,8,8,16")
271 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
272 (set_attr "type" "other,other,other,other,load,other,other,other")])
275 ;; ----------------------------------------------------------------------
277 ;; ----------------------------------------------------------------------
279 (define_insn "*v850_tst1"
280 [(set (cc0) (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
282 (match_operand:QI 1 "const_int_operand" "n")))]
285 [(set_attr "length" "4")
286 (set_attr "cc" "clobber")])
288 ;; This replaces ld.b;sar;andi with tst1;setf nz.
290 ;; ??? The zero_extract sets the Z bit to the opposite of what one would
291 ;; expect. This perhaps should be wrapped in a (eq: X (const_int 0)).
294 [(set (match_operand:SI 0 "register_operand" "")
295 (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
297 (match_operand 2 "const_int_operand" "")))]
299 [(set (cc0) (zero_extract:SI (match_dup 1)
302 (set (match_dup 0) (ne:SI (cc0) (const_int 0)))])
305 [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
308 [(set_attr "length" "2")
309 (set_attr "cc" "set_znv")])
313 (compare (match_operand:SI 0 "register_operand" "r,r")
314 (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
319 [(set_attr "length" "2,2")
320 (set_attr "cc" "compare")])
322 ;; ----------------------------------------------------------------------
324 ;; ----------------------------------------------------------------------
326 (define_insn "addsi3"
327 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
328 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
329 (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))]
335 [(set_attr "length" "2,4,4")
336 (set_attr "cc" "set_zn,set_zn,set_zn")])
338 ;; ----------------------------------------------------------------------
339 ;; SUBTRACT INSTRUCTIONS
340 ;; ----------------------------------------------------------------------
342 (define_insn "subsi3"
343 [(set (match_operand:SI 0 "register_operand" "=r,r")
344 (minus:SI (match_operand:SI 1 "register_operand" "0,r")
345 (match_operand:SI 2 "register_operand" "r,0")))]
350 [(set_attr "length" "2,2")
351 (set_attr "cc" "set_zn")])
353 (define_insn "negsi2"
354 [(set (match_operand:SI 0 "register_operand" "=r")
355 (neg:SI (match_operand:SI 1 "register_operand" "0")))]
358 [(set_attr "length" "2")
359 (set_attr "cc" "set_zn")])
361 ;; ----------------------------------------------------------------------
362 ;; MULTIPLY INSTRUCTIONS
363 ;; ----------------------------------------------------------------------
365 (define_expand "mulhisi3"
366 [(set (match_operand:SI 0 "register_operand" "")
368 (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
369 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
371 "if (GET_CODE (operands[2]) == CONST_INT)
373 emit_insn (gen_mulhisi3_internal2 (operands[0], operands[1], operands[2]));
377 (define_insn "*mulhisi3_internal1"
378 [(set (match_operand:SI 0 "register_operand" "=r")
380 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
381 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
384 [(set_attr "length" "2")
385 (set_attr "cc" "none_0hit")
386 (set_attr "type" "mult")])
388 (define_insn "mulhisi3_internal2"
389 [(set (match_operand:SI 0 "register_operand" "=r,r")
391 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
392 (match_operand:HI 2 "const_int_operand" "J,K")))]
397 [(set_attr "length" "2,4")
398 (set_attr "cc" "none_0hit,none_0hit")
399 (set_attr "type" "mult")])
401 ;; ??? The scheduling info is probably wrong.
403 ;; ??? This instruction can also generate the 32 bit highpart, but using it
404 ;; may increase code size counter to the desired result.
406 ;; ??? This instructions can also give a DImode result.
408 ;; ??? There is unsigned version, but it matters only for the DImode/highpart
411 (define_insn "mulsi3"
412 [(set (match_operand:SI 0 "register_operand" "=r")
413 (mult:SI (match_operand:SI 1 "register_operand" "%0")
414 (match_operand:SI 2 "reg_or_int9_operand" "rO")))]
417 [(set_attr "length" "4")
418 (set_attr "cc" "none_0hit")
419 (set_attr "type" "mult")])
421 ;; ----------------------------------------------------------------------
422 ;; DIVIDE INSTRUCTIONS
423 ;; ----------------------------------------------------------------------
425 ;; ??? These insns do set the Z/N condition codes, except that they are based
426 ;; on only one of the two results, so it doesn't seem to make sense to use
429 ;; ??? The scheduling info is probably wrong.
431 (define_insn "divmodsi4"
432 [(set (match_operand:SI 0 "register_operand" "=r")
433 (div:SI (match_operand:SI 1 "register_operand" "0")
434 (match_operand:SI 2 "register_operand" "r")))
435 (set (match_operand:SI 3 "register_operand" "=r")
436 (mod:SI (match_dup 1)
440 [(set_attr "length" "4")
441 (set_attr "cc" "clobber")
442 (set_attr "type" "other")])
444 (define_insn "udivmodsi4"
445 [(set (match_operand:SI 0 "register_operand" "=r")
446 (udiv:SI (match_operand:SI 1 "register_operand" "0")
447 (match_operand:SI 2 "register_operand" "r")))
448 (set (match_operand:SI 3 "register_operand" "=r")
449 (umod:SI (match_dup 1)
453 [(set_attr "length" "4")
454 (set_attr "cc" "clobber")
455 (set_attr "type" "other")])
457 ;; ??? There is a 2 byte instruction for generating only the quotient.
458 ;; However, it isn't clear how to compute the length field correctly.
460 (define_insn "divmodhi4"
461 [(set (match_operand:HI 0 "register_operand" "=r")
462 (div:HI (match_operand:HI 1 "register_operand" "0")
463 (match_operand:HI 2 "register_operand" "r")))
464 (set (match_operand:HI 3 "register_operand" "=r")
465 (mod:HI (match_dup 1)
469 [(set_attr "length" "4")
470 (set_attr "cc" "clobber")
471 (set_attr "type" "other")])
473 ;; Half-words are sign-extended by default, so we must zero extend to a word
474 ;; here before doing the divide.
476 (define_insn "udivmodhi4"
477 [(set (match_operand:HI 0 "register_operand" "=r")
478 (udiv:HI (match_operand:HI 1 "register_operand" "0")
479 (match_operand:HI 2 "register_operand" "r")))
480 (set (match_operand:HI 3 "register_operand" "=r")
481 (umod:HI (match_dup 1)
484 "zxh %0 ; divhu %2,%0,%3"
485 [(set_attr "length" "4")
486 (set_attr "cc" "clobber")
487 (set_attr "type" "other")])
489 ;; ----------------------------------------------------------------------
491 ;; ----------------------------------------------------------------------
493 (define_insn "*v850_clr1_1"
494 [(set (match_operand:QI 0 "memory_operand" "=m")
496 (and:SI (subreg:SI (match_dup 0) 0)
497 (match_operand:QI 1 "not_power_of_two_operand" "")) 0))]
502 xoperands[0] = operands[0];
503 xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
504 output_asm_insn (\"clr1 %M1,%0\", xoperands);
507 [(set_attr "length" "4")
508 (set_attr "cc" "clobber")])
510 (define_insn "*v850_clr1_2"
511 [(set (match_operand:HI 0 "indirect_operand" "=m")
513 (and:SI (subreg:SI (match_dup 0) 0)
514 (match_operand:HI 1 "not_power_of_two_operand" "")) 0))]
518 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
521 xoperands[0] = gen_rtx_MEM (QImode,
522 plus_constant (XEXP (operands[0], 0), log2 / 8));
523 xoperands[1] = GEN_INT (log2 % 8);
524 output_asm_insn (\"clr1 %1,%0\", xoperands);
527 [(set_attr "length" "4")
528 (set_attr "cc" "clobber")])
530 (define_insn "*v850_clr1_3"
531 [(set (match_operand:SI 0 "indirect_operand" "=m")
532 (and:SI (match_dup 0)
533 (match_operand:SI 1 "not_power_of_two_operand" "")))]
537 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
540 xoperands[0] = gen_rtx_MEM (QImode,
541 plus_constant (XEXP (operands[0], 0), log2 / 8));
542 xoperands[1] = GEN_INT (log2 % 8);
543 output_asm_insn (\"clr1 %1,%0\", xoperands);
546 [(set_attr "length" "4")
547 (set_attr "cc" "clobber")])
549 (define_insn "andsi3"
550 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
551 (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
552 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
558 [(set_attr "length" "2,2,4")
559 (set_attr "cc" "set_znv")])
561 ;; ----------------------------------------------------------------------
563 ;; ----------------------------------------------------------------------
565 (define_insn "*v850_set1_1"
566 [(set (match_operand:QI 0 "memory_operand" "=m")
567 (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
568 (match_operand 1 "power_of_two_operand" "")) 0))]
571 [(set_attr "length" "4")
572 (set_attr "cc" "clobber")])
574 (define_insn "*v850_set1_2"
575 [(set (match_operand:HI 0 "indirect_operand" "=m")
576 (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
577 (match_operand 1 "power_of_two_operand" "")) 0))]
581 int log2 = exact_log2 (INTVAL (operands[1]));
584 return \"set1 %M1,%0\";
588 xoperands[0] = gen_rtx_MEM (QImode,
589 plus_constant (XEXP (operands[0], 0),
591 xoperands[1] = GEN_INT (log2 % 8);
592 output_asm_insn (\"set1 %1,%0\", xoperands);
596 [(set_attr "length" "4")
597 (set_attr "cc" "clobber")])
599 (define_insn "*v850_set1_3"
600 [(set (match_operand:SI 0 "indirect_operand" "=m")
601 (ior:SI (match_dup 0)
602 (match_operand 1 "power_of_two_operand" "")))]
606 int log2 = exact_log2 (INTVAL (operands[1]));
609 return \"set1 %M1,%0\";
613 xoperands[0] = gen_rtx_MEM (QImode,
614 plus_constant (XEXP (operands[0], 0),
616 xoperands[1] = GEN_INT (log2 % 8);
617 output_asm_insn (\"set1 %1,%0\", xoperands);
621 [(set_attr "length" "4")
622 (set_attr "cc" "clobber")])
624 (define_insn "iorsi3"
625 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
626 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
627 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
633 [(set_attr "length" "2,2,4")
634 (set_attr "cc" "set_znv")])
636 ;; ----------------------------------------------------------------------
638 ;; ----------------------------------------------------------------------
640 (define_insn "*v850_not1_1"
641 [(set (match_operand:QI 0 "memory_operand" "=m")
642 (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0)
643 (match_operand 1 "power_of_two_operand" "")) 0))]
646 [(set_attr "length" "4")
647 (set_attr "cc" "clobber")])
649 (define_insn "*v850_not1_2"
650 [(set (match_operand:HI 0 "indirect_operand" "=m")
651 (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
652 (match_operand 1 "power_of_two_operand" "")) 0))]
656 int log2 = exact_log2 (INTVAL (operands[1]));
659 return \"not1 %M1,%0\";
663 xoperands[0] = gen_rtx_MEM (QImode,
664 plus_constant (XEXP (operands[0], 0),
666 xoperands[1] = GEN_INT (log2 % 8);
667 output_asm_insn (\"not1 %1,%0\", xoperands);
671 [(set_attr "length" "4")
672 (set_attr "cc" "clobber")])
674 (define_insn "*v850_not1_3"
675 [(set (match_operand:SI 0 "indirect_operand" "=m")
676 (xor:SI (match_dup 0)
677 (match_operand 1 "power_of_two_operand" "")))]
681 int log2 = exact_log2 (INTVAL (operands[1]));
684 return \"not1 %M1,%0\";
688 xoperands[0] = gen_rtx_MEM (QImode,
689 plus_constant (XEXP (operands[0], 0),
691 xoperands[1] = GEN_INT (log2 % 8);
692 output_asm_insn (\"not1 %1,%0\", xoperands);
696 [(set_attr "length" "4")
697 (set_attr "cc" "clobber")])
699 (define_insn "xorsi3"
700 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
701 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
702 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
708 [(set_attr "length" "2,2,4")
709 (set_attr "cc" "set_znv")])
711 ;; ----------------------------------------------------------------------
713 ;; ----------------------------------------------------------------------
715 (define_insn "one_cmplsi2"
716 [(set (match_operand:SI 0 "register_operand" "=r")
717 (not:SI (match_operand:SI 1 "register_operand" "r")))]
720 [(set_attr "length" "2")
721 (set_attr "cc" "set_znv")])
723 ;; -----------------------------------------------------------------
725 ;; -----------------------------------------------------------------
727 ;; ??? Is it worth defining insv and extv for the V850 series?!?
729 ;; An insv pattern would be useful, but does not get used because
730 ;; store_bit_field never calls insv when storing a constant value into a
731 ;; single-bit bitfield.
733 ;; extv/extzv patterns would be useful, but do not get used because
734 ;; optimize_bitfield_compare in fold-const usually converts single
735 ;; bit extracts into an AND with a mask.
737 ;; -----------------------------------------------------------------
739 ;; -----------------------------------------------------------------
742 [(set (match_operand:SI 0 "register_operand" "=r")
743 (le:SI (cc0) (const_int 0)))]
747 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
750 return \"setf le,%0\";
752 [(set_attr "length" "4")
753 (set_attr "cc" "none_0hit")])
756 [(set (match_operand:SI 0 "register_operand" "=r")
757 (leu:SI (cc0) (const_int 0)))]
760 [(set_attr "length" "4")
761 (set_attr "cc" "none_0hit")])
764 [(set (match_operand:SI 0 "register_operand" "=r")
765 (ge:SI (cc0) (const_int 0)))]
769 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
772 return \"setf ge,%0\";
774 [(set_attr "length" "4")
775 (set_attr "cc" "none_0hit")])
778 [(set (match_operand:SI 0 "register_operand" "=r")
779 (geu:SI (cc0) (const_int 0)))]
782 [(set_attr "length" "4")
783 (set_attr "cc" "none_0hit")])
786 [(set (match_operand:SI 0 "register_operand" "=r")
787 (lt:SI (cc0) (const_int 0)))]
791 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
794 return \"setf lt,%0\";
796 [(set_attr "length" "4")
797 (set_attr "cc" "none_0hit")])
800 [(set (match_operand:SI 0 "register_operand" "=r")
801 (ltu:SI (cc0) (const_int 0)))]
804 [(set_attr "length" "4")
805 (set_attr "cc" "none_0hit")])
808 [(set (match_operand:SI 0 "register_operand" "=r")
809 (gt:SI (cc0) (const_int 0)))]
813 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
816 return \"setf gt,%0\";
818 [(set_attr "length" "4")
819 (set_attr "cc" "none_0hit")])
822 [(set (match_operand:SI 0 "register_operand" "=r")
823 (gtu:SI (cc0) (const_int 0)))]
826 [(set_attr "length" "4")
827 (set_attr "cc" "none_0hit")])
830 [(set (match_operand:SI 0 "register_operand" "=r")
831 (eq:SI (cc0) (const_int 0)))]
834 [(set_attr "length" "4")
835 (set_attr "cc" "none_0hit")])
838 [(set (match_operand:SI 0 "register_operand" "=r")
839 (ne:SI (cc0) (const_int 0)))]
842 [(set_attr "length" "4")
843 (set_attr "cc" "none_0hit")])
845 ;; ----------------------------------------------------------------------
846 ;; CONDITIONAL MOVE INSTRUCTIONS
847 ;; ----------------------------------------------------------------------
849 ;; Instructions using cc0 aren't allowed to have input reloads, so we must
850 ;; hide the fact that this instruction uses cc0. We do so by including the
851 ;; compare instruction inside it.
853 ;; ??? This is very ugly. The right way to do this is to modify cmpsi so
854 ;; that it doesn't emit RTL, and then modify the bcc/scc patterns so that
855 ;; they emit RTL for the compare instruction. Unfortunately, this requires
856 ;; lots of changes that will be hard to sanitize. So for now, cmpsi still
857 ;; emits RTL, and I get the compare operands here from the previous insn.
859 (define_expand "movsicc"
860 [(set (match_operand:SI 0 "register_operand" "=r")
862 (match_operator 1 "comparison_operator"
863 [(match_dup 4) (match_dup 5)])
864 (match_operand:SI 2 "reg_or_const_operand" "rJ")
865 (match_operand:SI 3 "reg_or_const_operand" "rI")))]
869 rtx insn = get_last_insn_anywhere ();
871 if ( (GET_CODE (operands[2]) == CONST_INT
872 && GET_CODE (operands[3]) == CONST_INT))
874 int o2 = INTVAL (operands[2]);
875 int o3 = INTVAL (operands[3]);
877 if (o2 == 1 && o3 == 0)
879 if (o3 == 1 && o2 == 0)
881 if (o2 == 0 && (o3 < -16 || o3 > 15) && exact_log2 (o3) >= 0)
882 FAIL; /* setf + shift */
883 if (o3 == 0 && (o2 < -16 || o2 > 15) && exact_log2 (o2) >=0)
884 FAIL; /* setf + shift */
886 operands[2] = copy_to_mode_reg (SImode, operands[2]);
888 operands[3] = copy_to_mode_reg (SImode, operands[3]);
892 if (GET_CODE (operands[2]) != REG)
893 operands[2] = copy_to_mode_reg (SImode,operands[2]);
894 if (GET_CODE (operands[3]) != REG)
895 operands[3] = copy_to_mode_reg (SImode, operands[3]);
897 if (GET_CODE (insn) == INSN
898 && GET_CODE (PATTERN (insn)) == SET
899 && SET_DEST (PATTERN (insn)) == cc0_rtx)
901 rtx src = SET_SRC (PATTERN (insn));
903 if (GET_CODE (src) == COMPARE)
905 operands[4] = XEXP (src, 0);
906 operands[5] = XEXP (src, 1);
908 else if (GET_CODE (src) == REG
909 || GET_CODE (src) == SUBREG)
912 operands[5] = const0_rtx;
921 ;; ??? Clobbering the condition codes is overkill.
923 ;; ??? We sometimes emit an unnecessary compare instruction because the
924 ;; condition codes may have already been set by an earlier instruction,
925 ;; but we have no code here to avoid the compare if it is unnecessary.
927 (define_insn "*movsicc_normal"
928 [(set (match_operand:SI 0 "register_operand" "=r")
930 (match_operator 1 "comparison_operator"
931 [(match_operand:SI 4 "register_operand" "r")
932 (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
933 (match_operand:SI 2 "reg_or_int5_operand" "rJ")
934 (match_operand:SI 3 "reg_or_0_operand" "rI")))]
936 "cmp %5,%4 ; cmov %c1,%2,%z3,%0"
937 [(set_attr "length" "6")
938 (set_attr "cc" "clobber")])
940 (define_insn "*movsicc_reversed"
941 [(set (match_operand:SI 0 "register_operand" "=r")
943 (match_operator 1 "comparison_operator"
944 [(match_operand:SI 4 "register_operand" "r")
945 (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
946 (match_operand:SI 2 "reg_or_0_operand" "rI")
947 (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
949 "cmp %5,%4 ; cmov %C1,%3,%z2,%0"
950 [(set_attr "length" "6")
951 (set_attr "cc" "clobber")])
953 (define_insn "*movsicc_tst1"
954 [(set (match_operand:SI 0 "register_operand" "=r")
956 (match_operator 1 "comparison_operator"
958 (match_operand:QI 2 "memory_operand" "m")
960 (match_operand 3 "const_int_operand" "n"))
962 (match_operand:SI 4 "reg_or_int5_operand" "rJ")
963 (match_operand:SI 5 "reg_or_0_operand" "rI")))]
965 "tst1 %3,%2 ; cmov %c1,%4,%z5,%0"
966 [(set_attr "length" "8")
967 (set_attr "cc" "clobber")])
969 (define_insn "*movsicc_tst1_reversed"
970 [(set (match_operand:SI 0 "register_operand" "=r")
972 (match_operator 1 "comparison_operator"
974 (match_operand:QI 2 "memory_operand" "m")
976 (match_operand 3 "const_int_operand" "n"))
978 (match_operand:SI 4 "reg_or_0_operand" "rI")
979 (match_operand:SI 5 "reg_or_int5_operand" "rJ")))]
981 "tst1 %3,%2 ; cmov %C1,%5,%z4,%0"
982 [(set_attr "length" "8")
983 (set_attr "cc" "clobber")])
985 ;; Matching for sasf requires combining 4 instructions, so we provide a
986 ;; dummy pattern to match the first 3, which will always be turned into the
987 ;; second pattern by subsequent combining. As above, we must include the
988 ;; comparison to avoid input reloads in an insn using cc0.
990 (define_insn "*sasf_1"
991 [(set (match_operand:SI 0 "register_operand" "")
992 (ior:SI (match_operator 1 "comparison_operator" [(cc0) (const_int 0)])
993 (ashift:SI (match_operand:SI 2 "register_operand" "")
998 (define_insn "*sasf_2"
999 [(set (match_operand:SI 0 "register_operand" "=r")
1001 (match_operator 1 "comparison_operator"
1002 [(match_operand:SI 3 "register_operand" "r")
1003 (match_operand:SI 4 "reg_or_int5_operand" "rJ")])
1004 (ashift:SI (match_operand:SI 2 "register_operand" "0")
1007 "cmp %4,%3 ; sasf %c1,%0"
1008 [(set_attr "length" "6")
1009 (set_attr "cc" "clobber")])
1012 [(set (match_operand:SI 0 "register_operand" "")
1014 (match_operator 1 "comparison_operator"
1015 [(match_operand:SI 4 "register_operand" "")
1016 (match_operand:SI 5 "reg_or_int5_operand" "")])
1017 (match_operand:SI 2 "const_int_operand" "")
1018 (match_operand:SI 3 "const_int_operand" "")))]
1020 && ((INTVAL (operands[2]) ^ INTVAL (operands[3])) == 1)
1021 && ((INTVAL (operands[2]) + INTVAL (operands[3])) != 1)
1022 && (GET_CODE (operands[5]) == CONST_INT
1023 || REGNO (operands[0]) != REGNO (operands[5]))
1024 && REGNO (operands[0]) != REGNO (operands[4])"
1025 [(set (match_dup 0) (match_dup 6))
1027 (ior:SI (match_op_dup 7 [(match_dup 4) (match_dup 5)])
1028 (ashift:SI (match_dup 0) (const_int 1))))]
1031 operands[6] = GEN_INT (INTVAL (operands[2]) >> 1);
1032 if (INTVAL (operands[2]) & 0x1)
1033 operands[7] = operands[1];
1035 operands[7] = gen_rtx (reverse_condition (GET_CODE (operands[1])),
1036 GET_MODE (operands[1]), XEXP (operands[1], 0),
1037 XEXP (operands[1], 1));
1039 ;; ---------------------------------------------------------------------
1040 ;; BYTE SWAP INSTRUCTIONS
1041 ;; ---------------------------------------------------------------------
1043 (define_expand "rotlhi3"
1044 [(set (match_operand:HI 0 "register_operand" "")
1045 (rotate:HI (match_operand:HI 1 "register_operand" "")
1046 (match_operand:HI 2 "const_int_operand" "")))]
1050 if (INTVAL (operands[2]) != 8)
1054 (define_insn "*rotlhi3_8"
1055 [(set (match_operand:HI 0 "register_operand" "=r")
1056 (rotate:HI (match_operand:HI 1 "register_operand" "r")
1060 [(set_attr "length" "4")
1061 (set_attr "cc" "clobber")])
1063 (define_expand "rotlsi3"
1064 [(set (match_operand:SI 0 "register_operand" "")
1065 (rotate:SI (match_operand:SI 1 "register_operand" "")
1066 (match_operand:SI 2 "const_int_operand" "")))]
1070 if (INTVAL (operands[2]) != 16)
1074 (define_insn "*rotlsi3_16"
1075 [(set (match_operand:SI 0 "register_operand" "=r")
1076 (rotate:SI (match_operand:SI 1 "register_operand" "r")
1080 [(set_attr "length" "4")
1081 (set_attr "cc" "clobber")])
1083 ;; ----------------------------------------------------------------------
1084 ;; JUMP INSTRUCTIONS
1085 ;; ----------------------------------------------------------------------
1087 ;; Conditional jump instructions
1089 (define_expand "ble"
1091 (if_then_else (le (cc0)
1093 (label_ref (match_operand 0 "" ""))
1098 (define_expand "bleu"
1100 (if_then_else (leu (cc0)
1102 (label_ref (match_operand 0 "" ""))
1107 (define_expand "bge"
1109 (if_then_else (ge (cc0)
1111 (label_ref (match_operand 0 "" ""))
1116 (define_expand "bgeu"
1118 (if_then_else (geu (cc0)
1120 (label_ref (match_operand 0 "" ""))
1125 (define_expand "blt"
1127 (if_then_else (lt (cc0)
1129 (label_ref (match_operand 0 "" ""))
1134 (define_expand "bltu"
1136 (if_then_else (ltu (cc0)
1138 (label_ref (match_operand 0 "" ""))
1143 (define_expand "bgt"
1145 (if_then_else (gt (cc0)
1147 (label_ref (match_operand 0 "" ""))
1152 (define_expand "bgtu"
1154 (if_then_else (gtu (cc0)
1156 (label_ref (match_operand 0 "" ""))
1161 (define_expand "beq"
1163 (if_then_else (eq (cc0)
1165 (label_ref (match_operand 0 "" ""))
1170 (define_expand "bne"
1172 (if_then_else (ne (cc0)
1174 (label_ref (match_operand 0 "" ""))
1179 (define_insn "*branch_normal"
1181 (if_then_else (match_operator 1 "comparison_operator"
1182 [(cc0) (const_int 0)])
1183 (label_ref (match_operand 0 "" ""))
1188 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1189 && (GET_CODE (operands[1]) == GT
1190 || GET_CODE (operands[1]) == GE
1191 || GET_CODE (operands[1]) == LE
1192 || GET_CODE (operands[1]) == LT))
1195 if (get_attr_length (insn) == 2)
1196 return \"b%b1 %l0\";
1198 return \"b%B1 .+6 ; jr %l0\";
1200 [(set (attr "length")
1201 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1205 (set_attr "cc" "none")])
1207 (define_insn "*branch_invert"
1209 (if_then_else (match_operator 1 "comparison_operator"
1210 [(cc0) (const_int 0)])
1212 (label_ref (match_operand 0 "" ""))))]
1216 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1217 && (GET_CODE (operands[1]) == GT
1218 || GET_CODE (operands[1]) == GE
1219 || GET_CODE (operands[1]) == LE
1220 || GET_CODE (operands[1]) == LT))
1222 if (get_attr_length (insn) == 2)
1223 return \"b%B1 %l0\";
1225 return \"b%b1 .+6 ; jr %l0\";
1227 [(set (attr "length")
1228 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1232 (set_attr "cc" "none")])
1234 ;; Unconditional and other jump instructions.
1238 (label_ref (match_operand 0 "" "")))]
1242 if (get_attr_length (insn) == 2)
1247 [(set (attr "length")
1248 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
1252 (set_attr "cc" "none")])
1254 (define_insn "indirect_jump"
1255 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1258 [(set_attr "length" "2")
1259 (set_attr "cc" "none")])
1261 (define_insn "tablejump"
1262 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1263 (use (label_ref (match_operand 1 "" "")))]
1266 [(set_attr "length" "2")
1267 (set_attr "cc" "none")])
1269 (define_insn "switch"
1274 (plus:SI (ashift:SI (match_operand:SI 0 "register_operand" "r")
1276 (label_ref (match_operand 1 "" "")))))
1277 (label_ref (match_dup 1))))]
1280 [(set_attr "length" "2")
1281 (set_attr "cc" "none")])
1283 (define_expand "casesi"
1284 [(match_operand:SI 0 "register_operand" "")
1285 (match_operand:SI 1 "register_operand" "")
1286 (match_operand:SI 2 "register_operand" "")
1287 (match_operand 3 "" "") (match_operand 4 "" "")]
1291 rtx reg = gen_reg_rtx (SImode);
1292 rtx tableaddress = gen_reg_rtx (SImode);
1295 /* Subtract the lower bound from the index. */
1296 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
1297 /* Compare the result against the number of table entries. */
1298 emit_insn (gen_cmpsi (reg, operands[2]));
1299 /* Branch to the default label if out of range of the table. */
1300 emit_jump_insn (gen_bgtu (operands[4]));
1302 if (! TARGET_BIG_SWITCH && TARGET_V850E)
1304 emit_jump_insn (gen_switch (reg, operands[3]));
1308 /* Shift index for the table array access. */
1309 emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
1310 /* Load the table address into a pseudo. */
1311 emit_insn (gen_movsi (tableaddress,
1312 gen_rtx_LABEL_REF (Pmode, operands[3])));
1313 /* Add the table address to the index. */
1314 emit_insn (gen_addsi3 (reg, reg, tableaddress));
1315 /* Load the table entry. */
1316 mem = gen_rtx_MEM (CASE_VECTOR_MODE, reg);
1317 RTX_UNCHANGING_P (mem) = 1;
1318 if (! TARGET_BIG_SWITCH)
1320 rtx reg2 = gen_reg_rtx (HImode);
1321 emit_insn (gen_movhi (reg2, mem));
1322 emit_insn (gen_extendhisi2 (reg, reg2));
1325 emit_insn (gen_movsi (reg, mem));
1326 /* Add the table address. */
1327 emit_insn (gen_addsi3 (reg, reg, tableaddress));
1328 /* Branch to the switch label. */
1329 emit_jump_insn (gen_tablejump (reg, operands[3]));
1333 ;; Call subroutine with no return value.
1335 (define_expand "call"
1336 [(call (match_operand:QI 0 "general_operand" "")
1337 (match_operand:SI 1 "general_operand" ""))]
1341 if (! call_address_operand (XEXP (operands[0], 0), QImode)
1342 || TARGET_LONG_CALLS)
1343 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1344 if (TARGET_LONG_CALLS)
1345 emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));
1347 emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
1352 (define_insn "call_internal_short"
1353 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1354 (match_operand:SI 1 "general_operand" "g,g"))
1355 (clobber (reg:SI 31))]
1356 "! TARGET_LONG_CALLS"
1359 jarl .+4,r31 ; add 4,r31 ; jmp %0"
1360 [(set_attr "length" "4,8")]
1363 (define_insn "call_internal_long"
1364 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
1365 (match_operand:SI 1 "general_operand" "g,g"))
1366 (clobber (reg:SI 31))]
1370 if (which_alternative == 0)
1372 if (GET_CODE (operands[0]) == REG)
1373 return \"jarl %0,r31\";
1375 return \"movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11\";
1378 return \"jarl .+4,r31 ; add 4,r31 ; jmp %0\";
1380 [(set_attr "length" "16,8")]
1383 ;; Call subroutine, returning value in operand 0
1384 ;; (which must be a hard register).
1386 (define_expand "call_value"
1387 [(set (match_operand 0 "" "")
1388 (call (match_operand:QI 1 "general_operand" "")
1389 (match_operand:SI 2 "general_operand" "")))]
1393 if (! call_address_operand (XEXP (operands[1], 0), QImode)
1394 || TARGET_LONG_CALLS)
1395 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1396 if (TARGET_LONG_CALLS)
1397 emit_call_insn (gen_call_value_internal_long (operands[0],
1398 XEXP (operands[1], 0),
1401 emit_call_insn (gen_call_value_internal_short (operands[0],
1402 XEXP (operands[1], 0),
1407 (define_insn "call_value_internal_short"
1408 [(set (match_operand 0 "" "=r,r")
1409 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1410 (match_operand:SI 2 "general_operand" "g,g")))
1411 (clobber (reg:SI 31))]
1412 "! TARGET_LONG_CALLS"
1415 jarl .+4,r31 ; add 4,r31 ; jmp %1"
1416 [(set_attr "length" "4,8")]
1419 (define_insn "call_value_internal_long"
1420 [(set (match_operand 0 "" "=r,r")
1421 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1422 (match_operand:SI 2 "general_operand" "g,g")))
1423 (clobber (reg:SI 31))]
1427 if (which_alternative == 0)
1429 if (GET_CODE (operands[1]) == REG)
1430 return \"jarl %1, r31\";
1432 /* Reload can generate this pattern... */
1433 return \"movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11\";
1436 return \"jarl .+4, r31 ; add 4, r31 ; jmp %1\";
1438 [(set_attr "length" "16,8")]
1445 [(set_attr "length" "2")
1446 (set_attr "cc" "none")])
1448 ;; ----------------------------------------------------------------------
1449 ;; EXTEND INSTRUCTIONS
1450 ;; ----------------------------------------------------------------------
1453 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1455 (match_operand:HI 1 "nonimmediate_operand" "0,r,T,m")))]
1462 [(set_attr "length" "2,4,2,4")
1463 (set_attr "cc" "none_0hit,set_znv,none_0hit,none_0hit")])
1465 (define_insn "zero_extendhisi2"
1466 [(set (match_operand:SI 0 "register_operand" "=r")
1468 (match_operand:HI 1 "register_operand" "r")))]
1471 [(set_attr "length" "4")
1472 (set_attr "cc" "set_znv")])
1475 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1477 (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m")))]
1484 [(set_attr "length" "2,4,2,4")
1485 (set_attr "cc" "none_0hit,set_znv,none_0hit,none_0hit")])
1487 (define_insn "zero_extendqisi2"
1488 [(set (match_operand:SI 0 "register_operand" "=r")
1490 (match_operand:QI 1 "register_operand" "r")))]
1493 [(set_attr "length" "4")
1494 (set_attr "cc" "set_znv")])
1496 ;;- sign extension instructions
1498 ;; ??? The extendhisi2 pattern should not emit shifts for v850e?
1500 (define_insn "*extendhisi_insn"
1501 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1502 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))]
1508 [(set_attr "length" "2,2,4")
1509 (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1511 ;; ??? This is missing a sign extend from memory pattern to match the ld.h
1514 (define_expand "extendhisi2"
1516 (ashift:SI (match_operand:HI 1 "register_operand" "")
1518 (set (match_operand:SI 0 "register_operand" "")
1519 (ashiftrt:SI (match_dup 2)
1524 operands[1] = gen_lowpart (SImode, operands[1]);
1525 operands[2] = gen_reg_rtx (SImode);
1528 ;; ??? The extendqisi2 pattern should not emit shifts for v850e?
1530 (define_insn "*extendqisi_insn"
1531 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1532 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))]
1538 [(set_attr "length" "2,2,4")
1539 (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
1541 ;; ??? This is missing a sign extend from memory pattern to match the ld.b
1544 (define_expand "extendqisi2"
1546 (ashift:SI (match_operand:QI 1 "register_operand" "")
1548 (set (match_operand:SI 0 "register_operand" "")
1549 (ashiftrt:SI (match_dup 2)
1554 operands[1] = gen_lowpart (SImode, operands[1]);
1555 operands[2] = gen_reg_rtx (SImode);
1558 ;; ----------------------------------------------------------------------
1560 ;; ----------------------------------------------------------------------
1562 (define_insn "ashlsi3"
1563 [(set (match_operand:SI 0 "register_operand" "=r,r")
1565 (match_operand:SI 1 "register_operand" "0,0")
1566 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1571 [(set_attr "length" "4,2")
1572 (set_attr "cc" "set_znv")])
1574 (define_insn "lshrsi3"
1575 [(set (match_operand:SI 0 "register_operand" "=r,r")
1577 (match_operand:SI 1 "register_operand" "0,0")
1578 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1583 [(set_attr "length" "4,2")
1584 (set_attr "cc" "set_znv")])
1586 (define_insn "ashrsi3"
1587 [(set (match_operand:SI 0 "register_operand" "=r,r")
1589 (match_operand:SI 1 "register_operand" "0,0")
1590 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1595 [(set_attr "length" "4,2")
1596 (set_attr "cc" "set_znv")])
1598 ;; ----------------------------------------------------------------------
1599 ;; PROLOGUE/EPILOGUE
1600 ;; ----------------------------------------------------------------------
1601 (define_expand "prologue"
1604 "expand_prologue (); DONE;")
1606 (define_expand "epilogue"
1611 /* Try to use the trivial return first. Else use the
1614 emit_jump_insn (gen_return ());
1620 (define_insn "return"
1622 "reload_completed && compute_frame_size (get_frame_size (), (long *)0) == 0"
1624 [(set_attr "length" "2")
1625 (set_attr "cc" "none")])
1627 (define_insn "return_internal"
1632 [(set_attr "length" "2")
1633 (set_attr "cc" "none")])
1637 ;; ----------------------------------------------------------------------
1638 ;; HELPER INSTRUCTIONS for saving the prologue and epilog registers
1639 ;; ----------------------------------------------------------------------
1641 ;; This pattern will match a stack adjust RTX followed by any number of push
1642 ;; RTXs. These RTXs will then be turned into a suitable call to a worker
1646 ;; Actually, convert the RTXs into a PREPARE instruction.
1649 [(match_parallel 0 "pattern_is_ok_for_prepare"
1651 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1652 (set (mem:SI (plus:SI (reg:SI 3)
1653 (match_operand:SI 2 "immediate_operand" "i")))
1654 (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
1655 "TARGET_PROLOG_FUNCTION && TARGET_V850E"
1656 "* return construct_prepare_instruction (operands[0]);
1658 [(set_attr "length" "4")
1659 (set_attr "cc" "none")])
1662 [(match_parallel 0 "pattern_is_ok_for_prologue"
1664 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1665 (set (mem:SI (plus:SI (reg:SI 3)
1666 (match_operand:SI 2 "immediate_operand" "i")))
1667 (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
1668 "TARGET_PROLOG_FUNCTION && TARGET_V850"
1669 "* return construct_save_jarl (operands[0]);
1671 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
1673 (const_string "4")))
1674 (set_attr "cc" "clobber")])
1677 ;; Actually, turn the RTXs into a DISPOSE instruction.
1680 [(match_parallel 0 "pattern_is_ok_for_dispose"
1683 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1684 (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
1685 (mem:SI (plus:SI (reg:SI 3)
1686 (match_operand:SI 3 "immediate_operand" "i"))))])]
1687 "TARGET_PROLOG_FUNCTION && TARGET_V850E"
1688 "* return construct_dispose_instruction (operands[0]);
1690 [(set_attr "length" "4")
1691 (set_attr "cc" "none")])
1693 ;; This pattern will match a return RTX followed by any number of pop RTXs
1694 ;; and possible a stack adjustment as well. These RTXs will be turned into
1695 ;; a suitable call to a worker function.
1698 [(match_parallel 0 "pattern_is_ok_for_epilogue"
1701 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1702 (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
1703 (mem:SI (plus:SI (reg:SI 3)
1704 (match_operand:SI 3 "immediate_operand" "i"))))])]
1705 "TARGET_PROLOG_FUNCTION && TARGET_V850"
1706 "* return construct_restore_jr (operands[0]);
1708 [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
1710 (const_string "4")))
1711 (set_attr "cc" "clobber")])
1713 ;; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION.
1714 (define_insn "callt_save_interrupt"
1715 [(unspec_volatile [(const_int 0)] 2)]
1716 "TARGET_V850E && !TARGET_DISABLE_CALLT"
1717 ;; The CALLT instruction stores the next address of CALLT to CTPC register
1718 ;; without saving its previous value. So if the interrupt handler
1719 ;; or its caller could possibly execute the CALLT insn, save_interrupt
1720 ;; MUST NOT be called via CALLT.
1723 output_asm_insn (\"addi -24, sp, sp\", operands);
1724 output_asm_insn (\"st.w r10, 12[sp]\", operands);
1725 output_asm_insn (\"stsr ctpc, r10\", operands);
1726 output_asm_insn (\"st.w r10, 16[sp]\", operands);
1727 output_asm_insn (\"stsr ctpsw, r10\", operands);
1728 output_asm_insn (\"st.w r10, 20[sp]\", operands);
1729 output_asm_insn (\"callt ctoff(__callt_save_interrupt)\", operands);
1732 [(set_attr "length" "26")
1733 (set_attr "cc" "none")])
1735 (define_insn "callt_return_interrupt"
1736 [(unspec_volatile [(const_int 0)] 3)]
1737 "TARGET_V850E && !TARGET_DISABLE_CALLT"
1738 "callt ctoff(__callt_return_interrupt)"
1739 [(set_attr "length" "2")
1740 (set_attr "cc" "clobber")])
1742 (define_insn "save_interrupt"
1743 [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16)))
1744 (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 30))
1745 (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 4))
1746 (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 1))
1747 (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 10))]
1751 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1752 return \"add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10\";
1755 output_asm_insn (\"add -16, sp\", operands);
1756 output_asm_insn (\"st.w r10, 12[sp]\", operands);
1757 output_asm_insn (\"st.w ep, 0[sp]\", operands);
1758 output_asm_insn (\"st.w gp, 4[sp]\", operands);
1759 output_asm_insn (\"st.w r1, 8[sp]\", operands);
1760 output_asm_insn (\"movhi hi(__ep), r0, ep\", operands);
1761 output_asm_insn (\"movea lo(__ep), ep, ep\", operands);
1762 output_asm_insn (\"movhi hi(__gp), r0, gp\", operands);
1763 output_asm_insn (\"movea lo(__gp), gp, gp\", operands);
1767 [(set (attr "length")
1768 (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1771 (set_attr "cc" "clobber")])
1773 ;; Restore r1, r4, r10, and return from the interrupt
1774 (define_insn "return_interrupt"
1776 (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 16)))
1777 (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
1778 (set (reg:SI 1) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
1779 (set (reg:SI 4) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))
1780 (set (reg:SI 30) (mem:SI (reg:SI 3)))]
1784 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1785 return \"jr __return_interrupt\";
1788 output_asm_insn (\"ld.w 0[sp], ep\", operands);
1789 output_asm_insn (\"ld.w 4[sp], gp\", operands);
1790 output_asm_insn (\"ld.w 8[sp], r1\", operands);
1791 output_asm_insn (\"ld.w 12[sp], r10\", operands);
1792 output_asm_insn (\"addi 16, sp, sp\", operands);
1793 output_asm_insn (\"reti\", operands);
1797 [(set (attr "length")
1798 (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1801 (set_attr "cc" "clobber")])
1803 ;; Save all registers except for the registers saved in save_interrupt when
1804 ;; an interrupt function makes a call.
1805 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1806 ;; all of memory. This blocks insns from being moved across this point.
1807 ;; This is needed because the rest of the compiler is not ready to handle
1808 ;; insns this complicated.
1810 (define_insn "callt_save_all_interrupt"
1811 [(unspec_volatile [(const_int 0)] 0)]
1812 "TARGET_V850E && !TARGET_DISABLE_CALLT"
1813 "callt ctoff(__callt_save_all_interrupt)"
1814 [(set_attr "length" "2")
1815 (set_attr "cc" "none")])
1817 (define_insn "save_all_interrupt"
1818 [(unspec_volatile [(const_int 0)] 0)]
1822 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1823 return \"jarl __save_all_interrupt,r10\";
1825 output_asm_insn (\"addi -120, sp, sp\", operands);
1826 output_asm_insn (\"mov ep, r1\", operands);
1827 output_asm_insn (\"mov sp, ep\", operands);
1828 output_asm_insn (\"sst.w r31, 116[ep]\", operands);
1829 output_asm_insn (\"sst.w r2, 112[ep]\", operands);
1830 output_asm_insn (\"sst.w gp, 108[ep]\", operands);
1831 output_asm_insn (\"sst.w r6, 104[ep]\", operands);
1832 output_asm_insn (\"sst.w r7, 100[ep]\", operands);
1833 output_asm_insn (\"sst.w r8, 96[ep]\", operands);
1834 output_asm_insn (\"sst.w r9, 92[ep]\", operands);
1835 output_asm_insn (\"sst.w r11, 88[ep]\", operands);
1836 output_asm_insn (\"sst.w r12, 84[ep]\", operands);
1837 output_asm_insn (\"sst.w r13, 80[ep]\", operands);
1838 output_asm_insn (\"sst.w r14, 76[ep]\", operands);
1839 output_asm_insn (\"sst.w r15, 72[ep]\", operands);
1840 output_asm_insn (\"sst.w r16, 68[ep]\", operands);
1841 output_asm_insn (\"sst.w r17, 64[ep]\", operands);
1842 output_asm_insn (\"sst.w r18, 60[ep]\", operands);
1843 output_asm_insn (\"sst.w r19, 56[ep]\", operands);
1844 output_asm_insn (\"sst.w r20, 52[ep]\", operands);
1845 output_asm_insn (\"sst.w r21, 48[ep]\", operands);
1846 output_asm_insn (\"sst.w r22, 44[ep]\", operands);
1847 output_asm_insn (\"sst.w r23, 40[ep]\", operands);
1848 output_asm_insn (\"sst.w r24, 36[ep]\", operands);
1849 output_asm_insn (\"sst.w r25, 32[ep]\", operands);
1850 output_asm_insn (\"sst.w r26, 28[ep]\", operands);
1851 output_asm_insn (\"sst.w r27, 24[ep]\", operands);
1852 output_asm_insn (\"sst.w r28, 20[ep]\", operands);
1853 output_asm_insn (\"sst.w r29, 16[ep]\", operands);
1854 output_asm_insn (\"mov r1, ep\", operands);
1857 [(set (attr "length")
1858 (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1862 (set_attr "cc" "clobber")])
1864 (define_insn "_save_all_interrupt"
1865 [(unspec_volatile [(const_int 0)] 0)]
1866 "TARGET_V850 && ! TARGET_LONG_CALLS"
1867 "jarl __save_all_interrupt,r10"
1868 [(set_attr "length" "4")
1869 (set_attr "cc" "clobber")])
1871 ;; Restore all registers saved when an interrupt function makes a call.
1872 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1873 ;; all of memory. This blocks insns from being moved across this point.
1874 ;; This is needed because the rest of the compiler is not ready to handle
1875 ;; insns this complicated.
1877 (define_insn "callt_restore_all_interrupt"
1878 [(unspec_volatile [(const_int 0)] 1)]
1879 "TARGET_V850E && !TARGET_DISABLE_CALLT"
1880 "callt ctoff(__callt_restore_all_interrupt)"
1881 [(set_attr "length" "2")
1882 (set_attr "cc" "none")])
1884 (define_insn "restore_all_interrupt"
1885 [(unspec_volatile [(const_int 0)] 1)]
1889 if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
1890 return \"jarl __restore_all_interrupt,r10\";
1893 output_asm_insn (\"mov ep, r1\", operands);
1894 output_asm_insn (\"mov sp, ep\", operands);
1895 output_asm_insn (\"sld.w 116[ep], r31\", operands);
1896 output_asm_insn (\"sld.w 112[ep], r2\", operands);
1897 output_asm_insn (\"sld.w 108[ep], gp\", operands);
1898 output_asm_insn (\"sld.w 104[ep], r6\", operands);
1899 output_asm_insn (\"sld.w 100[ep], r7\", operands);
1900 output_asm_insn (\"sld.w 96[ep], r8\", operands);
1901 output_asm_insn (\"sld.w 92[ep], r9\", operands);
1902 output_asm_insn (\"sld.w 88[ep], r11\", operands);
1903 output_asm_insn (\"sld.w 84[ep], r12\", operands);
1904 output_asm_insn (\"sld.w 80[ep], r13\", operands);
1905 output_asm_insn (\"sld.w 76[ep], r14\", operands);
1906 output_asm_insn (\"sld.w 72[ep], r15\", operands);
1907 output_asm_insn (\"sld.w 68[ep], r16\", operands);
1908 output_asm_insn (\"sld.w 64[ep], r17\", operands);
1909 output_asm_insn (\"sld.w 60[ep], r18\", operands);
1910 output_asm_insn (\"sld.w 56[ep], r19\", operands);
1911 output_asm_insn (\"sld.w 52[ep], r20\", operands);
1912 output_asm_insn (\"sld.w 48[ep], r21\", operands);
1913 output_asm_insn (\"sld.w 44[ep], r22\", operands);
1914 output_asm_insn (\"sld.w 40[ep], r23\", operands);
1915 output_asm_insn (\"sld.w 36[ep], r24\", operands);
1916 output_asm_insn (\"sld.w 32[ep], r25\", operands);
1917 output_asm_insn (\"sld.w 28[ep], r26\", operands);
1918 output_asm_insn (\"sld.w 24[ep], r27\", operands);
1919 output_asm_insn (\"sld.w 20[ep], r28\", operands);
1920 output_asm_insn (\"sld.w 16[ep], r29\", operands);
1921 output_asm_insn (\"mov r1, ep\", operands);
1922 output_asm_insn (\"addi 120, sp, sp\", operands);
1926 [(set (attr "length")
1927 (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
1931 (set_attr "cc" "clobber")])
1933 (define_insn "_restore_all_interrupt"
1934 [(unspec_volatile [(const_int 0)] 1)]
1935 "TARGET_V850 && ! TARGET_LONG_CALLS"
1936 "jarl __restore_all_interrupt,r10"
1937 [(set_attr "length" "4")
1938 (set_attr "cc" "clobber")])
1940 ;; Save r6-r9 for a variable argument function
1941 (define_insn "save_r6_r9_v850e"
1942 [(set (mem:SI (reg:SI 3)) (reg:SI 6))
1943 (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
1944 (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
1945 (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
1947 "TARGET_PROLOG_FUNCTION && TARGET_V850E && !TARGET_DISABLE_CALLT"
1948 "callt ctoff(__callt_save_r6_r9)"
1949 [(set_attr "length" "2")
1950 (set_attr "cc" "none")])
1952 (define_insn "save_r6_r9"
1953 [(set (mem:SI (reg:SI 3)) (reg:SI 6))
1954 (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
1955 (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
1956 (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
1957 (clobber (reg:SI 10))]
1958 "TARGET_PROLOG_FUNCTION && ! TARGET_LONG_CALLS"
1959 "jarl __save_r6_r9,r10"
1960 [(set_attr "length" "4")
1961 (set_attr "cc" "clobber")])